diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a9154dd444e72ced5810f139d61578a7f207b42d Binary files /dev/null and b/.DS_Store differ diff --git a/.env b/.env new file mode 100644 index 0000000000000000000000000000000000000000..c29658ada2722851eef3495ccf362b96e88a08db --- /dev/null +++ b/.env @@ -0,0 +1,19 @@ +LLM_PROVIDER=openai +LLM_API_BASE=http://localhost:11434/v1 +LLM_MODEL='mistral-large:123b-instruct-2407-q4_0' +LLM_API_KEY=12345 + +EMBEDDINGS_PROVIDER=openai +EMBEDDINGS_API_BASE=http://localhost:11434 +EMBEDDINGS_MODEL='snowflake-arctic-embed:335m' +EMBEDDINGS_API_KEY=12345 + + +GRAPHRAG_API_KEY=12345 +ROOT_DIR=indexing +INPUT_DIR=${ROOT_DIR}/output/${timestamp}/artifacts +LLM_SERVICE_TYPE=openai_chat +EMBEDDINGS_SERVICE_TYPE=openai_embedding + +API_URL=http://localhost:8012 +API_PORT=8012 diff --git a/.github/workflows/update_space.yml b/.github/workflows/update_space.yml new file mode 100644 index 0000000000000000000000000000000000000000..67dbc84e4e59320a7c98b94460eb976e5cd2984f --- /dev/null +++ b/.github/workflows/update_space.yml @@ -0,0 +1,28 @@ +name: Run Python script + +on: + push: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.9' + + - name: Install Gradio + run: python -m pip install gradio + + - name: Log in to Hugging Face + run: python -c 'import huggingface_hub; huggingface_hub.login(token="${{ secrets.hf_token }}")' + + - name: Deploy to Spaces + run: gradio deploy diff --git a/.gradio/certificate.pem b/.gradio/certificate.pem new file mode 100644 index 0000000000000000000000000000000000000000..b85c8037f6b60976b2546fdbae88312c5246d9a3 --- /dev/null +++ b/.gradio/certificate.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..13566b81b018ad684f3a35fee301741b2734c8f4 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/GraphRAG-Local-UI.iml b/.idea/GraphRAG-Local-UI.iml new file mode 100644 index 0000000000000000000000000000000000000000..5fdd65ba2a46cb8059b0b493295bcc0519d4eee1 --- /dev/null +++ b/.idea/GraphRAG-Local-UI.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000000000000000000000000000000000000..bc9df01841f3655b028f06e38bb2c44c597c92aa --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..105ce2da2d6447d11dfe32bfb846c3d5b199fc99 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000000000000000000000000000000000000..1f602427f2d84848dc454401a3029f53a8164261 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000000000000000000000000000000000000..5870f71d72c68dfddc3942fbe7875425a608241c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000000000000000000000000000000000000..cf39572ac24fea05e50e875e7d16785d073e17d5 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1730493860140 + + + + + + \ No newline at end of file diff --git a/API_README.md b/API_README.md new file mode 100644 index 0000000000000000000000000000000000000000..92f4240268736aa4a155eab8bac985bb66cba98c --- /dev/null +++ b/API_README.md @@ -0,0 +1,170 @@ +# GraphRAG API + +This README provides a detailed guide on the `api.py` file, which serves as the API interface for the GraphRAG (Graph Retrieval-Augmented Generation) system. GraphRAG is a powerful tool that combines graph-based knowledge representation with retrieval-augmented generation techniques to provide context-aware responses to queries. + +## Table of Contents + +1. [Overview](#overview) +2. [Setup](#setup) +3. [API Endpoints](#api-endpoints) +4. [Data Models](#data-models) +5. [Core Functionality](#core-functionality) +6. [Usage Examples](#usage-examples) +7. [Configuration](#configuration) +8. [Troubleshooting](#troubleshooting) + +## Overview + +The `api.py` file implements a FastAPI-based server that provides various endpoints for interacting with the GraphRAG system. It supports different types of queries, including direct chat, GraphRAG-specific queries, DuckDuckGo searches, and a combined full-model search. + +Key features: +- Multiple query types (local and global searches) +- Context caching for improved performance +- Background tasks for long-running operations +- Customizable settings through environment variables and config files +- Integration with external services (e.g., Ollama for LLM interactions) + +## Setup + +1. Install dependencies: + ``` + pip install -r requirements.txt + ``` + +2. Set up environment variables: + Create a `.env` file in the `indexing` directory with the following variables: + ``` + LLM_API_BASE= + LLM_MODEL= + LLM_PROVIDER= + EMBEDDINGS_API_BASE= + EMBEDDINGS_MODEL= + EMBEDDINGS_PROVIDER= + INPUT_DIR=./indexing/output + ROOT_DIR=indexing + API_PORT=8012 + ``` + +3. Run the API server: + ``` + python api.py --host 0.0.0.0 --port 8012 + ``` + +## API Endpoints + +### `/v1/chat/completions` (POST) +Main endpoint for chat completions. Supports different models: +- `direct-chat`: Direct interaction with the LLM +- `graphrag-local-search:latest`: Local search using GraphRAG +- `graphrag-global-search:latest`: Global search using GraphRAG +- `duckduckgo-search:latest`: Web search using DuckDuckGo +- `full-model:latest`: Combined search using all available models + +### `/v1/prompt_tune` (POST) +Initiates prompt tuning process in the background. + +### `/v1/prompt_tune_status` (GET) +Retrieves the status and logs of the prompt tuning process. + +### `/v1/index` (POST) +Starts the indexing process for GraphRAG in the background. + +### `/v1/index_status` (GET) +Retrieves the status and logs of the indexing process. + +### `/health` (GET) +Health check endpoint. + +### `/v1/models` (GET) +Lists available models. + +## Data Models + +The API uses several Pydantic models for request and response handling: + +- `Message`: Represents a chat message with role and content. +- `QueryOptions`: Options for GraphRAG queries, including query type, preset, and community level. +- `ChatCompletionRequest`: Request model for chat completions. +- `ChatCompletionResponse`: Response model for chat completions. +- `PromptTuneRequest`: Request model for prompt tuning. +- `IndexingRequest`: Request model for indexing. + +## Core Functionality + +### Context Loading +The `load_context` function loads necessary data for GraphRAG queries, including entities, relationships, reports, text units, and covariates. + +### Search Engine Setup +`setup_search_engines` initializes both local and global search engines using the loaded context data. + +### Query Execution +Different query types are handled by separate functions: +- `run_direct_chat`: Sends queries directly to the LLM. +- `run_graphrag_query`: Executes GraphRAG queries (local or global). +- `run_duckduckgo_search`: Performs web searches using DuckDuckGo. +- `run_full_model_search`: Combines results from all search types. + +### Background Tasks +Long-running tasks like prompt tuning and indexing are executed as background tasks to prevent blocking the API. + +## Usage Examples + +### Sending a GraphRAG Query +```python +import requests + +url = "http://localhost:8012/v1/chat/completions" +payload = { + "model": "graphrag-local-search:latest", + "messages": [{"role": "user", "content": "What is GraphRAG?"}], + "query_options": { + "query_type": "local-search", + "selected_folder": "your_indexed_folder", + "community_level": 2, + "response_type": "Multiple Paragraphs" + } +} +response = requests.post(url, json=payload) +print(response.json()) +``` + +### Starting Indexing Process +```python +import requests + +url = "http://localhost:8012/v1/index" +payload = { + "llm_model": "your_llm_model", + "embed_model": "your_embed_model", + "root": "./indexing", + "verbose": True, + "emit": ["parquet", "csv"] +} +response = requests.post(url, json=payload) +print(response.json()) +``` + +## Configuration + +The API can be configured through: +1. Environment variables +2. A `config.yaml` file (path specified by `GRAPHRAG_CONFIG` environment variable) +3. Command-line arguments when starting the server + +Key configuration options: +- `llm_model`: The language model to use +- `embedding_model`: The embedding model for vector representations +- `community_level`: Depth of community analysis in GraphRAG +- `token_limit`: Maximum tokens for context +- `api_key`: API key for LLM service +- `api_base`: Base URL for LLM API +- `api_type`: Type of API (e.g., "openai") + +## Troubleshooting + +1. If you encounter connection errors with Ollama, ensure the service is running and accessible. +2. For "context loading failed" errors, check that the indexed data is present in the specified output folder. +3. If prompt tuning or indexing processes fail, review the logs using the respective status endpoints. +4. For performance issues, consider adjusting the `community_level` and `token_limit` settings. + +For more detailed information on GraphRAG's indexing and querying processes, refer to the official GraphRAG documentation. \ No newline at end of file diff --git a/EMBEDDING_PROXY_README.md b/EMBEDDING_PROXY_README.md new file mode 100644 index 0000000000000000000000000000000000000000..4bc1dff164b5c81288b6050f5550ac3b8a40b216 --- /dev/null +++ b/EMBEDDING_PROXY_README.md @@ -0,0 +1,36 @@ +# Using Ollama Embeddings with GraphRAG: A Quick Guide + +## Problem + +GraphRAG is designed to work with OpenAI-compatible APIs for both language models and embeddings and Ollama currently has their own way of doing embeddings. + +## Solution: Embeddings Proxy + +To bridge this gap, let's use an embeddings proxy. This proxy acts as a middleware between GraphRAG and Ollama, translating Ollama's embedding responses into a format that GraphRAG expects. + +## Use the Embeddings Proxy + +1. **Set up the proxy:** + - Save the provided `embedding_proxy.py` script to your project directory. + - Install required dependencies (not needed if you've already done this in the normal setup): `pip install fastapi uvicorn httpx` + +2. **Run the proxy:** + ```bash + python embedding_proxy.py --port 11435 --host http://localhost:11434 + ``` + This starts the proxy on port 11435, connecting to Ollama at localhost:11434. + +3. **Configure GraphRAG:** + Update your `settings.yaml` file to use the proxy for embeddings: + + ```yaml + embeddings: + llm: + api_key: ${GRAPHRAG_API_KEY} + type: openai_embedding + model: nomic-embed-text:latest + api_base: http://localhost:11435 # Point to your proxy + ``` + +4. **Run GraphRAG:** + With the proxy running and the configuration updated, you can now run GraphRAG as usual. It will use Ollama for embeddings through the proxy. diff --git a/INDEX_APP_README.md b/INDEX_APP_README.md new file mode 100644 index 0000000000000000000000000000000000000000..59ecc0d685aa3a32045c60e118af903c73cd14ea --- /dev/null +++ b/INDEX_APP_README.md @@ -0,0 +1,127 @@ +# GraphRAG Indexer Application + +## Table of Contents +1. [Introduction](#introduction) +2. [Setup](#setup) +3. [Application Structure](#application-structure) +4. [Indexing](#indexing) +5. [Prompt Tuning](#prompt-tuning) +6. [Data Management](#data-management) +7. [Configuration](#configuration) +8. [API Integration](#api-integration) +9. [Troubleshooting](#troubleshooting) + +## Introduction + +The GraphRAG Indexer Application is a Gradio-based user interface for managing the indexing and prompt tuning processes of the GraphRAG (Graph Retrieval-Augmented Generation) system. This application provides an intuitive way to configure, run, and monitor indexing and prompt tuning tasks, as well as manage related data files. + +## Setup + +1. Ensure you have Python 3.7+ installed. +2. Install required dependencies: + ``` + pip install gradio requests pydantic python-dotenv pyyaml pandas lancedb + ``` +3. Set up environment variables in `indexing/.env`: + ``` + API_BASE_URL=http://localhost:8012 + LLM_API_BASE=http://localhost:11434 + EMBEDDINGS_API_BASE=http://localhost:11434 + ROOT_DIR=indexing + ``` +4. Run the application: + ``` + python index_app.py + ``` + +## Application Structure + +The application is divided into three main tabs: +1. Indexing +2. Prompt Tuning +3. Data Management + +Each tab provides specific functionality related to its purpose. + +## Indexing + +The Indexing tab allows users to configure and run the GraphRAG indexing process. + +### Features: +- Select LLM and Embedding models +- Set root directory for indexing +- Configure verbose and cache options +- Advanced options for resuming, reporting, and output formats +- Run indexing and check status + +### Usage: +1. Select the desired LLM and Embedding models from the dropdowns. +2. Set the root directory for indexing. +3. Configure additional options as needed. +4. Click "Run Indexing" to start the process. +5. Use "Check Indexing Status" to monitor progress. + +## Prompt Tuning + +The Prompt Tuning tab enables users to configure and run prompt tuning for GraphRAG. + +### Features: +- Set root directory and domain +- Choose tuning method (random, top, all) +- Configure limit, language, max tokens, and chunk size +- Option to exclude entity types +- Run prompt tuning and check status + +### Usage: +1. Set the root directory and optional domain. +2. Choose the tuning method and configure parameters. +3. Click "Run Prompt Tuning" to start the process. +4. Use "Check Prompt Tuning Status" to monitor progress. + +## Data Management + +The Data Management tab provides tools for managing input files and viewing output folders. + +### Features: +- File upload functionality +- File list management (view, refresh, delete) +- Output folder exploration +- File content viewing and editing + +### Usage: +1. Use the File Upload section to add new input files. +2. Manage existing files in the File Management section. +3. Explore output folders and their contents in the Output Folders section. + +## Configuration + +The application uses a combination of environment variables and a `config.yaml` file for configuration. Key settings include: + +- LLM and Embedding models +- API endpoints +- Community level for GraphRAG +- Token limits +- API keys and types + +To modify these settings, edit the `.env` file or create a `config.yaml` file in the root directory. + +## API Integration + +The application integrates with a backend API for executing indexing and prompt tuning tasks. Key API endpoints used: + +- `/v1/index`: Start indexing process +- `/v1/index_status`: Check indexing status +- `/v1/prompt_tune`: Start prompt tuning process +- `/v1/prompt_tune_status`: Check prompt tuning status + +These endpoints are called using the `requests` library, with appropriate error handling and logging. + +## Troubleshooting + +Common issues and solutions: + +1. **Model loading fails**: Ensure the LLM_API_BASE is correctly set and the API is accessible. +2. **Indexing or Prompt Tuning doesn't start**: Check API connectivity and verify that all required fields are filled. +3. **File management issues**: Ensure proper read/write permissions in the ROOT_DIR. + +For any persistent issues, check the application logs (visible in the console) for detailed error messages. \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..d0f08b2b037f2b6c22beb433aa39156fa0cd8eee --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Beckett + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index bfdc87d079c89b785b770f08569ae5226b0b54c6..f770be411ceee83ec001a951f026981689cf476a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,268 @@ --- -title: GraphRAG Local UI -emoji: 🏆 -colorFrom: green -colorTo: red +title: GraphRAG-Local-UI +app_file: index_app.py sdk: gradio sdk_version: 5.4.0 -app_file: app.py -pinned: false --- +# 🕸️ GraphRAG Local -Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference +Welcome to **GraphRAG Local with Index/Prompt-Tuning and Querying/Chat UIs**! This project is an adaptation of Microsoft's [GraphRAG](https://github.com/microsoft/graphrag), tailored to support local models and featuring a comprehensive interactive user interface ecosystem. + +## 📄 Research Paper + +For more details on the original GraphRAG implementation, please refer to the [GraphRAG paper](https://arxiv.org/pdf/2404.16130). + +## 🌟 Features + +- **API-Centric Architecture:** A robust FastAPI-based server (`api.py`) serving as the core of the GraphRAG operations. +- **Dedicated Indexing and Prompt Tuning UI:** A separate Gradio-based interface (`index_app.py`) for managing indexing and prompt tuning processes. +- **Local Model Support:** Leverage local models for LLM and embeddings, including compatibility with Ollama and OpenAI-compatible APIs. +- **Cost-Effective:** Eliminate dependency on costly cloud-based models by using your own local models. +- **Interactive UI:** User-friendly interface for managing data, running queries, and visualizing results (main app). +- **Real-time Graph Visualization:** Visualize your knowledge graph in 2D or 3D using Plotly (main app). +- **File Management:** Upload, view, edit, and delete input files directly from the UI. +- **Settings Management:** Easily update and manage your GraphRAG settings through the UI. +- **Output Exploration:** Browse and view indexing outputs and artifacts. +- **Logging:** Real-time logging for better debugging and monitoring. +- **Flexible Querying:** Support for global, local, and direct chat queries with customizable parameters (main app). +- **Customizable Visualization:** Adjust graph layout, node sizes, colors, and more to suit your preferences (main app). + +![GraphRAG UI](uiv3.png) + +## 🗺️ Roadmap + +### **Important Note:** *Updates have been slow due to the day job and lack of immediate time, but I promise I am working on errors/issues in the background when able to. Please feel free to contribute/create a PR if you want to help out and find a great solution to an issue presented.* +**The GraphRAG Local UI ecosystem is currently undergoing a major transition. While the main app remains functional, I am actively developing separate applications for Indexing/Prompt Tuning and Querying/Chat, all built around a robust central API. Users should expect some changes and potential instability during this transition period.** + +*While it is currently functional, it has only been primarily tested on a Mac Studio M2.* + +My vision for the GraphRAG Local UI ecosystem is to become the ultimate set of tools for working with GraphRAG and local LLMs, incorporating as many cool features and knowledge graph tools as possible. I am continuously working on improvements and new features. + +### Recent Updates +- [x] New API-centric architecture (`api.py`) +- [x] Dedicated Indexing and Prompt Tuning UI (`index_app.py`) +- [x] Improved file management and output exploration +- [x] Background task handling for long-running operations +- [x] Enhanced configuration options through environment variables and YAML files + +### Upcoming Features +- [ ] Dedicated Querying/Chat UI that interacts with the API +- [ ] Dockerfile for easier deployment +- [ ] Launch your own GraphRAG API server for use in external applications +- [ ] Experimental: Mixture of Agents for Indexing/Query of knowledge graph +- [ ] Support for more file formats (CSV, PDF, etc.) +- [ ] Web search/Scraping capabilities +- [ ] Advanced graph analysis tools +- [ ] Integration with popular knowledge management tools +- [ ] Collaborative features for team-based knowledge graph building + +I am committed to making the GraphRAG Local UI ecosystem the most comprehensive and user-friendly toolset for working with knowledge graphs and LLMs. Your feedback and suggestions are much needed in shaping the future of this project. + +Feel free to open an Issue if you run into an error, and I will try to address it as soon as possible to minimize any downtime you might experience. + +--- + +## 📦 Installation and Setup + +Follow these steps to set up and run the GraphRAG Local UI ecosystem: + +1. **Create and activate a new conda environment:** + ```bash + conda create -n graphrag-local -y + conda activate graphrag-local + ``` + +2. **Install the required packages:** + + First install the GraphRAG dir from this repo (has changes not present in the Microsoft repo): + + ```bash + pip install -e ./graphrag + ``` + + Then install the rest of the dependencies: + + ```bash + pip install -r requirements.txt + ``` + +3. **Launch the API server:** + ```bash + python api.py --host 0.0.0.0 --port 8012 --reload + ``` + +4. **If using Ollama for embeddings, launch the embedding proxy:** + ```bash + python embedding_proxy.py --port 11435 --host http://localhost:11434 + ``` + Note: For detailed instructions on using Ollama embeddings with GraphRAG, refer to the EMBEDDING_PROXY_README.md file. + +5. **Launch the Indexing and Prompt Tuning UI:** + ```bash + gradio index_app.py + ``` + +6. **Launch the main interactive UI (legacy app):** + ```bash + gradio app.py + ``` + or + ```bash + python app.py + ``` + +7. **Access the UIs:** + - Indexing and Prompt Tuning UI: Open your web browser and navigate to `http://localhost:7861` + - Main UI (legacy): Open your web browser and navigate to `http://localhost:7860` + +--- + +## 🚀 Getting Started with GraphRAG Local + +GraphRAG is designed for flexibility, allowing you to quickly create and initialize your own indexing directory. Follow these steps to set up your environment: + +### 1. Create the Indexing Directory + +This repo comes with a pre-made Indexing folder but you may want to make your own, so here are the steps. First, create the required directory structure for your input data and indexing results: + +```bash +mkdir -p ./indexing/input +``` + +This directory will store: +- Input .txt files for indexing +- Output results +- Prompts for Prompt Tuning + +### 2. Add Sample Data (Optional) + +If you want to start with sample data, copy it to your new input directory: + +```bash +cp input/* ./indexing/input +``` + +You can also add your own .txt files to this directory for indexing. + +### 3. Initialize the Indexing Folder + +Run the following command to initialize the ./indexing folder with the required files: + +```bash +python -m graphrag.index --init --root ./indexing +``` + +### 4. Configure Settings + +Move the pre-configured `settings.yaml` file to your indexing directory: + +```bash +mv settings.yaml ./indexing +``` + +This file contains the main configuration, pre-set for use with local models. + +### 5. Customization + +You can customize your setup by modifying the following environment variables: +- `ROOT_DIR`: Points to your main indexing directory +- `INPUT_DIR`: Specifies the location of your input files + +### 📚 Additional Resources + +For more detailed information and advanced usage, refer to the [official GraphRAG documentation](https://microsoft.github.io/graphrag/posts/get_started/). + +--- + +## 🖥️ GraphRAG Application Ecosystem + +The GraphRAG Local UI ecosystem consists of three main components, each serving a specific purpose in the knowledge graph creation and querying process: + +### 1. Core API (`api.py`) + +The `api.py` file serves as the backbone of the GraphRAG system, providing a robust FastAPI-based server that handles all core operations. + +Key features: +- Manages indexing and prompt tuning processes +- Handles various query types (local, global, and direct chat) +- Integrates with local LLM and embedding models +- Provides endpoints for file management and system configuration + +Usage: +```bash +python api.py --host 0.0.0.0 --port 8012 --reload +``` + +Note: If using Ollama for embeddings, make sure to run the embedding proxy (`embedding_proxy.py`) alongside `api.py`. Refer to the EMBEDDING_PROXY_README.md for detailed instructions. + +### 2. Indexing and Prompt Tuning UI (`index_app.py`) + +#### Workflow Integration + +1. Start the Core API (`api.py`) to enable backend functionality. +2. If using Ollama for embeddings, start the embedding proxy (`embedding_proxy.py`). +3. Use the Indexing and Prompt Tuning UI (`index_app.py`) to prepare your data and fine-tune the system. +4. (Optional) Use the Main Interactive UI (`app.py`) for visualization and legacy features. + +This modular approach allows for greater flexibility and easier maintenance of the GraphRAG system. As development continues, the functionality of `app.py` will be gradually integrated into new, specialized interfaces that interact with the core API. + +### 2. Indexing and Prompt Tuning UI (`index_app.py`) + +The `index_app.py` file provides a user-friendly Gradio interface for managing the indexing and prompt tuning processes. + +Key features: +- Configure and run indexing tasks +- Set up and execute prompt tuning +- Manage input files and explore output data +- Adjust LLM and embedding settings + +Usage: +```bash +python index_app.py +``` +Access the UI at `http://localhost:7861` + +### 3. Main Interactive UI (Legacy App) (`app.py`) + +The `app.py` file is the pre-existing main application, which is being phased out but still provides useful functionality. + +Key features: +- Visualize knowledge graphs in 2D or 3D +- Run queries and view results +- Manage GraphRAG settings +- Explore indexed data + +Usage: +```bash +python app.py +``` +or +```bash +gradio app.py +``` +Access the UI at `http://localhost:7860` + +### Workflow Integration + +1. Start the Core API (`api.py`) to enable backend functionality. +2. Use the Indexing and Prompt Tuning UI (`index_app.py`) to prepare your data and fine-tune the system. +3. (Optional) Use the Main Interactive UI (`app.py`) for visualization and legacy features. + +This modular approach allows for greater flexibility and easier maintenance of the GraphRAG system. As development continues, the functionality of `app.py` will be gradually integrated into new, specialized interfaces that interact with the core API. + +--- + +## 📚 Citations + +- Original GraphRAG repository by Microsoft: [GraphRAG](https://github.com/microsoft/graphrag) +- This project took inspiration and used the GraphRAG4OpenWebUI repository by win4r (https://github.com/win4r/GraphRAG4OpenWebUI) as a starting point for the API implementation. + +--- + +## Troubleshooting + +- If you encounter any issues with the new API or Indexing UI, please check the console logs for detailed error messages. +- For the main app, if you can't run `gradio app.py`, try running `pip install --upgrade gradio` and then exit out and start a new terminal. It should then load and launch properly as a Gradio app. +- On Windows, if you run into an encoding/UTF error, you can change it to the correct format in the YAML Settings menu. + +For any issues or feature requests, please open an issue on the GitHub repository. Happy knowledge graphing! diff --git a/__pycache__/api.cpython-312.pyc b/__pycache__/api.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f7cea4ceaf192b2603e87ef677030c803de49c58 Binary files /dev/null and b/__pycache__/api.cpython-312.pyc differ diff --git a/__pycache__/app.cpython-312.pyc b/__pycache__/app.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f0327044e28fde1ec60748aca8d3b0b1d1748a98 Binary files /dev/null and b/__pycache__/app.cpython-312.pyc differ diff --git a/__pycache__/embedding_proxy.cpython-312.pyc b/__pycache__/embedding_proxy.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4eec950876999db1edddc8f34d25e0f9d5e0ffa9 Binary files /dev/null and b/__pycache__/embedding_proxy.cpython-312.pyc differ diff --git a/__pycache__/index_app.cpython-311.pyc b/__pycache__/index_app.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1bb21bab19146cbad2f33741a8ce403bd40f3fb7 Binary files /dev/null and b/__pycache__/index_app.cpython-311.pyc differ diff --git a/__pycache__/web.cpython-311.pyc b/__pycache__/web.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd784505d2d089d4f7e1a53ad107147c605b8138 Binary files /dev/null and b/__pycache__/web.cpython-311.pyc differ diff --git a/__pycache__/web.cpython-312.pyc b/__pycache__/web.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..44ba6c590a37974372ea8911911c8dc0d21ea770 Binary files /dev/null and b/__pycache__/web.cpython-312.pyc differ diff --git a/api.py b/api.py new file mode 100644 index 0000000000000000000000000000000000000000..3dbe0dc61b260b4bdd12756b313b6e252d6dd896 --- /dev/null +++ b/api.py @@ -0,0 +1,943 @@ +from dotenv import load_dotenv +import os +import asyncio +import tempfile +from collections import deque +import time +import uuid +import json +import re +import pandas as pd +import tiktoken +import logging +import yaml +import shutil +from fastapi import Body +from fastapi import FastAPI, HTTPException, Request, BackgroundTasks, Depends +from fastapi.responses import JSONResponse, StreamingResponse +from pydantic import BaseModel, Field +from typing import List, Optional, Dict, Any, Union +from contextlib import asynccontextmanager +from web import DuckDuckGoSearchAPIWrapper +from functools import lru_cache +import requests +import subprocess +import argparse + +# GraphRAG related imports +from graphrag.query.context_builder.entity_extraction import EntityVectorStoreKey +from graphrag.query.indexer_adapters import ( + read_indexer_covariates, + read_indexer_entities, + read_indexer_relationships, + read_indexer_reports, + read_indexer_text_units, +) +from graphrag.query.input.loaders.dfs import store_entity_semantic_embeddings +from graphrag.query.llm.oai.chat_openai import ChatOpenAI +from graphrag.query.llm.oai.embedding import OpenAIEmbedding +from graphrag.query.llm.oai.typing import OpenaiApiType +from graphrag.query.question_gen.local_gen import LocalQuestionGen +from graphrag.query.structured_search.local_search.mixed_context import LocalSearchMixedContext +from graphrag.query.structured_search.local_search.search import LocalSearch +from graphrag.query.structured_search.global_search.community_context import GlobalCommunityContext +from graphrag.query.structured_search.global_search.search import GlobalSearch +from graphrag.vector_stores.lancedb import LanceDBVectorStore + +# Set up logging +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') +logger = logging.getLogger(__name__) + +# Load environment variables +load_dotenv('indexing/.env') +LLM_API_BASE = os.getenv('LLM_API_BASE', '') +LLM_MODEL = os.getenv('LLM_MODEL') +LLM_PROVIDER = os.getenv('LLM_PROVIDER', 'openai').lower() +EMBEDDINGS_API_BASE = os.getenv('EMBEDDINGS_API_BASE', '') +EMBEDDINGS_MODEL = os.getenv('EMBEDDINGS_MODEL') +EMBEDDINGS_PROVIDER = os.getenv('EMBEDDINGS_PROVIDER', 'openai').lower() +INPUT_DIR = os.getenv('INPUT_DIR', './indexing/output') +ROOT_DIR = os.getenv('ROOT_DIR', 'indexing') +PORT = int(os.getenv('API_PORT', 8012)) +LANCEDB_URI = f"{INPUT_DIR}/lancedb" +COMMUNITY_REPORT_TABLE = "create_final_community_reports" +ENTITY_TABLE = "create_final_nodes" +ENTITY_EMBEDDING_TABLE = "create_final_entities" +RELATIONSHIP_TABLE = "create_final_relationships" +COVARIATE_TABLE = "create_final_covariates" +TEXT_UNIT_TABLE = "create_final_text_units" +COMMUNITY_LEVEL = 2 + +# Global variables for storing search engines and question generator +local_search_engine = None +global_search_engine = None +question_generator = None + +# Data models +class Message(BaseModel): + role: str + content: str + +class QueryOptions(BaseModel): + query_type: str + preset: Optional[str] = None + community_level: Optional[int] = None + response_type: Optional[str] = None + custom_cli_args: Optional[str] = None + selected_folder: Optional[str] = None + +class ChatCompletionRequest(BaseModel): + model: str + messages: List[Message] + temperature: Optional[float] = 0.7 + max_tokens: Optional[int] = None + stream: Optional[bool] = False + query_options: Optional[QueryOptions] = None + +class ChatCompletionResponseChoice(BaseModel): + index: int + message: Message + finish_reason: Optional[str] = None + +class Usage(BaseModel): + prompt_tokens: int + completion_tokens: int + total_tokens: int + +class ChatCompletionResponse(BaseModel): + id: str = Field(default_factory=lambda: f"chatcmpl-{uuid.uuid4().hex}") + object: str = "chat.completion" + created: int = Field(default_factory=lambda: int(time.time())) + model: str + choices: List[ChatCompletionResponseChoice] + usage: Usage + system_fingerprint: Optional[str] = None + +def list_output_folders(): + return [f for f in os.listdir(INPUT_DIR) if os.path.isdir(os.path.join(INPUT_DIR, f))] + +def list_folder_contents(folder_name): + folder_path = os.path.join(INPUT_DIR, folder_name, "artifacts") + if not os.path.exists(folder_path): + return [] + return [item for item in os.listdir(folder_path) if item.endswith('.parquet')] + +def normalize_api_base(api_base: str) -> str: + """Normalize the API base URL by removing trailing slashes and /v1 or /api suffixes.""" + api_base = api_base.rstrip('/') + if api_base.endswith('/v1') or api_base.endswith('/api'): + api_base = api_base[:-3] + return api_base + +def get_models_endpoint(api_base: str, api_type: str) -> str: + """Get the appropriate models endpoint based on the API type.""" + normalized_base = normalize_api_base(api_base) + if api_type.lower() == 'openai': + return f"{normalized_base}/v1/models" + elif api_type.lower() == 'azure': + return f"{normalized_base}/openai/deployments?api-version=2022-12-01" + else: # For other API types (e.g., local LLMs) + return f"{normalized_base}/models" + +async def fetch_available_models(settings: Dict[str, Any]) -> List[str]: + """Fetch available models from the API.""" + api_base = settings['api_base'] + api_type = settings['api_type'] + api_key = settings['api_key'] + + models_endpoint = get_models_endpoint(api_base, api_type) + headers = {"Authorization": f"Bearer {api_key}"} if api_key else {} + + try: + response = requests.get(models_endpoint, headers=headers, timeout=10) + response.raise_for_status() + data = response.json() + + if api_type.lower() == 'openai': + return [model['id'] for model in data['data']] + elif api_type.lower() == 'azure': + return [model['id'] for model in data['value']] + else: + # Adjust this based on the actual response format of your local LLM API + return [model['name'] for model in data['models']] + except requests.exceptions.RequestException as e: + logger.error(f"Error fetching models: {str(e)}") + return [] + +def load_settings(): + config_path = os.getenv('GRAPHRAG_CONFIG', 'config.yaml') + if os.path.exists(config_path): + with open(config_path, 'r') as config_file: + config = yaml.safe_load(config_file) + else: + config = {} + + settings = { + 'llm_model': os.getenv('LLM_MODEL', config.get('llm_model')), + 'embedding_model': os.getenv('EMBEDDINGS_MODEL', config.get('embedding_model')), + 'community_level': int(os.getenv('COMMUNITY_LEVEL', config.get('community_level', 2))), + 'token_limit': int(os.getenv('TOKEN_LIMIT', config.get('token_limit', 4096))), + 'api_key': os.getenv('GRAPHRAG_API_KEY', config.get('api_key')), + 'api_base': os.getenv('LLM_API_BASE', config.get('api_base')), + 'embeddings_api_base': os.getenv('EMBEDDINGS_API_BASE', config.get('embeddings_api_base')), + 'api_type': os.getenv('API_TYPE', config.get('api_type', 'openai')), + } + + return settings + + return settings + +async def setup_llm_and_embedder(settings): + logger.info("Setting up LLM and embedder") + try: + llm = ChatOpenAI( + api_key=settings['api_key'], + api_base=f"{settings['api_base']}/v1", + model=settings['llm_model'], + api_type=OpenaiApiType[settings['api_type'].capitalize()], + max_retries=20, + ) + + token_encoder = tiktoken.get_encoding("cl100k_base") + + text_embedder = OpenAIEmbedding( + api_key=settings['api_key'], + api_base=f"{settings['embeddings_api_base']}/v1", + api_type=OpenaiApiType[settings['api_type'].capitalize()], + model=settings['embedding_model'], + deployment_name=settings['embedding_model'], + max_retries=20, + ) + + logger.info("LLM and embedder setup complete") + return llm, token_encoder, text_embedder + except Exception as e: + logger.error(f"Error setting up LLM and embedder: {str(e)}") + raise HTTPException(status_code=500, detail=f"Failed to set up LLM and embedder: {str(e)}") + +async def load_context(selected_folder, settings): + """ + Load context data including entities, relationships, reports, text units, and covariates + """ + logger.info("Loading context data") + try: + input_dir = os.path.join(INPUT_DIR, selected_folder, "artifacts") + entity_df = pd.read_parquet(f"{input_dir}/{ENTITY_TABLE}.parquet") + entity_embedding_df = pd.read_parquet(f"{input_dir}/{ENTITY_EMBEDDING_TABLE}.parquet") + entities = read_indexer_entities(entity_df, entity_embedding_df, settings['community_level']) + + description_embedding_store = LanceDBVectorStore(collection_name="entity_description_embeddings") + description_embedding_store.connect(db_uri=LANCEDB_URI) + store_entity_semantic_embeddings(entities=entities, vectorstore=description_embedding_store) + + relationship_df = pd.read_parquet(f"{input_dir}/{RELATIONSHIP_TABLE}.parquet") + relationships = read_indexer_relationships(relationship_df) + + report_df = pd.read_parquet(f"{input_dir}/{COMMUNITY_REPORT_TABLE}.parquet") + reports = read_indexer_reports(report_df, entity_df, COMMUNITY_LEVEL) + + text_unit_df = pd.read_parquet(f"{input_dir}/{TEXT_UNIT_TABLE}.parquet") + text_units = read_indexer_text_units(text_unit_df) + + covariate_df = pd.read_parquet(f"{input_dir}/{COVARIATE_TABLE}.parquet") + claims = read_indexer_covariates(covariate_df) + logger.info(f"Number of claim records: {len(claims)}") + covariates = {"claims": claims} + + logger.info("Context data loading complete") + return entities, relationships, reports, text_units, description_embedding_store, covariates + except Exception as e: + logger.error(f"Error loading context data: {str(e)}") + raise + +async def setup_search_engines(llm, token_encoder, text_embedder, entities, relationships, reports, text_units, + description_embedding_store, covariates): + """ + Set up local and global search engines + """ + logger.info("Setting up search engines") + + # Set up local search engine + local_context_builder = LocalSearchMixedContext( + community_reports=reports, + text_units=text_units, + entities=entities, + relationships=relationships, + covariates=covariates, + entity_text_embeddings=description_embedding_store, + embedding_vectorstore_key=EntityVectorStoreKey.ID, + text_embedder=text_embedder, + token_encoder=token_encoder, + ) + + local_context_params = { + "text_unit_prop": 0.5, + "community_prop": 0.1, + "conversation_history_max_turns": 5, + "conversation_history_user_turns_only": True, + "top_k_mapped_entities": 10, + "top_k_relationships": 10, + "include_entity_rank": True, + "include_relationship_weight": True, + "include_community_rank": False, + "return_candidate_context": False, + "embedding_vectorstore_key": EntityVectorStoreKey.ID, + "max_tokens": 12_000, + } + + local_llm_params = { + "max_tokens": 2_000, + "temperature": 0.0, + } + + local_search_engine = LocalSearch( + llm=llm, + context_builder=local_context_builder, + token_encoder=token_encoder, + llm_params=local_llm_params, + context_builder_params=local_context_params, + response_type="multiple paragraphs", + ) + + # Set up global search engine + global_context_builder = GlobalCommunityContext( + community_reports=reports, + entities=entities, + token_encoder=token_encoder, + ) + + global_context_builder_params = { + "use_community_summary": False, + "shuffle_data": True, + "include_community_rank": True, + "min_community_rank": 0, + "community_rank_name": "rank", + "include_community_weight": True, + "community_weight_name": "occurrence weight", + "normalize_community_weight": True, + "max_tokens": 12_000, + "context_name": "Reports", + } + + map_llm_params = { + "max_tokens": 1000, + "temperature": 0.0, + "response_format": {"type": "json_object"}, + } + + reduce_llm_params = { + "max_tokens": 2000, + "temperature": 0.0, + } + + global_search_engine = GlobalSearch( + llm=llm, + context_builder=global_context_builder, + token_encoder=token_encoder, + max_data_tokens=12_000, + map_llm_params=map_llm_params, + reduce_llm_params=reduce_llm_params, + allow_general_knowledge=False, + json_mode=True, + context_builder_params=global_context_builder_params, + concurrent_coroutines=32, + response_type="multiple paragraphs", + ) + + logger.info("Search engines setup complete") + return local_search_engine, global_search_engine, local_context_builder, local_llm_params, local_context_params + +def format_response(response): + """ + Format the response by adding appropriate line breaks and paragraph separations. + """ + paragraphs = re.split(r'\n{2,}', response) + + formatted_paragraphs = [] + for para in paragraphs: + if '```' in para: + parts = para.split('```') + for i, part in enumerate(parts): + if i % 2 == 1: # This is a code block + parts[i] = f"\n```\n{part.strip()}\n```\n" + para = ''.join(parts) + else: + para = para.replace('. ', '.\n') + + formatted_paragraphs.append(para.strip()) + + return '\n\n'.join(formatted_paragraphs) + +@asynccontextmanager +async def lifespan(app: FastAPI): + global settings + try: + logger.info("Loading settings...") + settings = load_settings() + logger.info("Settings loaded successfully.") + except Exception as e: + logger.error(f"Error loading settings: {str(e)}") + raise + + yield + + logger.info("Shutting down...") + +app = FastAPI(lifespan=lifespan) + +# Create a cache for loaded contexts +context_cache = {} + +@lru_cache() +def get_settings(): + return load_settings() + +async def get_context(selected_folder: str, settings: dict = Depends(get_settings)): + if selected_folder not in context_cache: + try: + llm, token_encoder, text_embedder = await setup_llm_and_embedder(settings) + entities, relationships, reports, text_units, description_embedding_store, covariates = await load_context(selected_folder, settings) + local_search_engine, global_search_engine, local_context_builder, local_llm_params, local_context_params = await setup_search_engines( + llm, token_encoder, text_embedder, entities, relationships, reports, text_units, + description_embedding_store, covariates + ) + question_generator = LocalQuestionGen( + llm=llm, + context_builder=local_context_builder, + token_encoder=token_encoder, + llm_params=local_llm_params, + context_builder_params=local_context_params, + ) + context_cache[selected_folder] = { + "local_search_engine": local_search_engine, + "global_search_engine": global_search_engine, + "question_generator": question_generator + } + except Exception as e: + logger.error(f"Error loading context for folder {selected_folder}: {str(e)}") + raise HTTPException(status_code=500, detail=f"Failed to load context for folder {selected_folder}") + + return context_cache[selected_folder] + +@app.post("/v1/chat/completions") +async def chat_completions(request: ChatCompletionRequest): + try: + logger.info(f"Received request for model: {request.model}") + if request.model == "direct-chat": + logger.info("Routing to direct chat") + return await run_direct_chat(request) + elif request.model.startswith("graphrag-"): + logger.info("Routing to GraphRAG query") + if not request.query_options or not request.query_options.selected_folder: + raise HTTPException(status_code=400, detail="Selected folder is required for GraphRAG queries") + return await run_graphrag_query(request) + elif request.model == "duckduckgo-search:latest": + logger.info("Routing to DuckDuckGo search") + return await run_duckduckgo_search(request) + elif request.model == "full-model:latest": + logger.info("Routing to full model search") + return await run_full_model_search(request) + else: + raise HTTPException(status_code=400, detail=f"Invalid model specified: {request.model}") + except HTTPException as he: + logger.error(f"HTTP Exception: {str(he)}") + raise he + except Exception as e: + logger.error(f"Error in chat completion: {str(e)}", exc_info=True) + raise HTTPException(status_code=500, detail=str(e)) + +async def run_direct_chat(request: ChatCompletionRequest) -> ChatCompletionResponse: + try: + if not LLM_API_BASE: + raise ValueError("LLM_API_BASE environment variable is not set") + + headers = {"Content-Type": "application/json"} + + payload = { + "model": LLM_MODEL, + "messages": [{"role": msg.role, "content": msg.content} for msg in request.messages], + "stream": False + } + + # Optional parameters + if request.temperature is not None: + payload["temperature"] = request.temperature + if request.max_tokens is not None: + payload["max_tokens"] = request.max_tokens + + full_url = f"{normalize_api_base(LLM_API_BASE)}/v1/chat/completions" + + logger.info(f"Sending request to: {full_url}") + logger.info(f"Payload: {payload}") + + try: + response = requests.post(full_url, json=payload, headers=headers, timeout=10) + response.raise_for_status() + except requests.exceptions.RequestException as req_ex: + logger.error(f"Request to LLM API failed: {str(req_ex)}") + if isinstance(req_ex, requests.exceptions.ConnectionError): + raise HTTPException(status_code=503, detail="Unable to connect to LLM API. Please check your API settings.") + elif isinstance(req_ex, requests.exceptions.Timeout): + raise HTTPException(status_code=504, detail="Request to LLM API timed out") + else: + raise HTTPException(status_code=500, detail=f"Request to LLM API failed: {str(req_ex)}") + + result = response.json() + logger.info(f"Received response: {result}") + + content = result['choices'][0]['message']['content'] + + return ChatCompletionResponse( + model=LLM_MODEL, + choices=[ + ChatCompletionResponseChoice( + index=0, + message=Message( + role="assistant", + content=content + ), + finish_reason=None + ) + ], + usage=None + ) + except HTTPException as he: + logger.error(f"HTTP Exception in direct chat: {str(he)}") + raise he + except Exception as e: + logger.error(f"Unexpected error in direct chat: {str(e)}") + raise HTTPException(status_code=500, detail=f"An unexpected error occurred during the direct chat: {str(e)}") + +def get_embeddings(text: str) -> List[float]: + settings = load_settings() + embeddings_api_base = settings['embeddings_api_base'] + + headers = {"Content-Type": "application/json"} + + if EMBEDDINGS_PROVIDER == 'ollama': + payload = { + "model": EMBEDDINGS_MODEL, + "prompt": text + } + full_url = f"{embeddings_api_base}/api/embeddings" + else: # OpenAI-compatible API + payload = { + "model": EMBEDDINGS_MODEL, + "input": text + } + full_url = f"{embeddings_api_base}/v1/embeddings" + + try: + response = requests.post(full_url, json=payload, headers=headers) + response.raise_for_status() + except requests.exceptions.RequestException as req_ex: + logger.error(f"Request to Embeddings API failed: {str(req_ex)}") + raise HTTPException(status_code=500, detail=f"Failed to get embeddings: {str(req_ex)}") + + result = response.json() + + if EMBEDDINGS_PROVIDER == 'ollama': + return result['embedding'] + else: + return result['data'][0]['embedding'] + + +async def run_graphrag_query(request: ChatCompletionRequest) -> ChatCompletionResponse: + try: + query_options = request.query_options + query = request.messages[-1].content # Get the last user message as the query + + cmd = ["python", "-m", "graphrag.query"] + cmd.extend(["--data", f"./indexing/output/{query_options.selected_folder}/artifacts"]) + cmd.extend(["--method", query_options.query_type.split('-')[1]]) # 'global' or 'local' + + if query_options.community_level: + cmd.extend(["--community_level", str(query_options.community_level)]) + if query_options.response_type: + cmd.extend(["--response_type", query_options.response_type]) + + # Handle preset CLI args + if query_options.preset and query_options.preset != "Custom Query": + preset_args = get_preset_args(query_options.preset) + cmd.extend(preset_args) + + # Handle custom CLI args + if query_options.custom_cli_args: + cmd.extend(query_options.custom_cli_args.split()) + + cmd.append(query) + + logger.info(f"Executing GraphRAG query: {' '.join(cmd)}") + + result = subprocess.run(cmd, capture_output=True, text=True) + if result.returncode != 0: + raise Exception(f"GraphRAG query failed: {result.stderr}") + + return ChatCompletionResponse( + model=request.model, + choices=[ + ChatCompletionResponseChoice( + index=0, + message=Message( + role="assistant", + content=result.stdout + ), + finish_reason="stop" + ) + ], + usage=Usage( + prompt_tokens=0, + completion_tokens=0, + total_tokens=0 + ) + ) + except Exception as e: + logger.error(f"Error in GraphRAG query: {str(e)}") + raise HTTPException(status_code=500, detail=f"An error occurred during the GraphRAG query: {str(e)}") + + +def get_preset_args(preset: str) -> List[str]: + preset_args = { + "Default Global Search": ["--community_level", "2", "--response_type", "Multiple Paragraphs"], + "Default Local Search": ["--community_level", "2", "--response_type", "Multiple Paragraphs"], + "Detailed Global Analysis": ["--community_level", "3", "--response_type", "Multi-Page Report"], + "Detailed Local Analysis": ["--community_level", "3", "--response_type", "Multi-Page Report"], + "Quick Global Summary": ["--community_level", "1", "--response_type", "Single Paragraph"], + "Quick Local Summary": ["--community_level", "1", "--response_type", "Single Paragraph"], + "Global Bullet Points": ["--community_level", "2", "--response_type", "List of 3-7 Points"], + "Local Bullet Points": ["--community_level", "2", "--response_type", "List of 3-7 Points"], + "Comprehensive Global Report": ["--community_level", "4", "--response_type", "Multi-Page Report"], + "Comprehensive Local Report": ["--community_level", "4", "--response_type", "Multi-Page Report"], + "High-Level Global Overview": ["--community_level", "1", "--response_type", "Single Page"], + "High-Level Local Overview": ["--community_level", "1", "--response_type", "Single Page"], + "Focused Global Insight": ["--community_level", "3", "--response_type", "Single Paragraph"], + "Focused Local Insight": ["--community_level", "3", "--response_type", "Single Paragraph"], + } + return preset_args.get(preset, []) + +ddg_search = DuckDuckGoSearchAPIWrapper(max_results=5) + +async def run_duckduckgo_search(request: ChatCompletionRequest) -> ChatCompletionResponse: + query = request.messages[-1].content + results = ddg_search.results(query, max_results=5) + + if not results: + content = "No results found for the given query." + else: + content = "DuckDuckGo Search Results:\n\n" + for result in results: + content += f"Title: {result['title']}\n" + content += f"Snippet: {result['snippet']}\n" + content += f"Link: {result['link']}\n" + if 'date' in result: + content += f"Date: {result['date']}\n" + if 'source' in result: + content += f"Source: {result['source']}\n" + content += "\n" + + return ChatCompletionResponse( + model=request.model, + choices=[ + ChatCompletionResponseChoice( + index=0, + message=Message( + role="assistant", + content=content + ), + finish_reason="stop" + ) + ], + usage=Usage( + prompt_tokens=0, + completion_tokens=0, + total_tokens=0 + ) + ) + +async def run_full_model_search(request: ChatCompletionRequest) -> ChatCompletionResponse: + query = request.messages[-1].content + + # Run all search types + graphrag_global = await run_graphrag_query(ChatCompletionRequest(model="graphrag-global-search:latest", messages=request.messages, query_options=request.query_options)) + graphrag_local = await run_graphrag_query(ChatCompletionRequest(model="graphrag-local-search:latest", messages=request.messages, query_options=request.query_options)) + duckduckgo = await run_duckduckgo_search(request) + + # Combine results + combined_content = f"""Full Model Search Results: + +Global Search: +{graphrag_global.choices[0].message.content} + +Local Search: +{graphrag_local.choices[0].message.content} + +DuckDuckGo Search: +{duckduckgo.choices[0].message.content} +""" + + return ChatCompletionResponse( + model=request.model, + choices=[ + ChatCompletionResponseChoice( + index=0, + message=Message( + role="assistant", + content=combined_content + ), + finish_reason="stop" + ) + ], + usage=Usage( + prompt_tokens=0, + completion_tokens=0, + total_tokens=0 + ) + ) + +@app.get("/health") +async def health_check(): + return {"status": "ok"} + +@app.get("/v1/models") +async def list_models(): + settings = load_settings() + try: + api_models = await fetch_available_models(settings) + except Exception as e: + logger.error(f"Error fetching API models: {str(e)}") + api_models = [] + + # Include the hardcoded models + hardcoded_models = [ + {"id": "graphrag-local-search:latest", "object": "model", "owned_by": "graphrag"}, + {"id": "graphrag-global-search:latest", "object": "model", "owned_by": "graphrag"}, + {"id": "duckduckgo-search:latest", "object": "model", "owned_by": "duckduckgo"}, + {"id": "full-model:latest", "object": "model", "owned_by": "combined"}, + ] + + # Combine API models with hardcoded models + all_models = [{"id": model, "object": "model", "owned_by": "api"} for model in api_models] + hardcoded_models + + return JSONResponse(content={"data": all_models}) + +class PromptTuneRequest(BaseModel): + root: str = "./{ROOT_DIR}" + domain: Optional[str] = None + method: str = "random" + limit: int = 15 + language: Optional[str] = None + max_tokens: int = 2000 + chunk_size: int = 200 + no_entity_types: bool = False + output: str = "./{ROOT_DIR}/prompts" + +class PromptTuneResponse(BaseModel): + status: str + message: str + +# Global variable to store the latest logs +prompt_tune_logs = deque(maxlen=100) + +async def run_prompt_tuning(request: PromptTuneRequest): + cmd = ["python", "-m", "graphrag.prompt_tune"] + + # Create a temporary directory for output + with tempfile.TemporaryDirectory() as temp_output: + # Expand environment variables in the root path + root_path = os.path.expandvars(request.root) + + cmd.extend(["--root", root_path]) + cmd.extend(["--method", request.method]) + cmd.extend(["--limit", str(request.limit)]) + + if request.domain: + cmd.extend(["--domain", request.domain]) + + if request.language: + cmd.extend(["--language", request.language]) + + cmd.extend(["--max-tokens", str(request.max_tokens)]) + cmd.extend(["--chunk-size", str(request.chunk_size)]) + + if request.no_entity_types: + cmd.append("--no-entity-types") + + # Use the temporary directory for output + cmd.extend(["--output", temp_output]) + + logger.info(f"Executing prompt tuning command: {' '.join(cmd)}") + + try: + process = await asyncio.create_subprocess_exec( + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) + + async def read_stream(stream): + while True: + line = await stream.readline() + if not line: + break + line = line.decode().strip() + prompt_tune_logs.append(line) + logger.info(line) + + await asyncio.gather( + read_stream(process.stdout), + read_stream(process.stderr) + ) + + await process.wait() + + if process.returncode == 0: + logger.info("Prompt tuning completed successfully") + + # Replace the existing template files with the newly generated prompts + dest_dir = os.path.join(ROOT_DIR, "prompts") + + for filename in os.listdir(temp_output): + if filename.endswith(".txt"): + source_file = os.path.join(temp_output, filename) + dest_file = os.path.join(dest_dir, filename) + shutil.move(source_file, dest_file) + logger.info(f"Replaced {filename} in {dest_file}") + + return PromptTuneResponse(status="success", message="Prompt tuning completed successfully. Existing prompts have been replaced.") + else: + logger.error("Prompt tuning failed") + return PromptTuneResponse(status="error", message="Prompt tuning failed. Check logs for details.") + except Exception as e: + logger.error(f"Prompt tuning failed: {str(e)}") + return PromptTuneResponse(status="error", message=f"Prompt tuning failed: {str(e)}") + +@app.post("/v1/prompt_tune") +async def prompt_tune(request: PromptTuneRequest, background_tasks: BackgroundTasks): + background_tasks.add_task(run_prompt_tuning, request) + return {"status": "started", "message": "Prompt tuning process has been started in the background"} + +@app.get("/v1/prompt_tune_status") +async def prompt_tune_status(): + return { + "status": "running" if prompt_tune_logs else "idle", + "logs": list(prompt_tune_logs) + } + +class IndexingRequest(BaseModel): + llm_model: str + embed_model: str + llm_api_base: str + embed_api_base: str + root: str + verbose: bool = False + nocache: bool = False + resume: Optional[str] = None + reporter: str = "rich" + emit: List[str] = ["parquet"] + custom_args: Optional[str] = None + llm_params: Dict[str, Any] = Field(default_factory=dict) + embed_params: Dict[str, Any] = Field(default_factory=dict) + +# Global variable to store the latest indexing logs +indexing_logs = deque(maxlen=100) + +async def run_indexing(request: IndexingRequest): + cmd = ["python", "-m", "graphrag.index"] + + cmd.extend(["--root", request.root]) + + if request.verbose: + cmd.append("--verbose") + + if request.nocache: + cmd.append("--nocache") + + if request.resume: + cmd.extend(["--resume", request.resume]) + + cmd.extend(["--reporter", request.reporter]) + cmd.extend(["--emit", ",".join(request.emit)]) + + # Set environment variables for LLM and embedding models + env: Dict[str, Any] = os.environ.copy() + env["GRAPHRAG_LLM_MODEL"] = request.llm_model + env["GRAPHRAG_EMBED_MODEL"] = request.embed_model + env["GRAPHRAG_LLM_API_BASE"] = LLM_API_BASE + env["GRAPHRAG_EMBED_API_BASE"] = EMBEDDINGS_API_BASE + + # Set environment variables for LLM parameters + for key, value in request.llm_params.items(): + env[f"GRAPHRAG_LLM_{key.upper()}"] = str(value) + + # Set environment variables for embedding parameters + for key, value in request.embed_params.items(): + env[f"GRAPHRAG_EMBED_{key.upper()}"] = str(value) + + # Add custom CLI arguments + if request.custom_args: + cmd.extend(request.custom_args.split()) + + logger.info(f"Executing indexing command: {' '.join(cmd)}") + logger.info(f"Environment variables: {env}") + + try: + process = await asyncio.create_subprocess_exec( + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + env=env + ) + + async def read_stream(stream): + while True: + line = await stream.readline() + if not line: + break + line = line.decode().strip() + indexing_logs.append(line) + logger.info(line) + + await asyncio.gather( + read_stream(process.stdout), + read_stream(process.stderr) + ) + + await process.wait() + + if process.returncode == 0: + logger.info("Indexing completed successfully") + return {"status": "success", "message": "Indexing completed successfully"} + else: + logger.error("Indexing failed") + return {"status": "error", "message": "Indexing failed. Check logs for details."} + except Exception as e: + logger.error(f"Indexing failed: {str(e)}") + return {"status": "error", "message": f"Indexing failed: {str(e)}"} + + +@app.post("/v1/index") +async def start_indexing(request: IndexingRequest, background_tasks: BackgroundTasks): + background_tasks.add_task(run_indexing, request) + return {"status": "started", "message": "Indexing process has been started in the background"} + +@app.get("/v1/index_status") +async def indexing_status(): + return { + "status": "running" if indexing_logs else "idle", + "logs": list(indexing_logs) + } + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Launch the GraphRAG API server") + parser.add_argument("--host", type=str, default="127.0.0.1", help="Host to bind the server to") + parser.add_argument("--port", type=int, default=PORT, help="Port to bind the server to") + parser.add_argument("--reload", action="store_true", help="Enable auto-reload mode") + args = parser.parse_args() + + import uvicorn + uvicorn.run( + "api:app", + host=args.host, + port=args.port, + reload=args.reload + ) diff --git a/app.py b/app.py new file mode 100644 index 0000000000000000000000000000000000000000..890e4568e215d52bd50d9d4f78231d9c8651ba27 --- /dev/null +++ b/app.py @@ -0,0 +1,1786 @@ +import gradio as gr +from gradio.helpers import Progress +import asyncio +import subprocess +import yaml +import os +import networkx as nx +import plotly.graph_objects as go +import numpy as np +import plotly.io as pio +import lancedb +import random +import io +import shutil +import logging +import queue +import threading +import time +from collections import deque +import re +import glob +from datetime import datetime +import json +import requests +import aiohttp +from openai import OpenAI +from openai import AsyncOpenAI +import pyarrow.parquet as pq +import pandas as pd +import sys +import colorsys +from dotenv import load_dotenv, set_key +import argparse +import socket +import tiktoken +from graphrag.query.context_builder.entity_extraction import EntityVectorStoreKey +from graphrag.query.indexer_adapters import ( + read_indexer_covariates, + read_indexer_entities, + read_indexer_relationships, + read_indexer_reports, + read_indexer_text_units, +) +from graphrag.llm.openai import create_openai_chat_llm +from graphrag.llm.openai.factories import create_openai_embedding_llm +from graphrag.query.input.loaders.dfs import store_entity_semantic_embeddings +from graphrag.query.llm.oai.chat_openai import ChatOpenAI +from graphrag.llm.openai.openai_configuration import OpenAIConfiguration +from graphrag.llm.openai.openai_embeddings_llm import OpenAIEmbeddingsLLM +from graphrag.query.llm.oai.typing import OpenaiApiType +from graphrag.query.structured_search.local_search.mixed_context import LocalSearchMixedContext +from graphrag.query.structured_search.local_search.search import LocalSearch +from graphrag.query.structured_search.global_search.community_context import GlobalCommunityContext +from graphrag.query.structured_search.global_search.search import GlobalSearch +from graphrag.vector_stores.lancedb import LanceDBVectorStore +import textwrap + + + +# Suppress warnings +import warnings +warnings.filterwarnings("ignore", category=UserWarning, module="gradio_client.documentation") + + +load_dotenv('indexing/.env') + +# Set default values for API-related environment variables +os.environ.setdefault("LLM_API_BASE", os.getenv("LLM_API_BASE")) +os.environ.setdefault("LLM_API_KEY", os.getenv("LLM_API_KEY")) +os.environ.setdefault("LLM_MODEL", os.getenv("LLM_MODEL")) +os.environ.setdefault("EMBEDDINGS_API_BASE", os.getenv("EMBEDDINGS_API_BASE")) +os.environ.setdefault("EMBEDDINGS_API_KEY", os.getenv("EMBEDDINGS_API_KEY")) +os.environ.setdefault("EMBEDDINGS_MODEL", os.getenv("EMBEDDINGS_MODEL")) + +# Add the project root to the Python path +project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +sys.path.insert(0, project_root) + + +# Set up logging +log_queue = queue.Queue() +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + + +llm = None +text_embedder = None + +class QueueHandler(logging.Handler): + def __init__(self, log_queue): + super().__init__() + self.log_queue = log_queue + + def emit(self, record): + self.log_queue.put(self.format(record)) +queue_handler = QueueHandler(log_queue) +logging.getLogger().addHandler(queue_handler) + + + +def initialize_models(): + global llm, text_embedder + + llm_api_base = os.getenv("LLM_API_BASE") + llm_api_key = os.getenv("LLM_API_KEY") + embeddings_api_base = os.getenv("EMBEDDINGS_API_BASE") + embeddings_api_key = os.getenv("EMBEDDINGS_API_KEY") + + llm_service_type = os.getenv("LLM_SERVICE_TYPE", "openai_chat").lower() # Provide a default and lower it + embeddings_service_type = os.getenv("EMBEDDINGS_SERVICE_TYPE", "openai").lower() # Provide a default and lower it + + llm_model = os.getenv("LLM_MODEL") + embeddings_model = os.getenv("EMBEDDINGS_MODEL") + + logging.info("Fetching models...") + models = fetch_models(llm_api_base, llm_api_key, llm_service_type) + + # Use the same models list for both LLM and embeddings + llm_models = models + embeddings_models = models + + # Initialize LLM + if llm_service_type == "openai_chat": + llm = ChatOpenAI( + api_key=llm_api_key, + api_base=f"{llm_api_base}/v1", + model=llm_model, + api_type=OpenaiApiType.OpenAI, + max_retries=20, + ) + # Initialize OpenAI client for embeddings + openai_client = OpenAI( + api_key=embeddings_api_key or "dummy_key", + base_url=f"{embeddings_api_base}/v1" + ) + + # Initialize text embedder using OpenAIEmbeddingsLLM + text_embedder = OpenAIEmbeddingsLLM( + client=openai_client, + configuration={ + "model": embeddings_model, + "api_type": "open_ai", + "api_base": embeddings_api_base, + "api_key": embeddings_api_key or None, + "provider": embeddings_service_type + } + ) + + return llm_models, embeddings_models, llm_service_type, embeddings_service_type, llm_api_base, embeddings_api_base, text_embedder + +def find_latest_output_folder(): + root_dir = "./indexing/output" + folders = [f for f in os.listdir(root_dir) if os.path.isdir(os.path.join(root_dir, f))] + + if not folders: + raise ValueError("No output folders found") + + # Sort folders by creation time, most recent first + sorted_folders = sorted(folders, key=lambda x: os.path.getctime(os.path.join(root_dir, x)), reverse=True) + + latest_folder = None + timestamp = None + + for folder in sorted_folders: + try: + # Try to parse the folder name as a timestamp + timestamp = datetime.strptime(folder, "%Y%m%d-%H%M%S") + latest_folder = folder + break + except ValueError: + # If the folder name is not a valid timestamp, skip it + continue + + if latest_folder is None: + raise ValueError("No valid timestamp folders found") + + latest_path = os.path.join(root_dir, latest_folder) + artifacts_path = os.path.join(latest_path, "artifacts") + + if not os.path.exists(artifacts_path): + raise ValueError(f"Artifacts folder not found in {latest_path}") + + return latest_path, latest_folder + +def initialize_data(): + global entity_df, relationship_df, text_unit_df, report_df, covariate_df + + tables = { + "entity_df": "create_final_nodes", + "relationship_df": "create_final_edges", + "text_unit_df": "create_final_text_units", + "report_df": "create_final_reports", + "covariate_df": "create_final_covariates" + } + + timestamp = None # Initialize timestamp to None + + try: + latest_output_folder, timestamp = find_latest_output_folder() + artifacts_folder = os.path.join(latest_output_folder, "artifacts") + + for df_name, file_prefix in tables.items(): + file_pattern = os.path.join(artifacts_folder, f"{file_prefix}*.parquet") + matching_files = glob.glob(file_pattern) + + if matching_files: + latest_file = max(matching_files, key=os.path.getctime) + df = pd.read_parquet(latest_file) + globals()[df_name] = df + logging.info(f"Successfully loaded {df_name} from {latest_file}") + else: + logging.warning(f"No matching file found for {df_name} in {artifacts_folder}. Initializing as an empty DataFrame.") + globals()[df_name] = pd.DataFrame() + + except Exception as e: + logging.error(f"Error initializing data: {str(e)}") + for df_name in tables.keys(): + globals()[df_name] = pd.DataFrame() + + return timestamp + +# Call initialize_data and store the timestamp +current_timestamp = initialize_data() + + +def find_available_port(start_port, max_attempts=100): + for port in range(start_port, start_port + max_attempts): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + try: + s.bind(('', port)) + return port + except OSError: + continue + raise IOError("No free ports found") + +def start_api_server(port): + subprocess.Popen([sys.executable, "api_server.py", "--port", str(port)]) + +def wait_for_api_server(port): + max_retries = 30 + for _ in range(max_retries): + try: + response = requests.get(f"http://localhost:{port}") + if response.status_code == 200: + print(f"API server is up and running on port {port}") + return + else: + print(f"Unexpected response from API server: {response.status_code}") + except requests.ConnectionError: + time.sleep(1) + print("Failed to connect to API server") + +def load_settings(): + try: + with open("indexing/settings.yaml", "r") as f: + return yaml.safe_load(f) or {} + except FileNotFoundError: + return {} + +def update_setting(key, value): + settings = load_settings() + try: + settings[key] = json.loads(value) + except json.JSONDecodeError: + settings[key] = value + + try: + with open("indexing/settings.yaml", "w") as f: + yaml.dump(settings, f, default_flow_style=False) + return f"Setting '{key}' updated successfully" + except Exception as e: + return f"Error updating setting '{key}': {str(e)}" + +def create_setting_component(key, value): + with gr.Accordion(key, open=False): + if isinstance(value, (dict, list)): + value_str = json.dumps(value, indent=2) + lines = value_str.count('\n') + 1 + else: + value_str = str(value) + lines = 1 + + text_area = gr.TextArea(value=value_str, label="Value", lines=lines, max_lines=20) + update_btn = gr.Button("Update", variant="primary") + status = gr.Textbox(label="Status", visible=False) + + update_btn.click( + fn=update_setting, + inputs=[gr.Textbox(value=key, visible=False), text_area], + outputs=[status] + ).then( + fn=lambda: gr.update(visible=True), + outputs=[status] + ) + + + +def get_openai_client(): + return OpenAI( + base_url=os.getenv("LLM_API_BASE"), + api_key=os.getenv("LLM_API_KEY"), + llm_model = os.getenv("LLM_MODEL") + ) + +async def chat_with_openai(messages, model, temperature, max_tokens, api_base): + client = AsyncOpenAI( + base_url=api_base, + api_key=os.getenv("LLM_API_KEY") + ) + + try: + response = await client.chat.completions.create( + model=model, + messages=messages, + temperature=temperature, + max_tokens=max_tokens + ) + return response.choices[0].message.content + except Exception as e: + logging.error(f"Error in chat_with_openai: {str(e)}") + return f"An error occurred: {str(e)}" + return f"Error: {str(e)}" + +def chat_with_llm(query, history, system_message, temperature, max_tokens, model, api_base): + try: + messages = [{"role": "system", "content": system_message}] + for item in history: + if isinstance(item, tuple) and len(item) == 2: + human, ai = item + messages.append({"role": "user", "content": human}) + messages.append({"role": "assistant", "content": ai}) + messages.append({"role": "user", "content": query}) + + logging.info(f"Sending chat request to {api_base} with model {model}") + client = OpenAI(base_url=api_base, api_key=os.getenv("LLM_API_KEY", "dummy-key")) + response = client.chat.completions.create( + model=model, + messages=messages, + temperature=temperature, + max_tokens=max_tokens + ) + return response.choices[0].message.content + except Exception as e: + logging.error(f"Error in chat_with_llm: {str(e)}") + logging.error(f"Attempted with model: {model}, api_base: {api_base}") + raise RuntimeError(f"Chat request failed: {str(e)}") + +def run_graphrag_query(cli_args): + try: + command = ' '.join(cli_args) + logging.info(f"Executing command: {command}") + result = subprocess.run(cli_args, capture_output=True, text=True, check=True) + return result.stdout.strip() + except subprocess.CalledProcessError as e: + logging.error(f"Error running GraphRAG query: {e}") + logging.error(f"Command output (stdout): {e.stdout}") + logging.error(f"Command output (stderr): {e.stderr}") + raise RuntimeError(f"GraphRAG query failed: {e.stderr}") + +def parse_query_response(response: str): + try: + # Split the response into metadata and content + parts = response.split("\n\n", 1) + if len(parts) < 2: + return response # Return original response if it doesn't contain metadata + + metadata_str, content = parts + metadata = json.loads(metadata_str) + + # Extract relevant information from metadata + query_type = metadata.get("query_type", "Unknown") + execution_time = metadata.get("execution_time", "N/A") + tokens_used = metadata.get("tokens_used", "N/A") + + # Remove unwanted lines from the content + content_lines = content.split('\n') + filtered_content = '\n'.join([line for line in content_lines if not line.startswith("INFO:") and not line.startswith("creating llm client")]) + + # Format the parsed response + parsed_response = f""" +Query Type: {query_type} +Execution Time: {execution_time} seconds +Tokens Used: {tokens_used} + +{filtered_content.strip()} +""" + return parsed_response + except Exception as e: + print(f"Error parsing query response: {str(e)}") + return response + +def send_message(query_type, query, history, system_message, temperature, max_tokens, preset, community_level, response_type, custom_cli_args, selected_folder): + try: + if query_type in ["global", "local"]: + cli_args = construct_cli_args(query_type, preset, community_level, response_type, custom_cli_args, query, selected_folder) + logging.info(f"Executing {query_type} search with command: {' '.join(cli_args)}") + result = run_graphrag_query(cli_args) + parsed_result = parse_query_response(result) + logging.info(f"Parsed query result: {parsed_result}") + else: # Direct chat + llm_model = os.getenv("LLM_MODEL") + api_base = os.getenv("LLM_API_BASE") + logging.info(f"Executing direct chat with model: {llm_model}") + + try: + result = chat_with_llm(query, history, system_message, temperature, max_tokens, llm_model, api_base) + parsed_result = result # No parsing needed for direct chat + logging.info(f"Direct chat result: {parsed_result[:100]}...") # Log first 100 chars of result + except Exception as chat_error: + logging.error(f"Error in chat_with_llm: {str(chat_error)}") + raise RuntimeError(f"Direct chat failed: {str(chat_error)}") + + history.append((query, parsed_result)) + except Exception as e: + error_message = f"An error occurred: {str(e)}" + logging.error(error_message) + logging.exception("Exception details:") + history.append((query, error_message)) + + return history, gr.update(value=""), update_logs() + +def construct_cli_args(query_type, preset, community_level, response_type, custom_cli_args, query, selected_folder): + if not selected_folder: + raise ValueError("No folder selected. Please select an output folder before querying.") + + artifacts_folder = os.path.join("./indexing/output", selected_folder, "artifacts") + if not os.path.exists(artifacts_folder): + raise ValueError(f"Artifacts folder not found in {artifacts_folder}") + + base_args = [ + "python", "-m", "graphrag.query", + "--data", artifacts_folder, + "--method", query_type, + ] + + # Apply preset configurations + if preset.startswith("Default"): + base_args.extend(["--community_level", "2", "--response_type", "Multiple Paragraphs"]) + elif preset.startswith("Detailed"): + base_args.extend(["--community_level", "4", "--response_type", "Multi-Page Report"]) + elif preset.startswith("Quick"): + base_args.extend(["--community_level", "1", "--response_type", "Single Paragraph"]) + elif preset.startswith("Bullet"): + base_args.extend(["--community_level", "2", "--response_type", "List of 3-7 Points"]) + elif preset.startswith("Comprehensive"): + base_args.extend(["--community_level", "5", "--response_type", "Multi-Page Report"]) + elif preset.startswith("High-Level"): + base_args.extend(["--community_level", "1", "--response_type", "Single Page"]) + elif preset.startswith("Focused"): + base_args.extend(["--community_level", "3", "--response_type", "Multiple Paragraphs"]) + elif preset == "Custom Query": + base_args.extend([ + "--community_level", str(community_level), + "--response_type", f'"{response_type}"', + ]) + if custom_cli_args: + base_args.extend(custom_cli_args.split()) + + # Add the query at the end + base_args.append(query) + + return base_args + + + + + + +def upload_file(file): + if file is not None: + input_dir = os.path.join("indexing", "input") + os.makedirs(input_dir, exist_ok=True) + + # Get the original filename from the uploaded file + original_filename = file.name + + # Create the destination path + destination_path = os.path.join(input_dir, os.path.basename(original_filename)) + + # Move the uploaded file to the destination path + shutil.move(file.name, destination_path) + + logging.info(f"File uploaded and moved to: {destination_path}") + status = f"File uploaded: {os.path.basename(original_filename)}" + else: + status = "No file uploaded" + + # Get the updated file list + updated_file_list = [f["path"] for f in list_input_files()] + + return status, gr.update(choices=updated_file_list), update_logs() + +def list_input_files(): + input_dir = os.path.join("indexing", "input") + files = [] + if os.path.exists(input_dir): + files = os.listdir(input_dir) + return [{"name": f, "path": os.path.join(input_dir, f)} for f in files] + +def delete_file(file_path): + try: + os.remove(file_path) + logging.info(f"File deleted: {file_path}") + status = f"File deleted: {os.path.basename(file_path)}" + except Exception as e: + logging.error(f"Error deleting file: {str(e)}") + status = f"Error deleting file: {str(e)}" + + # Get the updated file list + updated_file_list = [f["path"] for f in list_input_files()] + + return status, gr.update(choices=updated_file_list), update_logs() + +def read_file_content(file_path): + try: + if file_path.endswith('.parquet'): + df = pd.read_parquet(file_path) + + # Get basic information about the DataFrame + info = f"Parquet File: {os.path.basename(file_path)}\n" + info += f"Rows: {len(df)}, Columns: {len(df.columns)}\n\n" + info += "Column Names:\n" + "\n".join(df.columns) + "\n\n" + + # Display first few rows + info += "First 5 rows:\n" + info += df.head().to_string() + "\n\n" + + # Display basic statistics + info += "Basic Statistics:\n" + info += df.describe().to_string() + + return info + else: + with open(file_path, 'r', encoding='utf-8', errors='replace') as file: + content = file.read() + return content + except Exception as e: + logging.error(f"Error reading file: {str(e)}") + return f"Error reading file: {str(e)}" + +def save_file_content(file_path, content): + try: + with open(file_path, 'w') as file: + file.write(content) + logging.info(f"File saved: {file_path}") + status = f"File saved: {os.path.basename(file_path)}" + except Exception as e: + logging.error(f"Error saving file: {str(e)}") + status = f"Error saving file: {str(e)}" + return status, update_logs() + +def manage_data(): + db = lancedb.connect("./indexing/lancedb") + tables = db.table_names() + table_info = "" + if tables: + table = db[tables[0]] + table_info = f"Table: {tables[0]}\nSchema: {table.schema}" + + input_files = list_input_files() + + return { + "database_info": f"Tables: {', '.join(tables)}\n\n{table_info}", + "input_files": input_files + } + + +def find_latest_graph_file(root_dir): + pattern = os.path.join(root_dir, "output", "*", "artifacts", "*.graphml") + graph_files = glob.glob(pattern) + if not graph_files: + # If no files found, try excluding .DS_Store + output_dir = os.path.join(root_dir, "output") + run_dirs = [d for d in os.listdir(output_dir) if os.path.isdir(os.path.join(output_dir, d)) and d != ".DS_Store"] + if run_dirs: + latest_run = max(run_dirs) + pattern = os.path.join(root_dir, "output", latest_run, "artifacts", "*.graphml") + graph_files = glob.glob(pattern) + + if not graph_files: + return None + + # Sort files by modification time, most recent first + latest_file = max(graph_files, key=os.path.getmtime) + return latest_file + +def update_visualization(folder_name, file_name, layout_type, node_size, edge_width, node_color_attribute, color_scheme, show_labels, label_size): + root_dir = "./indexing" + if not folder_name or not file_name: + return None, "Please select a folder and a GraphML file." + file_name = file_name.split("] ")[1] if "]" in file_name else file_name # Remove file type prefix + graph_path = os.path.join(root_dir, "output", folder_name, "artifacts", file_name) + if not graph_path.endswith('.graphml'): + return None, "Please select a GraphML file for visualization." + try: + # Load the GraphML file + graph = nx.read_graphml(graph_path) + + # Create layout based on user selection + if layout_type == "3D Spring": + pos = nx.spring_layout(graph, dim=3, seed=42, k=0.5) + elif layout_type == "2D Spring": + pos = nx.spring_layout(graph, dim=2, seed=42, k=0.5) + else: # Circular + pos = nx.circular_layout(graph) + + # Extract node positions + if layout_type == "3D Spring": + x_nodes = [pos[node][0] for node in graph.nodes()] + y_nodes = [pos[node][1] for node in graph.nodes()] + z_nodes = [pos[node][2] for node in graph.nodes()] + else: + x_nodes = [pos[node][0] for node in graph.nodes()] + y_nodes = [pos[node][1] for node in graph.nodes()] + z_nodes = [0] * len(graph.nodes()) # Set all z-coordinates to 0 for 2D layouts + + # Extract edge positions + x_edges, y_edges, z_edges = [], [], [] + for edge in graph.edges(): + x_edges.extend([pos[edge[0]][0], pos[edge[1]][0], None]) + y_edges.extend([pos[edge[0]][1], pos[edge[1]][1], None]) + if layout_type == "3D Spring": + z_edges.extend([pos[edge[0]][2], pos[edge[1]][2], None]) + else: + z_edges.extend([0, 0, None]) + + # Generate node colors based on user selection + if node_color_attribute == "Degree": + node_colors = [graph.degree(node) for node in graph.nodes()] + else: # Random + node_colors = [random.random() for _ in graph.nodes()] + node_colors = np.array(node_colors) + node_colors = (node_colors - node_colors.min()) / (node_colors.max() - node_colors.min()) + + # Create the trace for edges + edge_trace = go.Scatter3d( + x=x_edges, y=y_edges, z=z_edges, + mode='lines', + line=dict(color='lightgray', width=edge_width), + hoverinfo='none' + ) + + # Create the trace for nodes + node_trace = go.Scatter3d( + x=x_nodes, y=y_nodes, z=z_nodes, + mode='markers+text' if show_labels else 'markers', + marker=dict( + size=node_size, + color=node_colors, + colorscale=color_scheme, + colorbar=dict( + title='Node Degree' if node_color_attribute == "Degree" else "Random Value", + thickness=10, + x=1.1, + tickvals=[0, 1], + ticktext=['Low', 'High'] + ), + line=dict(width=1) + ), + text=[node for node in graph.nodes()], + textposition="top center", + textfont=dict(size=label_size, color='black'), + hoverinfo='text' + ) + + # Create the plot + fig = go.Figure(data=[edge_trace, node_trace]) + + # Update layout for better visualization + fig.update_layout( + title=f'{layout_type} Graph Visualization: {os.path.basename(graph_path)}', + showlegend=False, + scene=dict( + xaxis=dict(showbackground=False, showticklabels=False, title=''), + yaxis=dict(showbackground=False, showticklabels=False, title=''), + zaxis=dict(showbackground=False, showticklabels=False, title='') + ), + margin=dict(l=0, r=0, b=0, t=40), + annotations=[ + dict( + showarrow=False, + text=f"Interactive {layout_type} visualization of GraphML data", + xref="paper", + yref="paper", + x=0, + y=0 + ) + ], + autosize=True + ) + + fig.update_layout(autosize=True) + fig.update_layout(height=600) # Set a fixed height + return fig, f"Graph visualization generated successfully. Using file: {graph_path}" + except Exception as e: + return go.Figure(), f"Error visualizing graph: {str(e)}" + + + + + +def update_logs(): + logs = [] + while not log_queue.empty(): + logs.append(log_queue.get()) + return "\n".join(logs) + + + +def fetch_models(base_url, api_key, service_type): + try: + if service_type.lower() == "ollama": + response = requests.get(f"{base_url}/tags", timeout=10) + else: # OpenAI Compatible + headers = { + "Authorization": f"Bearer {api_key}", + "Content-Type": "application/json" + } + response = requests.get(f"{base_url}/models", headers=headers, timeout=10) + + logging.info(f"Raw API response: {response.text}") + + if response.status_code == 200: + data = response.json() + if service_type.lower() == "ollama": + models = [model.get('name', '') for model in data.get('models', data) if isinstance(model, dict)] + else: # OpenAI Compatible + models = [model.get('id', '') for model in data.get('data', []) if isinstance(model, dict)] + + models = [model for model in models if model] # Remove empty strings + + if not models: + logging.warning(f"No models found in {service_type} API response") + return ["No models available"] + + logging.info(f"Successfully fetched {service_type} models: {models}") + return models + else: + logging.error(f"Error fetching {service_type} models. Status code: {response.status_code}, Response: {response.text}") + return ["Error fetching models"] + except requests.RequestException as e: + logging.error(f"Exception while fetching {service_type} models: {str(e)}") + return ["Error: Connection failed"] + except Exception as e: + logging.error(f"Unexpected error in fetch_models: {str(e)}") + return ["Error: Unexpected issue"] + +def update_model_choices(base_url, api_key, service_type, settings_key): + models = fetch_models(base_url, api_key, service_type) + + if not models: + logging.warning(f"No models fetched for {service_type}.") + + # Get the current model from settings + current_model = settings.get(settings_key, {}).get('llm', {}).get('model') + + # If the current model is not in the list, add it + if current_model and current_model not in models: + models.append(current_model) + + return gr.update(choices=models, value=current_model if current_model in models else (models[0] if models else None)) + +def update_llm_model_choices(base_url, api_key, service_type): + return update_model_choices(base_url, api_key, service_type, 'llm') + +def update_embeddings_model_choices(base_url, api_key, service_type): + return update_model_choices(base_url, api_key, service_type, 'embeddings') + + + + +def update_llm_settings(llm_model, embeddings_model, context_window, system_message, temperature, max_tokens, + llm_api_base, llm_api_key, + embeddings_api_base, embeddings_api_key, embeddings_service_type): + try: + # Update settings.yaml + settings = load_settings() + settings['llm'].update({ + "type": "openai", # Always set to "openai" since we removed the radio button + "model": llm_model, + "api_base": llm_api_base, + "api_key": "${GRAPHRAG_API_KEY}", + "temperature": temperature, + "max_tokens": max_tokens, + "provider": "openai_chat" # Always set to "openai_chat" + }) + settings['embeddings']['llm'].update({ + "type": "openai_embedding", # Always use OpenAIEmbeddingsLLM + "model": embeddings_model, + "api_base": embeddings_api_base, + "api_key": "${GRAPHRAG_API_KEY}", + "provider": embeddings_service_type + }) + + with open("indexing/settings.yaml", 'w') as f: + yaml.dump(settings, f, default_flow_style=False) + + # Update .env file + update_env_file("LLM_API_BASE", llm_api_base) + update_env_file("LLM_API_KEY", llm_api_key) + update_env_file("LLM_MODEL", llm_model) + update_env_file("EMBEDDINGS_API_BASE", embeddings_api_base) + update_env_file("EMBEDDINGS_API_KEY", embeddings_api_key) + update_env_file("EMBEDDINGS_MODEL", embeddings_model) + update_env_file("CONTEXT_WINDOW", str(context_window)) + update_env_file("SYSTEM_MESSAGE", system_message) + update_env_file("TEMPERATURE", str(temperature)) + update_env_file("MAX_TOKENS", str(max_tokens)) + update_env_file("LLM_SERVICE_TYPE", "openai_chat") + update_env_file("EMBEDDINGS_SERVICE_TYPE", embeddings_service_type) + + # Reload environment variables + load_dotenv(override=True) + + return "LLM and embeddings settings updated successfully in both settings.yaml and .env files." + except Exception as e: + return f"Error updating LLM and embeddings settings: {str(e)}" + +def update_env_file(key, value): + env_path = 'indexing/.env' + with open(env_path, 'r') as file: + lines = file.readlines() + + updated = False + for i, line in enumerate(lines): + if line.startswith(f"{key}="): + lines[i] = f"{key}={value}\n" + updated = True + break + + if not updated: + lines.append(f"{key}={value}\n") + + with open(env_path, 'w') as file: + file.writelines(lines) + +custom_css = """ +html, body { + margin: 0; + padding: 0; + height: 100vh; + overflow: hidden; +} + +.gradio-container { + margin: 0 !important; + padding: 0 !important; + width: 100vw !important; + max-width: 100vw !important; + height: 100vh !important; + max-height: 100vh !important; + overflow: auto; + display: flex; + flex-direction: column; +} + +#main-container { + flex: 1; + display: flex; + overflow: hidden; +} + +#left-column, #right-column { + height: 100%; + overflow-y: auto; + padding: 10px; +} + +#left-column { + flex: 1; +} + +#right-column { + flex: 2; + display: flex; + flex-direction: column; +} + +#chat-container { + flex: 0 0 auto; /* Don't allow this to grow */ + height: 100%; + display: flex; + flex-direction: column; + overflow: hidden; + border: 1px solid var(--color-accent); + border-radius: 8px; + padding: 10px; + overflow-y: auto; +} + +#chatbot { + overflow-y: hidden; + height: 100%; +} + +#chat-input-row { + margin-top: 10px; +} + +#visualization-plot { + width: 100%; + aspect-ratio: 1 / 1; + max-height: 600px; /* Adjust this value as needed */ +} + +#vis-controls-row { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 10px; +} + +#vis-controls-row > * { + flex: 1; + margin: 0 5px; +} + +#vis-status { + margin-top: 10px; +} + +/* Chat input styling */ +#chat-input-row { + display: flex; + flex-direction: column; +} + +#chat-input-row > div { + width: 100% !important; +} + +#chat-input-row input[type="text"] { + width: 100% !important; +} + +/* Adjust padding for all containers */ +.gr-box, .gr-form, .gr-panel { + padding: 10px !important; +} + +/* Ensure all textboxes and textareas have full height */ +.gr-textbox, .gr-textarea { + height: auto !important; + min-height: 100px !important; +} + +/* Ensure all dropdowns have full width */ +.gr-dropdown { + width: 100% !important; +} + +:root { + --color-background: #2C3639; + --color-foreground: #3F4E4F; + --color-accent: #A27B5C; + --color-text: #DCD7C9; +} + +body, .gradio-container { + background-color: var(--color-background); + color: var(--color-text); +} + +.gr-button { + background-color: var(--color-accent); + color: var(--color-text); +} + +.gr-input, .gr-textarea, .gr-dropdown { + background-color: var(--color-foreground); + color: var(--color-text); + border: 1px solid var(--color-accent); +} + +.gr-panel { + background-color: var(--color-foreground); + border: 1px solid var(--color-accent); +} + +.gr-box { + border-radius: 8px; + margin-bottom: 10px; + background-color: var(--color-foreground); +} + +.gr-padded { + padding: 10px; +} + +.gr-form { + background-color: var(--color-foreground); +} + +.gr-input-label, .gr-radio-label { + color: var(--color-text); +} + +.gr-checkbox-label { + color: var(--color-text); +} + +.gr-markdown { + color: var(--color-text); +} + +.gr-accordion { + background-color: var(--color-foreground); + border: 1px solid var(--color-accent); +} + +.gr-accordion-header { + background-color: var(--color-accent); + color: var(--color-text); +} + +#visualization-container { + display: flex; + flex-direction: column; + border: 2px solid var(--color-accent); + border-radius: 8px; + margin-top: 20px; + padding: 10px; + background-color: var(--color-foreground); + height: calc(100vh - 300px); /* Adjust this value as needed */ +} + +#visualization-plot { + width: 100%; + height: 100%; +} + +#vis-controls-row { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 10px; +} + +#vis-controls-row > * { + flex: 1; + margin: 0 5px; +} + +#vis-status { + margin-top: 10px; +} + +#log-container { + background-color: var(--color-foreground); + border: 1px solid var(--color-accent); + border-radius: 8px; + padding: 10px; + margin-top: 20px; + max-height: auto; + overflow-y: auto; +} + +.setting-accordion .label-wrap { + cursor: pointer; +} + +.setting-accordion .icon { + transition: transform 0.3s ease; +} + +.setting-accordion[open] .icon { + transform: rotate(90deg); +} + +.gr-form.gr-box { + border: none !important; + background: none !important; +} + +.model-params { + border-top: 1px solid var(--color-accent); + margin-top: 10px; + padding-top: 10px; +} +""" + +def list_output_files(root_dir): + output_dir = os.path.join(root_dir, "output") + files = [] + for root, _, filenames in os.walk(output_dir): + for filename in filenames: + files.append(os.path.join(root, filename)) + return files + +def update_file_list(): + files = list_input_files() + return gr.update(choices=[f["path"] for f in files]) + +def update_file_content(file_path): + if not file_path: + return "" + try: + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + return content + except Exception as e: + logging.error(f"Error reading file: {str(e)}") + return f"Error reading file: {str(e)}" + +def list_output_folders(root_dir): + output_dir = os.path.join(root_dir, "output") + folders = [f for f in os.listdir(output_dir) if os.path.isdir(os.path.join(output_dir, f))] + return sorted(folders, reverse=True) + +def list_folder_contents(folder_path): + contents = [] + for item in os.listdir(folder_path): + item_path = os.path.join(folder_path, item) + if os.path.isdir(item_path): + contents.append(f"[DIR] {item}") + else: + _, ext = os.path.splitext(item) + contents.append(f"[{ext[1:].upper()}] {item}") + return contents + +def update_output_folder_list(): + root_dir = "./" + folders = list_output_folders(root_dir) + return gr.update(choices=folders, value=folders[0] if folders else None) + +def update_folder_content_list(folder_name): + root_dir = "./" + if not folder_name: + return gr.update(choices=[]) + contents = list_folder_contents(os.path.join(root_dir, "output", folder_name, "artifacts")) + return gr.update(choices=contents) + +def handle_content_selection(folder_name, selected_item): + root_dir = "./" + if isinstance(selected_item, list) and selected_item: + selected_item = selected_item[0] # Take the first item if it's a list + + if isinstance(selected_item, str) and selected_item.startswith("[DIR]"): + dir_name = selected_item[6:] # Remove "[DIR] " prefix + sub_contents = list_folder_contents(os.path.join(root_dir, "output", folder_name, dir_name)) + return gr.update(choices=sub_contents), "", "" + elif isinstance(selected_item, str): + file_name = selected_item.split("] ")[1] if "]" in selected_item else selected_item # Remove file type prefix if present + file_path = os.path.join(root_dir, "output", folder_name, "artifacts", file_name) + file_size = os.path.getsize(file_path) + file_type = os.path.splitext(file_name)[1] + file_info = f"File: {file_name}\nSize: {file_size} bytes\nType: {file_type}" + content = read_file_content(file_path) + return gr.update(), file_info, content + else: + return gr.update(), "", "" + +def initialize_selected_folder(folder_name): + root_dir = "./" + if not folder_name: + return "Please select a folder first.", gr.update(choices=[]) + folder_path = os.path.join(root_dir, "output", folder_name, "artifacts") + if not os.path.exists(folder_path): + return f"Artifacts folder not found in '{folder_name}'.", gr.update(choices=[]) + contents = list_folder_contents(folder_path) + return f"Folder '{folder_name}/artifacts' initialized with {len(contents)} items.", gr.update(choices=contents) + + +settings = load_settings() +default_model = settings['llm']['model'] +cli_args = gr.State({}) +stop_indexing = threading.Event() +indexing_thread = None + +def start_indexing(*args): + global indexing_thread, stop_indexing + stop_indexing = threading.Event() # Reset the stop_indexing event + indexing_thread = threading.Thread(target=run_indexing, args=args) + indexing_thread.start() + return gr.update(interactive=False), gr.update(interactive=True), gr.update(interactive=False) + +def stop_indexing_process(): + global indexing_thread + logging.info("Stop indexing requested") + stop_indexing.set() + if indexing_thread and indexing_thread.is_alive(): + logging.info("Waiting for indexing thread to finish") + indexing_thread.join(timeout=10) + logging.info("Indexing thread finished" if not indexing_thread.is_alive() else "Indexing thread did not finish within timeout") + indexing_thread = None # Reset the thread + return gr.update(interactive=True), gr.update(interactive=False), gr.update(interactive=True) + +def refresh_indexing(): + global indexing_thread, stop_indexing + if indexing_thread and indexing_thread.is_alive(): + logging.info("Cannot refresh: Indexing is still running") + return gr.update(interactive=False), gr.update(interactive=True), gr.update(interactive=False), "Cannot refresh: Indexing is still running" + else: + stop_indexing = threading.Event() # Reset the stop_indexing event + indexing_thread = None # Reset the thread + return gr.update(interactive=True), gr.update(interactive=False), gr.update(interactive=True), "Indexing process refreshed. You can start indexing again." + + + +def run_indexing(root_dir, config_file, verbose, nocache, resume, reporter, emit_formats, custom_args): + cmd = ["python", "-m", "graphrag.index", "--root", "./indexing"] + + # Add custom CLI arguments + if custom_args: + cmd.extend(custom_args.split()) + + logging.info(f"Executing command: {' '.join(cmd)}") + + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1, encoding='utf-8', universal_newlines=True) + + + output = [] + progress_value = 0 + iterations_completed = 0 + + while True: + if stop_indexing.is_set(): + process.terminate() + process.wait(timeout=5) + if process.poll() is None: + process.kill() + return ("\n".join(output + ["Indexing stopped by user."]), + "Indexing stopped.", + 100, + gr.update(interactive=True), + gr.update(interactive=False), + gr.update(interactive=True), + str(iterations_completed)) + + try: + line = process.stdout.readline() + if not line and process.poll() is not None: + break + + if line: + line = line.strip() + output.append(line) + + if "Processing file" in line: + progress_value += 1 + iterations_completed += 1 + elif "Indexing completed" in line: + progress_value = 100 + elif "ERROR" in line: + line = f"🚨 ERROR: {line}" + + yield ("\n".join(output), + line, + progress_value, + gr.update(interactive=False), + gr.update(interactive=True), + gr.update(interactive=False), + str(iterations_completed)) + except Exception as e: + logging.error(f"Error during indexing: {str(e)}") + return ("\n".join(output + [f"Error: {str(e)}"]), + "Error occurred during indexing.", + 100, + gr.update(interactive=True), + gr.update(interactive=False), + gr.update(interactive=True), + str(iterations_completed)) + + if process.returncode != 0 and not stop_indexing.is_set(): + final_output = "\n".join(output + [f"Error: Process exited with return code {process.returncode}"]) + final_progress = "Indexing failed. Check output for details." + else: + final_output = "\n".join(output) + final_progress = "Indexing completed successfully!" + + return (final_output, + final_progress, + 100, + gr.update(interactive=True), + gr.update(interactive=False), + gr.update(interactive=True), + str(iterations_completed)) + +global_vector_store_wrapper = None + +def create_gradio_interface(): + global global_vector_store_wrapper + llm_models, embeddings_models, llm_service_type, embeddings_service_type, llm_api_base, embeddings_api_base, text_embedder = initialize_models() + settings = load_settings() + + + log_output = gr.TextArea(label="Logs", elem_id="log-output", interactive=False, visible=False) + + with gr.Blocks(css=custom_css, theme=gr.themes.Base()) as demo: + gr.Markdown("# GraphRAG Local UI", elem_id="title") + + with gr.Row(elem_id="main-container"): + with gr.Column(scale=1, elem_id="left-column"): + with gr.Tabs(): + with gr.TabItem("Data Management"): + with gr.Accordion("File Upload (.txt)", open=True): + file_upload = gr.File(label="Upload .txt File", file_types=[".txt"]) + upload_btn = gr.Button("Upload File", variant="primary") + upload_output = gr.Textbox(label="Upload Status", visible=False) + + with gr.Accordion("File Management", open=True): + file_list = gr.Dropdown(label="Select File", choices=[], interactive=True) + refresh_btn = gr.Button("Refresh File List", variant="secondary") + + file_content = gr.TextArea(label="File Content", lines=10) + + with gr.Row(): + delete_btn = gr.Button("Delete Selected File", variant="stop") + save_btn = gr.Button("Save Changes", variant="primary") + + operation_status = gr.Textbox(label="Operation Status", visible=False) + + + + with gr.TabItem("Indexing"): + root_dir = gr.Textbox(label="Root Directory", value="./") + config_file = gr.File(label="Config File (optional)") + with gr.Row(): + verbose = gr.Checkbox(label="Verbose", value=True) + nocache = gr.Checkbox(label="No Cache", value=True) + with gr.Row(): + resume = gr.Textbox(label="Resume Timestamp (optional)") + reporter = gr.Dropdown(label="Reporter", choices=["rich", "print", "none"], value=None) + with gr.Row(): + emit_formats = gr.CheckboxGroup(label="Emit Formats", choices=["json", "csv", "parquet"], value=None) + with gr.Row(): + run_index_button = gr.Button("Run Indexing") + stop_index_button = gr.Button("Stop Indexing", variant="stop") + refresh_index_button = gr.Button("Refresh Indexing", variant="secondary") + + with gr.Accordion("Custom CLI Arguments", open=True): + custom_cli_args = gr.Textbox( + label="Custom CLI Arguments", + placeholder="--arg1 value1 --arg2 value2", + lines=3 + ) + cli_guide = gr.Markdown( + textwrap.dedent(""" + ### CLI Argument Key Guide: + - `--root `: Set the root directory for the project + - `--config `: Specify a custom configuration file + - `--verbose`: Enable verbose output + - `--nocache`: Disable caching + - `--resume `: Resume from a specific timestamp + - `--reporter `: Set the reporter type (rich, print, none) + - `--emit `: Specify output formats (json, csv, parquet) + + Example: `--verbose --nocache --emit json,csv` + """) + ) + + index_output = gr.Textbox(label="Indexing Output", lines=20, max_lines=30) + index_progress = gr.Textbox(label="Indexing Progress", lines=3) + iterations_completed = gr.Textbox(label="Iterations Completed", value="0") + refresh_status = gr.Textbox(label="Refresh Status", visible=True) + + run_index_button.click( + fn=start_indexing, + inputs=[root_dir, config_file, verbose, nocache, resume, reporter, emit_formats, custom_cli_args], + outputs=[run_index_button, stop_index_button, refresh_index_button] + ).then( + fn=run_indexing, + inputs=[root_dir, config_file, verbose, nocache, resume, reporter, emit_formats, custom_cli_args], + outputs=[index_output, index_progress, run_index_button, stop_index_button, refresh_index_button, iterations_completed] + ) + + stop_index_button.click( + fn=stop_indexing_process, + outputs=[run_index_button, stop_index_button, refresh_index_button] + ) + + refresh_index_button.click( + fn=refresh_indexing, + outputs=[run_index_button, stop_index_button, refresh_index_button, refresh_status] + ) + + with gr.TabItem("Indexing Outputs/Visuals"): + output_folder_list = gr.Dropdown(label="Select Output Folder (Select GraphML File to Visualize)", choices=list_output_folders("./indexing"), interactive=True) + refresh_folder_btn = gr.Button("Refresh Folder List", variant="secondary") + initialize_folder_btn = gr.Button("Initialize Selected Folder", variant="primary") + folder_content_list = gr.Dropdown(label="Select File or Directory", choices=[], interactive=True) + file_info = gr.Textbox(label="File Information", interactive=False) + output_content = gr.TextArea(label="File Content", lines=20, interactive=False) + initialization_status = gr.Textbox(label="Initialization Status") + + with gr.TabItem("LLM Settings"): + llm_base_url = gr.Textbox(label="LLM API Base URL", value=os.getenv("LLM_API_BASE")) + llm_api_key = gr.Textbox(label="LLM API Key", value=os.getenv("LLM_API_KEY"), type="password") + llm_service_type = gr.Radio( + label="LLM Service Type", + choices=["openai", "ollama"], + value="openai", + visible=False # Hide this if you want to always use OpenAI + ) + + llm_model_dropdown = gr.Dropdown( + label="LLM Model", + choices=[], # Start with an empty list + value=settings['llm'].get('model'), + allow_custom_value=True + ) + refresh_llm_models_btn = gr.Button("Refresh LLM Models", variant="secondary") + + embeddings_base_url = gr.Textbox(label="Embeddings API Base URL", value=os.getenv("EMBEDDINGS_API_BASE")) + embeddings_api_key = gr.Textbox(label="Embeddings API Key", value=os.getenv("EMBEDDINGS_API_KEY"), type="password") + embeddings_service_type = gr.Radio( + label="Embeddings Service Type", + choices=["openai", "ollama"], + value=settings.get('embeddings', {}).get('llm', {}).get('type', 'openai'), + visible=False, + ) + + embeddings_model_dropdown = gr.Dropdown( + label="Embeddings Model", + choices=[], + value=settings.get('embeddings', {}).get('llm', {}).get('model'), + allow_custom_value=True + ) + refresh_embeddings_models_btn = gr.Button("Refresh Embedding Models", variant="secondary") + system_message = gr.Textbox( + lines=5, + label="System Message", + value=os.getenv("SYSTEM_MESSAGE", "You are a helpful AI assistant.") + ) + context_window = gr.Slider( + label="Context Window", + minimum=512, + maximum=32768, + step=512, + value=int(os.getenv("CONTEXT_WINDOW", 4096)) + ) + temperature = gr.Slider( + label="Temperature", + minimum=0.0, + maximum=2.0, + step=0.1, + value=float(settings['llm'].get('TEMPERATURE', 0.5)) + ) + max_tokens = gr.Slider( + label="Max Tokens", + minimum=1, + maximum=8192, + step=1, + value=int(settings['llm'].get('MAX_TOKENS', 1024)) + ) + update_settings_btn = gr.Button("Update LLM Settings", variant="primary") + llm_settings_status = gr.Textbox(label="Status", interactive=False) + + llm_base_url.change( + fn=update_model_choices, + inputs=[llm_base_url, llm_api_key, llm_service_type, gr.Textbox(value='llm', visible=False)], + outputs=llm_model_dropdown + ) + # Update Embeddings model choices when service type or base URL changes + embeddings_service_type.change( + fn=update_embeddings_model_choices, + inputs=[embeddings_base_url, embeddings_api_key, embeddings_service_type], + outputs=embeddings_model_dropdown + ) + + embeddings_base_url.change( + fn=update_model_choices, + inputs=[embeddings_base_url, embeddings_api_key, embeddings_service_type, gr.Textbox(value='embeddings', visible=False)], + outputs=embeddings_model_dropdown + ) + + update_settings_btn.click( + fn=update_llm_settings, + inputs=[ + llm_model_dropdown, + embeddings_model_dropdown, + context_window, + system_message, + temperature, + max_tokens, + llm_base_url, + llm_api_key, + embeddings_base_url, + embeddings_api_key, + embeddings_service_type + ], + outputs=[llm_settings_status] + ) + + + refresh_llm_models_btn.click( + fn=update_model_choices, + inputs=[llm_base_url, llm_api_key, llm_service_type, gr.Textbox(value='llm', visible=False)], + outputs=[llm_model_dropdown] + ).then( + fn=update_logs, + outputs=[log_output] + ) + + refresh_embeddings_models_btn.click( + fn=update_model_choices, + inputs=[embeddings_base_url, embeddings_api_key, embeddings_service_type, gr.Textbox(value='embeddings', visible=False)], + outputs=[embeddings_model_dropdown] + ).then( + fn=update_logs, + outputs=[log_output] + ) + + with gr.TabItem("YAML Settings"): + settings = load_settings() + with gr.Group(): + for key, value in settings.items(): + if key != 'llm': + create_setting_component(key, value) + + with gr.Group(elem_id="log-container"): + gr.Markdown("### Logs") + log_output = gr.TextArea(label="Logs", elem_id="log-output", interactive=False) + + with gr.Column(scale=2, elem_id="right-column"): + with gr.Group(elem_id="chat-container"): + chatbot = gr.Chatbot(label="Chat History", elem_id="chatbot") + with gr.Row(elem_id="chat-input-row"): + with gr.Column(scale=1): + query_input = gr.Textbox( + label="Input", + placeholder="Enter your query here...", + elem_id="query-input" + ) + query_btn = gr.Button("Send Query", variant="primary") + + with gr.Accordion("Query Parameters", open=True): + query_type = gr.Radio( + ["global", "local", "direct"], + label="Query Type", + value="global", + info="Global: community-based search, Local: entity-based search, Direct: LLM chat" + ) + preset_dropdown = gr.Dropdown( + label="Preset Query Options", + choices=[ + "Default Global Search", + "Default Local Search", + "Detailed Global Analysis", + "Detailed Local Analysis", + "Quick Global Summary", + "Quick Local Summary", + "Global Bullet Points", + "Local Bullet Points", + "Comprehensive Global Report", + "Comprehensive Local Report", + "High-Level Global Overview", + "High-Level Local Overview", + "Focused Global Insight", + "Focused Local Insight", + "Custom Query" + ], + value="Default Global Search", + info="Select a preset or choose 'Custom Query' for manual configuration" + ) + selected_folder = gr.Dropdown( + label="Select Index Folder to Chat With", + choices=list_output_folders("./indexing"), + value=None, + interactive=True + ) + refresh_folder_btn = gr.Button("Refresh Folders", variant="secondary") + clear_chat_btn = gr.Button("Clear Chat", variant="secondary") + + with gr.Group(visible=False) as custom_options: + community_level = gr.Slider( + label="Community Level", + minimum=1, + maximum=10, + value=2, + step=1, + info="Higher values use reports on smaller communities" + ) + response_type = gr.Dropdown( + label="Response Type", + choices=[ + "Multiple Paragraphs", + "Single Paragraph", + "Single Sentence", + "List of 3-7 Points", + "Single Page", + "Multi-Page Report" + ], + value="Multiple Paragraphs", + info="Specify the desired format of the response" + ) + custom_cli_args = gr.Textbox( + label="Custom CLI Arguments", + placeholder="--arg1 value1 --arg2 value2", + info="Additional CLI arguments for advanced users" + ) + + def update_custom_options(preset): + if preset == "Custom Query": + return gr.update(visible=True) + else: + return gr.update(visible=False) + + preset_dropdown.change(fn=update_custom_options, inputs=[preset_dropdown], outputs=[custom_options]) + + + + + with gr.Group(elem_id="visualization-container"): + vis_output = gr.Plot(label="Graph Visualization", elem_id="visualization-plot") + with gr.Row(elem_id="vis-controls-row"): + vis_btn = gr.Button("Visualize Graph", variant="secondary") + + # Add new controls for customization + with gr.Accordion("Visualization Settings", open=False): + layout_type = gr.Dropdown(["3D Spring", "2D Spring", "Circular"], label="Layout Type", value="3D Spring") + node_size = gr.Slider(1, 20, 7, label="Node Size", step=1) + edge_width = gr.Slider(0.1, 5, 0.5, label="Edge Width", step=0.1) + node_color_attribute = gr.Dropdown(["Degree", "Random"], label="Node Color Attribute", value="Degree") + color_scheme = gr.Dropdown(["Viridis", "Plasma", "Inferno", "Magma", "Cividis"], label="Color Scheme", value="Viridis") + show_labels = gr.Checkbox(label="Show Node Labels", value=True) + label_size = gr.Slider(5, 20, 10, label="Label Size", step=1) + + + # Event handlers + upload_btn.click(fn=upload_file, inputs=[file_upload], outputs=[upload_output, file_list, log_output]) + refresh_btn.click(fn=update_file_list, outputs=[file_list]).then( + fn=update_logs, + outputs=[log_output] + ) + file_list.change(fn=update_file_content, inputs=[file_list], outputs=[file_content]).then( + fn=update_logs, + outputs=[log_output] + ) + delete_btn.click(fn=delete_file, inputs=[file_list], outputs=[operation_status, file_list, log_output]) + save_btn.click(fn=save_file_content, inputs=[file_list, file_content], outputs=[operation_status, log_output]) + + refresh_folder_btn.click( + fn=lambda: gr.update(choices=list_output_folders("./indexing")), + outputs=[selected_folder] + ) + + clear_chat_btn.click( + fn=lambda: ([], ""), + outputs=[chatbot, query_input] + ) + + refresh_folder_btn.click( + fn=update_output_folder_list, + outputs=[output_folder_list] + ).then( + fn=update_logs, + outputs=[log_output] + ) + + output_folder_list.change( + fn=update_folder_content_list, + inputs=[output_folder_list], + outputs=[folder_content_list] + ).then( + fn=update_logs, + outputs=[log_output] + ) + + folder_content_list.change( + fn=handle_content_selection, + inputs=[output_folder_list, folder_content_list], + outputs=[folder_content_list, file_info, output_content] + ).then( + fn=update_logs, + outputs=[log_output] + ) + + initialize_folder_btn.click( + fn=initialize_selected_folder, + inputs=[output_folder_list], + outputs=[initialization_status, folder_content_list] + ).then( + fn=update_logs, + outputs=[log_output] + ) + + vis_btn.click( + fn=update_visualization, + inputs=[ + output_folder_list, + folder_content_list, + layout_type, + node_size, + edge_width, + node_color_attribute, + color_scheme, + show_labels, + label_size + ], + outputs=[vis_output, gr.Textbox(label="Visualization Status")] + ) + + query_btn.click( + fn=send_message, + inputs=[ + query_type, + query_input, + chatbot, + system_message, + temperature, + max_tokens, + preset_dropdown, + community_level, + response_type, + custom_cli_args, + selected_folder + ], + outputs=[chatbot, query_input, log_output] + ) + + query_input.submit( + fn=send_message, + inputs=[ + query_type, + query_input, + chatbot, + system_message, + temperature, + max_tokens, + preset_dropdown, + community_level, + response_type, + custom_cli_args, + selected_folder + ], + outputs=[chatbot, query_input, log_output] + ) + refresh_llm_models_btn.click( + fn=update_model_choices, + inputs=[llm_base_url, llm_api_key, llm_service_type, gr.Textbox(value='llm', visible=False)], + outputs=[llm_model_dropdown] + ) + + # Update Embeddings model choices + refresh_embeddings_models_btn.click( + fn=update_model_choices, + inputs=[embeddings_base_url, embeddings_api_key, embeddings_service_type, gr.Textbox(value='embeddings', visible=False)], + outputs=[embeddings_model_dropdown] + ) + + # Add this JavaScript to enable Shift+Enter functionality + demo.load(js=""" + function addShiftEnterListener() { + const queryInput = document.getElementById('query-input'); + if (queryInput) { + queryInput.addEventListener('keydown', function(event) { + if (event.key === 'Enter' && event.shiftKey) { + event.preventDefault(); + const submitButton = queryInput.closest('.gradio-container').querySelector('button.primary'); + if (submitButton) { + submitButton.click(); + } + } + }); + } + } + document.addEventListener('DOMContentLoaded', addShiftEnterListener); + """) + + return demo.queue() + +async def main(): + api_port = 8088 + gradio_port = 7860 + + + print(f"Starting API server on port {api_port}") + start_api_server(api_port) + + # Wait for the API server to start in a separate thread + threading.Thread(target=wait_for_api_server, args=(api_port,)).start() + + # Create the Gradio app + demo = create_gradio_interface() + + print(f"Starting Gradio app on port {gradio_port}") + # Launch the Gradio app + demo.launch(server_port=gradio_port, share=True) + + +demo = create_gradio_interface() +app = demo.app + +if __name__ == "__main__": + initialize_data() + demo.launch(server_port=7860, share=True) diff --git a/css b/css new file mode 100644 index 0000000000000000000000000000000000000000..6d6bac4ff3e77dd5918e31d1e12b1011a979fcf8 --- /dev/null +++ b/css @@ -0,0 +1,242 @@ +html, body { + margin: 0; + padding: 0; + height: 100vh; + overflow: hidden; +} + +.gradio-container { + margin: 0 !important; + padding: 0 !important; + width: 100vw !important; + max-width: 100vw !important; + height: 100vh !important; + max-height: 100vh !important; + overflow: auto; + display: flex; + flex-direction: column; +} + +#main-container { + flex: 1; + display: flex; + overflow: hidden; +} + +#left-column, #right-column { + height: 100%; + overflow-y: auto; + padding: 10px; +} + +#left-column { + flex: 1; +} + +#right-column { + flex: 2; + display: flex; + flex-direction: column; +} + +#chat-container { + flex: 0 0 auto; /* Don't allow this to grow */ + height: 100%; + display: flex; + flex-direction: column; + overflow: hidden; + border: 1px solid var(--color-accent); + border-radius: 8px; + padding: 10px; + overflow-y: auto; +} + +#chatbot { + overflow-y: hidden; + height: 100%; +} + +#chat-input-row { + margin-top: 10px; +} + +#visualization-plot { + width: 100%; + aspect-ratio: 1 / 1; + max-height: 600px; /* Adjust this value as needed */ +} + +#vis-controls-row { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 10px; +} + +#vis-controls-row > * { + flex: 1; + margin: 0 5px; +} + +#vis-status { + margin-top: 10px; +} + +/* Chat input styling */ +#chat-input-row { + display: flex; + flex-direction: column; +} + +#chat-input-row > div { + width: 100% !important; +} + +#chat-input-row input[type="text"] { + width: 100% !important; +} + +/* Adjust padding for all containers */ +.gr-box, .gr-form, .gr-panel { + padding: 10px !important; +} + +/* Ensure all textboxes and textareas have full height */ +.gr-textbox, .gr-textarea { + height: auto !important; + min-height: 100px !important; +} + +/* Ensure all dropdowns have full width */ +.gr-dropdown { + width: 100% !important; +} + +:root { + --color-background: #2C3639; + --color-foreground: #3F4E4F; + --color-accent: #A27B5C; + --color-text: #DCD7C9; +} + +body, .gradio-container { + background-color: var(--color-background); + color: var(--color-text); +} + +.gr-button { + background-color: var(--color-accent); + color: var(--color-text); +} + +.gr-input, .gr-textarea, .gr-dropdown { + background-color: var(--color-foreground); + color: var(--color-text); + border: 1px solid var(--color-accent); +} + +.gr-panel { + background-color: var(--color-foreground); + border: 1px solid var(--color-accent); +} + +.gr-box { + border-radius: 8px; + margin-bottom: 10px; + background-color: var(--color-foreground); +} + +.gr-padded { + padding: 10px; +} + +.gr-form { + background-color: var(--color-foreground); +} + +.gr-input-label, .gr-radio-label { + color: var(--color-text); +} + +.gr-checkbox-label { + color: var(--color-text); +} + +.gr-markdown { + color: var(--color-text); +} + +.gr-accordion { + background-color: var(--color-foreground); + border: 1px solid var(--color-accent); +} + +.gr-accordion-header { + background-color: var(--color-accent); + color: var(--color-text); +} + +#visualization-container { + display: flex; + flex-direction: column; + border: 2px solid var(--color-accent); + border-radius: 8px; + margin-top: 20px; + padding: 10px; + background-color: var(--color-foreground); + height: calc(100vh - 300px); /* Adjust this value as needed */ +} + +#visualization-plot { + width: 100%; + height: 100%; +} + +#vis-controls-row { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 10px; +} + +#vis-controls-row > * { + flex: 1; + margin: 0 5px; +} + +#vis-status { + margin-top: 10px; +} + +#log-container { + background-color: var(--color-foreground); + border: 1px solid var(--color-accent); + border-radius: 8px; + padding: 10px; + margin-top: 20px; + max-height: auto; + overflow-y: auto; +} + +.setting-accordion .label-wrap { + cursor: pointer; +} + +.setting-accordion .icon { + transition: transform 0.3s ease; +} + +.setting-accordion[open] .icon { + transform: rotate(90deg); +} + +.gr-form.gr-box { + border: none !important; + background: none !important; +} + +.model-params { + border-top: 1px solid var(--color-accent); + margin-top: 10px; + padding-top: 10px; +} \ No newline at end of file diff --git a/embedding_proxy.py b/embedding_proxy.py new file mode 100644 index 0000000000000000000000000000000000000000..c2d8f02049fbc504797f8e0d7d1c25e9d801c055 --- /dev/null +++ b/embedding_proxy.py @@ -0,0 +1,62 @@ +import json +from fastapi import FastAPI, HTTPException +import uvicorn +import httpx +from pydantic import BaseModel +from typing import List, Union + +app = FastAPI() + +OLLAMA_URL = "http://localhost:11434" # Default Ollama URL + +class EmbeddingRequest(BaseModel): + input: Union[str, List[str]] + model: str + +class EmbeddingResponse(BaseModel): + object: str + data: List[dict] + model: str + usage: dict + +@app.post("/v1/embeddings") +async def create_embedding(request: EmbeddingRequest): + async with httpx.AsyncClient() as client: + if isinstance(request.input, str): + request.input = [request.input] + + ollama_requests = [{"model": request.model, "prompt": text} for text in request.input] + + embeddings = [] + + + for i, ollama_request in enumerate(ollama_requests): + response = await client.post(f"{OLLAMA_URL}/api/embeddings", json=ollama_request) + if response.status_code != 200: + raise HTTPException(status_code=response.status_code, detail="Ollama API error") + + result = response.json() + embeddings.append({ + "object": "embedding", + "embedding": result["embedding"], + "index": i + }) + + + return EmbeddingResponse( + object="list", + data=embeddings, + model=request.model, + + ) + +if __name__ == "__main__": + import argparse + parser = argparse.ArgumentParser(description="Run the embedding proxy server") + parser.add_argument("--port", type=int, default=11435, help="Port to run the server on") + parser.add_argument("--host", type=str, default="http://localhost:11434", help="URL of the Ollama server") + parser.add_argument("--reload", action="store_true", help="Enable auto-reload for development") + args = parser.parse_args() + + OLLAMA_URL = args.host + uvicorn.run("embedding_proxy:app", host="0.0.0.0", port=args.port, reload=args.reload) diff --git a/graphrag/.github/ISSUE_TEMPLATE.md b/graphrag/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000000000000000000000000000000000..ac8e9a602071594e572b1f1523c87e37f28305e5 --- /dev/null +++ b/graphrag/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,69 @@ +### Description + + + +### Environment + +- GraphRAG version: +- Python version: +- Operating System: + +### Steps to Reproduce (for bugs) + + + +1. Step 1 +2. Step 2 +3. ... + +### Expected Behavior + + + +### Actual Behavior + + + +### Screenshots / Logs (if applicable) + + + +### GraphRAG Configuration + + + +### Additional Information + + + +### Possible Solution (if you have one) + + + +### Is this a Bug or Feature Request? + + + +### Any related issues? + + + +### Any relevant discussions? + + + +### Checklist + + + +- [ ] I have searched for similar issues and didn't find any duplicates. +- [ ] I have provided a clear and concise description of the issue. +- [ ] I have included the necessary environment details. +- [ ] I have outlined the steps to reproduce the issue. +- [ ] I have included any relevant logs or screenshots. +- [ ] I have included the GraphRAG configuration for this run. +- [ ] I have indicated whether this is a bug or a feature request. + +### Additional Comments + + diff --git a/graphrag/.github/ISSUE_TEMPLATE/bug_report.yml b/graphrag/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000000000000000000000000000000000000..369a8a2564ef096e1b46e53c0cb19aaaba66dfe9 --- /dev/null +++ b/graphrag/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,57 @@ +name: Bug Report +description: File a bug report +title: "[Bug]: " +labels: ["bug", "triage"] + +body: + - type: textarea + id: description + attributes: + label: Describe the bug + description: A clear and concise description of what the bug is. + placeholder: What went wrong? + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce + description: | + Steps to reproduce the behavior: + + 1. Step 1 + 2. Step 2 + 3. ... + 4. See error + placeholder: How can we replicate the issue? + - type: textarea + id: expected_behavior + attributes: + label: Expected Behavior + description: A clear and concise description of what you expected to happen. + placeholder: What should have happened? + - type: textarea + id: configused + attributes: + label: GraphRAG Config Used + description: The GraphRAG configuration used for the run. + placeholder: The settings.yaml content or GraphRAG configuration + - type: textarea + id: screenshotslogs + attributes: + label: Logs and screenshots + description: If applicable, add screenshots and logs to help explain your problem. + placeholder: Add logs and screenshots here + - type: textarea + id: additional_information + attributes: + label: Additional Information + description: | + - GraphRAG Version: e.g., v0.1.1 + - Operating System: e.g., Windows 10, Ubuntu 20.04 + - Python Version: e.g., 3.8 + - Related Issues: e.g., #1 + - Any other relevant information. + value: | + - GraphRAG Version: + - Operating System: + - Python Version: + - Related Issues: diff --git a/graphrag/.github/ISSUE_TEMPLATE/config.yml b/graphrag/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..0086358db1eb971c0cfa8739c27518bbc18a5ff4 --- /dev/null +++ b/graphrag/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: true diff --git a/graphrag/.github/ISSUE_TEMPLATE/feature_request.yml b/graphrag/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000000000000000000000000000000000000..585d63aa75c7158bfa89da72f9c7c273c8940067 --- /dev/null +++ b/graphrag/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,26 @@ +name: Feature Request +description: File a feature request +labels: ["enhancement"] +title: "[Feature Request]: <title>" + +body: + - type: textarea + id: problem_description + attributes: + label: Is your feature request related to a problem? Please describe. + description: A clear and concise description of what the problem is. + placeholder: What problem are you trying to solve? + + - type: textarea + id: solution_description + attributes: + label: Describe the solution you'd like + description: A clear and concise description of what you want to happen. + placeholder: How do you envision the solution? + + - type: textarea + id: additional_context + attributes: + label: Additional context + description: Add any other context or screenshots about the feature request here. + placeholder: Any additional information diff --git a/graphrag/.github/ISSUE_TEMPLATE/general_issue.yml b/graphrag/.github/ISSUE_TEMPLATE/general_issue.yml new file mode 100644 index 0000000000000000000000000000000000000000..852bf9583a05eb55e25036e317e45261b8955c40 --- /dev/null +++ b/graphrag/.github/ISSUE_TEMPLATE/general_issue.yml @@ -0,0 +1,51 @@ +name: General Issue +description: File a general issue +title: "[Issue]: <title> " +labels: ["triage"] + +body: + - type: textarea + id: description + attributes: + label: Describe the issue + description: A clear and concise description of what the issue is. + placeholder: What went wrong? + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce + description: | + Steps to reproduce the behavior: + + 1. Step 1 + 2. Step 2 + 3. ... + 4. See error + placeholder: How can we replicate the issue? + - type: textarea + id: configused + attributes: + label: GraphRAG Config Used + description: The GraphRAG configuration used for the run. + placeholder: The settings.yaml content or GraphRAG configuration + - type: textarea + id: screenshotslogs + attributes: + label: Logs and screenshots + description: If applicable, add screenshots and logs to help explain your problem. + placeholder: Add logs and screenshots here + - type: textarea + id: additional_information + attributes: + label: Additional Information + description: | + - GraphRAG Version: e.g., v0.1.1 + - Operating System: e.g., Windows 10, Ubuntu 20.04 + - Python Version: e.g., 3.8 + - Related Issues: e.g., #1 + - Any other relevant information. + value: | + - GraphRAG Version: + - Operating System: + - Python Version: + - Related Issues: diff --git a/graphrag/.github/dependabot.yml b/graphrag/.github/dependabot.yml new file mode 100644 index 0000000000000000000000000000000000000000..3da41ebe5e2e62c8c1067b68bececd7a438a8f55 --- /dev/null +++ b/graphrag/.github/dependabot.yml @@ -0,0 +1,19 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file +version: 2 +updates: + - package-ecosystem: "npm" # See documentation for possible values + directory: "docsite/" # Location of package manifests + schedule: + interval: "weekly" + - package-ecosystem: "pip" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" + - package-ecosystem: "github-actions" + # Workflow files stored in the default location of `.github/workflows`. (You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`.) + directory: "/" + schedule: + interval: "weekly" diff --git a/graphrag/.github/pull_request_template.md b/graphrag/.github/pull_request_template.md new file mode 100644 index 0000000000000000000000000000000000000000..49ceff49e93f1ab3d5ad2de78e5075943cadeafc --- /dev/null +++ b/graphrag/.github/pull_request_template.md @@ -0,0 +1,36 @@ +<!-- +Thanks for contributing to GraphRAG! + +Please do not make *Draft* pull requests, as they still notify anyone watching the repo. + +Create a pull request when it is ready for review and feedback. + +About this template + +The following template aims to help contributors write a good description for their pull requests. +We'd like you to provide a description of the changes in your pull request (i.e. bugs fixed or features added), the motivation behind the changes, and complete the checklist below before opening a pull request. + +Feel free to discard it if you need to (e.g. when you just fix a typo). --> + +## Description + +[Provide a brief description of the changes made in this pull request.] + +## Related Issues + +[Reference any related issues or tasks that this pull request addresses.] + +## Proposed Changes + +[List the specific changes made in this pull request.] + +## Checklist + +- [ ] I have tested these changes locally. +- [ ] I have reviewed the code changes. +- [ ] I have updated the documentation (if necessary). +- [ ] I have added appropriate unit tests (if applicable). + +## Additional Notes + +[Add any additional notes or context that may be helpful for the reviewer(s).] diff --git a/graphrag/.github/workflows/gh-pages.yml b/graphrag/.github/workflows/gh-pages.yml new file mode 100644 index 0000000000000000000000000000000000000000..5ca57231cfb3f25ca5ac7b1538695e26da34f02b --- /dev/null +++ b/graphrag/.github/workflows/gh-pages.yml @@ -0,0 +1,97 @@ +name: gh-pages +on: + push: + branches: [main] + +permissions: + contents: write + +env: + POETRY_VERSION: 1.8.3 + PYTHON_VERSION: "3.11" + NODE_VERSION: 18.x + +jobs: + build: + runs-on: ubuntu-latest + env: + GH_PAGES: 1 + DEBUG: 1 + GRAPHRAG_LLM_TYPE: "azure_openai_chat" + GRAPHRAG_EMBEDDING_TYPE: "azure_openai_embedding" + GRAPHRAG_API_KEY: ${{ secrets.OPENAI_API_KEY }} + GRAPHRAG_API_BASE: ${{ secrets.GRAPHRAG_API_BASE }} + GRAPHRAG_API_VERSION: ${{ secrets.GRAPHRAG_API_VERSION }} + GRAPHRAG_LLM_DEPLOYMENT_NAME: ${{ secrets.GRAPHRAG_LLM_DEPLOYMENT_NAME }} + GRAPHRAG_EMBEDDING_DEPLOYMENT_NAME: ${{ secrets.GRAPHRAG_EMBEDDING_DEPLOYMENT_NAME }} + GRAPHRAG_CACHE_TYPE: "blob" + GRAPHRAG_CACHE_CONNECTION_STRING: ${{ secrets.BLOB_STORAGE_CONNECTION_STRING }} + GRAPHRAG_CACHE_CONTAINER_NAME: "cicache" + GRAPHRAG_CACHE_BASE_DIR": "cache" + GRAPHRAG_LLM_MODEL: gpt-3.5-turbo-16k + GRAPHRAG_EMBEDDING_MODEL: text-embedding-ada-002 + # We have Windows + Linux runners in 3.10 and 3.11, so we need to divide the rate limits by 4 + GRAPHRAG_LLM_TPM: 45_000 # 180,000 / 4 + GRAPHRAG_LLM_RPM: 270 # 1,080 / 4 + GRAPHRAG_EMBEDDING_TPM: 87_500 # 350,000 / 4 + GRAPHRAG_EMBEDDING_RPM: 525 # 2,100 / 4 + GRAPHRAG_CHUNK_SIZE: 1200 + GRAPHRAG_CHUNK_OVERLAP: 0 + # Azure AI Search config + AZURE_AI_SEARCH_URL_ENDPOINT: ${{ secrets.AZURE_AI_SEARCH_URL_ENDPOINT }} + AZURE_AI_SEARCH_API_KEY: ${{ secrets.AZURE_AI_SEARCH_API_KEY }} + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install Poetry ${{ env.POETRY_VERSION }} + uses: abatilo/actions-poetry@v3.0.0 + with: + poetry-version: ${{ env.POETRY_VERSION }} + + - name: Use Node ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Install Yarn dependencies + run: yarn install + working-directory: docsite + + - name: Install Poetry dependencies + run: poetry install + + - name: Install Azurite + id: azuright + uses: potatoqualitee/azuright@v1.1 + + - name: Generate Indexer Outputs + run: | + poetry run poe test_smoke + zip -jrm docsite/data/operation_dulce/dataset.zip tests/fixtures/min-csv/output/*/artifacts/*.parquet + + - name: Build Jupyter Notebooks + run: poetry run poe convert_docsite_notebooks + + - name: Build docsite + run: yarn build + working-directory: docsite + env: + DOCSITE_BASE_URL: "graphrag" + + - name: List docsite files + run: find docsite/_site + + - name: Deploy to GitHub Pages + uses: JamesIves/github-pages-deploy-action@v4.6.3 + with: + branch: gh-pages + folder: docsite/_site + clean: true diff --git a/graphrag/.github/workflows/javascript-ci.yml b/graphrag/.github/workflows/javascript-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..e1d45c6fc04d14f1589bdcbea627519f79eba714 --- /dev/null +++ b/graphrag/.github/workflows/javascript-ci.yml @@ -0,0 +1,30 @@ +name: JavaScript CI +on: + push: + branches: [main] + pull_request: + branches: [main] + +env: + NODE_VERSION: 18.x + +jobs: + javascript-ci: + runs-on: ubuntu-latest + strategy: + fail-fast: false + steps: + - name: Use Node ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - uses: actions/checkout@v4 + + - run: yarn install + working-directory: docsite + name: Install Dependencies + + - run: yarn build + working-directory: docsite + name: Build Docsite \ No newline at end of file diff --git a/graphrag/.github/workflows/python-ci.yml b/graphrag/.github/workflows/python-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..243f2cf02b53172d933781aaa7ffda2822f537bb --- /dev/null +++ b/graphrag/.github/workflows/python-ci.yml @@ -0,0 +1,122 @@ +name: Python CI +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + pull-requests: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + # Only run the for the latest commit + cancel-in-progress: true + +env: + POETRY_VERSION: 1.8.3 + +jobs: + python-ci: + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12"] + os: [ubuntu-latest, windows-latest] + env: + DEBUG: 1 + GRAPHRAG_LLM_TYPE: "azure_openai_chat" + GRAPHRAG_EMBEDDING_TYPE: "azure_openai_embedding" + GRAPHRAG_API_KEY: ${{ secrets.OPENAI_API_KEY }} + GRAPHRAG_API_BASE: ${{ secrets.GRAPHRAG_API_BASE }} + GRAPHRAG_API_VERSION: ${{ secrets.GRAPHRAG_API_VERSION }} + GRAPHRAG_LLM_DEPLOYMENT_NAME: ${{ secrets.GRAPHRAG_LLM_DEPLOYMENT_NAME }} + GRAPHRAG_EMBEDDING_DEPLOYMENT_NAME: ${{ secrets.GRAPHRAG_EMBEDDING_DEPLOYMENT_NAME }} + GRAPHRAG_CACHE_TYPE: "blob" + GRAPHRAG_CACHE_CONNECTION_STRING: ${{ secrets.BLOB_STORAGE_CONNECTION_STRING }} + GRAPHRAG_CACHE_CONTAINER_NAME: "cicache" + GRAPHRAG_CACHE_BASE_DIR": "cache" + GRAPHRAG_LLM_MODEL: gpt-3.5-turbo-16k + GRAPHRAG_EMBEDDING_MODEL: text-embedding-ada-002 + # We have Windows + Linux runners in 3.10 and 3.11, so we need to divide the rate limits by 4 + GRAPHRAG_LLM_TPM: 45_000 # 180,000 / 4 + GRAPHRAG_LLM_RPM: 270 # 1,080 / 4 + GRAPHRAG_EMBEDDING_TPM: 87_500 # 350,000 / 4 + GRAPHRAG_EMBEDDING_RPM: 525 # 2,100 / 4 + GRAPHRAG_CHUNK_SIZE: 1200 + GRAPHRAG_CHUNK_OVERLAP: 0 + # Azure AI Search config + AZURE_AI_SEARCH_URL_ENDPOINT: ${{ secrets.AZURE_AI_SEARCH_URL_ENDPOINT }} + AZURE_AI_SEARCH_API_KEY: ${{ secrets.AZURE_AI_SEARCH_API_KEY }} + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - uses: dorny/paths-filter@v3 + id: changes + with: + filters: | + python: + - 'graphrag/**/*' + - 'poetry.lock' + - 'pyproject.toml' + - '**/*.py' + - '**/*.toml' + - '**/*.ipynb' + - '.github/workflows/python*.yml' + - 'tests/smoke/*' + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install Poetry + uses: abatilo/actions-poetry@v3.0.0 + with: + poetry-version: $POETRY_VERSION + + - name: Install dependencies + shell: bash + run: poetry self add setuptools && poetry run python -m pip install gensim && poetry install + + - name: Check Semversioner + run: | + poetry run semversioner check + + - name: Check + run: | + poetry run poe check + + - name: Build + run: | + poetry build + + - name: Install Azurite + id: azuright + uses: potatoqualitee/azuright@v1.1 + + - name: Unit Test + run: | + poetry run poe test_unit + + - name: Integration Test + run: | + poetry run poe test_integration + + - name: Smoke Test + if: steps.changes.outputs.python == 'true' + run: | + poetry run poe test_smoke + + - uses: actions/upload-artifact@v4 + if: always() + with: + name: smoke-test-artifacts-${{ matrix.python-version }}-${{ matrix.poetry-version }}-${{ runner.os }} + path: tests/fixtures/*/output + + - name: E2E Test + if: steps.changes.outputs.python == 'true' + run: | + ./scripts/e2e-test.sh diff --git a/graphrag/.github/workflows/python-publish.yml b/graphrag/.github/workflows/python-publish.yml new file mode 100644 index 0000000000000000000000000000000000000000..b76d690564d164ffa842de5c0bbc0017322bf02b --- /dev/null +++ b/graphrag/.github/workflows/python-publish.yml @@ -0,0 +1,52 @@ +name: Python Publish +on: + release: + types: [created] + push: + branches: [main] + +env: + POETRY_VERSION: "1.8.3" + PYTHON_VERSION: "3.10" + +jobs: + publish: + name: Upload release to PyPI + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/graphrag + permissions: + id-token: write # IMPORTANT: this permission is mandatory for trusted publishing + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install Poetry + uses: abatilo/actions-poetry@v3.0.0 + with: + poetry-version: ${{ env.POETRY_VERSION }} + + - name: Install dependencies + shell: bash + run: poetry install + + - name: Build Distributable + shell: bash + run: poetry build + + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist + skip-existing: true + verbose: true diff --git a/graphrag/.github/workflows/semver.yml b/graphrag/.github/workflows/semver.yml new file mode 100644 index 0000000000000000000000000000000000000000..139b759a4015b58d65f93ad074600f6b713e9384 --- /dev/null +++ b/graphrag/.github/workflows/semver.yml @@ -0,0 +1,15 @@ +name: Semver Check +on: + pull_request: + branches: [main] + +jobs: + semver: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check Semver + run: ./scripts/semver-check.sh \ No newline at end of file diff --git a/graphrag/.github/workflows/spellcheck.yml b/graphrag/.github/workflows/spellcheck.yml new file mode 100644 index 0000000000000000000000000000000000000000..bbf2be9dfc992a34845e8c858eece7b4d554b2d4 --- /dev/null +++ b/graphrag/.github/workflows/spellcheck.yml @@ -0,0 +1,15 @@ +name: Spellcheck +on: + push: + branches: [main] + pull_request: + paths: + - '**/*' +jobs: + spellcheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Spellcheck + run: ./scripts/spellcheck.sh diff --git a/graphrag/.gitignore b/graphrag/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..bff8e24810d446d39878c2d1e71028b3a9299ed9 --- /dev/null +++ b/graphrag/.gitignore @@ -0,0 +1,68 @@ +# Node Artifacts +*/node_modules/ +docsite/*/src/**/*.js +docsite/*/lib/ +docsite/*/storybook-static/ +docsite/*/docsTemp/ +docsite/*/build/ +.swc/ +dist/ +.idea +# https://yarnpkg.com/advanced/qa#which-files-should-be-gitignored +docsite/.yarn/* +!docsite/.yarn/patches +!docsite/.yarn/releases +!docsite/.yarn/plugins +!docsite/.yarn/sdks +!docsite/.yarn/versions +docsite/.pnp.* + +.yarn/* +!.yarn/patches +!.yarn/releases +!.yarn/plugins +!.yarn/sdks +!.yarn/versions +.pnp.* + +# Python Artifacts +python/*/lib/ +# Test Output +.coverage +coverage/ +licenses.txt +examples_notebooks/*/lancedb +examples_notebooks/*/data +tests/fixtures/cache +tests/fixtures/*/cache +tests/fixtures/*/output +lancedb/ + +# Random +.DS_Store +*.log* +.venv +.conda +.tmp + + +.env +build.zip + +.turbo + +__pycache__ + +.pipeline + +# Azurite +temp_azurite/ +__azurite*.json +__blobstorage*.json +__blobstorage__/ + +# Getting started example +ragtest/ +.ragtest/ +.pipelines +.pipeline \ No newline at end of file diff --git a/graphrag/.semversioner/0.1.0.json b/graphrag/.semversioner/0.1.0.json new file mode 100644 index 0000000000000000000000000000000000000000..d1551513affe03b851ae5b0513d370c7b24f470b --- /dev/null +++ b/graphrag/.semversioner/0.1.0.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "description": "Initial Release", + "type": "minor" + } + ], + "created_at": "2024-07-01T21:48:50+00:00", + "version": "0.1.0" +} \ No newline at end of file diff --git a/graphrag/.semversioner/next-release/minor-20240710183748086411.json b/graphrag/.semversioner/next-release/minor-20240710183748086411.json new file mode 100644 index 0000000000000000000000000000000000000000..8e0f3659ac74cd71f9254b0d4abc38b65cb2bb13 --- /dev/null +++ b/graphrag/.semversioner/next-release/minor-20240710183748086411.json @@ -0,0 +1,4 @@ +{ + "type": "minor", + "description": "Add dynamic community report rating to the prompt tuning engine" +} diff --git a/graphrag/.semversioner/next-release/patch-20240701233152787373.json b/graphrag/.semversioner/next-release/patch-20240701233152787373.json new file mode 100644 index 0000000000000000000000000000000000000000..d2b107511abaf1350626ee09a53682d85ec69f55 --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240701233152787373.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Fix docsite base url" +} diff --git a/graphrag/.semversioner/next-release/patch-20240703152422358587.json b/graphrag/.semversioner/next-release/patch-20240703152422358587.json new file mode 100644 index 0000000000000000000000000000000000000000..37b415cc6d465642a429a03362d8bb595ae9eebd --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240703152422358587.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Add cli flag to overlay default values onto a provided config." +} diff --git a/graphrag/.semversioner/next-release/patch-20240703182750529114.json b/graphrag/.semversioner/next-release/patch-20240703182750529114.json new file mode 100644 index 0000000000000000000000000000000000000000..c36bb1f3b37a37a317df9bcb80b16cc5549a2e40 --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240703182750529114.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Fix broken prompt tuning link on docs" +} diff --git a/graphrag/.semversioner/next-release/patch-20240704181236015699.json b/graphrag/.semversioner/next-release/patch-20240704181236015699.json new file mode 100644 index 0000000000000000000000000000000000000000..9e69b50c4be7d119dcf7463a543260e75fa6c7e2 --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240704181236015699.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Fix for --limit exceeding the dataframe lenght" +} diff --git a/graphrag/.semversioner/next-release/patch-20240705184142723331.json b/graphrag/.semversioner/next-release/patch-20240705184142723331.json new file mode 100644 index 0000000000000000000000000000000000000000..8f4b32e9eaaac5eb9d395edf4cfac817991537b5 --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240705184142723331.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Add Minute-based Rate Limiting and fix rpm, tpm settings" +} diff --git a/graphrag/.semversioner/next-release/patch-20240705235656897489.json b/graphrag/.semversioner/next-release/patch-20240705235656897489.json new file mode 100644 index 0000000000000000000000000000000000000000..bb76d7081560d5fa3380f8863790b466a4918787 --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240705235656897489.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Add N parameter support" +} diff --git a/graphrag/.semversioner/next-release/patch-20240707063053679262.json b/graphrag/.semversioner/next-release/patch-20240707063053679262.json new file mode 100644 index 0000000000000000000000000000000000000000..51ebbc3ad182a416a68da5ca2be204133c693be2 --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240707063053679262.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "fix community_report doesn't work in settings.yaml" +} diff --git a/graphrag/.semversioner/next-release/patch-20240709225514193665.json b/graphrag/.semversioner/next-release/patch-20240709225514193665.json new file mode 100644 index 0000000000000000000000000000000000000000..dd8d6eecdf4df1686a4df7cfbe9bb689bf919baa --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240709225514193665.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Add language support to prompt tuning" +} diff --git a/graphrag/.semversioner/next-release/patch-20240710114442871595.json b/graphrag/.semversioner/next-release/patch-20240710114442871595.json new file mode 100644 index 0000000000000000000000000000000000000000..ccdf7d9a718fc95d5404eec96e1032e7eb007bfb --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240710114442871595.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Modify defaults for CHUNK_SIZE, CHUNK_OVERLAP and GLEANINGS to reduce time and LLM calls" +} diff --git a/graphrag/.semversioner/next-release/patch-20240710165603516866.json b/graphrag/.semversioner/next-release/patch-20240710165603516866.json new file mode 100644 index 0000000000000000000000000000000000000000..b5066cf1360f7ba9546b59441409b2df0310c86b --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240710165603516866.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Fixed an issue where base OpenAI embeddings can't work with Azure OpenAI LLM" +} diff --git a/graphrag/.semversioner/next-release/patch-20240711004716103302.json b/graphrag/.semversioner/next-release/patch-20240711004716103302.json new file mode 100644 index 0000000000000000000000000000000000000000..d912ee411975904810f89c0bf96adf076fd225f8 --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240711004716103302.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Fix encoding model parameter on prompt tune" +} diff --git a/graphrag/.semversioner/next-release/patch-20240711092703710242.json b/graphrag/.semversioner/next-release/patch-20240711092703710242.json new file mode 100644 index 0000000000000000000000000000000000000000..7868b33b56e0cda10ed51b7a42e49064a1a83ea4 --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240711092703710242.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "support non-open ai model config to prompt tune" +} diff --git a/graphrag/.semversioner/next-release/patch-20240711223132221685.json b/graphrag/.semversioner/next-release/patch-20240711223132221685.json new file mode 100644 index 0000000000000000000000000000000000000000..130b65ba5607295b574f4dfb5b2a70c002a6cd54 --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240711223132221685.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Fix delta none on query calls" +} diff --git a/graphrag/.semversioner/next-release/patch-20240712035356859335.json b/graphrag/.semversioner/next-release/patch-20240712035356859335.json new file mode 100644 index 0000000000000000000000000000000000000000..01e3d9a90268524703c43aa44398828fcaeb811b --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240712035356859335.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "fix llm response content is None in query" +} diff --git a/graphrag/.semversioner/next-release/patch-20240712210400518089.json b/graphrag/.semversioner/next-release/patch-20240712210400518089.json new file mode 100644 index 0000000000000000000000000000000000000000..4cb39affd665e2dd29b9fb317c3d7761858cd4af --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240712210400518089.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Add exception handling on file load" +} diff --git a/graphrag/.semversioner/next-release/patch-20240712235357550877.json b/graphrag/.semversioner/next-release/patch-20240712235357550877.json new file mode 100644 index 0000000000000000000000000000000000000000..818d609809671b2a2155a7b4dbc536d457eefd0f --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240712235357550877.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Add llm params to local and global search" +} diff --git a/graphrag/.semversioner/next-release/patch-20240716225953784804.json b/graphrag/.semversioner/next-release/patch-20240716225953784804.json new file mode 100644 index 0000000000000000000000000000000000000000..f818ce537609e489f137b0ef4eaca7e19173269a --- /dev/null +++ b/graphrag/.semversioner/next-release/patch-20240716225953784804.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Fix for Ruff 0.5.2" +} \ No newline at end of file diff --git a/graphrag/.vsts-ci.yml b/graphrag/.vsts-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..2a1e0964ce770b13923d8c0525d073c03f0d787d --- /dev/null +++ b/graphrag/.vsts-ci.yml @@ -0,0 +1,41 @@ +name: GraphRAG CI +pool: + vmImage: ubuntu-latest + +trigger: + batch: true + branches: + include: + - main + +variables: + isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')] + pythonVersion: "3.10" + poetryVersion: "1.6.1" + nodeVersion: "18.x" + artifactsFullFeedName: "Resilience/resilience_python" + +stages: + - stage: Compliance + dependsOn: [] + jobs: + - job: compliance + displayName: Compliance + pool: + vmImage: windows-latest + steps: + - task: CredScan@3 + inputs: + outputFormat: sarif + debugMode: false + + - task: ComponentGovernanceComponentDetection@0 + inputs: + scanType: "Register" + verbosity: "Verbose" + alertWarningLevel: "High" + + - task: PublishSecurityAnalysisLogs@3 + inputs: + ArtifactName: "CodeAnalysisLogs" + ArtifactType: "Container" \ No newline at end of file diff --git a/graphrag/CODEOWNERS b/graphrag/CODEOWNERS new file mode 100644 index 0000000000000000000000000000000000000000..47b118f4d84319f003648372580e2dc22f55056b --- /dev/null +++ b/graphrag/CODEOWNERS @@ -0,0 +1,6 @@ +# These owners will be the default owners for everything in +# the repo. Unless a later match takes precedence, +# @global-owner1 and @global-owner2 will be requested for +# review when someone opens a pull request. +* @microsoft/societal-resilience +* @microsoft/graphrag-core-team diff --git a/graphrag/CODE_OF_CONDUCT.md b/graphrag/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000000000000000000000000000000000..f9ba8cf65f3e3104dd061c178066ec8247811f33 --- /dev/null +++ b/graphrag/CODE_OF_CONDUCT.md @@ -0,0 +1,9 @@ +# Microsoft Open Source Code of Conduct + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). + +Resources: + +- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) +- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) +- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns diff --git a/graphrag/CONTRIBUTING.md b/graphrag/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..5f01e4bc362910523d8701379274c66685669733 --- /dev/null +++ b/graphrag/CONTRIBUTING.md @@ -0,0 +1,79 @@ +# Contributing to GraphRAG + +Thank you for your interest in contributing to GraphRAG! We welcome contributions from the community to help improve the project. + +## Code of Conduct + +This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) +declaring that you have the right to, and actually do, grant us the rights to use your contribution. +For details, visit https://cla.microsoft.com. + +When you submit a pull request, a CLA-bot will automatically determine whether you need +to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the +instructions provided by the bot. You will only need to do this once across all repositories using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) +or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +## How to Contribute + +1. Fork the repository and clone it to your local machine. +2. Create a new branch for your contribution: `git checkout -b my-contribution`. +3. Make your changes and ensure that the code passes all tests. +4. Commit your changes: `git commit -m "Add my contribution"`. +5. Create and commit a semver impact document by running `poetry run semversioner add-change -t <major|minor|patch> -d <description>`. +6. Push your changes to your forked repository: `git push origin my-contribution`. +7. Open a pull request to the main repository. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** Instead, please report them to the Microsoft Security Response Center (MSRC). +See [SECURITY.md](./SECURITY.md) for more information. + +## Before you start, file an issue + +Please follow this simple rule to help us eliminate any unnecessary wasted effort & frustration, and ensure an efficient and effective use of everyone's time - yours, ours, and other community members': + +> 👉 If you have a question, think you've discovered an issue, would like to propose a new feature, etc., then find/file an issue **BEFORE** starting work to fix/implement it. + +### Search existing issues first + +Before filing a new issue, search existing open and closed issues first: This project is moving fast! It is likely someone else has found the problem you're seeing, and someone may be working on or have already contributed a fix! + +If no existing item describes your issue/feature, great - please file a new issue: + +### File a new Issue + +- Don't know whether you're reporting an issue or requesting a feature? File an issue +- Have a question that you don't see answered in docs, videos, etc.? File an issue +- Want to know if we're planning on building a particular feature? File an issue +- Got a great idea for a new feature? File an issue/request/idea +- Don't understand how to do something? File an issue +- Found an existing issue that describes yours? Great - upvote and add additional commentary / info / repro-steps / etc. + +If from the previous guide you find yourself in the need of file an Issue please use the [issue tracker](https://github.com/microsoft/graphrag/issues). +Provide as much detail as possible to help us understand and address the problem. + +### Add information + +**Complete the new Issue form, providing as much information as possible**. The more information you provide, the more likely your issue/ask will be understood and implemented. Helpful information includes: + +- What device you're running (inc. CPU type, memory, disk, etc.) +- What OS your device is running +- What tools and apps you're using (e.g. VS 2022, VSCode, etc.) +- **We LOVE detailed repro steps!** What steps do we need to take to reproduce the issue? Assume we love to read repro steps. As much detail as you can stand is probably _barely_ enough detail for us! +- Prefer error message text where possible or screenshots of errors if text cannot be captured +- **If you intend to implement the fix/feature yourself then say so!** If you do not indicate otherwise we will assume that the issue is our to solve, or may label the issue as `Help-Wanted`. + +### DO NOT post "+1" comments + +> ⚠ DO NOT post "+1", "me too", or similar comments - they just add noise to an issue. + +If you don't have any additional info/context to add but would like to indicate that you're affected by the issue, upvote the original issue by clicking its [+😊] button and hitting 👍 (+1) icon. This way we can actually measure how impactful an issue is. + +--- + +## Thank you + +We appreciate your contributions to GraphRAG! diff --git a/graphrag/DEVELOPING.md b/graphrag/DEVELOPING.md new file mode 100644 index 0000000000000000000000000000000000000000..dd1763efa9c3be217414dbb9a8a0c7fc79efc7cd --- /dev/null +++ b/graphrag/DEVELOPING.md @@ -0,0 +1,85 @@ +# GraphRAG Development + +# Requirements + +| Name | Installation | Purpose | +| ------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------- | +| Python 3.10 or 3.11 | [Download](https://www.python.org/downloads/) | The library is Python-based. | +| Poetry | [Instructions](https://python-poetry.org/docs/#installation) | Poetry is used for package management and virtualenv management in Python codebases | + +# Getting Started + +## Install Dependencies + +```sh +# Install Python dependencies. +poetry install +``` + +## Execute the Indexing Engine + +```sh +poetry run poe index <...args> +``` + +## Executing Queries + +```sh +poetry run poe query <...args> +``` + +# Azurite + +Some unit and smoke tests use Azurite to emulate Azure resources. This can be started by running: + +```sh +./scripts/start-azurite.sh +``` + +or by simply running `azurite` in the terminal if already installed globally. See the [Azurite documentation](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite) for more information about how to install and use Azurite. + +# Lifecycle Scripts + +Our Python package utilizes Poetry to manage dependencies and [poethepoet](https://pypi.org/project/poethepoet/) to manage build scripts. + +Available scripts are: + +- `poetry run poe index` - Run the Indexing CLI +- `poetry run poe query` - Run the Query CLI +- `poetry build` - This invokes `poetry build`, which will build a wheel file and other distributable artifacts. +- `poetry run poe test` - This will execute all tests. +- `poetry run poe test_unit` - This will execute unit tests. +- `poetry run poe test_integration` - This will execute integration tests. +- `poetry run poe test_smoke` - This will execute smoke tests. +- `poetry run poe check` - This will perform a suite of static checks across the package, including: + - formatting + - documentation formatting + - linting + - security patterns + - type-checking +- `poetry run poe fix` - This will apply any available auto-fixes to the package. Usually this is just formatting fixes. +- `poetry run poe fix_unsafe` - This will apply any available auto-fixes to the package, including those that may be unsafe. +- `poetry run poe format` - Explicitly run the formatter across the package. + +## Troubleshooting + +### "RuntimeError: llvm-config failed executing, please point LLVM_CONFIG to the path for llvm-config" when running poetry install + +Make sure llvm-9 and llvm-9-dev are installed: + +`sudo apt-get install llvm-9 llvm-9-dev` + +and then in your bashrc, add + +`export LLVM_CONFIG=/usr/bin/llvm-config-9` + +### "numba/\_pymodule.h:6:10: fatal error: Python.h: No such file or directory" when running poetry install + +Make sure you have python3.10-dev installed or more generally `python<version>-dev` + +`sudo apt-get install python3.10-dev` + +### LLM call constantly exceeds TPM, RPM or time limits + +`GRAPHRAG_LLM_THREAD_COUNT` and `GRAPHRAG_EMBEDDING_THREAD_COUNT` are both set to 50 by default. You can modify this values +to reduce concurrency. Please refer to the [Configuration Documents](https://microsoft.github.io/graphrag/posts/config/overview/) diff --git a/graphrag/LICENSE b/graphrag/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..9e841e7a26e4eb057b24511e7b92d42b257a80e5 --- /dev/null +++ b/graphrag/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/graphrag/RAI_TRANSPARENCY.md b/graphrag/RAI_TRANSPARENCY.md new file mode 100644 index 0000000000000000000000000000000000000000..1a789aede716938549844fbbf74ede0646828896 --- /dev/null +++ b/graphrag/RAI_TRANSPARENCY.md @@ -0,0 +1,41 @@ +# GraphRAG: Responsible AI FAQ + +## What is GraphRAG? + +GraphRAG is an AI-based content interpretation and search capability. Using LLMs, it parses data to create a knowledge graph and answer user questions about a user-provided private dataset. + +## What can GraphRAG do? + +GraphRAG is able to connect information across large volumes of information and use these connections to answer questions that are difficult or impossible to answer using keyword and vector-based search mechanisms. Building on the previous question, provide semi-technical, high-level information on how the system offers functionality for various uses. This lets a system using GraphRAG to answer questions where the answers span many documents as well as thematic questions such as “what are the top themes in this dataset?.” + +## What are GraphRAG’s intended use(s)? + +* GraphRAG is intended to support critical information discovery and analysis use cases where the information required to arrive at a useful insight spans many documents, is noisy, is mixed with mis and/or dis-information, or when the questions users aim to answer are more abstract or thematic than the underlying data can directly answer. +* GraphRAG is designed to be used in settings where users are already trained on responsible analytic approaches and critical reasoning is expected. GraphRAG is capable of providing high degrees of insight on complex information topics, however human analysis by a domain expert of the answers is needed in order to verify and augment GraphRAG’s generated responses. +* GraphRAG is intended to be deployed and used with a domain specific corpus of text data. GraphRAG itself does not collect user data, but users are encouraged to verify data privacy policies of the chosen LLM used to configure GraphRAG. + +## How was GraphRAG evaluated? What metrics are used to measure performance? + +GraphRAG has been evaluated in multiple ways. The primary concerns are 1) accurate representation of the data set, 2) providing transparency and groundedness of responses, 3) resilience to prompt and data corpus injection attacks, and 4) low hallucination rates. Details on how each of these has been evaluated is outlined below by number. + +1) Accurate representation of the dataset has been tested by both manual inspection and automated testing against a “gold answer” that is created from randomly selected subsets of a test corpus. + +2) Transparency and groundedness of responses is tested via automated answer coverage evaluation and human inspection of the underlying context returned. + +3) We test both user prompt injection attacks (“jailbreaks”) and cross prompt injection attacks (“data attacks”) using manual and semi-automated techniques. + +4) Hallucination rates are evaluated using claim coverage metrics, manual inspection of answer and source, and adversarial attacks to attempt a forced hallucination through adversarial and exceptionally challenging datasets. + +## What are the limitations of GraphRAG? How can users minimize the impact of GraphRAG’s limitations when using the system? + +GraphRAG depends on a well-constructed indexing examples. For general applications (e.g. content oriented around people, places, organizations, things, etc.) we provide example indexing prompts. For unique datasets effective indexing can depend on proper identification of domain-specific concepts. + +Indexing is a relatively expensive operation; a best practice to mitigate indexing is to create a small test dataset in the target domain to ensure indexer performance prior to large indexing operations. + +## What operational factors and settings allow for effective and responsible use of GraphRAG? + +GraphRAG is designed for use by users with domain sophistication and experience working through difficult information challenges. While the approach is generally robust to injection attacks and identifying conflicting sources of information, the system is designed for trusted users. Proper human analysis of responses is important to generate reliable insights, and the provenance of information should be traced to ensure human agreement with the inferences made as part of the answer generation. + +GraphRAG yields the most effective results on natural language text data that is collectively focused on an overall topic or theme, and that is entity rich – entities being people, places, things, or objects that can be uniquely identified. + +While GraphRAG has been evaluated for its resilience to prompt and data corpus injection attacks, and has been probed for specific types of harms, the LLM that the user configures with GraphRAG may produce inappropriate or offensive content, which may make it inappropriate to deploy for sensitive contexts without additional mitigations that are specific to the use case and model. Developers should assess outputs for their context and use available safety classifiers, model specific safety filters and features (such as https://azure.microsoft.com/en-us/products/ai-services/ai-content-safety), or custom solutions appropriate for their use case. \ No newline at end of file diff --git a/graphrag/README.md b/graphrag/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e60cb56fa43a1e0eed7992809348ccc03ee2986f --- /dev/null +++ b/graphrag/README.md @@ -0,0 +1,71 @@ +# GraphRAG + +👉 [Use the GraphRAG Accelerator solution](https://github.com/Azure-Samples/graphrag-accelerator) <br/> +👉 [Microsoft Research Blog Post](https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/)<br/> +👉 [Read the docs](https://microsoft.github.io/graphrag)<br/> +👉 [GraphRAG Arxiv](https://arxiv.org/pdf/2404.16130) + +<div align="left"> + <a href="https://pypi.org/project/graphrag/"> + <img alt="PyPI - Version" src="https://img.shields.io/pypi/v/graphrag"> + </a> + <a href="https://pypi.org/project/graphrag/"> + <img alt="PyPI - Downloads" src="https://img.shields.io/pypi/dm/graphrag"> + </a> + <a href="https://github.com/microsoft/graphrag/issues"> + <img alt="GitHub Issues" src="https://img.shields.io/github/issues/microsoft/graphrag"> + </a> + <a href="https://github.com/microsoft/graphrag/discussions"> + <img alt="GitHub Discussions" src="https://img.shields.io/github/discussions/microsoft/graphrag"> + </a> +</div> + +## Overview + +The GraphRAG project is a data pipeline and transformation suite that is designed to extract meaningful, structured data from unstructured text using the power of LLMs. + +To learn more about GraphRAG and how it can be used to enhance your LLMs ability to reason about your private data, please visit the <a href="https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/" target="_blank">Microsoft Research Blog Post.</a> + +## Quickstart + +To get started with the GraphRAG system we recommend trying the [Solution Accelerator](https://github.com/Azure-Samples/graphrag-accelerator) package. This provides a user-friendly end-to-end experience with Azure resources. + +## Repository Guidance + +This repository presents a methodology for using knowledge graph memory structures to enhance LLM outputs. Please note that the provided code serves as a demonstration and is not an officially supported Microsoft offering. + +⚠️ *Warning: GraphRAG indexing can be an expensive operation, please read all of the documentation to understand the process and costs involved, and start small.* + +## Diving Deeper + +- To learn about our contribution guidelines, see [CONTRIBUTING.md](./CONTRIBUTING.md) +- To start developing _GraphRAG_, see [DEVELOPING.md](./DEVELOPING.md) +- Join the conversation and provide feedback in the [GitHub Discussions tab!](https://github.com/microsoft/graphrag/discussions) + +## Prompt Tuning + +Using _GraphRAG_ with your data out of the box may not yield the best possible results. +We strongly recommend to fine-tune your prompts following the [Prompt Tuning Guide](https://microsoft.github.io/graphrag/posts/prompt_tuning/overview/) in our documentation. + +## Responsible AI FAQ + +See [RAI_TRANSPARENCY.md](./RAI_TRANSPARENCY.md) + +- [What is GraphRAG?](./RAI_TRANSPARENCY.md#what-is-graphrag) +- [What can GraphRAG do?](./RAI_TRANSPARENCY.md#what-can-graphrag-do) +- [What are GraphRAG’s intended use(s)?](./RAI_TRANSPARENCY.md#what-are-graphrags-intended-uses) +- [How was GraphRAG evaluated? What metrics are used to measure performance?](./RAI_TRANSPARENCY.md#how-was-graphrag-evaluated-what-metrics-are-used-to-measure-performance) +- [What are the limitations of GraphRAG? How can users minimize the impact of GraphRAG’s limitations when using the system?](./RAI_TRANSPARENCY.md#what-are-the-limitations-of-graphrag-how-can-users-minimize-the-impact-of-graphrags-limitations-when-using-the-system) +- [What operational factors and settings allow for effective and responsible use of GraphRAG?](./RAI_TRANSPARENCY.md#what-operational-factors-and-settings-allow-for-effective-and-responsible-use-of-graphrag) + +## Trademarks + +This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft +trademarks or logos is subject to and must follow +[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). +Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. +Any use of third-party trademarks or logos are subject to those third-party's policies. + +## Privacy + +[Microsoft Privacy Statement](https://privacy.microsoft.com/en-us/privacystatement) diff --git a/graphrag/SECURITY.md b/graphrag/SECURITY.md new file mode 100644 index 0000000000000000000000000000000000000000..e5c7ae541b5634d57d75ffaaf2841c58b708f867 --- /dev/null +++ b/graphrag/SECURITY.md @@ -0,0 +1,37 @@ +## Security + +Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). + +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). + +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). \ No newline at end of file diff --git a/graphrag/SUPPORT.md b/graphrag/SUPPORT.md new file mode 100644 index 0000000000000000000000000000000000000000..2c18260cf9df61cb1de14f127373f2d36e155f93 --- /dev/null +++ b/graphrag/SUPPORT.md @@ -0,0 +1,27 @@ +# Support + +## How to file issues and get help + +This project uses GitHub Issues to track bugs and feature requests. Please search the existing +issues before filing new issues to avoid duplicates. For new issues, file your bug or +feature request as a new Issue. + +For help and questions about using this project, please create a GitHub issue with your question. + +## Microsoft Support Policy + +# Support for this **PROJECT or PRODUCT** is limited to the resources listed above. + +# Support + +## How to file issues and get help + +This project uses GitHub Issues to track bugs and feature requests. Please search the existing +issues before filing new issues to avoid duplicates. For new issues, file your bug or +feature request as a new Issue. + +For help and questions about using this project, please file an issue on the repo. + +## Microsoft Support Policy + +Support for this project is limited to the resources listed above. diff --git a/graphrag/cspell.config.yaml b/graphrag/cspell.config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..daa90e48256f299f8a1d1fa78c1ce46922c9c2fd --- /dev/null +++ b/graphrag/cspell.config.yaml @@ -0,0 +1,33 @@ +$schema: https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json +version: "0.2" +allowCompoundWords: true +dictionaryDefinitions: + - name: dictionary + path: "./dictionary.txt" + addWords: true +dictionaries: + - dictionary +ignorePaths: + - cspell.config.yaml + - node_modules + - _site + - /project-words.txt + - default_pipeline.yml + - .turbo + - output/ + - dist/ + - temp_azurite/ + - __pycache__ + - pyproject.toml + - entity_extraction.txt + - package.json + - tests/fixtures/ + - docsite/data/ + - docsite/nbdocsite_template/ + - docsite/posts/query/notebooks/inputs/ + - examples_notebooks/inputs/ + - "*.csv" + - "*.parquet" + - "*.faiss" + - "*.ipynb" + - "*.log" diff --git a/graphrag/dictionary.txt b/graphrag/dictionary.txt new file mode 100644 index 0000000000000000000000000000000000000000..f1cb4ce1921c91cdd4b31666abb8b4c5a8706f34 --- /dev/null +++ b/graphrag/dictionary.txt @@ -0,0 +1,146 @@ +# Team +Alonso + +# Pythonisms +PYTHONPATH +pycache +nopython +virtualenv +Pythonisms +pyproject +ipynb +pymodule +virtualenv +virtualenvs +signum +ospath +msecs +asdict +isna +getcwd +fillna +noqa + +# Azure +abfs +Hnsw +odata + +# NLTK Terms +chunker +wordnet +maxent +punkt + +# Libraries +Langchain +networkx +graspologic +graphml +dataframe +dataframes +nltk +datashaper +numba +graphintelligence +dotenv +tiktoken +pydantic +faiss +pyarrow +pyaml +Chakra +poethepoet +pyodbc +lancedb +httpx +pymongo +uvloop +aiofiles +asyncio +numpy +pypi +nbformat +semversioner + +# Library Methods +iterrows +rprint +ndarray +nprobe +astype +monkeypatches +nlist +ntotal +quantizer +arun +tiktokens +dtype +linewidths +asearch +iloc +itertuples +isin +nocache +nbconvert + +# Verbs +binarize +prechunked +openai +genid +umap +concat +unhot +groupby +retryer +agenerate +aembed +dedupe + +# LLM Terms +AOAI +embedder +llm +llms + +# Galaxy-Brain Terms +Unipartite +idempotently +covariate +covariates +logit +confusors + +# Charting +plottable +scatterplot + +# Resilience Team Terms +megapipeline +columnwise +docstore +datasource +devcontainers +codebases + +# Microsoft +MSRC + +# Broken Upstream +# TODO FIX IN DATASHAPER +Arrary + +# Prompt Inputs +dulce +Asadi +ABILA +Abila +POKRALLY + +# English +skippable +upvote + +# Misc +Arxiv diff --git a/graphrag/docsite/.eleventy.js b/graphrag/docsite/.eleventy.js new file mode 100644 index 0000000000000000000000000000000000000000..11141917f355a112fe77e8b80a9651be90079d1b --- /dev/null +++ b/graphrag/docsite/.eleventy.js @@ -0,0 +1,25 @@ +const { EleventyHtmlBasePlugin } = require("@11ty/eleventy"); +const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight"); +const codeClipboard = require("eleventy-plugin-code-clipboard"); +const pluginMermaid = require("@kevingimbel/eleventy-plugin-mermaid"); +const markdownIt = require('markdown-it'); + +module.exports = (eleventyConfig) => { + eleventyConfig.addPlugin(syntaxHighlight); + eleventyConfig.addPlugin(codeClipboard); + eleventyConfig.addPlugin(pluginMermaid); + eleventyConfig.addPlugin(EleventyHtmlBasePlugin, { + baseHref: process.env.DOCSITE_BASE_URL || "" + }); + eleventyConfig.addPassthroughCopy("data"); + eleventyConfig.addPassthroughCopy("img"); + // Ignore auto-generated content + eleventyConfig.setUseGitIgnore(false); + + const markdownLibrary = markdownIt({ + html: true + }).use(codeClipboard.markdownItCopyButton); + + eleventyConfig.setLibrary("md", markdownLibrary); + +}; \ No newline at end of file diff --git a/graphrag/docsite/.eleventyignore b/graphrag/docsite/.eleventyignore new file mode 100644 index 0000000000000000000000000000000000000000..f4c3c5d9185cad65c1bccce9ffd918d40f93edf1 --- /dev/null +++ b/graphrag/docsite/.eleventyignore @@ -0,0 +1,2 @@ +!posts/index/verbs/*.md +!posts/index/workflows/*.md diff --git a/graphrag/docsite/.gitignore b/graphrag/docsite/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..845c745ab60fc9cefa7f39d32457f02f55185f8e --- /dev/null +++ b/graphrag/docsite/.gitignore @@ -0,0 +1,6 @@ +_site +_posts +posts/query/notebooks/*.ipynb +posts/query/notebooks/*_nb.md +*.parquet +*.zip \ No newline at end of file diff --git a/graphrag/docsite/.yarn/releases/yarn-4.0.2.cjs b/graphrag/docsite/.yarn/releases/yarn-4.0.2.cjs new file mode 100644 index 0000000000000000000000000000000000000000..f12c120ed1392adb0b6ba8e48a276fb91f502b18 --- /dev/null +++ b/graphrag/docsite/.yarn/releases/yarn-4.0.2.cjs @@ -0,0 +1,893 @@ +#!/usr/bin/env node +/* eslint-disable */ +//prettier-ignore +(()=>{var n_e=Object.create;var MT=Object.defineProperty;var i_e=Object.getOwnPropertyDescriptor;var s_e=Object.getOwnPropertyNames;var o_e=Object.getPrototypeOf,a_e=Object.prototype.hasOwnProperty;var Be=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+t+'" is not supported')});var Et=(t,e)=>()=>(t&&(e=t(t=0)),e);var _=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),Kt=(t,e)=>{for(var r in e)MT(t,r,{get:e[r],enumerable:!0})},l_e=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of s_e(e))!a_e.call(t,a)&&a!==r&&MT(t,a,{get:()=>e[a],enumerable:!(o=i_e(e,a))||o.enumerable});return t};var $e=(t,e,r)=>(r=t!=null?n_e(o_e(t)):{},l_e(e||!t||!t.__esModule?MT(r,"default",{value:t,enumerable:!0}):r,t));var vi={};Kt(vi,{SAFE_TIME:()=>F7,S_IFDIR:()=>wD,S_IFLNK:()=>ID,S_IFMT:()=>Mu,S_IFREG:()=>Hw});var Mu,wD,Hw,ID,F7,T7=Et(()=>{Mu=61440,wD=16384,Hw=32768,ID=40960,F7=456789e3});var ar={};Kt(ar,{EBADF:()=>Io,EBUSY:()=>c_e,EEXIST:()=>g_e,EINVAL:()=>A_e,EISDIR:()=>h_e,ENOENT:()=>f_e,ENOSYS:()=>u_e,ENOTDIR:()=>p_e,ENOTEMPTY:()=>m_e,EOPNOTSUPP:()=>y_e,EROFS:()=>d_e,ERR_DIR_CLOSED:()=>OT});function Rl(t,e){return Object.assign(new Error(`${t}: ${e}`),{code:t})}function c_e(t){return Rl("EBUSY",t)}function u_e(t,e){return Rl("ENOSYS",`${t}, ${e}`)}function A_e(t){return Rl("EINVAL",`invalid argument, ${t}`)}function Io(t){return Rl("EBADF",`bad file descriptor, ${t}`)}function f_e(t){return Rl("ENOENT",`no such file or directory, ${t}`)}function p_e(t){return Rl("ENOTDIR",`not a directory, ${t}`)}function h_e(t){return Rl("EISDIR",`illegal operation on a directory, ${t}`)}function g_e(t){return Rl("EEXIST",`file already exists, ${t}`)}function d_e(t){return Rl("EROFS",`read-only filesystem, ${t}`)}function m_e(t){return Rl("ENOTEMPTY",`directory not empty, ${t}`)}function y_e(t){return Rl("EOPNOTSUPP",`operation not supported, ${t}`)}function OT(){return Rl("ERR_DIR_CLOSED","Directory handle was closed")}var BD=Et(()=>{});var Ea={};Kt(Ea,{BigIntStatsEntry:()=>ey,DEFAULT_MODE:()=>HT,DirEntry:()=>UT,StatEntry:()=>$m,areStatsEqual:()=>jT,clearStats:()=>vD,convertToBigIntStats:()=>C_e,makeDefaultStats:()=>R7,makeEmptyStats:()=>E_e});function R7(){return new $m}function E_e(){return vD(R7())}function vD(t){for(let e in t)if(Object.hasOwn(t,e)){let r=t[e];typeof r=="number"?t[e]=0:typeof r=="bigint"?t[e]=BigInt(0):_T.types.isDate(r)&&(t[e]=new Date(0))}return t}function C_e(t){let e=new ey;for(let r in t)if(Object.hasOwn(t,r)){let o=t[r];typeof o=="number"?e[r]=BigInt(o):_T.types.isDate(o)&&(e[r]=new Date(o))}return e.atimeNs=e.atimeMs*BigInt(1e6),e.mtimeNs=e.mtimeMs*BigInt(1e6),e.ctimeNs=e.ctimeMs*BigInt(1e6),e.birthtimeNs=e.birthtimeMs*BigInt(1e6),e}function jT(t,e){if(t.atimeMs!==e.atimeMs||t.birthtimeMs!==e.birthtimeMs||t.blksize!==e.blksize||t.blocks!==e.blocks||t.ctimeMs!==e.ctimeMs||t.dev!==e.dev||t.gid!==e.gid||t.ino!==e.ino||t.isBlockDevice()!==e.isBlockDevice()||t.isCharacterDevice()!==e.isCharacterDevice()||t.isDirectory()!==e.isDirectory()||t.isFIFO()!==e.isFIFO()||t.isFile()!==e.isFile()||t.isSocket()!==e.isSocket()||t.isSymbolicLink()!==e.isSymbolicLink()||t.mode!==e.mode||t.mtimeMs!==e.mtimeMs||t.nlink!==e.nlink||t.rdev!==e.rdev||t.size!==e.size||t.uid!==e.uid)return!1;let r=t,o=e;return!(r.atimeNs!==o.atimeNs||r.mtimeNs!==o.mtimeNs||r.ctimeNs!==o.ctimeNs||r.birthtimeNs!==o.birthtimeNs)}var _T,HT,UT,$m,ey,qT=Et(()=>{_T=$e(Be("util")),HT=33188,UT=class{constructor(){this.name="";this.path="";this.mode=0}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&61440)===16384}isFIFO(){return!1}isFile(){return(this.mode&61440)===32768}isSocket(){return!1}isSymbolicLink(){return(this.mode&61440)===40960}},$m=class{constructor(){this.uid=0;this.gid=0;this.size=0;this.blksize=0;this.atimeMs=0;this.mtimeMs=0;this.ctimeMs=0;this.birthtimeMs=0;this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=0;this.ino=0;this.mode=HT;this.nlink=1;this.rdev=0;this.blocks=1}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&61440)===16384}isFIFO(){return!1}isFile(){return(this.mode&61440)===32768}isSocket(){return!1}isSymbolicLink(){return(this.mode&61440)===40960}},ey=class{constructor(){this.uid=BigInt(0);this.gid=BigInt(0);this.size=BigInt(0);this.blksize=BigInt(0);this.atimeMs=BigInt(0);this.mtimeMs=BigInt(0);this.ctimeMs=BigInt(0);this.birthtimeMs=BigInt(0);this.atimeNs=BigInt(0);this.mtimeNs=BigInt(0);this.ctimeNs=BigInt(0);this.birthtimeNs=BigInt(0);this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=BigInt(0);this.ino=BigInt(0);this.mode=BigInt(HT);this.nlink=BigInt(1);this.rdev=BigInt(0);this.blocks=BigInt(1)}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&BigInt(61440))===BigInt(16384)}isFIFO(){return!1}isFile(){return(this.mode&BigInt(61440))===BigInt(32768)}isSocket(){return!1}isSymbolicLink(){return(this.mode&BigInt(61440))===BigInt(40960)}}});function D_e(t){let e,r;if(e=t.match(B_e))t=e[1];else if(r=t.match(v_e))t=`\\\\${r[1]?".\\":""}${r[2]}`;else return t;return t.replace(/\//g,"\\")}function P_e(t){t=t.replace(/\\/g,"/");let e,r;return(e=t.match(w_e))?t=`/${e[1]}`:(r=t.match(I_e))&&(t=`/unc/${r[1]?".dot/":""}${r[2]}`),t}function DD(t,e){return t===ue?L7(e):GT(e)}var jw,Bt,dr,ue,K,N7,w_e,I_e,B_e,v_e,GT,L7,Ca=Et(()=>{jw=$e(Be("path")),Bt={root:"/",dot:".",parent:".."},dr={home:"~",nodeModules:"node_modules",manifest:"package.json",lockfile:"yarn.lock",virtual:"__virtual__",pnpJs:".pnp.js",pnpCjs:".pnp.cjs",pnpData:".pnp.data.json",pnpEsmLoader:".pnp.loader.mjs",rc:".yarnrc.yml",env:".env"},ue=Object.create(jw.default),K=Object.create(jw.default.posix);ue.cwd=()=>process.cwd();K.cwd=process.platform==="win32"?()=>GT(process.cwd()):process.cwd;process.platform==="win32"&&(K.resolve=(...t)=>t.length>0&&K.isAbsolute(t[0])?jw.default.posix.resolve(...t):jw.default.posix.resolve(K.cwd(),...t));N7=function(t,e,r){return e=t.normalize(e),r=t.normalize(r),e===r?".":(e.endsWith(t.sep)||(e=e+t.sep),r.startsWith(e)?r.slice(e.length):null)};ue.contains=(t,e)=>N7(ue,t,e);K.contains=(t,e)=>N7(K,t,e);w_e=/^([a-zA-Z]:.*)$/,I_e=/^\/\/(\.\/)?(.*)$/,B_e=/^\/([a-zA-Z]:.*)$/,v_e=/^\/unc\/(\.dot\/)?(.*)$/;GT=process.platform==="win32"?P_e:t=>t,L7=process.platform==="win32"?D_e:t=>t;ue.fromPortablePath=L7;ue.toPortablePath=GT});async function PD(t,e){let r="0123456789abcdef";await t.mkdirPromise(e.indexPath,{recursive:!0});let o=[];for(let a of r)for(let n of r)o.push(t.mkdirPromise(t.pathUtils.join(e.indexPath,`${a}${n}`),{recursive:!0}));return await Promise.all(o),e.indexPath}async function M7(t,e,r,o,a){let n=t.pathUtils.normalize(e),u=r.pathUtils.normalize(o),A=[],p=[],{atime:h,mtime:E}=a.stableTime?{atime:Lg,mtime:Lg}:await r.lstatPromise(u);await t.mkdirpPromise(t.pathUtils.dirname(e),{utimes:[h,E]}),await YT(A,p,t,n,r,u,{...a,didParentExist:!0});for(let I of A)await I();await Promise.all(p.map(I=>I()))}async function YT(t,e,r,o,a,n,u){let A=u.didParentExist?await O7(r,o):null,p=await a.lstatPromise(n),{atime:h,mtime:E}=u.stableTime?{atime:Lg,mtime:Lg}:p,I;switch(!0){case p.isDirectory():I=await x_e(t,e,r,o,A,a,n,p,u);break;case p.isFile():I=await Q_e(t,e,r,o,A,a,n,p,u);break;case p.isSymbolicLink():I=await F_e(t,e,r,o,A,a,n,p,u);break;default:throw new Error(`Unsupported file type (${p.mode})`)}return(u.linkStrategy?.type!=="HardlinkFromIndex"||!p.isFile())&&((I||A?.mtime?.getTime()!==E.getTime()||A?.atime?.getTime()!==h.getTime())&&(e.push(()=>r.lutimesPromise(o,h,E)),I=!0),(A===null||(A.mode&511)!==(p.mode&511))&&(e.push(()=>r.chmodPromise(o,p.mode&511)),I=!0)),I}async function O7(t,e){try{return await t.lstatPromise(e)}catch{return null}}async function x_e(t,e,r,o,a,n,u,A,p){if(a!==null&&!a.isDirectory())if(p.overwrite)t.push(async()=>r.removePromise(o)),a=null;else return!1;let h=!1;a===null&&(t.push(async()=>{try{await r.mkdirPromise(o,{mode:A.mode})}catch(v){if(v.code!=="EEXIST")throw v}}),h=!0);let E=await n.readdirPromise(u),I=p.didParentExist&&!a?{...p,didParentExist:!1}:p;if(p.stableSort)for(let v of E.sort())await YT(t,e,r,r.pathUtils.join(o,v),n,n.pathUtils.join(u,v),I)&&(h=!0);else(await Promise.all(E.map(async b=>{await YT(t,e,r,r.pathUtils.join(o,b),n,n.pathUtils.join(u,b),I)}))).some(b=>b)&&(h=!0);return h}async function b_e(t,e,r,o,a,n,u,A,p,h){let E=await n.checksumFilePromise(u,{algorithm:"sha1"}),I=r.pathUtils.join(h.indexPath,E.slice(0,2),`${E}.dat`),v;(te=>(te[te.Lock=0]="Lock",te[te.Rename=1]="Rename"))(v||={});let b=1,C=await O7(r,I);if(a){let U=C&&a.dev===C.dev&&a.ino===C.ino,J=C?.mtimeMs!==S_e;if(U&&J&&h.autoRepair&&(b=0,C=null),!U)if(p.overwrite)t.push(async()=>r.removePromise(o)),a=null;else return!1}let T=!C&&b===1?`${I}.${Math.floor(Math.random()*4294967296).toString(16).padStart(8,"0")}`:null,L=!1;return t.push(async()=>{if(!C&&(b===0&&await r.lockPromise(I,async()=>{let U=await n.readFilePromise(u);await r.writeFilePromise(I,U)}),b===1&&T)){let U=await n.readFilePromise(u);await r.writeFilePromise(T,U);try{await r.linkPromise(T,I)}catch(J){if(J.code==="EEXIST")L=!0,await r.unlinkPromise(T);else throw J}}a||await r.linkPromise(I,o)}),e.push(async()=>{C||await r.lutimesPromise(I,Lg,Lg),T&&!L&&await r.unlinkPromise(T)}),!1}async function k_e(t,e,r,o,a,n,u,A,p){if(a!==null)if(p.overwrite)t.push(async()=>r.removePromise(o)),a=null;else return!1;return t.push(async()=>{let h=await n.readFilePromise(u);await r.writeFilePromise(o,h)}),!0}async function Q_e(t,e,r,o,a,n,u,A,p){return p.linkStrategy?.type==="HardlinkFromIndex"?b_e(t,e,r,o,a,n,u,A,p,p.linkStrategy):k_e(t,e,r,o,a,n,u,A,p)}async function F_e(t,e,r,o,a,n,u,A,p){if(a!==null)if(p.overwrite)t.push(async()=>r.removePromise(o)),a=null;else return!1;return t.push(async()=>{await r.symlinkPromise(DD(r.pathUtils,await n.readlinkPromise(u)),o)}),!0}var Lg,S_e,WT=Et(()=>{Ca();Lg=new Date(456789e3*1e3),S_e=Lg.getTime()});function SD(t,e,r,o){let a=()=>{let n=r.shift();if(typeof n>"u")return null;let u=t.pathUtils.join(e,n);return Object.assign(t.statSync(u),{name:n,path:void 0})};return new qw(e,a,o)}var qw,U7=Et(()=>{BD();qw=class{constructor(e,r,o={}){this.path=e;this.nextDirent=r;this.opts=o;this.closed=!1}throwIfClosed(){if(this.closed)throw OT()}async*[Symbol.asyncIterator](){try{let e;for(;(e=await this.read())!==null;)yield e}finally{await this.close()}}read(e){let r=this.readSync();return typeof e<"u"?e(null,r):Promise.resolve(r)}readSync(){return this.throwIfClosed(),this.nextDirent()}close(e){return this.closeSync(),typeof e<"u"?e(null):Promise.resolve()}closeSync(){this.throwIfClosed(),this.opts.onClose?.(),this.closed=!0}}});function _7(t,e){if(t!==e)throw new Error(`Invalid StatWatcher status: expected '${e}', got '${t}'`)}var H7,ty,j7=Et(()=>{H7=Be("events");qT();ty=class extends H7.EventEmitter{constructor(r,o,{bigint:a=!1}={}){super();this.status="ready";this.changeListeners=new Map;this.startTimeout=null;this.fakeFs=r,this.path=o,this.bigint=a,this.lastStats=this.stat()}static create(r,o,a){let n=new ty(r,o,a);return n.start(),n}start(){_7(this.status,"ready"),this.status="running",this.startTimeout=setTimeout(()=>{this.startTimeout=null,this.fakeFs.existsSync(this.path)||this.emit("change",this.lastStats,this.lastStats)},3)}stop(){_7(this.status,"running"),this.status="stopped",this.startTimeout!==null&&(clearTimeout(this.startTimeout),this.startTimeout=null),this.emit("stop")}stat(){try{return this.fakeFs.statSync(this.path,{bigint:this.bigint})}catch{let o=this.bigint?new ey:new $m;return vD(o)}}makeInterval(r){let o=setInterval(()=>{let a=this.stat(),n=this.lastStats;jT(a,n)||(this.lastStats=a,this.emit("change",a,n))},r.interval);return r.persistent?o:o.unref()}registerChangeListener(r,o){this.addListener("change",r),this.changeListeners.set(r,this.makeInterval(o))}unregisterChangeListener(r){this.removeListener("change",r);let o=this.changeListeners.get(r);typeof o<"u"&&clearInterval(o),this.changeListeners.delete(r)}unregisterAllChangeListeners(){for(let r of this.changeListeners.keys())this.unregisterChangeListener(r)}hasChangeListeners(){return this.changeListeners.size>0}ref(){for(let r of this.changeListeners.values())r.ref();return this}unref(){for(let r of this.changeListeners.values())r.unref();return this}}});function ry(t,e,r,o){let a,n,u,A;switch(typeof r){case"function":a=!1,n=!0,u=5007,A=r;break;default:({bigint:a=!1,persistent:n=!0,interval:u=5007}=r),A=o;break}let p=xD.get(t);typeof p>"u"&&xD.set(t,p=new Map);let h=p.get(e);return typeof h>"u"&&(h=ty.create(t,e,{bigint:a}),p.set(e,h)),h.registerChangeListener(A,{persistent:n,interval:u}),h}function Mg(t,e,r){let o=xD.get(t);if(typeof o>"u")return;let a=o.get(e);typeof a>"u"||(typeof r>"u"?a.unregisterAllChangeListeners():a.unregisterChangeListener(r),a.hasChangeListeners()||(a.stop(),o.delete(e)))}function Og(t){let e=xD.get(t);if(!(typeof e>"u"))for(let r of e.keys())Mg(t,r)}var xD,VT=Et(()=>{j7();xD=new WeakMap});function T_e(t){let e=t.match(/\r?\n/g);if(e===null)return G7.EOL;let r=e.filter(a=>a===`\r +`).length,o=e.length-r;return r>o?`\r +`:` +`}function Ug(t,e){return e.replace(/\r?\n/g,T_e(t))}var q7,G7,hf,Ou,_g=Et(()=>{q7=Be("crypto"),G7=Be("os");WT();Ca();hf=class{constructor(e){this.pathUtils=e}async*genTraversePromise(e,{stableSort:r=!1}={}){let o=[e];for(;o.length>0;){let a=o.shift();if((await this.lstatPromise(a)).isDirectory()){let u=await this.readdirPromise(a);if(r)for(let A of u.sort())o.push(this.pathUtils.join(a,A));else throw new Error("Not supported")}else yield a}}async checksumFilePromise(e,{algorithm:r="sha512"}={}){let o=await this.openPromise(e,"r");try{let n=Buffer.allocUnsafeSlow(65536),u=(0,q7.createHash)(r),A=0;for(;(A=await this.readPromise(o,n,0,65536))!==0;)u.update(A===65536?n:n.slice(0,A));return u.digest("hex")}finally{await this.closePromise(o)}}async removePromise(e,{recursive:r=!0,maxRetries:o=5}={}){let a;try{a=await this.lstatPromise(e)}catch(n){if(n.code==="ENOENT")return;throw n}if(a.isDirectory()){if(r){let n=await this.readdirPromise(e);await Promise.all(n.map(u=>this.removePromise(this.pathUtils.resolve(e,u))))}for(let n=0;n<=o;n++)try{await this.rmdirPromise(e);break}catch(u){if(u.code!=="EBUSY"&&u.code!=="ENOTEMPTY")throw u;n<o&&await new Promise(A=>setTimeout(A,n*100))}}else await this.unlinkPromise(e)}removeSync(e,{recursive:r=!0}={}){let o;try{o=this.lstatSync(e)}catch(a){if(a.code==="ENOENT")return;throw a}if(o.isDirectory()){if(r)for(let a of this.readdirSync(e))this.removeSync(this.pathUtils.resolve(e,a));this.rmdirSync(e)}else this.unlinkSync(e)}async mkdirpPromise(e,{chmod:r,utimes:o}={}){if(e=this.resolve(e),e===this.pathUtils.dirname(e))return;let a=e.split(this.pathUtils.sep),n;for(let u=2;u<=a.length;++u){let A=a.slice(0,u).join(this.pathUtils.sep);if(!this.existsSync(A)){try{await this.mkdirPromise(A)}catch(p){if(p.code==="EEXIST")continue;throw p}if(n??=A,r!=null&&await this.chmodPromise(A,r),o!=null)await this.utimesPromise(A,o[0],o[1]);else{let p=await this.statPromise(this.pathUtils.dirname(A));await this.utimesPromise(A,p.atime,p.mtime)}}}return n}mkdirpSync(e,{chmod:r,utimes:o}={}){if(e=this.resolve(e),e===this.pathUtils.dirname(e))return;let a=e.split(this.pathUtils.sep),n;for(let u=2;u<=a.length;++u){let A=a.slice(0,u).join(this.pathUtils.sep);if(!this.existsSync(A)){try{this.mkdirSync(A)}catch(p){if(p.code==="EEXIST")continue;throw p}if(n??=A,r!=null&&this.chmodSync(A,r),o!=null)this.utimesSync(A,o[0],o[1]);else{let p=this.statSync(this.pathUtils.dirname(A));this.utimesSync(A,p.atime,p.mtime)}}}return n}async copyPromise(e,r,{baseFs:o=this,overwrite:a=!0,stableSort:n=!1,stableTime:u=!1,linkStrategy:A=null}={}){return await M7(this,e,o,r,{overwrite:a,stableSort:n,stableTime:u,linkStrategy:A})}copySync(e,r,{baseFs:o=this,overwrite:a=!0}={}){let n=o.lstatSync(r),u=this.existsSync(e);if(n.isDirectory()){this.mkdirpSync(e);let p=o.readdirSync(r);for(let h of p)this.copySync(this.pathUtils.join(e,h),o.pathUtils.join(r,h),{baseFs:o,overwrite:a})}else if(n.isFile()){if(!u||a){u&&this.removeSync(e);let p=o.readFileSync(r);this.writeFileSync(e,p)}}else if(n.isSymbolicLink()){if(!u||a){u&&this.removeSync(e);let p=o.readlinkSync(r);this.symlinkSync(DD(this.pathUtils,p),e)}}else throw new Error(`Unsupported file type (file: ${r}, mode: 0o${n.mode.toString(8).padStart(6,"0")})`);let A=n.mode&511;this.chmodSync(e,A)}async changeFilePromise(e,r,o={}){return Buffer.isBuffer(r)?this.changeFileBufferPromise(e,r,o):this.changeFileTextPromise(e,r,o)}async changeFileBufferPromise(e,r,{mode:o}={}){let a=Buffer.alloc(0);try{a=await this.readFilePromise(e)}catch{}Buffer.compare(a,r)!==0&&await this.writeFilePromise(e,r,{mode:o})}async changeFileTextPromise(e,r,{automaticNewlines:o,mode:a}={}){let n="";try{n=await this.readFilePromise(e,"utf8")}catch{}let u=o?Ug(n,r):r;n!==u&&await this.writeFilePromise(e,u,{mode:a})}changeFileSync(e,r,o={}){return Buffer.isBuffer(r)?this.changeFileBufferSync(e,r,o):this.changeFileTextSync(e,r,o)}changeFileBufferSync(e,r,{mode:o}={}){let a=Buffer.alloc(0);try{a=this.readFileSync(e)}catch{}Buffer.compare(a,r)!==0&&this.writeFileSync(e,r,{mode:o})}changeFileTextSync(e,r,{automaticNewlines:o=!1,mode:a}={}){let n="";try{n=this.readFileSync(e,"utf8")}catch{}let u=o?Ug(n,r):r;n!==u&&this.writeFileSync(e,u,{mode:a})}async movePromise(e,r){try{await this.renamePromise(e,r)}catch(o){if(o.code==="EXDEV")await this.copyPromise(r,e),await this.removePromise(e);else throw o}}moveSync(e,r){try{this.renameSync(e,r)}catch(o){if(o.code==="EXDEV")this.copySync(r,e),this.removeSync(e);else throw o}}async lockPromise(e,r){let o=`${e}.flock`,a=1e3/60,n=Date.now(),u=null,A=async()=>{let p;try{[p]=await this.readJsonPromise(o)}catch{return Date.now()-n<500}try{return process.kill(p,0),!0}catch{return!1}};for(;u===null;)try{u=await this.openPromise(o,"wx")}catch(p){if(p.code==="EEXIST"){if(!await A())try{await this.unlinkPromise(o);continue}catch{}if(Date.now()-n<60*1e3)await new Promise(h=>setTimeout(h,a));else throw new Error(`Couldn't acquire a lock in a reasonable time (via ${o})`)}else throw p}await this.writePromise(u,JSON.stringify([process.pid]));try{return await r()}finally{try{await this.closePromise(u),await this.unlinkPromise(o)}catch{}}}async readJsonPromise(e){let r=await this.readFilePromise(e,"utf8");try{return JSON.parse(r)}catch(o){throw o.message+=` (in ${e})`,o}}readJsonSync(e){let r=this.readFileSync(e,"utf8");try{return JSON.parse(r)}catch(o){throw o.message+=` (in ${e})`,o}}async writeJsonPromise(e,r,{compact:o=!1}={}){let a=o?0:2;return await this.writeFilePromise(e,`${JSON.stringify(r,null,a)} +`)}writeJsonSync(e,r,{compact:o=!1}={}){let a=o?0:2;return this.writeFileSync(e,`${JSON.stringify(r,null,a)} +`)}async preserveTimePromise(e,r){let o=await this.lstatPromise(e),a=await r();typeof a<"u"&&(e=a),await this.lutimesPromise(e,o.atime,o.mtime)}async preserveTimeSync(e,r){let o=this.lstatSync(e),a=r();typeof a<"u"&&(e=a),this.lutimesSync(e,o.atime,o.mtime)}},Ou=class extends hf{constructor(){super(K)}}});var Ps,gf=Et(()=>{_g();Ps=class extends hf{getExtractHint(e){return this.baseFs.getExtractHint(e)}resolve(e){return this.mapFromBase(this.baseFs.resolve(this.mapToBase(e)))}getRealPath(){return this.mapFromBase(this.baseFs.getRealPath())}async openPromise(e,r,o){return this.baseFs.openPromise(this.mapToBase(e),r,o)}openSync(e,r,o){return this.baseFs.openSync(this.mapToBase(e),r,o)}async opendirPromise(e,r){return Object.assign(await this.baseFs.opendirPromise(this.mapToBase(e),r),{path:e})}opendirSync(e,r){return Object.assign(this.baseFs.opendirSync(this.mapToBase(e),r),{path:e})}async readPromise(e,r,o,a,n){return await this.baseFs.readPromise(e,r,o,a,n)}readSync(e,r,o,a,n){return this.baseFs.readSync(e,r,o,a,n)}async writePromise(e,r,o,a,n){return typeof r=="string"?await this.baseFs.writePromise(e,r,o):await this.baseFs.writePromise(e,r,o,a,n)}writeSync(e,r,o,a,n){return typeof r=="string"?this.baseFs.writeSync(e,r,o):this.baseFs.writeSync(e,r,o,a,n)}async closePromise(e){return this.baseFs.closePromise(e)}closeSync(e){this.baseFs.closeSync(e)}createReadStream(e,r){return this.baseFs.createReadStream(e!==null?this.mapToBase(e):e,r)}createWriteStream(e,r){return this.baseFs.createWriteStream(e!==null?this.mapToBase(e):e,r)}async realpathPromise(e){return this.mapFromBase(await this.baseFs.realpathPromise(this.mapToBase(e)))}realpathSync(e){return this.mapFromBase(this.baseFs.realpathSync(this.mapToBase(e)))}async existsPromise(e){return this.baseFs.existsPromise(this.mapToBase(e))}existsSync(e){return this.baseFs.existsSync(this.mapToBase(e))}accessSync(e,r){return this.baseFs.accessSync(this.mapToBase(e),r)}async accessPromise(e,r){return this.baseFs.accessPromise(this.mapToBase(e),r)}async statPromise(e,r){return this.baseFs.statPromise(this.mapToBase(e),r)}statSync(e,r){return this.baseFs.statSync(this.mapToBase(e),r)}async fstatPromise(e,r){return this.baseFs.fstatPromise(e,r)}fstatSync(e,r){return this.baseFs.fstatSync(e,r)}lstatPromise(e,r){return this.baseFs.lstatPromise(this.mapToBase(e),r)}lstatSync(e,r){return this.baseFs.lstatSync(this.mapToBase(e),r)}async fchmodPromise(e,r){return this.baseFs.fchmodPromise(e,r)}fchmodSync(e,r){return this.baseFs.fchmodSync(e,r)}async chmodPromise(e,r){return this.baseFs.chmodPromise(this.mapToBase(e),r)}chmodSync(e,r){return this.baseFs.chmodSync(this.mapToBase(e),r)}async fchownPromise(e,r,o){return this.baseFs.fchownPromise(e,r,o)}fchownSync(e,r,o){return this.baseFs.fchownSync(e,r,o)}async chownPromise(e,r,o){return this.baseFs.chownPromise(this.mapToBase(e),r,o)}chownSync(e,r,o){return this.baseFs.chownSync(this.mapToBase(e),r,o)}async renamePromise(e,r){return this.baseFs.renamePromise(this.mapToBase(e),this.mapToBase(r))}renameSync(e,r){return this.baseFs.renameSync(this.mapToBase(e),this.mapToBase(r))}async copyFilePromise(e,r,o=0){return this.baseFs.copyFilePromise(this.mapToBase(e),this.mapToBase(r),o)}copyFileSync(e,r,o=0){return this.baseFs.copyFileSync(this.mapToBase(e),this.mapToBase(r),o)}async appendFilePromise(e,r,o){return this.baseFs.appendFilePromise(this.fsMapToBase(e),r,o)}appendFileSync(e,r,o){return this.baseFs.appendFileSync(this.fsMapToBase(e),r,o)}async writeFilePromise(e,r,o){return this.baseFs.writeFilePromise(this.fsMapToBase(e),r,o)}writeFileSync(e,r,o){return this.baseFs.writeFileSync(this.fsMapToBase(e),r,o)}async unlinkPromise(e){return this.baseFs.unlinkPromise(this.mapToBase(e))}unlinkSync(e){return this.baseFs.unlinkSync(this.mapToBase(e))}async utimesPromise(e,r,o){return this.baseFs.utimesPromise(this.mapToBase(e),r,o)}utimesSync(e,r,o){return this.baseFs.utimesSync(this.mapToBase(e),r,o)}async lutimesPromise(e,r,o){return this.baseFs.lutimesPromise(this.mapToBase(e),r,o)}lutimesSync(e,r,o){return this.baseFs.lutimesSync(this.mapToBase(e),r,o)}async mkdirPromise(e,r){return this.baseFs.mkdirPromise(this.mapToBase(e),r)}mkdirSync(e,r){return this.baseFs.mkdirSync(this.mapToBase(e),r)}async rmdirPromise(e,r){return this.baseFs.rmdirPromise(this.mapToBase(e),r)}rmdirSync(e,r){return this.baseFs.rmdirSync(this.mapToBase(e),r)}async linkPromise(e,r){return this.baseFs.linkPromise(this.mapToBase(e),this.mapToBase(r))}linkSync(e,r){return this.baseFs.linkSync(this.mapToBase(e),this.mapToBase(r))}async symlinkPromise(e,r,o){let a=this.mapToBase(r);if(this.pathUtils.isAbsolute(e))return this.baseFs.symlinkPromise(this.mapToBase(e),a,o);let n=this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(r),e)),u=this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(a),n);return this.baseFs.symlinkPromise(u,a,o)}symlinkSync(e,r,o){let a=this.mapToBase(r);if(this.pathUtils.isAbsolute(e))return this.baseFs.symlinkSync(this.mapToBase(e),a,o);let n=this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(r),e)),u=this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(a),n);return this.baseFs.symlinkSync(u,a,o)}async readFilePromise(e,r){return this.baseFs.readFilePromise(this.fsMapToBase(e),r)}readFileSync(e,r){return this.baseFs.readFileSync(this.fsMapToBase(e),r)}readdirPromise(e,r){return this.baseFs.readdirPromise(this.mapToBase(e),r)}readdirSync(e,r){return this.baseFs.readdirSync(this.mapToBase(e),r)}async readlinkPromise(e){return this.mapFromBase(await this.baseFs.readlinkPromise(this.mapToBase(e)))}readlinkSync(e){return this.mapFromBase(this.baseFs.readlinkSync(this.mapToBase(e)))}async truncatePromise(e,r){return this.baseFs.truncatePromise(this.mapToBase(e),r)}truncateSync(e,r){return this.baseFs.truncateSync(this.mapToBase(e),r)}async ftruncatePromise(e,r){return this.baseFs.ftruncatePromise(e,r)}ftruncateSync(e,r){return this.baseFs.ftruncateSync(e,r)}watch(e,r,o){return this.baseFs.watch(this.mapToBase(e),r,o)}watchFile(e,r,o){return this.baseFs.watchFile(this.mapToBase(e),r,o)}unwatchFile(e,r){return this.baseFs.unwatchFile(this.mapToBase(e),r)}fsMapToBase(e){return typeof e=="number"?e:this.mapToBase(e)}}});var Uu,Y7=Et(()=>{gf();Uu=class extends Ps{constructor(r,{baseFs:o,pathUtils:a}){super(a);this.target=r,this.baseFs=o}getRealPath(){return this.target}getBaseFs(){return this.baseFs}mapFromBase(r){return r}mapToBase(r){return r}}});function W7(t){let e=t;return typeof t.path=="string"&&(e.path=ue.toPortablePath(t.path)),e}var V7,Rn,Hg=Et(()=>{V7=$e(Be("fs"));_g();Ca();Rn=class extends Ou{constructor(r=V7.default){super();this.realFs=r}getExtractHint(){return!1}getRealPath(){return Bt.root}resolve(r){return K.resolve(r)}async openPromise(r,o,a){return await new Promise((n,u)=>{this.realFs.open(ue.fromPortablePath(r),o,a,this.makeCallback(n,u))})}openSync(r,o,a){return this.realFs.openSync(ue.fromPortablePath(r),o,a)}async opendirPromise(r,o){return await new Promise((a,n)=>{typeof o<"u"?this.realFs.opendir(ue.fromPortablePath(r),o,this.makeCallback(a,n)):this.realFs.opendir(ue.fromPortablePath(r),this.makeCallback(a,n))}).then(a=>{let n=a;return Object.defineProperty(n,"path",{value:r,configurable:!0,writable:!0}),n})}opendirSync(r,o){let n=typeof o<"u"?this.realFs.opendirSync(ue.fromPortablePath(r),o):this.realFs.opendirSync(ue.fromPortablePath(r));return Object.defineProperty(n,"path",{value:r,configurable:!0,writable:!0}),n}async readPromise(r,o,a=0,n=0,u=-1){return await new Promise((A,p)=>{this.realFs.read(r,o,a,n,u,(h,E)=>{h?p(h):A(E)})})}readSync(r,o,a,n,u){return this.realFs.readSync(r,o,a,n,u)}async writePromise(r,o,a,n,u){return await new Promise((A,p)=>typeof o=="string"?this.realFs.write(r,o,a,this.makeCallback(A,p)):this.realFs.write(r,o,a,n,u,this.makeCallback(A,p)))}writeSync(r,o,a,n,u){return typeof o=="string"?this.realFs.writeSync(r,o,a):this.realFs.writeSync(r,o,a,n,u)}async closePromise(r){await new Promise((o,a)=>{this.realFs.close(r,this.makeCallback(o,a))})}closeSync(r){this.realFs.closeSync(r)}createReadStream(r,o){let a=r!==null?ue.fromPortablePath(r):r;return this.realFs.createReadStream(a,o)}createWriteStream(r,o){let a=r!==null?ue.fromPortablePath(r):r;return this.realFs.createWriteStream(a,o)}async realpathPromise(r){return await new Promise((o,a)=>{this.realFs.realpath(ue.fromPortablePath(r),{},this.makeCallback(o,a))}).then(o=>ue.toPortablePath(o))}realpathSync(r){return ue.toPortablePath(this.realFs.realpathSync(ue.fromPortablePath(r),{}))}async existsPromise(r){return await new Promise(o=>{this.realFs.exists(ue.fromPortablePath(r),o)})}accessSync(r,o){return this.realFs.accessSync(ue.fromPortablePath(r),o)}async accessPromise(r,o){return await new Promise((a,n)=>{this.realFs.access(ue.fromPortablePath(r),o,this.makeCallback(a,n))})}existsSync(r){return this.realFs.existsSync(ue.fromPortablePath(r))}async statPromise(r,o){return await new Promise((a,n)=>{o?this.realFs.stat(ue.fromPortablePath(r),o,this.makeCallback(a,n)):this.realFs.stat(ue.fromPortablePath(r),this.makeCallback(a,n))})}statSync(r,o){return o?this.realFs.statSync(ue.fromPortablePath(r),o):this.realFs.statSync(ue.fromPortablePath(r))}async fstatPromise(r,o){return await new Promise((a,n)=>{o?this.realFs.fstat(r,o,this.makeCallback(a,n)):this.realFs.fstat(r,this.makeCallback(a,n))})}fstatSync(r,o){return o?this.realFs.fstatSync(r,o):this.realFs.fstatSync(r)}async lstatPromise(r,o){return await new Promise((a,n)=>{o?this.realFs.lstat(ue.fromPortablePath(r),o,this.makeCallback(a,n)):this.realFs.lstat(ue.fromPortablePath(r),this.makeCallback(a,n))})}lstatSync(r,o){return o?this.realFs.lstatSync(ue.fromPortablePath(r),o):this.realFs.lstatSync(ue.fromPortablePath(r))}async fchmodPromise(r,o){return await new Promise((a,n)=>{this.realFs.fchmod(r,o,this.makeCallback(a,n))})}fchmodSync(r,o){return this.realFs.fchmodSync(r,o)}async chmodPromise(r,o){return await new Promise((a,n)=>{this.realFs.chmod(ue.fromPortablePath(r),o,this.makeCallback(a,n))})}chmodSync(r,o){return this.realFs.chmodSync(ue.fromPortablePath(r),o)}async fchownPromise(r,o,a){return await new Promise((n,u)=>{this.realFs.fchown(r,o,a,this.makeCallback(n,u))})}fchownSync(r,o,a){return this.realFs.fchownSync(r,o,a)}async chownPromise(r,o,a){return await new Promise((n,u)=>{this.realFs.chown(ue.fromPortablePath(r),o,a,this.makeCallback(n,u))})}chownSync(r,o,a){return this.realFs.chownSync(ue.fromPortablePath(r),o,a)}async renamePromise(r,o){return await new Promise((a,n)=>{this.realFs.rename(ue.fromPortablePath(r),ue.fromPortablePath(o),this.makeCallback(a,n))})}renameSync(r,o){return this.realFs.renameSync(ue.fromPortablePath(r),ue.fromPortablePath(o))}async copyFilePromise(r,o,a=0){return await new Promise((n,u)=>{this.realFs.copyFile(ue.fromPortablePath(r),ue.fromPortablePath(o),a,this.makeCallback(n,u))})}copyFileSync(r,o,a=0){return this.realFs.copyFileSync(ue.fromPortablePath(r),ue.fromPortablePath(o),a)}async appendFilePromise(r,o,a){return await new Promise((n,u)=>{let A=typeof r=="string"?ue.fromPortablePath(r):r;a?this.realFs.appendFile(A,o,a,this.makeCallback(n,u)):this.realFs.appendFile(A,o,this.makeCallback(n,u))})}appendFileSync(r,o,a){let n=typeof r=="string"?ue.fromPortablePath(r):r;a?this.realFs.appendFileSync(n,o,a):this.realFs.appendFileSync(n,o)}async writeFilePromise(r,o,a){return await new Promise((n,u)=>{let A=typeof r=="string"?ue.fromPortablePath(r):r;a?this.realFs.writeFile(A,o,a,this.makeCallback(n,u)):this.realFs.writeFile(A,o,this.makeCallback(n,u))})}writeFileSync(r,o,a){let n=typeof r=="string"?ue.fromPortablePath(r):r;a?this.realFs.writeFileSync(n,o,a):this.realFs.writeFileSync(n,o)}async unlinkPromise(r){return await new Promise((o,a)=>{this.realFs.unlink(ue.fromPortablePath(r),this.makeCallback(o,a))})}unlinkSync(r){return this.realFs.unlinkSync(ue.fromPortablePath(r))}async utimesPromise(r,o,a){return await new Promise((n,u)=>{this.realFs.utimes(ue.fromPortablePath(r),o,a,this.makeCallback(n,u))})}utimesSync(r,o,a){this.realFs.utimesSync(ue.fromPortablePath(r),o,a)}async lutimesPromise(r,o,a){return await new Promise((n,u)=>{this.realFs.lutimes(ue.fromPortablePath(r),o,a,this.makeCallback(n,u))})}lutimesSync(r,o,a){this.realFs.lutimesSync(ue.fromPortablePath(r),o,a)}async mkdirPromise(r,o){return await new Promise((a,n)=>{this.realFs.mkdir(ue.fromPortablePath(r),o,this.makeCallback(a,n))})}mkdirSync(r,o){return this.realFs.mkdirSync(ue.fromPortablePath(r),o)}async rmdirPromise(r,o){return await new Promise((a,n)=>{o?this.realFs.rmdir(ue.fromPortablePath(r),o,this.makeCallback(a,n)):this.realFs.rmdir(ue.fromPortablePath(r),this.makeCallback(a,n))})}rmdirSync(r,o){return this.realFs.rmdirSync(ue.fromPortablePath(r),o)}async linkPromise(r,o){return await new Promise((a,n)=>{this.realFs.link(ue.fromPortablePath(r),ue.fromPortablePath(o),this.makeCallback(a,n))})}linkSync(r,o){return this.realFs.linkSync(ue.fromPortablePath(r),ue.fromPortablePath(o))}async symlinkPromise(r,o,a){return await new Promise((n,u)=>{this.realFs.symlink(ue.fromPortablePath(r.replace(/\/+$/,"")),ue.fromPortablePath(o),a,this.makeCallback(n,u))})}symlinkSync(r,o,a){return this.realFs.symlinkSync(ue.fromPortablePath(r.replace(/\/+$/,"")),ue.fromPortablePath(o),a)}async readFilePromise(r,o){return await new Promise((a,n)=>{let u=typeof r=="string"?ue.fromPortablePath(r):r;this.realFs.readFile(u,o,this.makeCallback(a,n))})}readFileSync(r,o){let a=typeof r=="string"?ue.fromPortablePath(r):r;return this.realFs.readFileSync(a,o)}async readdirPromise(r,o){return await new Promise((a,n)=>{o?o.recursive&&process.platform==="win32"?o.withFileTypes?this.realFs.readdir(ue.fromPortablePath(r),o,this.makeCallback(u=>a(u.map(W7)),n)):this.realFs.readdir(ue.fromPortablePath(r),o,this.makeCallback(u=>a(u.map(ue.toPortablePath)),n)):this.realFs.readdir(ue.fromPortablePath(r),o,this.makeCallback(a,n)):this.realFs.readdir(ue.fromPortablePath(r),this.makeCallback(a,n))})}readdirSync(r,o){return o?o.recursive&&process.platform==="win32"?o.withFileTypes?this.realFs.readdirSync(ue.fromPortablePath(r),o).map(W7):this.realFs.readdirSync(ue.fromPortablePath(r),o).map(ue.toPortablePath):this.realFs.readdirSync(ue.fromPortablePath(r),o):this.realFs.readdirSync(ue.fromPortablePath(r))}async readlinkPromise(r){return await new Promise((o,a)=>{this.realFs.readlink(ue.fromPortablePath(r),this.makeCallback(o,a))}).then(o=>ue.toPortablePath(o))}readlinkSync(r){return ue.toPortablePath(this.realFs.readlinkSync(ue.fromPortablePath(r)))}async truncatePromise(r,o){return await new Promise((a,n)=>{this.realFs.truncate(ue.fromPortablePath(r),o,this.makeCallback(a,n))})}truncateSync(r,o){return this.realFs.truncateSync(ue.fromPortablePath(r),o)}async ftruncatePromise(r,o){return await new Promise((a,n)=>{this.realFs.ftruncate(r,o,this.makeCallback(a,n))})}ftruncateSync(r,o){return this.realFs.ftruncateSync(r,o)}watch(r,o,a){return this.realFs.watch(ue.fromPortablePath(r),o,a)}watchFile(r,o,a){return this.realFs.watchFile(ue.fromPortablePath(r),o,a)}unwatchFile(r,o){return this.realFs.unwatchFile(ue.fromPortablePath(r),o)}makeCallback(r,o){return(a,n)=>{a?o(a):r(n)}}}});var gn,K7=Et(()=>{Hg();gf();Ca();gn=class extends Ps{constructor(r,{baseFs:o=new Rn}={}){super(K);this.target=this.pathUtils.normalize(r),this.baseFs=o}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.target)}resolve(r){return this.pathUtils.isAbsolute(r)?K.normalize(r):this.baseFs.resolve(K.join(this.target,r))}mapFromBase(r){return r}mapToBase(r){return this.pathUtils.isAbsolute(r)?r:this.pathUtils.join(this.target,r)}}});var J7,_u,z7=Et(()=>{Hg();gf();Ca();J7=Bt.root,_u=class extends Ps{constructor(r,{baseFs:o=new Rn}={}){super(K);this.target=this.pathUtils.resolve(Bt.root,r),this.baseFs=o}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.pathUtils.relative(Bt.root,this.target))}getTarget(){return this.target}getBaseFs(){return this.baseFs}mapToBase(r){let o=this.pathUtils.normalize(r);if(this.pathUtils.isAbsolute(r))return this.pathUtils.resolve(this.target,this.pathUtils.relative(J7,r));if(o.match(/^\.\.\/?/))throw new Error(`Resolving this path (${r}) would escape the jail`);return this.pathUtils.resolve(this.target,r)}mapFromBase(r){return this.pathUtils.resolve(J7,this.pathUtils.relative(this.target,r))}}});var ny,X7=Et(()=>{gf();ny=class extends Ps{constructor(r,o){super(o);this.instance=null;this.factory=r}get baseFs(){return this.instance||(this.instance=this.factory()),this.instance}set baseFs(r){this.instance=r}mapFromBase(r){return r}mapToBase(r){return r}}});var jg,wa,_p,Z7=Et(()=>{jg=Be("fs");_g();Hg();VT();BD();Ca();wa=4278190080,_p=class extends Ou{constructor({baseFs:r=new Rn,filter:o=null,magicByte:a=42,maxOpenFiles:n=1/0,useCache:u=!0,maxAge:A=5e3,typeCheck:p=jg.constants.S_IFREG,getMountPoint:h,factoryPromise:E,factorySync:I}){if(Math.floor(a)!==a||!(a>1&&a<=127))throw new Error("The magic byte must be set to a round value between 1 and 127 included");super();this.fdMap=new Map;this.nextFd=3;this.isMount=new Set;this.notMount=new Set;this.realPaths=new Map;this.limitOpenFilesTimeout=null;this.baseFs=r,this.mountInstances=u?new Map:null,this.factoryPromise=E,this.factorySync=I,this.filter=o,this.getMountPoint=h,this.magic=a<<24,this.maxAge=A,this.maxOpenFiles=n,this.typeCheck=p}getExtractHint(r){return this.baseFs.getExtractHint(r)}getRealPath(){return this.baseFs.getRealPath()}saveAndClose(){if(Og(this),this.mountInstances)for(let[r,{childFs:o}]of this.mountInstances.entries())o.saveAndClose?.(),this.mountInstances.delete(r)}discardAndClose(){if(Og(this),this.mountInstances)for(let[r,{childFs:o}]of this.mountInstances.entries())o.discardAndClose?.(),this.mountInstances.delete(r)}resolve(r){return this.baseFs.resolve(r)}remapFd(r,o){let a=this.nextFd++|this.magic;return this.fdMap.set(a,[r,o]),a}async openPromise(r,o,a){return await this.makeCallPromise(r,async()=>await this.baseFs.openPromise(r,o,a),async(n,{subPath:u})=>this.remapFd(n,await n.openPromise(u,o,a)))}openSync(r,o,a){return this.makeCallSync(r,()=>this.baseFs.openSync(r,o,a),(n,{subPath:u})=>this.remapFd(n,n.openSync(u,o,a)))}async opendirPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.opendirPromise(r,o),async(a,{subPath:n})=>await a.opendirPromise(n,o),{requireSubpath:!1})}opendirSync(r,o){return this.makeCallSync(r,()=>this.baseFs.opendirSync(r,o),(a,{subPath:n})=>a.opendirSync(n,o),{requireSubpath:!1})}async readPromise(r,o,a,n,u){if((r&wa)!==this.magic)return await this.baseFs.readPromise(r,o,a,n,u);let A=this.fdMap.get(r);if(typeof A>"u")throw Io("read");let[p,h]=A;return await p.readPromise(h,o,a,n,u)}readSync(r,o,a,n,u){if((r&wa)!==this.magic)return this.baseFs.readSync(r,o,a,n,u);let A=this.fdMap.get(r);if(typeof A>"u")throw Io("readSync");let[p,h]=A;return p.readSync(h,o,a,n,u)}async writePromise(r,o,a,n,u){if((r&wa)!==this.magic)return typeof o=="string"?await this.baseFs.writePromise(r,o,a):await this.baseFs.writePromise(r,o,a,n,u);let A=this.fdMap.get(r);if(typeof A>"u")throw Io("write");let[p,h]=A;return typeof o=="string"?await p.writePromise(h,o,a):await p.writePromise(h,o,a,n,u)}writeSync(r,o,a,n,u){if((r&wa)!==this.magic)return typeof o=="string"?this.baseFs.writeSync(r,o,a):this.baseFs.writeSync(r,o,a,n,u);let A=this.fdMap.get(r);if(typeof A>"u")throw Io("writeSync");let[p,h]=A;return typeof o=="string"?p.writeSync(h,o,a):p.writeSync(h,o,a,n,u)}async closePromise(r){if((r&wa)!==this.magic)return await this.baseFs.closePromise(r);let o=this.fdMap.get(r);if(typeof o>"u")throw Io("close");this.fdMap.delete(r);let[a,n]=o;return await a.closePromise(n)}closeSync(r){if((r&wa)!==this.magic)return this.baseFs.closeSync(r);let o=this.fdMap.get(r);if(typeof o>"u")throw Io("closeSync");this.fdMap.delete(r);let[a,n]=o;return a.closeSync(n)}createReadStream(r,o){return r===null?this.baseFs.createReadStream(r,o):this.makeCallSync(r,()=>this.baseFs.createReadStream(r,o),(a,{archivePath:n,subPath:u})=>{let A=a.createReadStream(u,o);return A.path=ue.fromPortablePath(this.pathUtils.join(n,u)),A})}createWriteStream(r,o){return r===null?this.baseFs.createWriteStream(r,o):this.makeCallSync(r,()=>this.baseFs.createWriteStream(r,o),(a,{subPath:n})=>a.createWriteStream(n,o))}async realpathPromise(r){return await this.makeCallPromise(r,async()=>await this.baseFs.realpathPromise(r),async(o,{archivePath:a,subPath:n})=>{let u=this.realPaths.get(a);return typeof u>"u"&&(u=await this.baseFs.realpathPromise(a),this.realPaths.set(a,u)),this.pathUtils.join(u,this.pathUtils.relative(Bt.root,await o.realpathPromise(n)))})}realpathSync(r){return this.makeCallSync(r,()=>this.baseFs.realpathSync(r),(o,{archivePath:a,subPath:n})=>{let u=this.realPaths.get(a);return typeof u>"u"&&(u=this.baseFs.realpathSync(a),this.realPaths.set(a,u)),this.pathUtils.join(u,this.pathUtils.relative(Bt.root,o.realpathSync(n)))})}async existsPromise(r){return await this.makeCallPromise(r,async()=>await this.baseFs.existsPromise(r),async(o,{subPath:a})=>await o.existsPromise(a))}existsSync(r){return this.makeCallSync(r,()=>this.baseFs.existsSync(r),(o,{subPath:a})=>o.existsSync(a))}async accessPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.accessPromise(r,o),async(a,{subPath:n})=>await a.accessPromise(n,o))}accessSync(r,o){return this.makeCallSync(r,()=>this.baseFs.accessSync(r,o),(a,{subPath:n})=>a.accessSync(n,o))}async statPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.statPromise(r,o),async(a,{subPath:n})=>await a.statPromise(n,o))}statSync(r,o){return this.makeCallSync(r,()=>this.baseFs.statSync(r,o),(a,{subPath:n})=>a.statSync(n,o))}async fstatPromise(r,o){if((r&wa)!==this.magic)return this.baseFs.fstatPromise(r,o);let a=this.fdMap.get(r);if(typeof a>"u")throw Io("fstat");let[n,u]=a;return n.fstatPromise(u,o)}fstatSync(r,o){if((r&wa)!==this.magic)return this.baseFs.fstatSync(r,o);let a=this.fdMap.get(r);if(typeof a>"u")throw Io("fstatSync");let[n,u]=a;return n.fstatSync(u,o)}async lstatPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.lstatPromise(r,o),async(a,{subPath:n})=>await a.lstatPromise(n,o))}lstatSync(r,o){return this.makeCallSync(r,()=>this.baseFs.lstatSync(r,o),(a,{subPath:n})=>a.lstatSync(n,o))}async fchmodPromise(r,o){if((r&wa)!==this.magic)return this.baseFs.fchmodPromise(r,o);let a=this.fdMap.get(r);if(typeof a>"u")throw Io("fchmod");let[n,u]=a;return n.fchmodPromise(u,o)}fchmodSync(r,o){if((r&wa)!==this.magic)return this.baseFs.fchmodSync(r,o);let a=this.fdMap.get(r);if(typeof a>"u")throw Io("fchmodSync");let[n,u]=a;return n.fchmodSync(u,o)}async chmodPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.chmodPromise(r,o),async(a,{subPath:n})=>await a.chmodPromise(n,o))}chmodSync(r,o){return this.makeCallSync(r,()=>this.baseFs.chmodSync(r,o),(a,{subPath:n})=>a.chmodSync(n,o))}async fchownPromise(r,o,a){if((r&wa)!==this.magic)return this.baseFs.fchownPromise(r,o,a);let n=this.fdMap.get(r);if(typeof n>"u")throw Io("fchown");let[u,A]=n;return u.fchownPromise(A,o,a)}fchownSync(r,o,a){if((r&wa)!==this.magic)return this.baseFs.fchownSync(r,o,a);let n=this.fdMap.get(r);if(typeof n>"u")throw Io("fchownSync");let[u,A]=n;return u.fchownSync(A,o,a)}async chownPromise(r,o,a){return await this.makeCallPromise(r,async()=>await this.baseFs.chownPromise(r,o,a),async(n,{subPath:u})=>await n.chownPromise(u,o,a))}chownSync(r,o,a){return this.makeCallSync(r,()=>this.baseFs.chownSync(r,o,a),(n,{subPath:u})=>n.chownSync(u,o,a))}async renamePromise(r,o){return await this.makeCallPromise(r,async()=>await this.makeCallPromise(o,async()=>await this.baseFs.renamePromise(r,o),async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),async(a,{subPath:n})=>await this.makeCallPromise(o,async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})},async(u,{subPath:A})=>{if(a!==u)throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"});return await a.renamePromise(n,A)}))}renameSync(r,o){return this.makeCallSync(r,()=>this.makeCallSync(o,()=>this.baseFs.renameSync(r,o),()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),(a,{subPath:n})=>this.makeCallSync(o,()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})},(u,{subPath:A})=>{if(a!==u)throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"});return a.renameSync(n,A)}))}async copyFilePromise(r,o,a=0){let n=async(u,A,p,h)=>{if((a&jg.constants.COPYFILE_FICLONE_FORCE)!==0)throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${A}' -> ${h}'`),{code:"EXDEV"});if(a&jg.constants.COPYFILE_EXCL&&await this.existsPromise(A))throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${A}' -> '${h}'`),{code:"EEXIST"});let E;try{E=await u.readFilePromise(A)}catch{throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${A}' -> '${h}'`),{code:"EINVAL"})}await p.writeFilePromise(h,E)};return await this.makeCallPromise(r,async()=>await this.makeCallPromise(o,async()=>await this.baseFs.copyFilePromise(r,o,a),async(u,{subPath:A})=>await n(this.baseFs,r,u,A)),async(u,{subPath:A})=>await this.makeCallPromise(o,async()=>await n(u,A,this.baseFs,o),async(p,{subPath:h})=>u!==p?await n(u,A,p,h):await u.copyFilePromise(A,h,a)))}copyFileSync(r,o,a=0){let n=(u,A,p,h)=>{if((a&jg.constants.COPYFILE_FICLONE_FORCE)!==0)throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${A}' -> ${h}'`),{code:"EXDEV"});if(a&jg.constants.COPYFILE_EXCL&&this.existsSync(A))throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${A}' -> '${h}'`),{code:"EEXIST"});let E;try{E=u.readFileSync(A)}catch{throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${A}' -> '${h}'`),{code:"EINVAL"})}p.writeFileSync(h,E)};return this.makeCallSync(r,()=>this.makeCallSync(o,()=>this.baseFs.copyFileSync(r,o,a),(u,{subPath:A})=>n(this.baseFs,r,u,A)),(u,{subPath:A})=>this.makeCallSync(o,()=>n(u,A,this.baseFs,o),(p,{subPath:h})=>u!==p?n(u,A,p,h):u.copyFileSync(A,h,a)))}async appendFilePromise(r,o,a){return await this.makeCallPromise(r,async()=>await this.baseFs.appendFilePromise(r,o,a),async(n,{subPath:u})=>await n.appendFilePromise(u,o,a))}appendFileSync(r,o,a){return this.makeCallSync(r,()=>this.baseFs.appendFileSync(r,o,a),(n,{subPath:u})=>n.appendFileSync(u,o,a))}async writeFilePromise(r,o,a){return await this.makeCallPromise(r,async()=>await this.baseFs.writeFilePromise(r,o,a),async(n,{subPath:u})=>await n.writeFilePromise(u,o,a))}writeFileSync(r,o,a){return this.makeCallSync(r,()=>this.baseFs.writeFileSync(r,o,a),(n,{subPath:u})=>n.writeFileSync(u,o,a))}async unlinkPromise(r){return await this.makeCallPromise(r,async()=>await this.baseFs.unlinkPromise(r),async(o,{subPath:a})=>await o.unlinkPromise(a))}unlinkSync(r){return this.makeCallSync(r,()=>this.baseFs.unlinkSync(r),(o,{subPath:a})=>o.unlinkSync(a))}async utimesPromise(r,o,a){return await this.makeCallPromise(r,async()=>await this.baseFs.utimesPromise(r,o,a),async(n,{subPath:u})=>await n.utimesPromise(u,o,a))}utimesSync(r,o,a){return this.makeCallSync(r,()=>this.baseFs.utimesSync(r,o,a),(n,{subPath:u})=>n.utimesSync(u,o,a))}async lutimesPromise(r,o,a){return await this.makeCallPromise(r,async()=>await this.baseFs.lutimesPromise(r,o,a),async(n,{subPath:u})=>await n.lutimesPromise(u,o,a))}lutimesSync(r,o,a){return this.makeCallSync(r,()=>this.baseFs.lutimesSync(r,o,a),(n,{subPath:u})=>n.lutimesSync(u,o,a))}async mkdirPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.mkdirPromise(r,o),async(a,{subPath:n})=>await a.mkdirPromise(n,o))}mkdirSync(r,o){return this.makeCallSync(r,()=>this.baseFs.mkdirSync(r,o),(a,{subPath:n})=>a.mkdirSync(n,o))}async rmdirPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.rmdirPromise(r,o),async(a,{subPath:n})=>await a.rmdirPromise(n,o))}rmdirSync(r,o){return this.makeCallSync(r,()=>this.baseFs.rmdirSync(r,o),(a,{subPath:n})=>a.rmdirSync(n,o))}async linkPromise(r,o){return await this.makeCallPromise(o,async()=>await this.baseFs.linkPromise(r,o),async(a,{subPath:n})=>await a.linkPromise(r,n))}linkSync(r,o){return this.makeCallSync(o,()=>this.baseFs.linkSync(r,o),(a,{subPath:n})=>a.linkSync(r,n))}async symlinkPromise(r,o,a){return await this.makeCallPromise(o,async()=>await this.baseFs.symlinkPromise(r,o,a),async(n,{subPath:u})=>await n.symlinkPromise(r,u))}symlinkSync(r,o,a){return this.makeCallSync(o,()=>this.baseFs.symlinkSync(r,o,a),(n,{subPath:u})=>n.symlinkSync(r,u))}async readFilePromise(r,o){return this.makeCallPromise(r,async()=>await this.baseFs.readFilePromise(r,o),async(a,{subPath:n})=>await a.readFilePromise(n,o))}readFileSync(r,o){return this.makeCallSync(r,()=>this.baseFs.readFileSync(r,o),(a,{subPath:n})=>a.readFileSync(n,o))}async readdirPromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.readdirPromise(r,o),async(a,{subPath:n})=>await a.readdirPromise(n,o),{requireSubpath:!1})}readdirSync(r,o){return this.makeCallSync(r,()=>this.baseFs.readdirSync(r,o),(a,{subPath:n})=>a.readdirSync(n,o),{requireSubpath:!1})}async readlinkPromise(r){return await this.makeCallPromise(r,async()=>await this.baseFs.readlinkPromise(r),async(o,{subPath:a})=>await o.readlinkPromise(a))}readlinkSync(r){return this.makeCallSync(r,()=>this.baseFs.readlinkSync(r),(o,{subPath:a})=>o.readlinkSync(a))}async truncatePromise(r,o){return await this.makeCallPromise(r,async()=>await this.baseFs.truncatePromise(r,o),async(a,{subPath:n})=>await a.truncatePromise(n,o))}truncateSync(r,o){return this.makeCallSync(r,()=>this.baseFs.truncateSync(r,o),(a,{subPath:n})=>a.truncateSync(n,o))}async ftruncatePromise(r,o){if((r&wa)!==this.magic)return this.baseFs.ftruncatePromise(r,o);let a=this.fdMap.get(r);if(typeof a>"u")throw Io("ftruncate");let[n,u]=a;return n.ftruncatePromise(u,o)}ftruncateSync(r,o){if((r&wa)!==this.magic)return this.baseFs.ftruncateSync(r,o);let a=this.fdMap.get(r);if(typeof a>"u")throw Io("ftruncateSync");let[n,u]=a;return n.ftruncateSync(u,o)}watch(r,o,a){return this.makeCallSync(r,()=>this.baseFs.watch(r,o,a),(n,{subPath:u})=>n.watch(u,o,a))}watchFile(r,o,a){return this.makeCallSync(r,()=>this.baseFs.watchFile(r,o,a),()=>ry(this,r,o,a))}unwatchFile(r,o){return this.makeCallSync(r,()=>this.baseFs.unwatchFile(r,o),()=>Mg(this,r,o))}async makeCallPromise(r,o,a,{requireSubpath:n=!0}={}){if(typeof r!="string")return await o();let u=this.resolve(r),A=this.findMount(u);return A?n&&A.subPath==="/"?await o():await this.getMountPromise(A.archivePath,async p=>await a(p,A)):await o()}makeCallSync(r,o,a,{requireSubpath:n=!0}={}){if(typeof r!="string")return o();let u=this.resolve(r),A=this.findMount(u);return!A||n&&A.subPath==="/"?o():this.getMountSync(A.archivePath,p=>a(p,A))}findMount(r){if(this.filter&&!this.filter.test(r))return null;let o="";for(;;){let a=r.substring(o.length),n=this.getMountPoint(a,o);if(!n)return null;if(o=this.pathUtils.join(o,n),!this.isMount.has(o)){if(this.notMount.has(o))continue;try{if(this.typeCheck!==null&&(this.baseFs.lstatSync(o).mode&jg.constants.S_IFMT)!==this.typeCheck){this.notMount.add(o);continue}}catch{return null}this.isMount.add(o)}return{archivePath:o,subPath:this.pathUtils.join(Bt.root,r.substring(o.length))}}}limitOpenFiles(r){if(this.mountInstances===null)return;let o=Date.now(),a=o+this.maxAge,n=r===null?0:this.mountInstances.size-r;for(let[u,{childFs:A,expiresAt:p,refCount:h}]of this.mountInstances.entries())if(!(h!==0||A.hasOpenFileHandles?.())){if(o>=p){A.saveAndClose?.(),this.mountInstances.delete(u),n-=1;continue}else if(r===null||n<=0){a=p;break}A.saveAndClose?.(),this.mountInstances.delete(u),n-=1}this.limitOpenFilesTimeout===null&&(r===null&&this.mountInstances.size>0||r!==null)&&isFinite(a)&&(this.limitOpenFilesTimeout=setTimeout(()=>{this.limitOpenFilesTimeout=null,this.limitOpenFiles(null)},a-o).unref())}async getMountPromise(r,o){if(this.mountInstances){let a=this.mountInstances.get(r);if(!a){let n=await this.factoryPromise(this.baseFs,r);a=this.mountInstances.get(r),a||(a={childFs:n(),expiresAt:0,refCount:0})}this.mountInstances.delete(r),this.limitOpenFiles(this.maxOpenFiles-1),this.mountInstances.set(r,a),a.expiresAt=Date.now()+this.maxAge,a.refCount+=1;try{return await o(a.childFs)}finally{a.refCount-=1}}else{let a=(await this.factoryPromise(this.baseFs,r))();try{return await o(a)}finally{a.saveAndClose?.()}}}getMountSync(r,o){if(this.mountInstances){let a=this.mountInstances.get(r);return a||(a={childFs:this.factorySync(this.baseFs,r),expiresAt:0,refCount:0}),this.mountInstances.delete(r),this.limitOpenFiles(this.maxOpenFiles-1),this.mountInstances.set(r,a),a.expiresAt=Date.now()+this.maxAge,o(a.childFs)}else{let a=this.factorySync(this.baseFs,r);try{return o(a)}finally{a.saveAndClose?.()}}}}});var Zt,KT,Gw,$7=Et(()=>{_g();Ca();Zt=()=>Object.assign(new Error("ENOSYS: unsupported filesystem access"),{code:"ENOSYS"}),KT=class extends hf{constructor(){super(K)}getExtractHint(){throw Zt()}getRealPath(){throw Zt()}resolve(){throw Zt()}async openPromise(){throw Zt()}openSync(){throw Zt()}async opendirPromise(){throw Zt()}opendirSync(){throw Zt()}async readPromise(){throw Zt()}readSync(){throw Zt()}async writePromise(){throw Zt()}writeSync(){throw Zt()}async closePromise(){throw Zt()}closeSync(){throw Zt()}createWriteStream(){throw Zt()}createReadStream(){throw Zt()}async realpathPromise(){throw Zt()}realpathSync(){throw Zt()}async readdirPromise(){throw Zt()}readdirSync(){throw Zt()}async existsPromise(e){throw Zt()}existsSync(e){throw Zt()}async accessPromise(){throw Zt()}accessSync(){throw Zt()}async statPromise(){throw Zt()}statSync(){throw Zt()}async fstatPromise(e){throw Zt()}fstatSync(e){throw Zt()}async lstatPromise(e){throw Zt()}lstatSync(e){throw Zt()}async fchmodPromise(){throw Zt()}fchmodSync(){throw Zt()}async chmodPromise(){throw Zt()}chmodSync(){throw Zt()}async fchownPromise(){throw Zt()}fchownSync(){throw Zt()}async chownPromise(){throw Zt()}chownSync(){throw Zt()}async mkdirPromise(){throw Zt()}mkdirSync(){throw Zt()}async rmdirPromise(){throw Zt()}rmdirSync(){throw Zt()}async linkPromise(){throw Zt()}linkSync(){throw Zt()}async symlinkPromise(){throw Zt()}symlinkSync(){throw Zt()}async renamePromise(){throw Zt()}renameSync(){throw Zt()}async copyFilePromise(){throw Zt()}copyFileSync(){throw Zt()}async appendFilePromise(){throw Zt()}appendFileSync(){throw Zt()}async writeFilePromise(){throw Zt()}writeFileSync(){throw Zt()}async unlinkPromise(){throw Zt()}unlinkSync(){throw Zt()}async utimesPromise(){throw Zt()}utimesSync(){throw Zt()}async lutimesPromise(){throw Zt()}lutimesSync(){throw Zt()}async readFilePromise(){throw Zt()}readFileSync(){throw Zt()}async readlinkPromise(){throw Zt()}readlinkSync(){throw Zt()}async truncatePromise(){throw Zt()}truncateSync(){throw Zt()}async ftruncatePromise(e,r){throw Zt()}ftruncateSync(e,r){throw Zt()}watch(){throw Zt()}watchFile(){throw Zt()}unwatchFile(){throw Zt()}},Gw=KT;Gw.instance=new KT});var Hp,eY=Et(()=>{gf();Ca();Hp=class extends Ps{constructor(r){super(ue);this.baseFs=r}mapFromBase(r){return ue.fromPortablePath(r)}mapToBase(r){return ue.toPortablePath(r)}}});var R_e,JT,N_e,mi,tY=Et(()=>{Hg();gf();Ca();R_e=/^[0-9]+$/,JT=/^(\/(?:[^/]+\/)*?(?:\$\$virtual|__virtual__))((?:\/((?:[^/]+-)?[a-f0-9]+)(?:\/([^/]+))?)?((?:\/.*)?))$/,N_e=/^([^/]+-)?[a-f0-9]+$/,mi=class extends Ps{constructor({baseFs:r=new Rn}={}){super(K);this.baseFs=r}static makeVirtualPath(r,o,a){if(K.basename(r)!=="__virtual__")throw new Error('Assertion failed: Virtual folders must be named "__virtual__"');if(!K.basename(o).match(N_e))throw new Error("Assertion failed: Virtual components must be ended by an hexadecimal hash");let u=K.relative(K.dirname(r),a).split("/"),A=0;for(;A<u.length&&u[A]==="..";)A+=1;let p=u.slice(A);return K.join(r,o,String(A),...p)}static resolveVirtual(r){let o=r.match(JT);if(!o||!o[3]&&o[5])return r;let a=K.dirname(o[1]);if(!o[3]||!o[4])return a;if(!R_e.test(o[4]))return r;let u=Number(o[4]),A="../".repeat(u),p=o[5]||".";return mi.resolveVirtual(K.join(a,A,p))}getExtractHint(r){return this.baseFs.getExtractHint(r)}getRealPath(){return this.baseFs.getRealPath()}realpathSync(r){let o=r.match(JT);if(!o)return this.baseFs.realpathSync(r);if(!o[5])return r;let a=this.baseFs.realpathSync(this.mapToBase(r));return mi.makeVirtualPath(o[1],o[3],a)}async realpathPromise(r){let o=r.match(JT);if(!o)return await this.baseFs.realpathPromise(r);if(!o[5])return r;let a=await this.baseFs.realpathPromise(this.mapToBase(r));return mi.makeVirtualPath(o[1],o[3],a)}mapToBase(r){if(r==="")return r;if(this.pathUtils.isAbsolute(r))return mi.resolveVirtual(r);let o=mi.resolveVirtual(this.baseFs.resolve(Bt.dot)),a=mi.resolveVirtual(this.baseFs.resolve(r));return K.relative(o,a)||Bt.dot}mapFromBase(r){return r}}});function L_e(t,e){return typeof zT.default.isUtf8<"u"?zT.default.isUtf8(t):Buffer.byteLength(e)===t.byteLength}var zT,kD,rY,bD,nY=Et(()=>{zT=$e(Be("buffer")),kD=Be("url"),rY=Be("util");gf();Ca();bD=class extends Ps{constructor(r){super(ue);this.baseFs=r}mapFromBase(r){return r}mapToBase(r){if(typeof r=="string")return r;if(r instanceof kD.URL)return(0,kD.fileURLToPath)(r);if(Buffer.isBuffer(r)){let o=r.toString();if(!L_e(r,o))throw new Error("Non-utf8 buffers are not supported at the moment. Please upvote the following issue if you encounter this error: https://github.com/yarnpkg/berry/issues/4942");return o}throw new Error(`Unsupported path type: ${(0,rY.inspect)(r)}`)}}});var iY,Bo,df,jp,QD,FD,iy,Rc,Nc,M_e,O_e,U_e,__e,Yw,sY=Et(()=>{iY=Be("readline"),Bo=Symbol("kBaseFs"),df=Symbol("kFd"),jp=Symbol("kClosePromise"),QD=Symbol("kCloseResolve"),FD=Symbol("kCloseReject"),iy=Symbol("kRefs"),Rc=Symbol("kRef"),Nc=Symbol("kUnref"),Yw=class{constructor(e,r){this[M_e]=1;this[O_e]=void 0;this[U_e]=void 0;this[__e]=void 0;this[Bo]=r,this[df]=e}get fd(){return this[df]}async appendFile(e,r){try{this[Rc](this.appendFile);let o=(typeof r=="string"?r:r?.encoding)??void 0;return await this[Bo].appendFilePromise(this.fd,e,o?{encoding:o}:void 0)}finally{this[Nc]()}}async chown(e,r){try{return this[Rc](this.chown),await this[Bo].fchownPromise(this.fd,e,r)}finally{this[Nc]()}}async chmod(e){try{return this[Rc](this.chmod),await this[Bo].fchmodPromise(this.fd,e)}finally{this[Nc]()}}createReadStream(e){return this[Bo].createReadStream(null,{...e,fd:this.fd})}createWriteStream(e){return this[Bo].createWriteStream(null,{...e,fd:this.fd})}datasync(){throw new Error("Method not implemented.")}sync(){throw new Error("Method not implemented.")}async read(e,r,o,a){try{this[Rc](this.read);let n;return Buffer.isBuffer(e)?n=e:(e??={},n=e.buffer??Buffer.alloc(16384),r=e.offset||0,o=e.length??n.byteLength,a=e.position??null),r??=0,o??=0,o===0?{bytesRead:o,buffer:n}:{bytesRead:await this[Bo].readPromise(this.fd,n,r,o,a),buffer:n}}finally{this[Nc]()}}async readFile(e){try{this[Rc](this.readFile);let r=(typeof e=="string"?e:e?.encoding)??void 0;return await this[Bo].readFilePromise(this.fd,r)}finally{this[Nc]()}}readLines(e){return(0,iY.createInterface)({input:this.createReadStream(e),crlfDelay:1/0})}async stat(e){try{return this[Rc](this.stat),await this[Bo].fstatPromise(this.fd,e)}finally{this[Nc]()}}async truncate(e){try{return this[Rc](this.truncate),await this[Bo].ftruncatePromise(this.fd,e)}finally{this[Nc]()}}utimes(e,r){throw new Error("Method not implemented.")}async writeFile(e,r){try{this[Rc](this.writeFile);let o=(typeof r=="string"?r:r?.encoding)??void 0;await this[Bo].writeFilePromise(this.fd,e,o)}finally{this[Nc]()}}async write(...e){try{if(this[Rc](this.write),ArrayBuffer.isView(e[0])){let[r,o,a,n]=e;return{bytesWritten:await this[Bo].writePromise(this.fd,r,o??void 0,a??void 0,n??void 0),buffer:r}}else{let[r,o,a]=e;return{bytesWritten:await this[Bo].writePromise(this.fd,r,o,a),buffer:r}}}finally{this[Nc]()}}async writev(e,r){try{this[Rc](this.writev);let o=0;if(typeof r<"u")for(let a of e){let n=await this.write(a,void 0,void 0,r);o+=n.bytesWritten,r+=n.bytesWritten}else for(let a of e){let n=await this.write(a);o+=n.bytesWritten}return{buffers:e,bytesWritten:o}}finally{this[Nc]()}}readv(e,r){throw new Error("Method not implemented.")}close(){if(this[df]===-1)return Promise.resolve();if(this[jp])return this[jp];if(this[iy]--,this[iy]===0){let e=this[df];this[df]=-1,this[jp]=this[Bo].closePromise(e).finally(()=>{this[jp]=void 0})}else this[jp]=new Promise((e,r)=>{this[QD]=e,this[FD]=r}).finally(()=>{this[jp]=void 0,this[FD]=void 0,this[QD]=void 0});return this[jp]}[(Bo,df,M_e=iy,O_e=jp,U_e=QD,__e=FD,Rc)](e){if(this[df]===-1){let r=new Error("file closed");throw r.code="EBADF",r.syscall=e.name,r}this[iy]++}[Nc](){if(this[iy]--,this[iy]===0){let e=this[df];this[df]=-1,this[Bo].closePromise(e).then(this[QD],this[FD])}}}});function Ww(t,e){e=new bD(e);let r=(o,a,n)=>{let u=o[a];o[a]=n,typeof u?.[sy.promisify.custom]<"u"&&(n[sy.promisify.custom]=u[sy.promisify.custom])};{r(t,"exists",(o,...a)=>{let u=typeof a[a.length-1]=="function"?a.pop():()=>{};process.nextTick(()=>{e.existsPromise(o).then(A=>{u(A)},()=>{u(!1)})})}),r(t,"read",(...o)=>{let[a,n,u,A,p,h]=o;if(o.length<=3){let E={};o.length<3?h=o[1]:(E=o[1],h=o[2]),{buffer:n=Buffer.alloc(16384),offset:u=0,length:A=n.byteLength,position:p}=E}if(u==null&&(u=0),A|=0,A===0){process.nextTick(()=>{h(null,0,n)});return}p==null&&(p=-1),process.nextTick(()=>{e.readPromise(a,n,u,A,p).then(E=>{h(null,E,n)},E=>{h(E,0,n)})})});for(let o of oY){let a=o.replace(/Promise$/,"");if(typeof t[a]>"u")continue;let n=e[o];if(typeof n>"u")continue;r(t,a,(...A)=>{let h=typeof A[A.length-1]=="function"?A.pop():()=>{};process.nextTick(()=>{n.apply(e,A).then(E=>{h(null,E)},E=>{h(E)})})})}t.realpath.native=t.realpath}{r(t,"existsSync",o=>{try{return e.existsSync(o)}catch{return!1}}),r(t,"readSync",(...o)=>{let[a,n,u,A,p]=o;return o.length<=3&&({offset:u=0,length:A=n.byteLength,position:p}=o[2]||{}),u==null&&(u=0),A|=0,A===0?0:(p==null&&(p=-1),e.readSync(a,n,u,A,p))});for(let o of H_e){let a=o;if(typeof t[a]>"u")continue;let n=e[o];typeof n>"u"||r(t,a,n.bind(e))}t.realpathSync.native=t.realpathSync}{let o=t.promises;for(let a of oY){let n=a.replace(/Promise$/,"");if(typeof o[n]>"u")continue;let u=e[a];typeof u>"u"||a!=="open"&&r(o,n,(A,...p)=>A instanceof Yw?A[n].apply(A,p):u.call(e,A,...p))}r(o,"open",async(...a)=>{let n=await e.openPromise(...a);return new Yw(n,e)})}t.read[sy.promisify.custom]=async(o,a,...n)=>({bytesRead:await e.readPromise(o,a,...n),buffer:a}),t.write[sy.promisify.custom]=async(o,a,...n)=>({bytesWritten:await e.writePromise(o,a,...n),buffer:a})}function TD(t,e){let r=Object.create(t);return Ww(r,e),r}var sy,H_e,oY,aY=Et(()=>{sy=Be("util");nY();sY();H_e=new Set(["accessSync","appendFileSync","createReadStream","createWriteStream","chmodSync","fchmodSync","chownSync","fchownSync","closeSync","copyFileSync","linkSync","lstatSync","fstatSync","lutimesSync","mkdirSync","openSync","opendirSync","readlinkSync","readFileSync","readdirSync","readlinkSync","realpathSync","renameSync","rmdirSync","statSync","symlinkSync","truncateSync","ftruncateSync","unlinkSync","unwatchFile","utimesSync","watch","watchFile","writeFileSync","writeSync"]),oY=new Set(["accessPromise","appendFilePromise","fchmodPromise","chmodPromise","fchownPromise","chownPromise","closePromise","copyFilePromise","linkPromise","fstatPromise","lstatPromise","lutimesPromise","mkdirPromise","openPromise","opendirPromise","readdirPromise","realpathPromise","readFilePromise","readdirPromise","readlinkPromise","renamePromise","rmdirPromise","statPromise","symlinkPromise","truncatePromise","ftruncatePromise","unlinkPromise","utimesPromise","writeFilePromise","writeSync"])});function lY(t){let e=Math.ceil(Math.random()*4294967296).toString(16).padStart(8,"0");return`${t}${e}`}function cY(){if(XT)return XT;let t=ue.toPortablePath(uY.default.tmpdir()),e=oe.realpathSync(t);return process.once("exit",()=>{oe.rmtempSync()}),XT={tmpdir:t,realTmpdir:e}}var uY,Lc,XT,oe,AY=Et(()=>{uY=$e(Be("os"));Hg();Ca();Lc=new Set,XT=null;oe=Object.assign(new Rn,{detachTemp(t){Lc.delete(t)},mktempSync(t){let{tmpdir:e,realTmpdir:r}=cY();for(;;){let o=lY("xfs-");try{this.mkdirSync(K.join(e,o))}catch(n){if(n.code==="EEXIST")continue;throw n}let a=K.join(r,o);if(Lc.add(a),typeof t>"u")return a;try{return t(a)}finally{if(Lc.has(a)){Lc.delete(a);try{this.removeSync(a)}catch{}}}}},async mktempPromise(t){let{tmpdir:e,realTmpdir:r}=cY();for(;;){let o=lY("xfs-");try{await this.mkdirPromise(K.join(e,o))}catch(n){if(n.code==="EEXIST")continue;throw n}let a=K.join(r,o);if(Lc.add(a),typeof t>"u")return a;try{return await t(a)}finally{if(Lc.has(a)){Lc.delete(a);try{await this.removePromise(a)}catch{}}}}},async rmtempPromise(){await Promise.all(Array.from(Lc.values()).map(async t=>{try{await oe.removePromise(t,{maxRetries:0}),Lc.delete(t)}catch{}}))},rmtempSync(){for(let t of Lc)try{oe.removeSync(t),Lc.delete(t)}catch{}}})});var Vw={};Kt(Vw,{AliasFS:()=>Uu,BasePortableFakeFS:()=>Ou,CustomDir:()=>qw,CwdFS:()=>gn,FakeFS:()=>hf,Filename:()=>dr,JailFS:()=>_u,LazyFS:()=>ny,MountFS:()=>_p,NoFS:()=>Gw,NodeFS:()=>Rn,PortablePath:()=>Bt,PosixFS:()=>Hp,ProxiedFS:()=>Ps,VirtualFS:()=>mi,constants:()=>vi,errors:()=>ar,extendFs:()=>TD,normalizeLineEndings:()=>Ug,npath:()=>ue,opendir:()=>SD,patchFs:()=>Ww,ppath:()=>K,setupCopyIndex:()=>PD,statUtils:()=>Ea,unwatchAllFiles:()=>Og,unwatchFile:()=>Mg,watchFile:()=>ry,xfs:()=>oe});var Pt=Et(()=>{T7();BD();qT();WT();U7();VT();_g();Ca();Ca();Y7();_g();K7();z7();X7();Z7();$7();Hg();eY();gf();tY();aY();AY()});var dY=_((axt,gY)=>{gY.exports=hY;hY.sync=q_e;var fY=Be("fs");function j_e(t,e){var r=e.pathExt!==void 0?e.pathExt:process.env.PATHEXT;if(!r||(r=r.split(";"),r.indexOf("")!==-1))return!0;for(var o=0;o<r.length;o++){var a=r[o].toLowerCase();if(a&&t.substr(-a.length).toLowerCase()===a)return!0}return!1}function pY(t,e,r){return!t.isSymbolicLink()&&!t.isFile()?!1:j_e(e,r)}function hY(t,e,r){fY.stat(t,function(o,a){r(o,o?!1:pY(a,t,e))})}function q_e(t,e){return pY(fY.statSync(t),t,e)}});var wY=_((lxt,CY)=>{CY.exports=yY;yY.sync=G_e;var mY=Be("fs");function yY(t,e,r){mY.stat(t,function(o,a){r(o,o?!1:EY(a,e))})}function G_e(t,e){return EY(mY.statSync(t),e)}function EY(t,e){return t.isFile()&&Y_e(t,e)}function Y_e(t,e){var r=t.mode,o=t.uid,a=t.gid,n=e.uid!==void 0?e.uid:process.getuid&&process.getuid(),u=e.gid!==void 0?e.gid:process.getgid&&process.getgid(),A=parseInt("100",8),p=parseInt("010",8),h=parseInt("001",8),E=A|p,I=r&h||r&p&&a===u||r&A&&o===n||r&E&&n===0;return I}});var BY=_((uxt,IY)=>{var cxt=Be("fs"),RD;process.platform==="win32"||global.TESTING_WINDOWS?RD=dY():RD=wY();IY.exports=ZT;ZT.sync=W_e;function ZT(t,e,r){if(typeof e=="function"&&(r=e,e={}),!r){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(o,a){ZT(t,e||{},function(n,u){n?a(n):o(u)})})}RD(t,e||{},function(o,a){o&&(o.code==="EACCES"||e&&e.ignoreErrors)&&(o=null,a=!1),r(o,a)})}function W_e(t,e){try{return RD.sync(t,e||{})}catch(r){if(e&&e.ignoreErrors||r.code==="EACCES")return!1;throw r}}});var kY=_((Axt,bY)=>{var oy=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",vY=Be("path"),V_e=oy?";":":",DY=BY(),PY=t=>Object.assign(new Error(`not found: ${t}`),{code:"ENOENT"}),SY=(t,e)=>{let r=e.colon||V_e,o=t.match(/\//)||oy&&t.match(/\\/)?[""]:[...oy?[process.cwd()]:[],...(e.path||process.env.PATH||"").split(r)],a=oy?e.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",n=oy?a.split(r):[""];return oy&&t.indexOf(".")!==-1&&n[0]!==""&&n.unshift(""),{pathEnv:o,pathExt:n,pathExtExe:a}},xY=(t,e,r)=>{typeof e=="function"&&(r=e,e={}),e||(e={});let{pathEnv:o,pathExt:a,pathExtExe:n}=SY(t,e),u=[],A=h=>new Promise((E,I)=>{if(h===o.length)return e.all&&u.length?E(u):I(PY(t));let v=o[h],b=/^".*"$/.test(v)?v.slice(1,-1):v,C=vY.join(b,t),T=!b&&/^\.[\\\/]/.test(t)?t.slice(0,2)+C:C;E(p(T,h,0))}),p=(h,E,I)=>new Promise((v,b)=>{if(I===a.length)return v(A(E+1));let C=a[I];DY(h+C,{pathExt:n},(T,L)=>{if(!T&&L)if(e.all)u.push(h+C);else return v(h+C);return v(p(h,E,I+1))})});return r?A(0).then(h=>r(null,h),r):A(0)},K_e=(t,e)=>{e=e||{};let{pathEnv:r,pathExt:o,pathExtExe:a}=SY(t,e),n=[];for(let u=0;u<r.length;u++){let A=r[u],p=/^".*"$/.test(A)?A.slice(1,-1):A,h=vY.join(p,t),E=!p&&/^\.[\\\/]/.test(t)?t.slice(0,2)+h:h;for(let I=0;I<o.length;I++){let v=E+o[I];try{if(DY.sync(v,{pathExt:a}))if(e.all)n.push(v);else return v}catch{}}}if(e.all&&n.length)return n;if(e.nothrow)return null;throw PY(t)};bY.exports=xY;xY.sync=K_e});var FY=_((fxt,$T)=>{"use strict";var QY=(t={})=>{let e=t.env||process.env;return(t.platform||process.platform)!=="win32"?"PATH":Object.keys(e).reverse().find(o=>o.toUpperCase()==="PATH")||"Path"};$T.exports=QY;$T.exports.default=QY});var LY=_((pxt,NY)=>{"use strict";var TY=Be("path"),J_e=kY(),z_e=FY();function RY(t,e){let r=t.options.env||process.env,o=process.cwd(),a=t.options.cwd!=null,n=a&&process.chdir!==void 0&&!process.chdir.disabled;if(n)try{process.chdir(t.options.cwd)}catch{}let u;try{u=J_e.sync(t.command,{path:r[z_e({env:r})],pathExt:e?TY.delimiter:void 0})}catch{}finally{n&&process.chdir(o)}return u&&(u=TY.resolve(a?t.options.cwd:"",u)),u}function X_e(t){return RY(t)||RY(t,!0)}NY.exports=X_e});var MY=_((hxt,tR)=>{"use strict";var eR=/([()\][%!^"`<>&|;, *?])/g;function Z_e(t){return t=t.replace(eR,"^$1"),t}function $_e(t,e){return t=`${t}`,t=t.replace(/(\\*)"/g,'$1$1\\"'),t=t.replace(/(\\*)$/,"$1$1"),t=`"${t}"`,t=t.replace(eR,"^$1"),e&&(t=t.replace(eR,"^$1")),t}tR.exports.command=Z_e;tR.exports.argument=$_e});var UY=_((gxt,OY)=>{"use strict";OY.exports=/^#!(.*)/});var HY=_((dxt,_Y)=>{"use strict";var e8e=UY();_Y.exports=(t="")=>{let e=t.match(e8e);if(!e)return null;let[r,o]=e[0].replace(/#! ?/,"").split(" "),a=r.split("/").pop();return a==="env"?o:o?`${a} ${o}`:a}});var qY=_((mxt,jY)=>{"use strict";var rR=Be("fs"),t8e=HY();function r8e(t){let r=Buffer.alloc(150),o;try{o=rR.openSync(t,"r"),rR.readSync(o,r,0,150,0),rR.closeSync(o)}catch{}return t8e(r.toString())}jY.exports=r8e});var VY=_((yxt,WY)=>{"use strict";var n8e=Be("path"),GY=LY(),YY=MY(),i8e=qY(),s8e=process.platform==="win32",o8e=/\.(?:com|exe)$/i,a8e=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function l8e(t){t.file=GY(t);let e=t.file&&i8e(t.file);return e?(t.args.unshift(t.file),t.command=e,GY(t)):t.file}function c8e(t){if(!s8e)return t;let e=l8e(t),r=!o8e.test(e);if(t.options.forceShell||r){let o=a8e.test(e);t.command=n8e.normalize(t.command),t.command=YY.command(t.command),t.args=t.args.map(n=>YY.argument(n,o));let a=[t.command].concat(t.args).join(" ");t.args=["/d","/s","/c",`"${a}"`],t.command=process.env.comspec||"cmd.exe",t.options.windowsVerbatimArguments=!0}return t}function u8e(t,e,r){e&&!Array.isArray(e)&&(r=e,e=null),e=e?e.slice(0):[],r=Object.assign({},r);let o={command:t,args:e,options:r,file:void 0,original:{command:t,args:e}};return r.shell?o:c8e(o)}WY.exports=u8e});var zY=_((Ext,JY)=>{"use strict";var nR=process.platform==="win32";function iR(t,e){return Object.assign(new Error(`${e} ${t.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${e} ${t.command}`,path:t.command,spawnargs:t.args})}function A8e(t,e){if(!nR)return;let r=t.emit;t.emit=function(o,a){if(o==="exit"){let n=KY(a,e,"spawn");if(n)return r.call(t,"error",n)}return r.apply(t,arguments)}}function KY(t,e){return nR&&t===1&&!e.file?iR(e.original,"spawn"):null}function f8e(t,e){return nR&&t===1&&!e.file?iR(e.original,"spawnSync"):null}JY.exports={hookChildProcess:A8e,verifyENOENT:KY,verifyENOENTSync:f8e,notFoundError:iR}});var aR=_((Cxt,ay)=>{"use strict";var XY=Be("child_process"),sR=VY(),oR=zY();function ZY(t,e,r){let o=sR(t,e,r),a=XY.spawn(o.command,o.args,o.options);return oR.hookChildProcess(a,o),a}function p8e(t,e,r){let o=sR(t,e,r),a=XY.spawnSync(o.command,o.args,o.options);return a.error=a.error||oR.verifyENOENTSync(a.status,o),a}ay.exports=ZY;ay.exports.spawn=ZY;ay.exports.sync=p8e;ay.exports._parse=sR;ay.exports._enoent=oR});var eW=_((wxt,$Y)=>{"use strict";function h8e(t,e){function r(){this.constructor=t}r.prototype=e.prototype,t.prototype=new r}function qg(t,e,r,o){this.message=t,this.expected=e,this.found=r,this.location=o,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,qg)}h8e(qg,Error);qg.buildMessage=function(t,e){var r={literal:function(h){return'"'+a(h.text)+'"'},class:function(h){var E="",I;for(I=0;I<h.parts.length;I++)E+=h.parts[I]instanceof Array?n(h.parts[I][0])+"-"+n(h.parts[I][1]):n(h.parts[I]);return"["+(h.inverted?"^":"")+E+"]"},any:function(h){return"any character"},end:function(h){return"end of input"},other:function(h){return h.description}};function o(h){return h.charCodeAt(0).toString(16).toUpperCase()}function a(h){return h.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(E){return"\\x0"+o(E)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(E){return"\\x"+o(E)})}function n(h){return h.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(E){return"\\x0"+o(E)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(E){return"\\x"+o(E)})}function u(h){return r[h.type](h)}function A(h){var E=new Array(h.length),I,v;for(I=0;I<h.length;I++)E[I]=u(h[I]);if(E.sort(),E.length>0){for(I=1,v=1;I<E.length;I++)E[I-1]!==E[I]&&(E[v]=E[I],v++);E.length=v}switch(E.length){case 1:return E[0];case 2:return E[0]+" or "+E[1];default:return E.slice(0,-1).join(", ")+", or "+E[E.length-1]}}function p(h){return h?'"'+a(h)+'"':"end of input"}return"Expected "+A(t)+" but "+p(e)+" found."};function g8e(t,e){e=e!==void 0?e:{};var r={},o={Start:pg},a=pg,n=function(N){return N||[]},u=function(N,V,re){return[{command:N,type:V}].concat(re||[])},A=function(N,V){return[{command:N,type:V||";"}]},p=function(N){return N},h=";",E=Br(";",!1),I="&",v=Br("&",!1),b=function(N,V){return V?{chain:N,then:V}:{chain:N}},C=function(N,V){return{type:N,line:V}},T="&&",L=Br("&&",!1),U="||",J=Br("||",!1),te=function(N,V){return V?{...N,then:V}:N},le=function(N,V){return{type:N,chain:V}},pe="|&",Ae=Br("|&",!1),ye="|",ae=Br("|",!1),we="=",Pe=Br("=",!1),g=function(N,V){return{name:N,args:[V]}},Ee=function(N){return{name:N,args:[]}},De="(",ce=Br("(",!1),ne=")",ee=Br(")",!1),Ie=function(N,V){return{type:"subshell",subshell:N,args:V}},ke="{",ht=Br("{",!1),H="}",lt=Br("}",!1),Re=function(N,V){return{type:"group",group:N,args:V}},Qe=function(N,V){return{type:"command",args:V,envs:N}},be=function(N){return{type:"envs",envs:N}},_e=function(N){return N},Te=function(N){return N},Je=/^[0-9]/,He=Cs([["0","9"]],!1,!1),x=function(N,V,re){return{type:"redirection",subtype:V,fd:N!==null?parseInt(N):null,args:[re]}},w=">>",S=Br(">>",!1),y=">&",F=Br(">&",!1),z=">",X=Br(">",!1),Z="<<<",ie=Br("<<<",!1),Se="<&",Ne=Br("<&",!1),ot="<",dt=Br("<",!1),jt=function(N){return{type:"argument",segments:[].concat(...N)}},$t=function(N){return N},xt="$'",an=Br("$'",!1),Qr="'",mr=Br("'",!1),xr=function(N){return[{type:"text",text:N}]},Wr='""',Vn=Br('""',!1),Ns=function(){return{type:"text",text:""}},Ri='"',ps=Br('"',!1),io=function(N){return N},Si=function(N){return{type:"arithmetic",arithmetic:N,quoted:!0}},Ls=function(N){return{type:"shell",shell:N,quoted:!0}},so=function(N){return{type:"variable",...N,quoted:!0}},cc=function(N){return{type:"text",text:N}},cu=function(N){return{type:"arithmetic",arithmetic:N,quoted:!1}},ap=function(N){return{type:"shell",shell:N,quoted:!1}},lp=function(N){return{type:"variable",...N,quoted:!1}},Ms=function(N){return{type:"glob",pattern:N}},Dn=/^[^']/,oo=Cs(["'"],!0,!1),Os=function(N){return N.join("")},ml=/^[^$"]/,yl=Cs(["$",'"'],!0,!1),ao=`\\ +`,Kn=Br(`\\ +`,!1),Mn=function(){return""},Ni="\\",On=Br("\\",!1),_i=/^[\\$"`]/,tr=Cs(["\\","$",'"',"`"],!1,!1),Me=function(N){return N},ii="\\a",Oa=Br("\\a",!1),hr=function(){return"a"},uc="\\b",uu=Br("\\b",!1),Ac=function(){return"\b"},El=/^[Ee]/,vA=Cs(["E","e"],!1,!1),Au=function(){return"\x1B"},Ce="\\f",Tt=Br("\\f",!1),fc=function(){return"\f"},Hi="\\n",fu=Br("\\n",!1),Yt=function(){return` +`},Cl="\\r",DA=Br("\\r",!1),cp=function(){return"\r"},pc="\\t",PA=Br("\\t",!1),Qn=function(){return" "},hi="\\v",hc=Br("\\v",!1),SA=function(){return"\v"},sa=/^[\\'"?]/,Li=Cs(["\\","'",'"',"?"],!1,!1),_o=function(N){return String.fromCharCode(parseInt(N,16))},Ze="\\x",lo=Br("\\x",!1),gc="\\u",pu=Br("\\u",!1),ji="\\U",hu=Br("\\U",!1),xA=function(N){return String.fromCodePoint(parseInt(N,16))},Ua=/^[0-7]/,dc=Cs([["0","7"]],!1,!1),hs=/^[0-9a-fA-f]/,_t=Cs([["0","9"],["a","f"],["A","f"]],!1,!1),Fn=cg(),Ci="{}",oa=Br("{}",!1),co=function(){return"{}"},Us="-",aa=Br("-",!1),la="+",Ho=Br("+",!1),wi=".",gs=Br(".",!1),ds=function(N,V,re){return{type:"number",value:(N==="-"?-1:1)*parseFloat(V.join("")+"."+re.join(""))}},ms=function(N,V){return{type:"number",value:(N==="-"?-1:1)*parseInt(V.join(""))}},_s=function(N){return{type:"variable",...N}},Un=function(N){return{type:"variable",name:N}},Pn=function(N){return N},ys="*",We=Br("*",!1),tt="/",It=Br("/",!1),nr=function(N,V,re){return{type:V==="*"?"multiplication":"division",right:re}},$=function(N,V){return V.reduce((re,he)=>({left:re,...he}),N)},me=function(N,V,re){return{type:V==="+"?"addition":"subtraction",right:re}},Le="$((",ft=Br("$((",!1),pt="))",Rt=Br("))",!1),er=function(N){return N},Zr="$(",qi=Br("$(",!1),es=function(N){return N},xi="${",jo=Br("${",!1),bA=":-",kA=Br(":-",!1),up=function(N,V){return{name:N,defaultValue:V}},ng=":-}",gu=Br(":-}",!1),ig=function(N){return{name:N,defaultValue:[]}},du=":+",uo=Br(":+",!1),QA=function(N,V){return{name:N,alternativeValue:V}},mc=":+}",ca=Br(":+}",!1),sg=function(N){return{name:N,alternativeValue:[]}},yc=function(N){return{name:N}},Pm="$",og=Br("$",!1),$n=function(N){return e.isGlobPattern(N)},Ap=function(N){return N},ag=/^[a-zA-Z0-9_]/,FA=Cs([["a","z"],["A","Z"],["0","9"],"_"],!1,!1),Hs=function(){return lg()},mu=/^[$@*?#a-zA-Z0-9_\-]/,Ha=Cs(["$","@","*","?","#",["a","z"],["A","Z"],["0","9"],"_","-"],!1,!1),Gi=/^[()}<>$|&; \t"']/,ua=Cs(["(",")","}","<",">","$","|","&",";"," "," ",'"',"'"],!1,!1),yu=/^[<>&; \t"']/,Es=Cs(["<",">","&",";"," "," ",'"',"'"],!1,!1),Ec=/^[ \t]/,Cc=Cs([" "," "],!1,!1),G=0,Dt=0,wl=[{line:1,column:1}],bi=0,wc=[],ct=0,Eu;if("startRule"in e){if(!(e.startRule in o))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');a=o[e.startRule]}function lg(){return t.substring(Dt,G)}function mw(){return Ic(Dt,G)}function TA(N,V){throw V=V!==void 0?V:Ic(Dt,G),fg([Ag(N)],t.substring(Dt,G),V)}function fp(N,V){throw V=V!==void 0?V:Ic(Dt,G),Sm(N,V)}function Br(N,V){return{type:"literal",text:N,ignoreCase:V}}function Cs(N,V,re){return{type:"class",parts:N,inverted:V,ignoreCase:re}}function cg(){return{type:"any"}}function ug(){return{type:"end"}}function Ag(N){return{type:"other",description:N}}function pp(N){var V=wl[N],re;if(V)return V;for(re=N-1;!wl[re];)re--;for(V=wl[re],V={line:V.line,column:V.column};re<N;)t.charCodeAt(re)===10?(V.line++,V.column=1):V.column++,re++;return wl[N]=V,V}function Ic(N,V){var re=pp(N),he=pp(V);return{start:{offset:N,line:re.line,column:re.column},end:{offset:V,line:he.line,column:he.column}}}function Ct(N){G<bi||(G>bi&&(bi=G,wc=[]),wc.push(N))}function Sm(N,V){return new qg(N,null,null,V)}function fg(N,V,re){return new qg(qg.buildMessage(N,V),N,V,re)}function pg(){var N,V,re;for(N=G,V=[],re=Qt();re!==r;)V.push(re),re=Qt();return V!==r?(re=Cu(),re===r&&(re=null),re!==r?(Dt=N,V=n(re),N=V):(G=N,N=r)):(G=N,N=r),N}function Cu(){var N,V,re,he,ze;if(N=G,V=wu(),V!==r){for(re=[],he=Qt();he!==r;)re.push(he),he=Qt();re!==r?(he=hg(),he!==r?(ze=xm(),ze===r&&(ze=null),ze!==r?(Dt=N,V=u(V,he,ze),N=V):(G=N,N=r)):(G=N,N=r)):(G=N,N=r)}else G=N,N=r;if(N===r)if(N=G,V=wu(),V!==r){for(re=[],he=Qt();he!==r;)re.push(he),he=Qt();re!==r?(he=hg(),he===r&&(he=null),he!==r?(Dt=N,V=A(V,he),N=V):(G=N,N=r)):(G=N,N=r)}else G=N,N=r;return N}function xm(){var N,V,re,he,ze;for(N=G,V=[],re=Qt();re!==r;)V.push(re),re=Qt();if(V!==r)if(re=Cu(),re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();he!==r?(Dt=N,V=p(re),N=V):(G=N,N=r)}else G=N,N=r;else G=N,N=r;return N}function hg(){var N;return t.charCodeAt(G)===59?(N=h,G++):(N=r,ct===0&&Ct(E)),N===r&&(t.charCodeAt(G)===38?(N=I,G++):(N=r,ct===0&&Ct(v))),N}function wu(){var N,V,re;return N=G,V=Aa(),V!==r?(re=yw(),re===r&&(re=null),re!==r?(Dt=N,V=b(V,re),N=V):(G=N,N=r)):(G=N,N=r),N}function yw(){var N,V,re,he,ze,mt,fr;for(N=G,V=[],re=Qt();re!==r;)V.push(re),re=Qt();if(V!==r)if(re=bm(),re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();if(he!==r)if(ze=wu(),ze!==r){for(mt=[],fr=Qt();fr!==r;)mt.push(fr),fr=Qt();mt!==r?(Dt=N,V=C(re,ze),N=V):(G=N,N=r)}else G=N,N=r;else G=N,N=r}else G=N,N=r;else G=N,N=r;return N}function bm(){var N;return t.substr(G,2)===T?(N=T,G+=2):(N=r,ct===0&&Ct(L)),N===r&&(t.substr(G,2)===U?(N=U,G+=2):(N=r,ct===0&&Ct(J))),N}function Aa(){var N,V,re;return N=G,V=gg(),V!==r?(re=Bc(),re===r&&(re=null),re!==r?(Dt=N,V=te(V,re),N=V):(G=N,N=r)):(G=N,N=r),N}function Bc(){var N,V,re,he,ze,mt,fr;for(N=G,V=[],re=Qt();re!==r;)V.push(re),re=Qt();if(V!==r)if(re=Il(),re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();if(he!==r)if(ze=Aa(),ze!==r){for(mt=[],fr=Qt();fr!==r;)mt.push(fr),fr=Qt();mt!==r?(Dt=N,V=le(re,ze),N=V):(G=N,N=r)}else G=N,N=r;else G=N,N=r}else G=N,N=r;else G=N,N=r;return N}function Il(){var N;return t.substr(G,2)===pe?(N=pe,G+=2):(N=r,ct===0&&Ct(Ae)),N===r&&(t.charCodeAt(G)===124?(N=ye,G++):(N=r,ct===0&&Ct(ae))),N}function Iu(){var N,V,re,he,ze,mt;if(N=G,V=Eg(),V!==r)if(t.charCodeAt(G)===61?(re=we,G++):(re=r,ct===0&&Ct(Pe)),re!==r)if(he=qo(),he!==r){for(ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();ze!==r?(Dt=N,V=g(V,he),N=V):(G=N,N=r)}else G=N,N=r;else G=N,N=r;else G=N,N=r;if(N===r)if(N=G,V=Eg(),V!==r)if(t.charCodeAt(G)===61?(re=we,G++):(re=r,ct===0&&Ct(Pe)),re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();he!==r?(Dt=N,V=Ee(V),N=V):(G=N,N=r)}else G=N,N=r;else G=N,N=r;return N}function gg(){var N,V,re,he,ze,mt,fr,Cr,yn,oi,Mi;for(N=G,V=[],re=Qt();re!==r;)V.push(re),re=Qt();if(V!==r)if(t.charCodeAt(G)===40?(re=De,G++):(re=r,ct===0&&Ct(ce)),re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();if(he!==r)if(ze=Cu(),ze!==r){for(mt=[],fr=Qt();fr!==r;)mt.push(fr),fr=Qt();if(mt!==r)if(t.charCodeAt(G)===41?(fr=ne,G++):(fr=r,ct===0&&Ct(ee)),fr!==r){for(Cr=[],yn=Qt();yn!==r;)Cr.push(yn),yn=Qt();if(Cr!==r){for(yn=[],oi=ja();oi!==r;)yn.push(oi),oi=ja();if(yn!==r){for(oi=[],Mi=Qt();Mi!==r;)oi.push(Mi),Mi=Qt();oi!==r?(Dt=N,V=Ie(ze,yn),N=V):(G=N,N=r)}else G=N,N=r}else G=N,N=r}else G=N,N=r;else G=N,N=r}else G=N,N=r;else G=N,N=r}else G=N,N=r;else G=N,N=r;if(N===r){for(N=G,V=[],re=Qt();re!==r;)V.push(re),re=Qt();if(V!==r)if(t.charCodeAt(G)===123?(re=ke,G++):(re=r,ct===0&&Ct(ht)),re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();if(he!==r)if(ze=Cu(),ze!==r){for(mt=[],fr=Qt();fr!==r;)mt.push(fr),fr=Qt();if(mt!==r)if(t.charCodeAt(G)===125?(fr=H,G++):(fr=r,ct===0&&Ct(lt)),fr!==r){for(Cr=[],yn=Qt();yn!==r;)Cr.push(yn),yn=Qt();if(Cr!==r){for(yn=[],oi=ja();oi!==r;)yn.push(oi),oi=ja();if(yn!==r){for(oi=[],Mi=Qt();Mi!==r;)oi.push(Mi),Mi=Qt();oi!==r?(Dt=N,V=Re(ze,yn),N=V):(G=N,N=r)}else G=N,N=r}else G=N,N=r}else G=N,N=r;else G=N,N=r}else G=N,N=r;else G=N,N=r}else G=N,N=r;else G=N,N=r;if(N===r){for(N=G,V=[],re=Qt();re!==r;)V.push(re),re=Qt();if(V!==r){for(re=[],he=Iu();he!==r;)re.push(he),he=Iu();if(re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();if(he!==r){if(ze=[],mt=hp(),mt!==r)for(;mt!==r;)ze.push(mt),mt=hp();else ze=r;if(ze!==r){for(mt=[],fr=Qt();fr!==r;)mt.push(fr),fr=Qt();mt!==r?(Dt=N,V=Qe(re,ze),N=V):(G=N,N=r)}else G=N,N=r}else G=N,N=r}else G=N,N=r}else G=N,N=r;if(N===r){for(N=G,V=[],re=Qt();re!==r;)V.push(re),re=Qt();if(V!==r){if(re=[],he=Iu(),he!==r)for(;he!==r;)re.push(he),he=Iu();else re=r;if(re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();he!==r?(Dt=N,V=be(re),N=V):(G=N,N=r)}else G=N,N=r}else G=N,N=r}}}return N}function RA(){var N,V,re,he,ze;for(N=G,V=[],re=Qt();re!==r;)V.push(re),re=Qt();if(V!==r){if(re=[],he=gp(),he!==r)for(;he!==r;)re.push(he),he=gp();else re=r;if(re!==r){for(he=[],ze=Qt();ze!==r;)he.push(ze),ze=Qt();he!==r?(Dt=N,V=_e(re),N=V):(G=N,N=r)}else G=N,N=r}else G=N,N=r;return N}function hp(){var N,V,re;for(N=G,V=[],re=Qt();re!==r;)V.push(re),re=Qt();if(V!==r?(re=ja(),re!==r?(Dt=N,V=Te(re),N=V):(G=N,N=r)):(G=N,N=r),N===r){for(N=G,V=[],re=Qt();re!==r;)V.push(re),re=Qt();V!==r?(re=gp(),re!==r?(Dt=N,V=Te(re),N=V):(G=N,N=r)):(G=N,N=r)}return N}function ja(){var N,V,re,he,ze;for(N=G,V=[],re=Qt();re!==r;)V.push(re),re=Qt();return V!==r?(Je.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(He)),re===r&&(re=null),re!==r?(he=dg(),he!==r?(ze=gp(),ze!==r?(Dt=N,V=x(re,he,ze),N=V):(G=N,N=r)):(G=N,N=r)):(G=N,N=r)):(G=N,N=r),N}function dg(){var N;return t.substr(G,2)===w?(N=w,G+=2):(N=r,ct===0&&Ct(S)),N===r&&(t.substr(G,2)===y?(N=y,G+=2):(N=r,ct===0&&Ct(F)),N===r&&(t.charCodeAt(G)===62?(N=z,G++):(N=r,ct===0&&Ct(X)),N===r&&(t.substr(G,3)===Z?(N=Z,G+=3):(N=r,ct===0&&Ct(ie)),N===r&&(t.substr(G,2)===Se?(N=Se,G+=2):(N=r,ct===0&&Ct(Ne)),N===r&&(t.charCodeAt(G)===60?(N=ot,G++):(N=r,ct===0&&Ct(dt))))))),N}function gp(){var N,V,re;for(N=G,V=[],re=Qt();re!==r;)V.push(re),re=Qt();return V!==r?(re=qo(),re!==r?(Dt=N,V=Te(re),N=V):(G=N,N=r)):(G=N,N=r),N}function qo(){var N,V,re;if(N=G,V=[],re=ws(),re!==r)for(;re!==r;)V.push(re),re=ws();else V=r;return V!==r&&(Dt=N,V=jt(V)),N=V,N}function ws(){var N,V;return N=G,V=Ii(),V!==r&&(Dt=N,V=$t(V)),N=V,N===r&&(N=G,V=km(),V!==r&&(Dt=N,V=$t(V)),N=V,N===r&&(N=G,V=Qm(),V!==r&&(Dt=N,V=$t(V)),N=V,N===r&&(N=G,V=Go(),V!==r&&(Dt=N,V=$t(V)),N=V))),N}function Ii(){var N,V,re,he;return N=G,t.substr(G,2)===xt?(V=xt,G+=2):(V=r,ct===0&&Ct(an)),V!==r?(re=ln(),re!==r?(t.charCodeAt(G)===39?(he=Qr,G++):(he=r,ct===0&&Ct(mr)),he!==r?(Dt=N,V=xr(re),N=V):(G=N,N=r)):(G=N,N=r)):(G=N,N=r),N}function km(){var N,V,re,he;return N=G,t.charCodeAt(G)===39?(V=Qr,G++):(V=r,ct===0&&Ct(mr)),V!==r?(re=mp(),re!==r?(t.charCodeAt(G)===39?(he=Qr,G++):(he=r,ct===0&&Ct(mr)),he!==r?(Dt=N,V=xr(re),N=V):(G=N,N=r)):(G=N,N=r)):(G=N,N=r),N}function Qm(){var N,V,re,he;if(N=G,t.substr(G,2)===Wr?(V=Wr,G+=2):(V=r,ct===0&&Ct(Vn)),V!==r&&(Dt=N,V=Ns()),N=V,N===r)if(N=G,t.charCodeAt(G)===34?(V=Ri,G++):(V=r,ct===0&&Ct(ps)),V!==r){for(re=[],he=NA();he!==r;)re.push(he),he=NA();re!==r?(t.charCodeAt(G)===34?(he=Ri,G++):(he=r,ct===0&&Ct(ps)),he!==r?(Dt=N,V=io(re),N=V):(G=N,N=r)):(G=N,N=r)}else G=N,N=r;return N}function Go(){var N,V,re;if(N=G,V=[],re=dp(),re!==r)for(;re!==r;)V.push(re),re=dp();else V=r;return V!==r&&(Dt=N,V=io(V)),N=V,N}function NA(){var N,V;return N=G,V=Gr(),V!==r&&(Dt=N,V=Si(V)),N=V,N===r&&(N=G,V=yp(),V!==r&&(Dt=N,V=Ls(V)),N=V,N===r&&(N=G,V=Dc(),V!==r&&(Dt=N,V=so(V)),N=V,N===r&&(N=G,V=mg(),V!==r&&(Dt=N,V=cc(V)),N=V))),N}function dp(){var N,V;return N=G,V=Gr(),V!==r&&(Dt=N,V=cu(V)),N=V,N===r&&(N=G,V=yp(),V!==r&&(Dt=N,V=ap(V)),N=V,N===r&&(N=G,V=Dc(),V!==r&&(Dt=N,V=lp(V)),N=V,N===r&&(N=G,V=Ew(),V!==r&&(Dt=N,V=Ms(V)),N=V,N===r&&(N=G,V=pa(),V!==r&&(Dt=N,V=cc(V)),N=V)))),N}function mp(){var N,V,re;for(N=G,V=[],Dn.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(oo));re!==r;)V.push(re),Dn.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(oo));return V!==r&&(Dt=N,V=Os(V)),N=V,N}function mg(){var N,V,re;if(N=G,V=[],re=fa(),re===r&&(ml.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(yl))),re!==r)for(;re!==r;)V.push(re),re=fa(),re===r&&(ml.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(yl)));else V=r;return V!==r&&(Dt=N,V=Os(V)),N=V,N}function fa(){var N,V,re;return N=G,t.substr(G,2)===ao?(V=ao,G+=2):(V=r,ct===0&&Ct(Kn)),V!==r&&(Dt=N,V=Mn()),N=V,N===r&&(N=G,t.charCodeAt(G)===92?(V=Ni,G++):(V=r,ct===0&&Ct(On)),V!==r?(_i.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(tr)),re!==r?(Dt=N,V=Me(re),N=V):(G=N,N=r)):(G=N,N=r)),N}function ln(){var N,V,re;for(N=G,V=[],re=Ao(),re===r&&(Dn.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(oo)));re!==r;)V.push(re),re=Ao(),re===r&&(Dn.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(oo)));return V!==r&&(Dt=N,V=Os(V)),N=V,N}function Ao(){var N,V,re;return N=G,t.substr(G,2)===ii?(V=ii,G+=2):(V=r,ct===0&&Ct(Oa)),V!==r&&(Dt=N,V=hr()),N=V,N===r&&(N=G,t.substr(G,2)===uc?(V=uc,G+=2):(V=r,ct===0&&Ct(uu)),V!==r&&(Dt=N,V=Ac()),N=V,N===r&&(N=G,t.charCodeAt(G)===92?(V=Ni,G++):(V=r,ct===0&&Ct(On)),V!==r?(El.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(vA)),re!==r?(Dt=N,V=Au(),N=V):(G=N,N=r)):(G=N,N=r),N===r&&(N=G,t.substr(G,2)===Ce?(V=Ce,G+=2):(V=r,ct===0&&Ct(Tt)),V!==r&&(Dt=N,V=fc()),N=V,N===r&&(N=G,t.substr(G,2)===Hi?(V=Hi,G+=2):(V=r,ct===0&&Ct(fu)),V!==r&&(Dt=N,V=Yt()),N=V,N===r&&(N=G,t.substr(G,2)===Cl?(V=Cl,G+=2):(V=r,ct===0&&Ct(DA)),V!==r&&(Dt=N,V=cp()),N=V,N===r&&(N=G,t.substr(G,2)===pc?(V=pc,G+=2):(V=r,ct===0&&Ct(PA)),V!==r&&(Dt=N,V=Qn()),N=V,N===r&&(N=G,t.substr(G,2)===hi?(V=hi,G+=2):(V=r,ct===0&&Ct(hc)),V!==r&&(Dt=N,V=SA()),N=V,N===r&&(N=G,t.charCodeAt(G)===92?(V=Ni,G++):(V=r,ct===0&&Ct(On)),V!==r?(sa.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(Li)),re!==r?(Dt=N,V=Me(re),N=V):(G=N,N=r)):(G=N,N=r),N===r&&(N=LA()))))))))),N}function LA(){var N,V,re,he,ze,mt,fr,Cr,yn,oi,Mi,wg;return N=G,t.charCodeAt(G)===92?(V=Ni,G++):(V=r,ct===0&&Ct(On)),V!==r?(re=qa(),re!==r?(Dt=N,V=_o(re),N=V):(G=N,N=r)):(G=N,N=r),N===r&&(N=G,t.substr(G,2)===Ze?(V=Ze,G+=2):(V=r,ct===0&&Ct(lo)),V!==r?(re=G,he=G,ze=qa(),ze!==r?(mt=si(),mt!==r?(ze=[ze,mt],he=ze):(G=he,he=r)):(G=he,he=r),he===r&&(he=qa()),he!==r?re=t.substring(re,G):re=he,re!==r?(Dt=N,V=_o(re),N=V):(G=N,N=r)):(G=N,N=r),N===r&&(N=G,t.substr(G,2)===gc?(V=gc,G+=2):(V=r,ct===0&&Ct(pu)),V!==r?(re=G,he=G,ze=si(),ze!==r?(mt=si(),mt!==r?(fr=si(),fr!==r?(Cr=si(),Cr!==r?(ze=[ze,mt,fr,Cr],he=ze):(G=he,he=r)):(G=he,he=r)):(G=he,he=r)):(G=he,he=r),he!==r?re=t.substring(re,G):re=he,re!==r?(Dt=N,V=_o(re),N=V):(G=N,N=r)):(G=N,N=r),N===r&&(N=G,t.substr(G,2)===ji?(V=ji,G+=2):(V=r,ct===0&&Ct(hu)),V!==r?(re=G,he=G,ze=si(),ze!==r?(mt=si(),mt!==r?(fr=si(),fr!==r?(Cr=si(),Cr!==r?(yn=si(),yn!==r?(oi=si(),oi!==r?(Mi=si(),Mi!==r?(wg=si(),wg!==r?(ze=[ze,mt,fr,Cr,yn,oi,Mi,wg],he=ze):(G=he,he=r)):(G=he,he=r)):(G=he,he=r)):(G=he,he=r)):(G=he,he=r)):(G=he,he=r)):(G=he,he=r)):(G=he,he=r),he!==r?re=t.substring(re,G):re=he,re!==r?(Dt=N,V=xA(re),N=V):(G=N,N=r)):(G=N,N=r)))),N}function qa(){var N;return Ua.test(t.charAt(G))?(N=t.charAt(G),G++):(N=r,ct===0&&Ct(dc)),N}function si(){var N;return hs.test(t.charAt(G))?(N=t.charAt(G),G++):(N=r,ct===0&&Ct(_t)),N}function pa(){var N,V,re,he,ze;if(N=G,V=[],re=G,t.charCodeAt(G)===92?(he=Ni,G++):(he=r,ct===0&&Ct(On)),he!==r?(t.length>G?(ze=t.charAt(G),G++):(ze=r,ct===0&&Ct(Fn)),ze!==r?(Dt=re,he=Me(ze),re=he):(G=re,re=r)):(G=re,re=r),re===r&&(re=G,t.substr(G,2)===Ci?(he=Ci,G+=2):(he=r,ct===0&&Ct(oa)),he!==r&&(Dt=re,he=co()),re=he,re===r&&(re=G,he=G,ct++,ze=Fm(),ct--,ze===r?he=void 0:(G=he,he=r),he!==r?(t.length>G?(ze=t.charAt(G),G++):(ze=r,ct===0&&Ct(Fn)),ze!==r?(Dt=re,he=Me(ze),re=he):(G=re,re=r)):(G=re,re=r))),re!==r)for(;re!==r;)V.push(re),re=G,t.charCodeAt(G)===92?(he=Ni,G++):(he=r,ct===0&&Ct(On)),he!==r?(t.length>G?(ze=t.charAt(G),G++):(ze=r,ct===0&&Ct(Fn)),ze!==r?(Dt=re,he=Me(ze),re=he):(G=re,re=r)):(G=re,re=r),re===r&&(re=G,t.substr(G,2)===Ci?(he=Ci,G+=2):(he=r,ct===0&&Ct(oa)),he!==r&&(Dt=re,he=co()),re=he,re===r&&(re=G,he=G,ct++,ze=Fm(),ct--,ze===r?he=void 0:(G=he,he=r),he!==r?(t.length>G?(ze=t.charAt(G),G++):(ze=r,ct===0&&Ct(Fn)),ze!==r?(Dt=re,he=Me(ze),re=he):(G=re,re=r)):(G=re,re=r)));else V=r;return V!==r&&(Dt=N,V=Os(V)),N=V,N}function vc(){var N,V,re,he,ze,mt;if(N=G,t.charCodeAt(G)===45?(V=Us,G++):(V=r,ct===0&&Ct(aa)),V===r&&(t.charCodeAt(G)===43?(V=la,G++):(V=r,ct===0&&Ct(Ho))),V===r&&(V=null),V!==r){if(re=[],Je.test(t.charAt(G))?(he=t.charAt(G),G++):(he=r,ct===0&&Ct(He)),he!==r)for(;he!==r;)re.push(he),Je.test(t.charAt(G))?(he=t.charAt(G),G++):(he=r,ct===0&&Ct(He));else re=r;if(re!==r)if(t.charCodeAt(G)===46?(he=wi,G++):(he=r,ct===0&&Ct(gs)),he!==r){if(ze=[],Je.test(t.charAt(G))?(mt=t.charAt(G),G++):(mt=r,ct===0&&Ct(He)),mt!==r)for(;mt!==r;)ze.push(mt),Je.test(t.charAt(G))?(mt=t.charAt(G),G++):(mt=r,ct===0&&Ct(He));else ze=r;ze!==r?(Dt=N,V=ds(V,re,ze),N=V):(G=N,N=r)}else G=N,N=r;else G=N,N=r}else G=N,N=r;if(N===r){if(N=G,t.charCodeAt(G)===45?(V=Us,G++):(V=r,ct===0&&Ct(aa)),V===r&&(t.charCodeAt(G)===43?(V=la,G++):(V=r,ct===0&&Ct(Ho))),V===r&&(V=null),V!==r){if(re=[],Je.test(t.charAt(G))?(he=t.charAt(G),G++):(he=r,ct===0&&Ct(He)),he!==r)for(;he!==r;)re.push(he),Je.test(t.charAt(G))?(he=t.charAt(G),G++):(he=r,ct===0&&Ct(He));else re=r;re!==r?(Dt=N,V=ms(V,re),N=V):(G=N,N=r)}else G=N,N=r;if(N===r&&(N=G,V=Dc(),V!==r&&(Dt=N,V=_s(V)),N=V,N===r&&(N=G,V=Ga(),V!==r&&(Dt=N,V=Un(V)),N=V,N===r)))if(N=G,t.charCodeAt(G)===40?(V=De,G++):(V=r,ct===0&&Ct(ce)),V!==r){for(re=[],he=Qt();he!==r;)re.push(he),he=Qt();if(re!==r)if(he=ts(),he!==r){for(ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();ze!==r?(t.charCodeAt(G)===41?(mt=ne,G++):(mt=r,ct===0&&Ct(ee)),mt!==r?(Dt=N,V=Pn(he),N=V):(G=N,N=r)):(G=N,N=r)}else G=N,N=r;else G=N,N=r}else G=N,N=r}return N}function Bl(){var N,V,re,he,ze,mt,fr,Cr;if(N=G,V=vc(),V!==r){for(re=[],he=G,ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();if(ze!==r)if(t.charCodeAt(G)===42?(mt=ys,G++):(mt=r,ct===0&&Ct(We)),mt===r&&(t.charCodeAt(G)===47?(mt=tt,G++):(mt=r,ct===0&&Ct(It))),mt!==r){for(fr=[],Cr=Qt();Cr!==r;)fr.push(Cr),Cr=Qt();fr!==r?(Cr=vc(),Cr!==r?(Dt=he,ze=nr(V,mt,Cr),he=ze):(G=he,he=r)):(G=he,he=r)}else G=he,he=r;else G=he,he=r;for(;he!==r;){for(re.push(he),he=G,ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();if(ze!==r)if(t.charCodeAt(G)===42?(mt=ys,G++):(mt=r,ct===0&&Ct(We)),mt===r&&(t.charCodeAt(G)===47?(mt=tt,G++):(mt=r,ct===0&&Ct(It))),mt!==r){for(fr=[],Cr=Qt();Cr!==r;)fr.push(Cr),Cr=Qt();fr!==r?(Cr=vc(),Cr!==r?(Dt=he,ze=nr(V,mt,Cr),he=ze):(G=he,he=r)):(G=he,he=r)}else G=he,he=r;else G=he,he=r}re!==r?(Dt=N,V=$(V,re),N=V):(G=N,N=r)}else G=N,N=r;return N}function ts(){var N,V,re,he,ze,mt,fr,Cr;if(N=G,V=Bl(),V!==r){for(re=[],he=G,ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();if(ze!==r)if(t.charCodeAt(G)===43?(mt=la,G++):(mt=r,ct===0&&Ct(Ho)),mt===r&&(t.charCodeAt(G)===45?(mt=Us,G++):(mt=r,ct===0&&Ct(aa))),mt!==r){for(fr=[],Cr=Qt();Cr!==r;)fr.push(Cr),Cr=Qt();fr!==r?(Cr=Bl(),Cr!==r?(Dt=he,ze=me(V,mt,Cr),he=ze):(G=he,he=r)):(G=he,he=r)}else G=he,he=r;else G=he,he=r;for(;he!==r;){for(re.push(he),he=G,ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();if(ze!==r)if(t.charCodeAt(G)===43?(mt=la,G++):(mt=r,ct===0&&Ct(Ho)),mt===r&&(t.charCodeAt(G)===45?(mt=Us,G++):(mt=r,ct===0&&Ct(aa))),mt!==r){for(fr=[],Cr=Qt();Cr!==r;)fr.push(Cr),Cr=Qt();fr!==r?(Cr=Bl(),Cr!==r?(Dt=he,ze=me(V,mt,Cr),he=ze):(G=he,he=r)):(G=he,he=r)}else G=he,he=r;else G=he,he=r}re!==r?(Dt=N,V=$(V,re),N=V):(G=N,N=r)}else G=N,N=r;return N}function Gr(){var N,V,re,he,ze,mt;if(N=G,t.substr(G,3)===Le?(V=Le,G+=3):(V=r,ct===0&&Ct(ft)),V!==r){for(re=[],he=Qt();he!==r;)re.push(he),he=Qt();if(re!==r)if(he=ts(),he!==r){for(ze=[],mt=Qt();mt!==r;)ze.push(mt),mt=Qt();ze!==r?(t.substr(G,2)===pt?(mt=pt,G+=2):(mt=r,ct===0&&Ct(Rt)),mt!==r?(Dt=N,V=er(he),N=V):(G=N,N=r)):(G=N,N=r)}else G=N,N=r;else G=N,N=r}else G=N,N=r;return N}function yp(){var N,V,re,he;return N=G,t.substr(G,2)===Zr?(V=Zr,G+=2):(V=r,ct===0&&Ct(qi)),V!==r?(re=Cu(),re!==r?(t.charCodeAt(G)===41?(he=ne,G++):(he=r,ct===0&&Ct(ee)),he!==r?(Dt=N,V=es(re),N=V):(G=N,N=r)):(G=N,N=r)):(G=N,N=r),N}function Dc(){var N,V,re,he,ze,mt;return N=G,t.substr(G,2)===xi?(V=xi,G+=2):(V=r,ct===0&&Ct(jo)),V!==r?(re=Ga(),re!==r?(t.substr(G,2)===bA?(he=bA,G+=2):(he=r,ct===0&&Ct(kA)),he!==r?(ze=RA(),ze!==r?(t.charCodeAt(G)===125?(mt=H,G++):(mt=r,ct===0&&Ct(lt)),mt!==r?(Dt=N,V=up(re,ze),N=V):(G=N,N=r)):(G=N,N=r)):(G=N,N=r)):(G=N,N=r)):(G=N,N=r),N===r&&(N=G,t.substr(G,2)===xi?(V=xi,G+=2):(V=r,ct===0&&Ct(jo)),V!==r?(re=Ga(),re!==r?(t.substr(G,3)===ng?(he=ng,G+=3):(he=r,ct===0&&Ct(gu)),he!==r?(Dt=N,V=ig(re),N=V):(G=N,N=r)):(G=N,N=r)):(G=N,N=r),N===r&&(N=G,t.substr(G,2)===xi?(V=xi,G+=2):(V=r,ct===0&&Ct(jo)),V!==r?(re=Ga(),re!==r?(t.substr(G,2)===du?(he=du,G+=2):(he=r,ct===0&&Ct(uo)),he!==r?(ze=RA(),ze!==r?(t.charCodeAt(G)===125?(mt=H,G++):(mt=r,ct===0&&Ct(lt)),mt!==r?(Dt=N,V=QA(re,ze),N=V):(G=N,N=r)):(G=N,N=r)):(G=N,N=r)):(G=N,N=r)):(G=N,N=r),N===r&&(N=G,t.substr(G,2)===xi?(V=xi,G+=2):(V=r,ct===0&&Ct(jo)),V!==r?(re=Ga(),re!==r?(t.substr(G,3)===mc?(he=mc,G+=3):(he=r,ct===0&&Ct(ca)),he!==r?(Dt=N,V=sg(re),N=V):(G=N,N=r)):(G=N,N=r)):(G=N,N=r),N===r&&(N=G,t.substr(G,2)===xi?(V=xi,G+=2):(V=r,ct===0&&Ct(jo)),V!==r?(re=Ga(),re!==r?(t.charCodeAt(G)===125?(he=H,G++):(he=r,ct===0&&Ct(lt)),he!==r?(Dt=N,V=yc(re),N=V):(G=N,N=r)):(G=N,N=r)):(G=N,N=r),N===r&&(N=G,t.charCodeAt(G)===36?(V=Pm,G++):(V=r,ct===0&&Ct(og)),V!==r?(re=Ga(),re!==r?(Dt=N,V=yc(re),N=V):(G=N,N=r)):(G=N,N=r)))))),N}function Ew(){var N,V,re;return N=G,V=yg(),V!==r?(Dt=G,re=$n(V),re?re=void 0:re=r,re!==r?(Dt=N,V=Ap(V),N=V):(G=N,N=r)):(G=N,N=r),N}function yg(){var N,V,re,he,ze;if(N=G,V=[],re=G,he=G,ct++,ze=Cg(),ct--,ze===r?he=void 0:(G=he,he=r),he!==r?(t.length>G?(ze=t.charAt(G),G++):(ze=r,ct===0&&Ct(Fn)),ze!==r?(Dt=re,he=Me(ze),re=he):(G=re,re=r)):(G=re,re=r),re!==r)for(;re!==r;)V.push(re),re=G,he=G,ct++,ze=Cg(),ct--,ze===r?he=void 0:(G=he,he=r),he!==r?(t.length>G?(ze=t.charAt(G),G++):(ze=r,ct===0&&Ct(Fn)),ze!==r?(Dt=re,he=Me(ze),re=he):(G=re,re=r)):(G=re,re=r);else V=r;return V!==r&&(Dt=N,V=Os(V)),N=V,N}function Eg(){var N,V,re;if(N=G,V=[],ag.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(FA)),re!==r)for(;re!==r;)V.push(re),ag.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(FA));else V=r;return V!==r&&(Dt=N,V=Hs()),N=V,N}function Ga(){var N,V,re;if(N=G,V=[],mu.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(Ha)),re!==r)for(;re!==r;)V.push(re),mu.test(t.charAt(G))?(re=t.charAt(G),G++):(re=r,ct===0&&Ct(Ha));else V=r;return V!==r&&(Dt=N,V=Hs()),N=V,N}function Fm(){var N;return Gi.test(t.charAt(G))?(N=t.charAt(G),G++):(N=r,ct===0&&Ct(ua)),N}function Cg(){var N;return yu.test(t.charAt(G))?(N=t.charAt(G),G++):(N=r,ct===0&&Ct(Es)),N}function Qt(){var N,V;if(N=[],Ec.test(t.charAt(G))?(V=t.charAt(G),G++):(V=r,ct===0&&Ct(Cc)),V!==r)for(;V!==r;)N.push(V),Ec.test(t.charAt(G))?(V=t.charAt(G),G++):(V=r,ct===0&&Ct(Cc));else N=r;return N}if(Eu=a(),Eu!==r&&G===t.length)return Eu;throw Eu!==r&&G<t.length&&Ct(ug()),fg(wc,bi<t.length?t.charAt(bi):null,bi<t.length?Ic(bi,bi+1):Ic(bi,bi))}$Y.exports={SyntaxError:qg,parse:g8e}});function LD(t,e={isGlobPattern:()=>!1}){try{return(0,tW.parse)(t,e)}catch(r){throw r.location&&(r.message=r.message.replace(/(\.)?$/,` (line ${r.location.start.line}, column ${r.location.start.column})$1`)),r}}function ly(t,{endSemicolon:e=!1}={}){return t.map(({command:r,type:o},a)=>`${MD(r)}${o===";"?a!==t.length-1||e?";":"":" &"}`).join(" ")}function MD(t){return`${cy(t.chain)}${t.then?` ${lR(t.then)}`:""}`}function lR(t){return`${t.type} ${MD(t.line)}`}function cy(t){return`${uR(t)}${t.then?` ${cR(t.then)}`:""}`}function cR(t){return`${t.type} ${cy(t.chain)}`}function uR(t){switch(t.type){case"command":return`${t.envs.length>0?`${t.envs.map(e=>ND(e)).join(" ")} `:""}${t.args.map(e=>AR(e)).join(" ")}`;case"subshell":return`(${ly(t.subshell)})${t.args.length>0?` ${t.args.map(e=>Kw(e)).join(" ")}`:""}`;case"group":return`{ ${ly(t.group,{endSemicolon:!0})} }${t.args.length>0?` ${t.args.map(e=>Kw(e)).join(" ")}`:""}`;case"envs":return t.envs.map(e=>ND(e)).join(" ");default:throw new Error(`Unsupported command type: "${t.type}"`)}}function ND(t){return`${t.name}=${t.args[0]?Gg(t.args[0]):""}`}function AR(t){switch(t.type){case"redirection":return Kw(t);case"argument":return Gg(t);default:throw new Error(`Unsupported argument type: "${t.type}"`)}}function Kw(t){return`${t.subtype} ${t.args.map(e=>Gg(e)).join(" ")}`}function Gg(t){return t.segments.map(e=>fR(e)).join("")}function fR(t){let e=(o,a)=>a?`"${o}"`:o,r=o=>o===""?"''":o.match(/[()}<>$|&;"'\n\t ]/)?o.match(/['\t\p{C}]/u)?o.match(/'/)?`"${o.replace(/["$\t\p{C}]/u,m8e)}"`:`$'${o.replace(/[\t\p{C}]/u,nW)}'`:`'${o}'`:o;switch(t.type){case"text":return r(t.text);case"glob":return t.pattern;case"shell":return e(`\${${ly(t.shell)}}`,t.quoted);case"variable":return e(typeof t.defaultValue>"u"?typeof t.alternativeValue>"u"?`\${${t.name}}`:t.alternativeValue.length===0?`\${${t.name}:+}`:`\${${t.name}:+${t.alternativeValue.map(o=>Gg(o)).join(" ")}}`:t.defaultValue.length===0?`\${${t.name}:-}`:`\${${t.name}:-${t.defaultValue.map(o=>Gg(o)).join(" ")}}`,t.quoted);case"arithmetic":return`$(( ${OD(t.arithmetic)} ))`;default:throw new Error(`Unsupported argument segment type: "${t.type}"`)}}function OD(t){let e=a=>{switch(a){case"addition":return"+";case"subtraction":return"-";case"multiplication":return"*";case"division":return"/";default:throw new Error(`Can't extract operator from arithmetic expression of type "${a}"`)}},r=(a,n)=>n?`( ${a} )`:a,o=a=>r(OD(a),!["number","variable"].includes(a.type));switch(t.type){case"number":return String(t.value);case"variable":return t.name;default:return`${o(t.left)} ${e(t.type)} ${o(t.right)}`}}var tW,rW,d8e,nW,m8e,iW=Et(()=>{tW=$e(eW());rW=new Map([["\f","\\f"],[` +`,"\\n"],["\r","\\r"],[" ","\\t"],["\v","\\v"],["\0","\\0"]]),d8e=new Map([["\\","\\\\"],["$","\\$"],['"','\\"'],...Array.from(rW,([t,e])=>[t,`"$'${e}'"`])]),nW=t=>rW.get(t)??`\\x${t.charCodeAt(0).toString(16).padStart(2,"0")}`,m8e=t=>d8e.get(t)??`"$'${nW(t)}'"`});var oW=_((Nxt,sW)=>{"use strict";function y8e(t,e){function r(){this.constructor=t}r.prototype=e.prototype,t.prototype=new r}function Yg(t,e,r,o){this.message=t,this.expected=e,this.found=r,this.location=o,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,Yg)}y8e(Yg,Error);Yg.buildMessage=function(t,e){var r={literal:function(h){return'"'+a(h.text)+'"'},class:function(h){var E="",I;for(I=0;I<h.parts.length;I++)E+=h.parts[I]instanceof Array?n(h.parts[I][0])+"-"+n(h.parts[I][1]):n(h.parts[I]);return"["+(h.inverted?"^":"")+E+"]"},any:function(h){return"any character"},end:function(h){return"end of input"},other:function(h){return h.description}};function o(h){return h.charCodeAt(0).toString(16).toUpperCase()}function a(h){return h.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(E){return"\\x0"+o(E)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(E){return"\\x"+o(E)})}function n(h){return h.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(E){return"\\x0"+o(E)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(E){return"\\x"+o(E)})}function u(h){return r[h.type](h)}function A(h){var E=new Array(h.length),I,v;for(I=0;I<h.length;I++)E[I]=u(h[I]);if(E.sort(),E.length>0){for(I=1,v=1;I<E.length;I++)E[I-1]!==E[I]&&(E[v]=E[I],v++);E.length=v}switch(E.length){case 1:return E[0];case 2:return E[0]+" or "+E[1];default:return E.slice(0,-1).join(", ")+", or "+E[E.length-1]}}function p(h){return h?'"'+a(h)+'"':"end of input"}return"Expected "+A(t)+" but "+p(e)+" found."};function E8e(t,e){e=e!==void 0?e:{};var r={},o={resolution:Qe},a=Qe,n="/",u=De("/",!1),A=function(He,x){return{from:He,descriptor:x}},p=function(He){return{descriptor:He}},h="@",E=De("@",!1),I=function(He,x){return{fullName:He,description:x}},v=function(He){return{fullName:He}},b=function(){return we()},C=/^[^\/@]/,T=ce(["/","@"],!0,!1),L=/^[^\/]/,U=ce(["/"],!0,!1),J=0,te=0,le=[{line:1,column:1}],pe=0,Ae=[],ye=0,ae;if("startRule"in e){if(!(e.startRule in o))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');a=o[e.startRule]}function we(){return t.substring(te,J)}function Pe(){return ht(te,J)}function g(He,x){throw x=x!==void 0?x:ht(te,J),Re([Ie(He)],t.substring(te,J),x)}function Ee(He,x){throw x=x!==void 0?x:ht(te,J),lt(He,x)}function De(He,x){return{type:"literal",text:He,ignoreCase:x}}function ce(He,x,w){return{type:"class",parts:He,inverted:x,ignoreCase:w}}function ne(){return{type:"any"}}function ee(){return{type:"end"}}function Ie(He){return{type:"other",description:He}}function ke(He){var x=le[He],w;if(x)return x;for(w=He-1;!le[w];)w--;for(x=le[w],x={line:x.line,column:x.column};w<He;)t.charCodeAt(w)===10?(x.line++,x.column=1):x.column++,w++;return le[He]=x,x}function ht(He,x){var w=ke(He),S=ke(x);return{start:{offset:He,line:w.line,column:w.column},end:{offset:x,line:S.line,column:S.column}}}function H(He){J<pe||(J>pe&&(pe=J,Ae=[]),Ae.push(He))}function lt(He,x){return new Yg(He,null,null,x)}function Re(He,x,w){return new Yg(Yg.buildMessage(He,x),He,x,w)}function Qe(){var He,x,w,S;return He=J,x=be(),x!==r?(t.charCodeAt(J)===47?(w=n,J++):(w=r,ye===0&&H(u)),w!==r?(S=be(),S!==r?(te=He,x=A(x,S),He=x):(J=He,He=r)):(J=He,He=r)):(J=He,He=r),He===r&&(He=J,x=be(),x!==r&&(te=He,x=p(x)),He=x),He}function be(){var He,x,w,S;return He=J,x=_e(),x!==r?(t.charCodeAt(J)===64?(w=h,J++):(w=r,ye===0&&H(E)),w!==r?(S=Je(),S!==r?(te=He,x=I(x,S),He=x):(J=He,He=r)):(J=He,He=r)):(J=He,He=r),He===r&&(He=J,x=_e(),x!==r&&(te=He,x=v(x)),He=x),He}function _e(){var He,x,w,S,y;return He=J,t.charCodeAt(J)===64?(x=h,J++):(x=r,ye===0&&H(E)),x!==r?(w=Te(),w!==r?(t.charCodeAt(J)===47?(S=n,J++):(S=r,ye===0&&H(u)),S!==r?(y=Te(),y!==r?(te=He,x=b(),He=x):(J=He,He=r)):(J=He,He=r)):(J=He,He=r)):(J=He,He=r),He===r&&(He=J,x=Te(),x!==r&&(te=He,x=b()),He=x),He}function Te(){var He,x,w;if(He=J,x=[],C.test(t.charAt(J))?(w=t.charAt(J),J++):(w=r,ye===0&&H(T)),w!==r)for(;w!==r;)x.push(w),C.test(t.charAt(J))?(w=t.charAt(J),J++):(w=r,ye===0&&H(T));else x=r;return x!==r&&(te=He,x=b()),He=x,He}function Je(){var He,x,w;if(He=J,x=[],L.test(t.charAt(J))?(w=t.charAt(J),J++):(w=r,ye===0&&H(U)),w!==r)for(;w!==r;)x.push(w),L.test(t.charAt(J))?(w=t.charAt(J),J++):(w=r,ye===0&&H(U));else x=r;return x!==r&&(te=He,x=b()),He=x,He}if(ae=a(),ae!==r&&J===t.length)return ae;throw ae!==r&&J<t.length&&H(ee()),Re(Ae,pe<t.length?t.charAt(pe):null,pe<t.length?ht(pe,pe+1):ht(pe,pe))}sW.exports={SyntaxError:Yg,parse:E8e}});function UD(t){let e=t.match(/^\*{1,2}\/(.*)/);if(e)throw new Error(`The override for '${t}' includes a glob pattern. Glob patterns have been removed since their behaviours don't match what you'd expect. Set the override to '${e[1]}' instead.`);try{return(0,aW.parse)(t)}catch(r){throw r.location&&(r.message=r.message.replace(/(\.)?$/,` (line ${r.location.start.line}, column ${r.location.start.column})$1`)),r}}function _D(t){let e="";return t.from&&(e+=t.from.fullName,t.from.description&&(e+=`@${t.from.description}`),e+="/"),e+=t.descriptor.fullName,t.descriptor.description&&(e+=`@${t.descriptor.description}`),e}var aW,lW=Et(()=>{aW=$e(oW())});var Vg=_((Mxt,Wg)=>{"use strict";function cW(t){return typeof t>"u"||t===null}function C8e(t){return typeof t=="object"&&t!==null}function w8e(t){return Array.isArray(t)?t:cW(t)?[]:[t]}function I8e(t,e){var r,o,a,n;if(e)for(n=Object.keys(e),r=0,o=n.length;r<o;r+=1)a=n[r],t[a]=e[a];return t}function B8e(t,e){var r="",o;for(o=0;o<e;o+=1)r+=t;return r}function v8e(t){return t===0&&Number.NEGATIVE_INFINITY===1/t}Wg.exports.isNothing=cW;Wg.exports.isObject=C8e;Wg.exports.toArray=w8e;Wg.exports.repeat=B8e;Wg.exports.isNegativeZero=v8e;Wg.exports.extend=I8e});var uy=_((Oxt,uW)=>{"use strict";function Jw(t,e){Error.call(this),this.name="YAMLException",this.reason=t,this.mark=e,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():""),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack||""}Jw.prototype=Object.create(Error.prototype);Jw.prototype.constructor=Jw;Jw.prototype.toString=function(e){var r=this.name+": ";return r+=this.reason||"(unknown reason)",!e&&this.mark&&(r+=" "+this.mark.toString()),r};uW.exports=Jw});var pW=_((Uxt,fW)=>{"use strict";var AW=Vg();function pR(t,e,r,o,a){this.name=t,this.buffer=e,this.position=r,this.line=o,this.column=a}pR.prototype.getSnippet=function(e,r){var o,a,n,u,A;if(!this.buffer)return null;for(e=e||4,r=r||75,o="",a=this.position;a>0&&`\0\r +\x85\u2028\u2029`.indexOf(this.buffer.charAt(a-1))===-1;)if(a-=1,this.position-a>r/2-1){o=" ... ",a+=5;break}for(n="",u=this.position;u<this.buffer.length&&`\0\r +\x85\u2028\u2029`.indexOf(this.buffer.charAt(u))===-1;)if(u+=1,u-this.position>r/2-1){n=" ... ",u-=5;break}return A=this.buffer.slice(a,u),AW.repeat(" ",e)+o+A+n+` +`+AW.repeat(" ",e+this.position-a+o.length)+"^"};pR.prototype.toString=function(e){var r,o="";return this.name&&(o+='in "'+this.name+'" '),o+="at line "+(this.line+1)+", column "+(this.column+1),e||(r=this.getSnippet(),r&&(o+=`: +`+r)),o};fW.exports=pR});var os=_((_xt,gW)=>{"use strict";var hW=uy(),D8e=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],P8e=["scalar","sequence","mapping"];function S8e(t){var e={};return t!==null&&Object.keys(t).forEach(function(r){t[r].forEach(function(o){e[String(o)]=r})}),e}function x8e(t,e){if(e=e||{},Object.keys(e).forEach(function(r){if(D8e.indexOf(r)===-1)throw new hW('Unknown option "'+r+'" is met in definition of "'+t+'" YAML type.')}),this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(r){return r},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=S8e(e.styleAliases||null),P8e.indexOf(this.kind)===-1)throw new hW('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')}gW.exports=x8e});var Kg=_((Hxt,mW)=>{"use strict";var dW=Vg(),HD=uy(),b8e=os();function hR(t,e,r){var o=[];return t.include.forEach(function(a){r=hR(a,e,r)}),t[e].forEach(function(a){r.forEach(function(n,u){n.tag===a.tag&&n.kind===a.kind&&o.push(u)}),r.push(a)}),r.filter(function(a,n){return o.indexOf(n)===-1})}function k8e(){var t={scalar:{},sequence:{},mapping:{},fallback:{}},e,r;function o(a){t[a.kind][a.tag]=t.fallback[a.tag]=a}for(e=0,r=arguments.length;e<r;e+=1)arguments[e].forEach(o);return t}function Ay(t){this.include=t.include||[],this.implicit=t.implicit||[],this.explicit=t.explicit||[],this.implicit.forEach(function(e){if(e.loadKind&&e.loadKind!=="scalar")throw new HD("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")}),this.compiledImplicit=hR(this,"implicit",[]),this.compiledExplicit=hR(this,"explicit",[]),this.compiledTypeMap=k8e(this.compiledImplicit,this.compiledExplicit)}Ay.DEFAULT=null;Ay.create=function(){var e,r;switch(arguments.length){case 1:e=Ay.DEFAULT,r=arguments[0];break;case 2:e=arguments[0],r=arguments[1];break;default:throw new HD("Wrong number of arguments for Schema.create function")}if(e=dW.toArray(e),r=dW.toArray(r),!e.every(function(o){return o instanceof Ay}))throw new HD("Specified list of super schemas (or a single Schema object) contains a non-Schema object.");if(!r.every(function(o){return o instanceof b8e}))throw new HD("Specified list of YAML types (or a single Type object) contains a non-Type object.");return new Ay({include:e,explicit:r})};mW.exports=Ay});var EW=_((jxt,yW)=>{"use strict";var Q8e=os();yW.exports=new Q8e("tag:yaml.org,2002:str",{kind:"scalar",construct:function(t){return t!==null?t:""}})});var wW=_((qxt,CW)=>{"use strict";var F8e=os();CW.exports=new F8e("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(t){return t!==null?t:[]}})});var BW=_((Gxt,IW)=>{"use strict";var T8e=os();IW.exports=new T8e("tag:yaml.org,2002:map",{kind:"mapping",construct:function(t){return t!==null?t:{}}})});var jD=_((Yxt,vW)=>{"use strict";var R8e=Kg();vW.exports=new R8e({explicit:[EW(),wW(),BW()]})});var PW=_((Wxt,DW)=>{"use strict";var N8e=os();function L8e(t){if(t===null)return!0;var e=t.length;return e===1&&t==="~"||e===4&&(t==="null"||t==="Null"||t==="NULL")}function M8e(){return null}function O8e(t){return t===null}DW.exports=new N8e("tag:yaml.org,2002:null",{kind:"scalar",resolve:L8e,construct:M8e,predicate:O8e,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})});var xW=_((Vxt,SW)=>{"use strict";var U8e=os();function _8e(t){if(t===null)return!1;var e=t.length;return e===4&&(t==="true"||t==="True"||t==="TRUE")||e===5&&(t==="false"||t==="False"||t==="FALSE")}function H8e(t){return t==="true"||t==="True"||t==="TRUE"}function j8e(t){return Object.prototype.toString.call(t)==="[object Boolean]"}SW.exports=new U8e("tag:yaml.org,2002:bool",{kind:"scalar",resolve:_8e,construct:H8e,predicate:j8e,represent:{lowercase:function(t){return t?"true":"false"},uppercase:function(t){return t?"TRUE":"FALSE"},camelcase:function(t){return t?"True":"False"}},defaultStyle:"lowercase"})});var kW=_((Kxt,bW)=>{"use strict";var q8e=Vg(),G8e=os();function Y8e(t){return 48<=t&&t<=57||65<=t&&t<=70||97<=t&&t<=102}function W8e(t){return 48<=t&&t<=55}function V8e(t){return 48<=t&&t<=57}function K8e(t){if(t===null)return!1;var e=t.length,r=0,o=!1,a;if(!e)return!1;if(a=t[r],(a==="-"||a==="+")&&(a=t[++r]),a==="0"){if(r+1===e)return!0;if(a=t[++r],a==="b"){for(r++;r<e;r++)if(a=t[r],a!=="_"){if(a!=="0"&&a!=="1")return!1;o=!0}return o&&a!=="_"}if(a==="x"){for(r++;r<e;r++)if(a=t[r],a!=="_"){if(!Y8e(t.charCodeAt(r)))return!1;o=!0}return o&&a!=="_"}for(;r<e;r++)if(a=t[r],a!=="_"){if(!W8e(t.charCodeAt(r)))return!1;o=!0}return o&&a!=="_"}if(a==="_")return!1;for(;r<e;r++)if(a=t[r],a!=="_"){if(a===":")break;if(!V8e(t.charCodeAt(r)))return!1;o=!0}return!o||a==="_"?!1:a!==":"?!0:/^(:[0-5]?[0-9])+$/.test(t.slice(r))}function J8e(t){var e=t,r=1,o,a,n=[];return e.indexOf("_")!==-1&&(e=e.replace(/_/g,"")),o=e[0],(o==="-"||o==="+")&&(o==="-"&&(r=-1),e=e.slice(1),o=e[0]),e==="0"?0:o==="0"?e[1]==="b"?r*parseInt(e.slice(2),2):e[1]==="x"?r*parseInt(e,16):r*parseInt(e,8):e.indexOf(":")!==-1?(e.split(":").forEach(function(u){n.unshift(parseInt(u,10))}),e=0,a=1,n.forEach(function(u){e+=u*a,a*=60}),r*e):r*parseInt(e,10)}function z8e(t){return Object.prototype.toString.call(t)==="[object Number]"&&t%1===0&&!q8e.isNegativeZero(t)}bW.exports=new G8e("tag:yaml.org,2002:int",{kind:"scalar",resolve:K8e,construct:J8e,predicate:z8e,represent:{binary:function(t){return t>=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},octal:function(t){return t>=0?"0"+t.toString(8):"-0"+t.toString(8).slice(1)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})});var TW=_((Jxt,FW)=>{"use strict";var QW=Vg(),X8e=os(),Z8e=new RegExp("^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function $8e(t){return!(t===null||!Z8e.test(t)||t[t.length-1]==="_")}function eHe(t){var e,r,o,a;return e=t.replace(/_/g,"").toLowerCase(),r=e[0]==="-"?-1:1,a=[],"+-".indexOf(e[0])>=0&&(e=e.slice(1)),e===".inf"?r===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:e===".nan"?NaN:e.indexOf(":")>=0?(e.split(":").forEach(function(n){a.unshift(parseFloat(n,10))}),e=0,o=1,a.forEach(function(n){e+=n*o,o*=60}),r*e):r*parseFloat(e,10)}var tHe=/^[-+]?[0-9]+e/;function rHe(t,e){var r;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(QW.isNegativeZero(t))return"-0.0";return r=t.toString(10),tHe.test(r)?r.replace("e",".e"):r}function nHe(t){return Object.prototype.toString.call(t)==="[object Number]"&&(t%1!==0||QW.isNegativeZero(t))}FW.exports=new X8e("tag:yaml.org,2002:float",{kind:"scalar",resolve:$8e,construct:eHe,predicate:nHe,represent:rHe,defaultStyle:"lowercase"})});var gR=_((zxt,RW)=>{"use strict";var iHe=Kg();RW.exports=new iHe({include:[jD()],implicit:[PW(),xW(),kW(),TW()]})});var dR=_((Xxt,NW)=>{"use strict";var sHe=Kg();NW.exports=new sHe({include:[gR()]})});var UW=_((Zxt,OW)=>{"use strict";var oHe=os(),LW=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),MW=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");function aHe(t){return t===null?!1:LW.exec(t)!==null||MW.exec(t)!==null}function lHe(t){var e,r,o,a,n,u,A,p=0,h=null,E,I,v;if(e=LW.exec(t),e===null&&(e=MW.exec(t)),e===null)throw new Error("Date resolve error");if(r=+e[1],o=+e[2]-1,a=+e[3],!e[4])return new Date(Date.UTC(r,o,a));if(n=+e[4],u=+e[5],A=+e[6],e[7]){for(p=e[7].slice(0,3);p.length<3;)p+="0";p=+p}return e[9]&&(E=+e[10],I=+(e[11]||0),h=(E*60+I)*6e4,e[9]==="-"&&(h=-h)),v=new Date(Date.UTC(r,o,a,n,u,A,p)),h&&v.setTime(v.getTime()-h),v}function cHe(t){return t.toISOString()}OW.exports=new oHe("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:aHe,construct:lHe,instanceOf:Date,represent:cHe})});var HW=_(($xt,_W)=>{"use strict";var uHe=os();function AHe(t){return t==="<<"||t===null}_W.exports=new uHe("tag:yaml.org,2002:merge",{kind:"scalar",resolve:AHe})});var GW=_((ebt,qW)=>{"use strict";var Jg;try{jW=Be,Jg=jW("buffer").Buffer}catch{}var jW,fHe=os(),mR=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= +\r`;function pHe(t){if(t===null)return!1;var e,r,o=0,a=t.length,n=mR;for(r=0;r<a;r++)if(e=n.indexOf(t.charAt(r)),!(e>64)){if(e<0)return!1;o+=6}return o%8===0}function hHe(t){var e,r,o=t.replace(/[\r\n=]/g,""),a=o.length,n=mR,u=0,A=[];for(e=0;e<a;e++)e%4===0&&e&&(A.push(u>>16&255),A.push(u>>8&255),A.push(u&255)),u=u<<6|n.indexOf(o.charAt(e));return r=a%4*6,r===0?(A.push(u>>16&255),A.push(u>>8&255),A.push(u&255)):r===18?(A.push(u>>10&255),A.push(u>>2&255)):r===12&&A.push(u>>4&255),Jg?Jg.from?Jg.from(A):new Jg(A):A}function gHe(t){var e="",r=0,o,a,n=t.length,u=mR;for(o=0;o<n;o++)o%3===0&&o&&(e+=u[r>>18&63],e+=u[r>>12&63],e+=u[r>>6&63],e+=u[r&63]),r=(r<<8)+t[o];return a=n%3,a===0?(e+=u[r>>18&63],e+=u[r>>12&63],e+=u[r>>6&63],e+=u[r&63]):a===2?(e+=u[r>>10&63],e+=u[r>>4&63],e+=u[r<<2&63],e+=u[64]):a===1&&(e+=u[r>>2&63],e+=u[r<<4&63],e+=u[64],e+=u[64]),e}function dHe(t){return Jg&&Jg.isBuffer(t)}qW.exports=new fHe("tag:yaml.org,2002:binary",{kind:"scalar",resolve:pHe,construct:hHe,predicate:dHe,represent:gHe})});var WW=_((rbt,YW)=>{"use strict";var mHe=os(),yHe=Object.prototype.hasOwnProperty,EHe=Object.prototype.toString;function CHe(t){if(t===null)return!0;var e=[],r,o,a,n,u,A=t;for(r=0,o=A.length;r<o;r+=1){if(a=A[r],u=!1,EHe.call(a)!=="[object Object]")return!1;for(n in a)if(yHe.call(a,n))if(!u)u=!0;else return!1;if(!u)return!1;if(e.indexOf(n)===-1)e.push(n);else return!1}return!0}function wHe(t){return t!==null?t:[]}YW.exports=new mHe("tag:yaml.org,2002:omap",{kind:"sequence",resolve:CHe,construct:wHe})});var KW=_((nbt,VW)=>{"use strict";var IHe=os(),BHe=Object.prototype.toString;function vHe(t){if(t===null)return!0;var e,r,o,a,n,u=t;for(n=new Array(u.length),e=0,r=u.length;e<r;e+=1){if(o=u[e],BHe.call(o)!=="[object Object]"||(a=Object.keys(o),a.length!==1))return!1;n[e]=[a[0],o[a[0]]]}return!0}function DHe(t){if(t===null)return[];var e,r,o,a,n,u=t;for(n=new Array(u.length),e=0,r=u.length;e<r;e+=1)o=u[e],a=Object.keys(o),n[e]=[a[0],o[a[0]]];return n}VW.exports=new IHe("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:vHe,construct:DHe})});var zW=_((ibt,JW)=>{"use strict";var PHe=os(),SHe=Object.prototype.hasOwnProperty;function xHe(t){if(t===null)return!0;var e,r=t;for(e in r)if(SHe.call(r,e)&&r[e]!==null)return!1;return!0}function bHe(t){return t!==null?t:{}}JW.exports=new PHe("tag:yaml.org,2002:set",{kind:"mapping",resolve:xHe,construct:bHe})});var fy=_((sbt,XW)=>{"use strict";var kHe=Kg();XW.exports=new kHe({include:[dR()],implicit:[UW(),HW()],explicit:[GW(),WW(),KW(),zW()]})});var $W=_((obt,ZW)=>{"use strict";var QHe=os();function FHe(){return!0}function THe(){}function RHe(){return""}function NHe(t){return typeof t>"u"}ZW.exports=new QHe("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:FHe,construct:THe,predicate:NHe,represent:RHe})});var tV=_((abt,eV)=>{"use strict";var LHe=os();function MHe(t){if(t===null||t.length===0)return!1;var e=t,r=/\/([gim]*)$/.exec(t),o="";return!(e[0]==="/"&&(r&&(o=r[1]),o.length>3||e[e.length-o.length-1]!=="/"))}function OHe(t){var e=t,r=/\/([gim]*)$/.exec(t),o="";return e[0]==="/"&&(r&&(o=r[1]),e=e.slice(1,e.length-o.length-1)),new RegExp(e,o)}function UHe(t){var e="/"+t.source+"/";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),e}function _He(t){return Object.prototype.toString.call(t)==="[object RegExp]"}eV.exports=new LHe("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:MHe,construct:OHe,predicate:_He,represent:UHe})});var iV=_((lbt,nV)=>{"use strict";var qD;try{rV=Be,qD=rV("esprima")}catch{typeof window<"u"&&(qD=window.esprima)}var rV,HHe=os();function jHe(t){if(t===null)return!1;try{var e="("+t+")",r=qD.parse(e,{range:!0});return!(r.type!=="Program"||r.body.length!==1||r.body[0].type!=="ExpressionStatement"||r.body[0].expression.type!=="ArrowFunctionExpression"&&r.body[0].expression.type!=="FunctionExpression")}catch{return!1}}function qHe(t){var e="("+t+")",r=qD.parse(e,{range:!0}),o=[],a;if(r.type!=="Program"||r.body.length!==1||r.body[0].type!=="ExpressionStatement"||r.body[0].expression.type!=="ArrowFunctionExpression"&&r.body[0].expression.type!=="FunctionExpression")throw new Error("Failed to resolve function");return r.body[0].expression.params.forEach(function(n){o.push(n.name)}),a=r.body[0].expression.body.range,r.body[0].expression.body.type==="BlockStatement"?new Function(o,e.slice(a[0]+1,a[1]-1)):new Function(o,"return "+e.slice(a[0],a[1]))}function GHe(t){return t.toString()}function YHe(t){return Object.prototype.toString.call(t)==="[object Function]"}nV.exports=new HHe("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:jHe,construct:qHe,predicate:YHe,represent:GHe})});var zw=_((ubt,oV)=>{"use strict";var sV=Kg();oV.exports=sV.DEFAULT=new sV({include:[fy()],explicit:[$W(),tV(),iV()]})});var DV=_((Abt,Xw)=>{"use strict";var mf=Vg(),pV=uy(),WHe=pW(),hV=fy(),VHe=zw(),Gp=Object.prototype.hasOwnProperty,GD=1,gV=2,dV=3,YD=4,yR=1,KHe=2,aV=3,JHe=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,zHe=/[\x85\u2028\u2029]/,XHe=/[,\[\]\{\}]/,mV=/^(?:!|!!|![a-z\-]+!)$/i,yV=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function lV(t){return Object.prototype.toString.call(t)}function Hu(t){return t===10||t===13}function Xg(t){return t===9||t===32}function Ia(t){return t===9||t===32||t===10||t===13}function py(t){return t===44||t===91||t===93||t===123||t===125}function ZHe(t){var e;return 48<=t&&t<=57?t-48:(e=t|32,97<=e&&e<=102?e-97+10:-1)}function $He(t){return t===120?2:t===117?4:t===85?8:0}function e6e(t){return 48<=t&&t<=57?t-48:-1}function cV(t){return t===48?"\0":t===97?"\x07":t===98?"\b":t===116||t===9?" ":t===110?` +`:t===118?"\v":t===102?"\f":t===114?"\r":t===101?"\x1B":t===32?" ":t===34?'"':t===47?"/":t===92?"\\":t===78?"\x85":t===95?"\xA0":t===76?"\u2028":t===80?"\u2029":""}function t6e(t){return t<=65535?String.fromCharCode(t):String.fromCharCode((t-65536>>10)+55296,(t-65536&1023)+56320)}var EV=new Array(256),CV=new Array(256);for(zg=0;zg<256;zg++)EV[zg]=cV(zg)?1:0,CV[zg]=cV(zg);var zg;function r6e(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||VHe,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function wV(t,e){return new pV(e,new WHe(t.filename,t.input,t.position,t.line,t.position-t.lineStart))}function Sr(t,e){throw wV(t,e)}function WD(t,e){t.onWarning&&t.onWarning.call(null,wV(t,e))}var uV={YAML:function(e,r,o){var a,n,u;e.version!==null&&Sr(e,"duplication of %YAML directive"),o.length!==1&&Sr(e,"YAML directive accepts exactly one argument"),a=/^([0-9]+)\.([0-9]+)$/.exec(o[0]),a===null&&Sr(e,"ill-formed argument of the YAML directive"),n=parseInt(a[1],10),u=parseInt(a[2],10),n!==1&&Sr(e,"unacceptable YAML version of the document"),e.version=o[0],e.checkLineBreaks=u<2,u!==1&&u!==2&&WD(e,"unsupported YAML version of the document")},TAG:function(e,r,o){var a,n;o.length!==2&&Sr(e,"TAG directive accepts exactly two arguments"),a=o[0],n=o[1],mV.test(a)||Sr(e,"ill-formed tag handle (first argument) of the TAG directive"),Gp.call(e.tagMap,a)&&Sr(e,'there is a previously declared suffix for "'+a+'" tag handle'),yV.test(n)||Sr(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[a]=n}};function qp(t,e,r,o){var a,n,u,A;if(e<r){if(A=t.input.slice(e,r),o)for(a=0,n=A.length;a<n;a+=1)u=A.charCodeAt(a),u===9||32<=u&&u<=1114111||Sr(t,"expected valid JSON character");else JHe.test(A)&&Sr(t,"the stream contains non-printable characters");t.result+=A}}function AV(t,e,r,o){var a,n,u,A;for(mf.isObject(r)||Sr(t,"cannot merge mappings; the provided source object is unacceptable"),a=Object.keys(r),u=0,A=a.length;u<A;u+=1)n=a[u],Gp.call(e,n)||(e[n]=r[n],o[n]=!0)}function hy(t,e,r,o,a,n,u,A){var p,h;if(Array.isArray(a))for(a=Array.prototype.slice.call(a),p=0,h=a.length;p<h;p+=1)Array.isArray(a[p])&&Sr(t,"nested arrays are not supported inside keys"),typeof a=="object"&&lV(a[p])==="[object Object]"&&(a[p]="[object Object]");if(typeof a=="object"&&lV(a)==="[object Object]"&&(a="[object Object]"),a=String(a),e===null&&(e={}),o==="tag:yaml.org,2002:merge")if(Array.isArray(n))for(p=0,h=n.length;p<h;p+=1)AV(t,e,n[p],r);else AV(t,e,n,r);else!t.json&&!Gp.call(r,a)&&Gp.call(e,a)&&(t.line=u||t.line,t.position=A||t.position,Sr(t,"duplicated mapping key")),e[a]=n,delete r[a];return e}function ER(t){var e;e=t.input.charCodeAt(t.position),e===10?t.position++:e===13?(t.position++,t.input.charCodeAt(t.position)===10&&t.position++):Sr(t,"a line break is expected"),t.line+=1,t.lineStart=t.position}function Wi(t,e,r){for(var o=0,a=t.input.charCodeAt(t.position);a!==0;){for(;Xg(a);)a=t.input.charCodeAt(++t.position);if(e&&a===35)do a=t.input.charCodeAt(++t.position);while(a!==10&&a!==13&&a!==0);if(Hu(a))for(ER(t),a=t.input.charCodeAt(t.position),o++,t.lineIndent=0;a===32;)t.lineIndent++,a=t.input.charCodeAt(++t.position);else break}return r!==-1&&o!==0&&t.lineIndent<r&&WD(t,"deficient indentation"),o}function VD(t){var e=t.position,r;return r=t.input.charCodeAt(e),!!((r===45||r===46)&&r===t.input.charCodeAt(e+1)&&r===t.input.charCodeAt(e+2)&&(e+=3,r=t.input.charCodeAt(e),r===0||Ia(r)))}function CR(t,e){e===1?t.result+=" ":e>1&&(t.result+=mf.repeat(` +`,e-1))}function n6e(t,e,r){var o,a,n,u,A,p,h,E,I=t.kind,v=t.result,b;if(b=t.input.charCodeAt(t.position),Ia(b)||py(b)||b===35||b===38||b===42||b===33||b===124||b===62||b===39||b===34||b===37||b===64||b===96||(b===63||b===45)&&(a=t.input.charCodeAt(t.position+1),Ia(a)||r&&py(a)))return!1;for(t.kind="scalar",t.result="",n=u=t.position,A=!1;b!==0;){if(b===58){if(a=t.input.charCodeAt(t.position+1),Ia(a)||r&&py(a))break}else if(b===35){if(o=t.input.charCodeAt(t.position-1),Ia(o))break}else{if(t.position===t.lineStart&&VD(t)||r&&py(b))break;if(Hu(b))if(p=t.line,h=t.lineStart,E=t.lineIndent,Wi(t,!1,-1),t.lineIndent>=e){A=!0,b=t.input.charCodeAt(t.position);continue}else{t.position=u,t.line=p,t.lineStart=h,t.lineIndent=E;break}}A&&(qp(t,n,u,!1),CR(t,t.line-p),n=u=t.position,A=!1),Xg(b)||(u=t.position+1),b=t.input.charCodeAt(++t.position)}return qp(t,n,u,!1),t.result?!0:(t.kind=I,t.result=v,!1)}function i6e(t,e){var r,o,a;if(r=t.input.charCodeAt(t.position),r!==39)return!1;for(t.kind="scalar",t.result="",t.position++,o=a=t.position;(r=t.input.charCodeAt(t.position))!==0;)if(r===39)if(qp(t,o,t.position,!0),r=t.input.charCodeAt(++t.position),r===39)o=t.position,t.position++,a=t.position;else return!0;else Hu(r)?(qp(t,o,a,!0),CR(t,Wi(t,!1,e)),o=a=t.position):t.position===t.lineStart&&VD(t)?Sr(t,"unexpected end of the document within a single quoted scalar"):(t.position++,a=t.position);Sr(t,"unexpected end of the stream within a single quoted scalar")}function s6e(t,e){var r,o,a,n,u,A;if(A=t.input.charCodeAt(t.position),A!==34)return!1;for(t.kind="scalar",t.result="",t.position++,r=o=t.position;(A=t.input.charCodeAt(t.position))!==0;){if(A===34)return qp(t,r,t.position,!0),t.position++,!0;if(A===92){if(qp(t,r,t.position,!0),A=t.input.charCodeAt(++t.position),Hu(A))Wi(t,!1,e);else if(A<256&&EV[A])t.result+=CV[A],t.position++;else if((u=$He(A))>0){for(a=u,n=0;a>0;a--)A=t.input.charCodeAt(++t.position),(u=ZHe(A))>=0?n=(n<<4)+u:Sr(t,"expected hexadecimal character");t.result+=t6e(n),t.position++}else Sr(t,"unknown escape sequence");r=o=t.position}else Hu(A)?(qp(t,r,o,!0),CR(t,Wi(t,!1,e)),r=o=t.position):t.position===t.lineStart&&VD(t)?Sr(t,"unexpected end of the document within a double quoted scalar"):(t.position++,o=t.position)}Sr(t,"unexpected end of the stream within a double quoted scalar")}function o6e(t,e){var r=!0,o,a=t.tag,n,u=t.anchor,A,p,h,E,I,v={},b,C,T,L;if(L=t.input.charCodeAt(t.position),L===91)p=93,I=!1,n=[];else if(L===123)p=125,I=!0,n={};else return!1;for(t.anchor!==null&&(t.anchorMap[t.anchor]=n),L=t.input.charCodeAt(++t.position);L!==0;){if(Wi(t,!0,e),L=t.input.charCodeAt(t.position),L===p)return t.position++,t.tag=a,t.anchor=u,t.kind=I?"mapping":"sequence",t.result=n,!0;r||Sr(t,"missed comma between flow collection entries"),C=b=T=null,h=E=!1,L===63&&(A=t.input.charCodeAt(t.position+1),Ia(A)&&(h=E=!0,t.position++,Wi(t,!0,e))),o=t.line,gy(t,e,GD,!1,!0),C=t.tag,b=t.result,Wi(t,!0,e),L=t.input.charCodeAt(t.position),(E||t.line===o)&&L===58&&(h=!0,L=t.input.charCodeAt(++t.position),Wi(t,!0,e),gy(t,e,GD,!1,!0),T=t.result),I?hy(t,n,v,C,b,T):h?n.push(hy(t,null,v,C,b,T)):n.push(b),Wi(t,!0,e),L=t.input.charCodeAt(t.position),L===44?(r=!0,L=t.input.charCodeAt(++t.position)):r=!1}Sr(t,"unexpected end of the stream within a flow collection")}function a6e(t,e){var r,o,a=yR,n=!1,u=!1,A=e,p=0,h=!1,E,I;if(I=t.input.charCodeAt(t.position),I===124)o=!1;else if(I===62)o=!0;else return!1;for(t.kind="scalar",t.result="";I!==0;)if(I=t.input.charCodeAt(++t.position),I===43||I===45)yR===a?a=I===43?aV:KHe:Sr(t,"repeat of a chomping mode identifier");else if((E=e6e(I))>=0)E===0?Sr(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):u?Sr(t,"repeat of an indentation width identifier"):(A=e+E-1,u=!0);else break;if(Xg(I)){do I=t.input.charCodeAt(++t.position);while(Xg(I));if(I===35)do I=t.input.charCodeAt(++t.position);while(!Hu(I)&&I!==0)}for(;I!==0;){for(ER(t),t.lineIndent=0,I=t.input.charCodeAt(t.position);(!u||t.lineIndent<A)&&I===32;)t.lineIndent++,I=t.input.charCodeAt(++t.position);if(!u&&t.lineIndent>A&&(A=t.lineIndent),Hu(I)){p++;continue}if(t.lineIndent<A){a===aV?t.result+=mf.repeat(` +`,n?1+p:p):a===yR&&n&&(t.result+=` +`);break}for(o?Xg(I)?(h=!0,t.result+=mf.repeat(` +`,n?1+p:p)):h?(h=!1,t.result+=mf.repeat(` +`,p+1)):p===0?n&&(t.result+=" "):t.result+=mf.repeat(` +`,p):t.result+=mf.repeat(` +`,n?1+p:p),n=!0,u=!0,p=0,r=t.position;!Hu(I)&&I!==0;)I=t.input.charCodeAt(++t.position);qp(t,r,t.position,!1)}return!0}function fV(t,e){var r,o=t.tag,a=t.anchor,n=[],u,A=!1,p;for(t.anchor!==null&&(t.anchorMap[t.anchor]=n),p=t.input.charCodeAt(t.position);p!==0&&!(p!==45||(u=t.input.charCodeAt(t.position+1),!Ia(u)));){if(A=!0,t.position++,Wi(t,!0,-1)&&t.lineIndent<=e){n.push(null),p=t.input.charCodeAt(t.position);continue}if(r=t.line,gy(t,e,dV,!1,!0),n.push(t.result),Wi(t,!0,-1),p=t.input.charCodeAt(t.position),(t.line===r||t.lineIndent>e)&&p!==0)Sr(t,"bad indentation of a sequence entry");else if(t.lineIndent<e)break}return A?(t.tag=o,t.anchor=a,t.kind="sequence",t.result=n,!0):!1}function l6e(t,e,r){var o,a,n,u,A=t.tag,p=t.anchor,h={},E={},I=null,v=null,b=null,C=!1,T=!1,L;for(t.anchor!==null&&(t.anchorMap[t.anchor]=h),L=t.input.charCodeAt(t.position);L!==0;){if(o=t.input.charCodeAt(t.position+1),n=t.line,u=t.position,(L===63||L===58)&&Ia(o))L===63?(C&&(hy(t,h,E,I,v,null),I=v=b=null),T=!0,C=!0,a=!0):C?(C=!1,a=!0):Sr(t,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),t.position+=1,L=o;else if(gy(t,r,gV,!1,!0))if(t.line===n){for(L=t.input.charCodeAt(t.position);Xg(L);)L=t.input.charCodeAt(++t.position);if(L===58)L=t.input.charCodeAt(++t.position),Ia(L)||Sr(t,"a whitespace character is expected after the key-value separator within a block mapping"),C&&(hy(t,h,E,I,v,null),I=v=b=null),T=!0,C=!1,a=!1,I=t.tag,v=t.result;else if(T)Sr(t,"can not read an implicit mapping pair; a colon is missed");else return t.tag=A,t.anchor=p,!0}else if(T)Sr(t,"can not read a block mapping entry; a multiline key may not be an implicit key");else return t.tag=A,t.anchor=p,!0;else break;if((t.line===n||t.lineIndent>e)&&(gy(t,e,YD,!0,a)&&(C?v=t.result:b=t.result),C||(hy(t,h,E,I,v,b,n,u),I=v=b=null),Wi(t,!0,-1),L=t.input.charCodeAt(t.position)),t.lineIndent>e&&L!==0)Sr(t,"bad indentation of a mapping entry");else if(t.lineIndent<e)break}return C&&hy(t,h,E,I,v,null),T&&(t.tag=A,t.anchor=p,t.kind="mapping",t.result=h),T}function c6e(t){var e,r=!1,o=!1,a,n,u;if(u=t.input.charCodeAt(t.position),u!==33)return!1;if(t.tag!==null&&Sr(t,"duplication of a tag property"),u=t.input.charCodeAt(++t.position),u===60?(r=!0,u=t.input.charCodeAt(++t.position)):u===33?(o=!0,a="!!",u=t.input.charCodeAt(++t.position)):a="!",e=t.position,r){do u=t.input.charCodeAt(++t.position);while(u!==0&&u!==62);t.position<t.length?(n=t.input.slice(e,t.position),u=t.input.charCodeAt(++t.position)):Sr(t,"unexpected end of the stream within a verbatim tag")}else{for(;u!==0&&!Ia(u);)u===33&&(o?Sr(t,"tag suffix cannot contain exclamation marks"):(a=t.input.slice(e-1,t.position+1),mV.test(a)||Sr(t,"named tag handle cannot contain such characters"),o=!0,e=t.position+1)),u=t.input.charCodeAt(++t.position);n=t.input.slice(e,t.position),XHe.test(n)&&Sr(t,"tag suffix cannot contain flow indicator characters")}return n&&!yV.test(n)&&Sr(t,"tag name cannot contain such characters: "+n),r?t.tag=n:Gp.call(t.tagMap,a)?t.tag=t.tagMap[a]+n:a==="!"?t.tag="!"+n:a==="!!"?t.tag="tag:yaml.org,2002:"+n:Sr(t,'undeclared tag handle "'+a+'"'),!0}function u6e(t){var e,r;if(r=t.input.charCodeAt(t.position),r!==38)return!1;for(t.anchor!==null&&Sr(t,"duplication of an anchor property"),r=t.input.charCodeAt(++t.position),e=t.position;r!==0&&!Ia(r)&&!py(r);)r=t.input.charCodeAt(++t.position);return t.position===e&&Sr(t,"name of an anchor node must contain at least one character"),t.anchor=t.input.slice(e,t.position),!0}function A6e(t){var e,r,o;if(o=t.input.charCodeAt(t.position),o!==42)return!1;for(o=t.input.charCodeAt(++t.position),e=t.position;o!==0&&!Ia(o)&&!py(o);)o=t.input.charCodeAt(++t.position);return t.position===e&&Sr(t,"name of an alias node must contain at least one character"),r=t.input.slice(e,t.position),Gp.call(t.anchorMap,r)||Sr(t,'unidentified alias "'+r+'"'),t.result=t.anchorMap[r],Wi(t,!0,-1),!0}function gy(t,e,r,o,a){var n,u,A,p=1,h=!1,E=!1,I,v,b,C,T;if(t.listener!==null&&t.listener("open",t),t.tag=null,t.anchor=null,t.kind=null,t.result=null,n=u=A=YD===r||dV===r,o&&Wi(t,!0,-1)&&(h=!0,t.lineIndent>e?p=1:t.lineIndent===e?p=0:t.lineIndent<e&&(p=-1)),p===1)for(;c6e(t)||u6e(t);)Wi(t,!0,-1)?(h=!0,A=n,t.lineIndent>e?p=1:t.lineIndent===e?p=0:t.lineIndent<e&&(p=-1)):A=!1;if(A&&(A=h||a),(p===1||YD===r)&&(GD===r||gV===r?C=e:C=e+1,T=t.position-t.lineStart,p===1?A&&(fV(t,T)||l6e(t,T,C))||o6e(t,C)?E=!0:(u&&a6e(t,C)||i6e(t,C)||s6e(t,C)?E=!0:A6e(t)?(E=!0,(t.tag!==null||t.anchor!==null)&&Sr(t,"alias node should not have any properties")):n6e(t,C,GD===r)&&(E=!0,t.tag===null&&(t.tag="?")),t.anchor!==null&&(t.anchorMap[t.anchor]=t.result)):p===0&&(E=A&&fV(t,T))),t.tag!==null&&t.tag!=="!")if(t.tag==="?"){for(t.result!==null&&t.kind!=="scalar"&&Sr(t,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+t.kind+'"'),I=0,v=t.implicitTypes.length;I<v;I+=1)if(b=t.implicitTypes[I],b.resolve(t.result)){t.result=b.construct(t.result),t.tag=b.tag,t.anchor!==null&&(t.anchorMap[t.anchor]=t.result);break}}else Gp.call(t.typeMap[t.kind||"fallback"],t.tag)?(b=t.typeMap[t.kind||"fallback"][t.tag],t.result!==null&&b.kind!==t.kind&&Sr(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+b.kind+'", not "'+t.kind+'"'),b.resolve(t.result)?(t.result=b.construct(t.result),t.anchor!==null&&(t.anchorMap[t.anchor]=t.result)):Sr(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")):Sr(t,"unknown tag !<"+t.tag+">");return t.listener!==null&&t.listener("close",t),t.tag!==null||t.anchor!==null||E}function f6e(t){var e=t.position,r,o,a,n=!1,u;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap={},t.anchorMap={};(u=t.input.charCodeAt(t.position))!==0&&(Wi(t,!0,-1),u=t.input.charCodeAt(t.position),!(t.lineIndent>0||u!==37));){for(n=!0,u=t.input.charCodeAt(++t.position),r=t.position;u!==0&&!Ia(u);)u=t.input.charCodeAt(++t.position);for(o=t.input.slice(r,t.position),a=[],o.length<1&&Sr(t,"directive name must not be less than one character in length");u!==0;){for(;Xg(u);)u=t.input.charCodeAt(++t.position);if(u===35){do u=t.input.charCodeAt(++t.position);while(u!==0&&!Hu(u));break}if(Hu(u))break;for(r=t.position;u!==0&&!Ia(u);)u=t.input.charCodeAt(++t.position);a.push(t.input.slice(r,t.position))}u!==0&&ER(t),Gp.call(uV,o)?uV[o](t,o,a):WD(t,'unknown document directive "'+o+'"')}if(Wi(t,!0,-1),t.lineIndent===0&&t.input.charCodeAt(t.position)===45&&t.input.charCodeAt(t.position+1)===45&&t.input.charCodeAt(t.position+2)===45?(t.position+=3,Wi(t,!0,-1)):n&&Sr(t,"directives end mark is expected"),gy(t,t.lineIndent-1,YD,!1,!0),Wi(t,!0,-1),t.checkLineBreaks&&zHe.test(t.input.slice(e,t.position))&&WD(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&VD(t)){t.input.charCodeAt(t.position)===46&&(t.position+=3,Wi(t,!0,-1));return}if(t.position<t.length-1)Sr(t,"end of the stream or a document separator is expected");else return}function IV(t,e){t=String(t),e=e||{},t.length!==0&&(t.charCodeAt(t.length-1)!==10&&t.charCodeAt(t.length-1)!==13&&(t+=` +`),t.charCodeAt(0)===65279&&(t=t.slice(1)));var r=new r6e(t,e),o=t.indexOf("\0");for(o!==-1&&(r.position=o,Sr(r,"null byte is not allowed in input")),r.input+="\0";r.input.charCodeAt(r.position)===32;)r.lineIndent+=1,r.position+=1;for(;r.position<r.length-1;)f6e(r);return r.documents}function BV(t,e,r){e!==null&&typeof e=="object"&&typeof r>"u"&&(r=e,e=null);var o=IV(t,r);if(typeof e!="function")return o;for(var a=0,n=o.length;a<n;a+=1)e(o[a])}function vV(t,e){var r=IV(t,e);if(r.length!==0){if(r.length===1)return r[0];throw new pV("expected a single document in the stream, but found more")}}function p6e(t,e,r){return typeof e=="object"&&e!==null&&typeof r>"u"&&(r=e,e=null),BV(t,e,mf.extend({schema:hV},r))}function h6e(t,e){return vV(t,mf.extend({schema:hV},e))}Xw.exports.loadAll=BV;Xw.exports.load=vV;Xw.exports.safeLoadAll=p6e;Xw.exports.safeLoad=h6e});var KV=_((fbt,vR)=>{"use strict";var $w=Vg(),eI=uy(),g6e=zw(),d6e=fy(),TV=Object.prototype.toString,RV=Object.prototype.hasOwnProperty,m6e=9,Zw=10,y6e=13,E6e=32,C6e=33,w6e=34,NV=35,I6e=37,B6e=38,v6e=39,D6e=42,LV=44,P6e=45,MV=58,S6e=61,x6e=62,b6e=63,k6e=64,OV=91,UV=93,Q6e=96,_V=123,F6e=124,HV=125,vo={};vo[0]="\\0";vo[7]="\\a";vo[8]="\\b";vo[9]="\\t";vo[10]="\\n";vo[11]="\\v";vo[12]="\\f";vo[13]="\\r";vo[27]="\\e";vo[34]='\\"';vo[92]="\\\\";vo[133]="\\N";vo[160]="\\_";vo[8232]="\\L";vo[8233]="\\P";var T6e=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];function R6e(t,e){var r,o,a,n,u,A,p;if(e===null)return{};for(r={},o=Object.keys(e),a=0,n=o.length;a<n;a+=1)u=o[a],A=String(e[u]),u.slice(0,2)==="!!"&&(u="tag:yaml.org,2002:"+u.slice(2)),p=t.compiledTypeMap.fallback[u],p&&RV.call(p.styleAliases,A)&&(A=p.styleAliases[A]),r[u]=A;return r}function PV(t){var e,r,o;if(e=t.toString(16).toUpperCase(),t<=255)r="x",o=2;else if(t<=65535)r="u",o=4;else if(t<=4294967295)r="U",o=8;else throw new eI("code point within a string may not be greater than 0xFFFFFFFF");return"\\"+r+$w.repeat("0",o-e.length)+e}function N6e(t){this.schema=t.schema||g6e,this.indent=Math.max(1,t.indent||2),this.noArrayIndent=t.noArrayIndent||!1,this.skipInvalid=t.skipInvalid||!1,this.flowLevel=$w.isNothing(t.flowLevel)?-1:t.flowLevel,this.styleMap=R6e(this.schema,t.styles||null),this.sortKeys=t.sortKeys||!1,this.lineWidth=t.lineWidth||80,this.noRefs=t.noRefs||!1,this.noCompatMode=t.noCompatMode||!1,this.condenseFlow=t.condenseFlow||!1,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function SV(t,e){for(var r=$w.repeat(" ",e),o=0,a=-1,n="",u,A=t.length;o<A;)a=t.indexOf(` +`,o),a===-1?(u=t.slice(o),o=A):(u=t.slice(o,a+1),o=a+1),u.length&&u!==` +`&&(n+=r),n+=u;return n}function wR(t,e){return` +`+$w.repeat(" ",t.indent*e)}function L6e(t,e){var r,o,a;for(r=0,o=t.implicitTypes.length;r<o;r+=1)if(a=t.implicitTypes[r],a.resolve(e))return!0;return!1}function BR(t){return t===E6e||t===m6e}function dy(t){return 32<=t&&t<=126||161<=t&&t<=55295&&t!==8232&&t!==8233||57344<=t&&t<=65533&&t!==65279||65536<=t&&t<=1114111}function M6e(t){return dy(t)&&!BR(t)&&t!==65279&&t!==y6e&&t!==Zw}function xV(t,e){return dy(t)&&t!==65279&&t!==LV&&t!==OV&&t!==UV&&t!==_V&&t!==HV&&t!==MV&&(t!==NV||e&&M6e(e))}function O6e(t){return dy(t)&&t!==65279&&!BR(t)&&t!==P6e&&t!==b6e&&t!==MV&&t!==LV&&t!==OV&&t!==UV&&t!==_V&&t!==HV&&t!==NV&&t!==B6e&&t!==D6e&&t!==C6e&&t!==F6e&&t!==S6e&&t!==x6e&&t!==v6e&&t!==w6e&&t!==I6e&&t!==k6e&&t!==Q6e}function jV(t){var e=/^\n* /;return e.test(t)}var qV=1,GV=2,YV=3,WV=4,KD=5;function U6e(t,e,r,o,a){var n,u,A,p=!1,h=!1,E=o!==-1,I=-1,v=O6e(t.charCodeAt(0))&&!BR(t.charCodeAt(t.length-1));if(e)for(n=0;n<t.length;n++){if(u=t.charCodeAt(n),!dy(u))return KD;A=n>0?t.charCodeAt(n-1):null,v=v&&xV(u,A)}else{for(n=0;n<t.length;n++){if(u=t.charCodeAt(n),u===Zw)p=!0,E&&(h=h||n-I-1>o&&t[I+1]!==" ",I=n);else if(!dy(u))return KD;A=n>0?t.charCodeAt(n-1):null,v=v&&xV(u,A)}h=h||E&&n-I-1>o&&t[I+1]!==" "}return!p&&!h?v&&!a(t)?qV:GV:r>9&&jV(t)?KD:h?WV:YV}function _6e(t,e,r,o){t.dump=function(){if(e.length===0)return"''";if(!t.noCompatMode&&T6e.indexOf(e)!==-1)return"'"+e+"'";var a=t.indent*Math.max(1,r),n=t.lineWidth===-1?-1:Math.max(Math.min(t.lineWidth,40),t.lineWidth-a),u=o||t.flowLevel>-1&&r>=t.flowLevel;function A(p){return L6e(t,p)}switch(U6e(e,u,t.indent,n,A)){case qV:return e;case GV:return"'"+e.replace(/'/g,"''")+"'";case YV:return"|"+bV(e,t.indent)+kV(SV(e,a));case WV:return">"+bV(e,t.indent)+kV(SV(H6e(e,n),a));case KD:return'"'+j6e(e,n)+'"';default:throw new eI("impossible error: invalid scalar style")}}()}function bV(t,e){var r=jV(t)?String(e):"",o=t[t.length-1]===` +`,a=o&&(t[t.length-2]===` +`||t===` +`),n=a?"+":o?"":"-";return r+n+` +`}function kV(t){return t[t.length-1]===` +`?t.slice(0,-1):t}function H6e(t,e){for(var r=/(\n+)([^\n]*)/g,o=function(){var h=t.indexOf(` +`);return h=h!==-1?h:t.length,r.lastIndex=h,QV(t.slice(0,h),e)}(),a=t[0]===` +`||t[0]===" ",n,u;u=r.exec(t);){var A=u[1],p=u[2];n=p[0]===" ",o+=A+(!a&&!n&&p!==""?` +`:"")+QV(p,e),a=n}return o}function QV(t,e){if(t===""||t[0]===" ")return t;for(var r=/ [^ ]/g,o,a=0,n,u=0,A=0,p="";o=r.exec(t);)A=o.index,A-a>e&&(n=u>a?u:A,p+=` +`+t.slice(a,n),a=n+1),u=A;return p+=` +`,t.length-a>e&&u>a?p+=t.slice(a,u)+` +`+t.slice(u+1):p+=t.slice(a),p.slice(1)}function j6e(t){for(var e="",r,o,a,n=0;n<t.length;n++){if(r=t.charCodeAt(n),r>=55296&&r<=56319&&(o=t.charCodeAt(n+1),o>=56320&&o<=57343)){e+=PV((r-55296)*1024+o-56320+65536),n++;continue}a=vo[r],e+=!a&&dy(r)?t[n]:a||PV(r)}return e}function q6e(t,e,r){var o="",a=t.tag,n,u;for(n=0,u=r.length;n<u;n+=1)Zg(t,e,r[n],!1,!1)&&(n!==0&&(o+=","+(t.condenseFlow?"":" ")),o+=t.dump);t.tag=a,t.dump="["+o+"]"}function G6e(t,e,r,o){var a="",n=t.tag,u,A;for(u=0,A=r.length;u<A;u+=1)Zg(t,e+1,r[u],!0,!0)&&((!o||u!==0)&&(a+=wR(t,e)),t.dump&&Zw===t.dump.charCodeAt(0)?a+="-":a+="- ",a+=t.dump);t.tag=n,t.dump=a||"[]"}function Y6e(t,e,r){var o="",a=t.tag,n=Object.keys(r),u,A,p,h,E;for(u=0,A=n.length;u<A;u+=1)E="",u!==0&&(E+=", "),t.condenseFlow&&(E+='"'),p=n[u],h=r[p],Zg(t,e,p,!1,!1)&&(t.dump.length>1024&&(E+="? "),E+=t.dump+(t.condenseFlow?'"':"")+":"+(t.condenseFlow?"":" "),Zg(t,e,h,!1,!1)&&(E+=t.dump,o+=E));t.tag=a,t.dump="{"+o+"}"}function W6e(t,e,r,o){var a="",n=t.tag,u=Object.keys(r),A,p,h,E,I,v;if(t.sortKeys===!0)u.sort();else if(typeof t.sortKeys=="function")u.sort(t.sortKeys);else if(t.sortKeys)throw new eI("sortKeys must be a boolean or a function");for(A=0,p=u.length;A<p;A+=1)v="",(!o||A!==0)&&(v+=wR(t,e)),h=u[A],E=r[h],Zg(t,e+1,h,!0,!0,!0)&&(I=t.tag!==null&&t.tag!=="?"||t.dump&&t.dump.length>1024,I&&(t.dump&&Zw===t.dump.charCodeAt(0)?v+="?":v+="? "),v+=t.dump,I&&(v+=wR(t,e)),Zg(t,e+1,E,!0,I)&&(t.dump&&Zw===t.dump.charCodeAt(0)?v+=":":v+=": ",v+=t.dump,a+=v));t.tag=n,t.dump=a||"{}"}function FV(t,e,r){var o,a,n,u,A,p;for(a=r?t.explicitTypes:t.implicitTypes,n=0,u=a.length;n<u;n+=1)if(A=a[n],(A.instanceOf||A.predicate)&&(!A.instanceOf||typeof e=="object"&&e instanceof A.instanceOf)&&(!A.predicate||A.predicate(e))){if(t.tag=r?A.tag:"?",A.represent){if(p=t.styleMap[A.tag]||A.defaultStyle,TV.call(A.represent)==="[object Function]")o=A.represent(e,p);else if(RV.call(A.represent,p))o=A.represent[p](e,p);else throw new eI("!<"+A.tag+'> tag resolver accepts not "'+p+'" style');t.dump=o}return!0}return!1}function Zg(t,e,r,o,a,n){t.tag=null,t.dump=r,FV(t,r,!1)||FV(t,r,!0);var u=TV.call(t.dump);o&&(o=t.flowLevel<0||t.flowLevel>e);var A=u==="[object Object]"||u==="[object Array]",p,h;if(A&&(p=t.duplicates.indexOf(r),h=p!==-1),(t.tag!==null&&t.tag!=="?"||h||t.indent!==2&&e>0)&&(a=!1),h&&t.usedDuplicates[p])t.dump="*ref_"+p;else{if(A&&h&&!t.usedDuplicates[p]&&(t.usedDuplicates[p]=!0),u==="[object Object]")o&&Object.keys(t.dump).length!==0?(W6e(t,e,t.dump,a),h&&(t.dump="&ref_"+p+t.dump)):(Y6e(t,e,t.dump),h&&(t.dump="&ref_"+p+" "+t.dump));else if(u==="[object Array]"){var E=t.noArrayIndent&&e>0?e-1:e;o&&t.dump.length!==0?(G6e(t,E,t.dump,a),h&&(t.dump="&ref_"+p+t.dump)):(q6e(t,E,t.dump),h&&(t.dump="&ref_"+p+" "+t.dump))}else if(u==="[object String]")t.tag!=="?"&&_6e(t,t.dump,e,n);else{if(t.skipInvalid)return!1;throw new eI("unacceptable kind of an object to dump "+u)}t.tag!==null&&t.tag!=="?"&&(t.dump="!<"+t.tag+"> "+t.dump)}return!0}function V6e(t,e){var r=[],o=[],a,n;for(IR(t,r,o),a=0,n=o.length;a<n;a+=1)e.duplicates.push(r[o[a]]);e.usedDuplicates=new Array(n)}function IR(t,e,r){var o,a,n;if(t!==null&&typeof t=="object")if(a=e.indexOf(t),a!==-1)r.indexOf(a)===-1&&r.push(a);else if(e.push(t),Array.isArray(t))for(a=0,n=t.length;a<n;a+=1)IR(t[a],e,r);else for(o=Object.keys(t),a=0,n=o.length;a<n;a+=1)IR(t[o[a]],e,r)}function VV(t,e){e=e||{};var r=new N6e(e);return r.noRefs||V6e(t,r),Zg(r,0,t,!0,!0)?r.dump+` +`:""}function K6e(t,e){return VV(t,$w.extend({schema:d6e},e))}vR.exports.dump=VV;vR.exports.safeDump=K6e});var zV=_((pbt,ki)=>{"use strict";var JD=DV(),JV=KV();function zD(t){return function(){throw new Error("Function "+t+" is deprecated and cannot be used.")}}ki.exports.Type=os();ki.exports.Schema=Kg();ki.exports.FAILSAFE_SCHEMA=jD();ki.exports.JSON_SCHEMA=gR();ki.exports.CORE_SCHEMA=dR();ki.exports.DEFAULT_SAFE_SCHEMA=fy();ki.exports.DEFAULT_FULL_SCHEMA=zw();ki.exports.load=JD.load;ki.exports.loadAll=JD.loadAll;ki.exports.safeLoad=JD.safeLoad;ki.exports.safeLoadAll=JD.safeLoadAll;ki.exports.dump=JV.dump;ki.exports.safeDump=JV.safeDump;ki.exports.YAMLException=uy();ki.exports.MINIMAL_SCHEMA=jD();ki.exports.SAFE_SCHEMA=fy();ki.exports.DEFAULT_SCHEMA=zw();ki.exports.scan=zD("scan");ki.exports.parse=zD("parse");ki.exports.compose=zD("compose");ki.exports.addConstructor=zD("addConstructor")});var ZV=_((hbt,XV)=>{"use strict";var J6e=zV();XV.exports=J6e});var eK=_((gbt,$V)=>{"use strict";function z6e(t,e){function r(){this.constructor=t}r.prototype=e.prototype,t.prototype=new r}function $g(t,e,r,o){this.message=t,this.expected=e,this.found=r,this.location=o,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,$g)}z6e($g,Error);$g.buildMessage=function(t,e){var r={literal:function(h){return'"'+a(h.text)+'"'},class:function(h){var E="",I;for(I=0;I<h.parts.length;I++)E+=h.parts[I]instanceof Array?n(h.parts[I][0])+"-"+n(h.parts[I][1]):n(h.parts[I]);return"["+(h.inverted?"^":"")+E+"]"},any:function(h){return"any character"},end:function(h){return"end of input"},other:function(h){return h.description}};function o(h){return h.charCodeAt(0).toString(16).toUpperCase()}function a(h){return h.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(E){return"\\x0"+o(E)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(E){return"\\x"+o(E)})}function n(h){return h.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(E){return"\\x0"+o(E)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(E){return"\\x"+o(E)})}function u(h){return r[h.type](h)}function A(h){var E=new Array(h.length),I,v;for(I=0;I<h.length;I++)E[I]=u(h[I]);if(E.sort(),E.length>0){for(I=1,v=1;I<E.length;I++)E[I-1]!==E[I]&&(E[v]=E[I],v++);E.length=v}switch(E.length){case 1:return E[0];case 2:return E[0]+" or "+E[1];default:return E.slice(0,-1).join(", ")+", or "+E[E.length-1]}}function p(h){return h?'"'+a(h)+'"':"end of input"}return"Expected "+A(t)+" but "+p(e)+" found."};function X6e(t,e){e=e!==void 0?e:{};var r={},o={Start:pu},a=pu,n=function($){return[].concat(...$)},u="-",A=Qn("-",!1),p=function($){return $},h=function($){return Object.assign({},...$)},E="#",I=Qn("#",!1),v=hc(),b=function(){return{}},C=":",T=Qn(":",!1),L=function($,me){return{[$]:me}},U=",",J=Qn(",",!1),te=function($,me){return me},le=function($,me,Le){return Object.assign({},...[$].concat(me).map(ft=>({[ft]:Le})))},pe=function($){return $},Ae=function($){return $},ye=sa("correct indentation"),ae=" ",we=Qn(" ",!1),Pe=function($){return $.length===nr*It},g=function($){return $.length===(nr+1)*It},Ee=function(){return nr++,!0},De=function(){return nr--,!0},ce=function(){return DA()},ne=sa("pseudostring"),ee=/^[^\r\n\t ?:,\][{}#&*!|>'"%@`\-]/,Ie=hi(["\r",` +`," "," ","?",":",",","]","[","{","}","#","&","*","!","|",">","'",'"',"%","@","`","-"],!0,!1),ke=/^[^\r\n\t ,\][{}:#"']/,ht=hi(["\r",` +`," "," ",",","]","[","{","}",":","#",'"',"'"],!0,!1),H=function(){return DA().replace(/^ *| *$/g,"")},lt="--",Re=Qn("--",!1),Qe=/^[a-zA-Z\/0-9]/,be=hi([["a","z"],["A","Z"],"/",["0","9"]],!1,!1),_e=/^[^\r\n\t :,]/,Te=hi(["\r",` +`," "," ",":",","],!0,!1),Je="null",He=Qn("null",!1),x=function(){return null},w="true",S=Qn("true",!1),y=function(){return!0},F="false",z=Qn("false",!1),X=function(){return!1},Z=sa("string"),ie='"',Se=Qn('"',!1),Ne=function(){return""},ot=function($){return $},dt=function($){return $.join("")},jt=/^[^"\\\0-\x1F\x7F]/,$t=hi(['"',"\\",["\0",""],"\x7F"],!0,!1),xt='\\"',an=Qn('\\"',!1),Qr=function(){return'"'},mr="\\\\",xr=Qn("\\\\",!1),Wr=function(){return"\\"},Vn="\\/",Ns=Qn("\\/",!1),Ri=function(){return"/"},ps="\\b",io=Qn("\\b",!1),Si=function(){return"\b"},Ls="\\f",so=Qn("\\f",!1),cc=function(){return"\f"},cu="\\n",ap=Qn("\\n",!1),lp=function(){return` +`},Ms="\\r",Dn=Qn("\\r",!1),oo=function(){return"\r"},Os="\\t",ml=Qn("\\t",!1),yl=function(){return" "},ao="\\u",Kn=Qn("\\u",!1),Mn=function($,me,Le,ft){return String.fromCharCode(parseInt(`0x${$}${me}${Le}${ft}`))},Ni=/^[0-9a-fA-F]/,On=hi([["0","9"],["a","f"],["A","F"]],!1,!1),_i=sa("blank space"),tr=/^[ \t]/,Me=hi([" "," "],!1,!1),ii=sa("white space"),Oa=/^[ \t\n\r]/,hr=hi([" "," ",` +`,"\r"],!1,!1),uc=`\r +`,uu=Qn(`\r +`,!1),Ac=` +`,El=Qn(` +`,!1),vA="\r",Au=Qn("\r",!1),Ce=0,Tt=0,fc=[{line:1,column:1}],Hi=0,fu=[],Yt=0,Cl;if("startRule"in e){if(!(e.startRule in o))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');a=o[e.startRule]}function DA(){return t.substring(Tt,Ce)}function cp(){return _o(Tt,Ce)}function pc($,me){throw me=me!==void 0?me:_o(Tt,Ce),gc([sa($)],t.substring(Tt,Ce),me)}function PA($,me){throw me=me!==void 0?me:_o(Tt,Ce),lo($,me)}function Qn($,me){return{type:"literal",text:$,ignoreCase:me}}function hi($,me,Le){return{type:"class",parts:$,inverted:me,ignoreCase:Le}}function hc(){return{type:"any"}}function SA(){return{type:"end"}}function sa($){return{type:"other",description:$}}function Li($){var me=fc[$],Le;if(me)return me;for(Le=$-1;!fc[Le];)Le--;for(me=fc[Le],me={line:me.line,column:me.column};Le<$;)t.charCodeAt(Le)===10?(me.line++,me.column=1):me.column++,Le++;return fc[$]=me,me}function _o($,me){var Le=Li($),ft=Li(me);return{start:{offset:$,line:Le.line,column:Le.column},end:{offset:me,line:ft.line,column:ft.column}}}function Ze($){Ce<Hi||(Ce>Hi&&(Hi=Ce,fu=[]),fu.push($))}function lo($,me){return new $g($,null,null,me)}function gc($,me,Le){return new $g($g.buildMessage($,me),$,me,Le)}function pu(){var $;return $=xA(),$}function ji(){var $,me,Le;for($=Ce,me=[],Le=hu();Le!==r;)me.push(Le),Le=hu();return me!==r&&(Tt=$,me=n(me)),$=me,$}function hu(){var $,me,Le,ft,pt;return $=Ce,me=hs(),me!==r?(t.charCodeAt(Ce)===45?(Le=u,Ce++):(Le=r,Yt===0&&Ze(A)),Le!==r?(ft=Pn(),ft!==r?(pt=dc(),pt!==r?(Tt=$,me=p(pt),$=me):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r),$}function xA(){var $,me,Le;for($=Ce,me=[],Le=Ua();Le!==r;)me.push(Le),Le=Ua();return me!==r&&(Tt=$,me=h(me)),$=me,$}function Ua(){var $,me,Le,ft,pt,Rt,er,Zr,qi;if($=Ce,me=Pn(),me===r&&(me=null),me!==r){if(Le=Ce,t.charCodeAt(Ce)===35?(ft=E,Ce++):(ft=r,Yt===0&&Ze(I)),ft!==r){if(pt=[],Rt=Ce,er=Ce,Yt++,Zr=tt(),Yt--,Zr===r?er=void 0:(Ce=er,er=r),er!==r?(t.length>Ce?(Zr=t.charAt(Ce),Ce++):(Zr=r,Yt===0&&Ze(v)),Zr!==r?(er=[er,Zr],Rt=er):(Ce=Rt,Rt=r)):(Ce=Rt,Rt=r),Rt!==r)for(;Rt!==r;)pt.push(Rt),Rt=Ce,er=Ce,Yt++,Zr=tt(),Yt--,Zr===r?er=void 0:(Ce=er,er=r),er!==r?(t.length>Ce?(Zr=t.charAt(Ce),Ce++):(Zr=r,Yt===0&&Ze(v)),Zr!==r?(er=[er,Zr],Rt=er):(Ce=Rt,Rt=r)):(Ce=Rt,Rt=r);else pt=r;pt!==r?(ft=[ft,pt],Le=ft):(Ce=Le,Le=r)}else Ce=Le,Le=r;if(Le===r&&(Le=null),Le!==r){if(ft=[],pt=We(),pt!==r)for(;pt!==r;)ft.push(pt),pt=We();else ft=r;ft!==r?(Tt=$,me=b(),$=me):(Ce=$,$=r)}else Ce=$,$=r}else Ce=$,$=r;if($===r&&($=Ce,me=hs(),me!==r?(Le=oa(),Le!==r?(ft=Pn(),ft===r&&(ft=null),ft!==r?(t.charCodeAt(Ce)===58?(pt=C,Ce++):(pt=r,Yt===0&&Ze(T)),pt!==r?(Rt=Pn(),Rt===r&&(Rt=null),Rt!==r?(er=dc(),er!==r?(Tt=$,me=L(Le,er),$=me):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r),$===r&&($=Ce,me=hs(),me!==r?(Le=co(),Le!==r?(ft=Pn(),ft===r&&(ft=null),ft!==r?(t.charCodeAt(Ce)===58?(pt=C,Ce++):(pt=r,Yt===0&&Ze(T)),pt!==r?(Rt=Pn(),Rt===r&&(Rt=null),Rt!==r?(er=dc(),er!==r?(Tt=$,me=L(Le,er),$=me):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r),$===r))){if($=Ce,me=hs(),me!==r)if(Le=co(),Le!==r)if(ft=Pn(),ft!==r)if(pt=aa(),pt!==r){if(Rt=[],er=We(),er!==r)for(;er!==r;)Rt.push(er),er=We();else Rt=r;Rt!==r?(Tt=$,me=L(Le,pt),$=me):(Ce=$,$=r)}else Ce=$,$=r;else Ce=$,$=r;else Ce=$,$=r;else Ce=$,$=r;if($===r)if($=Ce,me=hs(),me!==r)if(Le=co(),Le!==r){if(ft=[],pt=Ce,Rt=Pn(),Rt===r&&(Rt=null),Rt!==r?(t.charCodeAt(Ce)===44?(er=U,Ce++):(er=r,Yt===0&&Ze(J)),er!==r?(Zr=Pn(),Zr===r&&(Zr=null),Zr!==r?(qi=co(),qi!==r?(Tt=pt,Rt=te(Le,qi),pt=Rt):(Ce=pt,pt=r)):(Ce=pt,pt=r)):(Ce=pt,pt=r)):(Ce=pt,pt=r),pt!==r)for(;pt!==r;)ft.push(pt),pt=Ce,Rt=Pn(),Rt===r&&(Rt=null),Rt!==r?(t.charCodeAt(Ce)===44?(er=U,Ce++):(er=r,Yt===0&&Ze(J)),er!==r?(Zr=Pn(),Zr===r&&(Zr=null),Zr!==r?(qi=co(),qi!==r?(Tt=pt,Rt=te(Le,qi),pt=Rt):(Ce=pt,pt=r)):(Ce=pt,pt=r)):(Ce=pt,pt=r)):(Ce=pt,pt=r);else ft=r;ft!==r?(pt=Pn(),pt===r&&(pt=null),pt!==r?(t.charCodeAt(Ce)===58?(Rt=C,Ce++):(Rt=r,Yt===0&&Ze(T)),Rt!==r?(er=Pn(),er===r&&(er=null),er!==r?(Zr=dc(),Zr!==r?(Tt=$,me=le(Le,ft,Zr),$=me):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)}else Ce=$,$=r;else Ce=$,$=r}return $}function dc(){var $,me,Le,ft,pt,Rt,er;if($=Ce,me=Ce,Yt++,Le=Ce,ft=tt(),ft!==r?(pt=_t(),pt!==r?(t.charCodeAt(Ce)===45?(Rt=u,Ce++):(Rt=r,Yt===0&&Ze(A)),Rt!==r?(er=Pn(),er!==r?(ft=[ft,pt,Rt,er],Le=ft):(Ce=Le,Le=r)):(Ce=Le,Le=r)):(Ce=Le,Le=r)):(Ce=Le,Le=r),Yt--,Le!==r?(Ce=me,me=void 0):me=r,me!==r?(Le=We(),Le!==r?(ft=Fn(),ft!==r?(pt=ji(),pt!==r?(Rt=Ci(),Rt!==r?(Tt=$,me=pe(pt),$=me):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r),$===r&&($=Ce,me=tt(),me!==r?(Le=Fn(),Le!==r?(ft=xA(),ft!==r?(pt=Ci(),pt!==r?(Tt=$,me=pe(ft),$=me):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r),$===r))if($=Ce,me=Us(),me!==r){if(Le=[],ft=We(),ft!==r)for(;ft!==r;)Le.push(ft),ft=We();else Le=r;Le!==r?(Tt=$,me=Ae(me),$=me):(Ce=$,$=r)}else Ce=$,$=r;return $}function hs(){var $,me,Le;for(Yt++,$=Ce,me=[],t.charCodeAt(Ce)===32?(Le=ae,Ce++):(Le=r,Yt===0&&Ze(we));Le!==r;)me.push(Le),t.charCodeAt(Ce)===32?(Le=ae,Ce++):(Le=r,Yt===0&&Ze(we));return me!==r?(Tt=Ce,Le=Pe(me),Le?Le=void 0:Le=r,Le!==r?(me=[me,Le],$=me):(Ce=$,$=r)):(Ce=$,$=r),Yt--,$===r&&(me=r,Yt===0&&Ze(ye)),$}function _t(){var $,me,Le;for($=Ce,me=[],t.charCodeAt(Ce)===32?(Le=ae,Ce++):(Le=r,Yt===0&&Ze(we));Le!==r;)me.push(Le),t.charCodeAt(Ce)===32?(Le=ae,Ce++):(Le=r,Yt===0&&Ze(we));return me!==r?(Tt=Ce,Le=g(me),Le?Le=void 0:Le=r,Le!==r?(me=[me,Le],$=me):(Ce=$,$=r)):(Ce=$,$=r),$}function Fn(){var $;return Tt=Ce,$=Ee(),$?$=void 0:$=r,$}function Ci(){var $;return Tt=Ce,$=De(),$?$=void 0:$=r,$}function oa(){var $;return $=ds(),$===r&&($=la()),$}function co(){var $,me,Le;if($=ds(),$===r){if($=Ce,me=[],Le=Ho(),Le!==r)for(;Le!==r;)me.push(Le),Le=Ho();else me=r;me!==r&&(Tt=$,me=ce()),$=me}return $}function Us(){var $;return $=wi(),$===r&&($=gs(),$===r&&($=ds(),$===r&&($=la()))),$}function aa(){var $;return $=wi(),$===r&&($=ds(),$===r&&($=Ho())),$}function la(){var $,me,Le,ft,pt,Rt;if(Yt++,$=Ce,ee.test(t.charAt(Ce))?(me=t.charAt(Ce),Ce++):(me=r,Yt===0&&Ze(Ie)),me!==r){for(Le=[],ft=Ce,pt=Pn(),pt===r&&(pt=null),pt!==r?(ke.test(t.charAt(Ce))?(Rt=t.charAt(Ce),Ce++):(Rt=r,Yt===0&&Ze(ht)),Rt!==r?(pt=[pt,Rt],ft=pt):(Ce=ft,ft=r)):(Ce=ft,ft=r);ft!==r;)Le.push(ft),ft=Ce,pt=Pn(),pt===r&&(pt=null),pt!==r?(ke.test(t.charAt(Ce))?(Rt=t.charAt(Ce),Ce++):(Rt=r,Yt===0&&Ze(ht)),Rt!==r?(pt=[pt,Rt],ft=pt):(Ce=ft,ft=r)):(Ce=ft,ft=r);Le!==r?(Tt=$,me=H(),$=me):(Ce=$,$=r)}else Ce=$,$=r;return Yt--,$===r&&(me=r,Yt===0&&Ze(ne)),$}function Ho(){var $,me,Le,ft,pt;if($=Ce,t.substr(Ce,2)===lt?(me=lt,Ce+=2):(me=r,Yt===0&&Ze(Re)),me===r&&(me=null),me!==r)if(Qe.test(t.charAt(Ce))?(Le=t.charAt(Ce),Ce++):(Le=r,Yt===0&&Ze(be)),Le!==r){for(ft=[],_e.test(t.charAt(Ce))?(pt=t.charAt(Ce),Ce++):(pt=r,Yt===0&&Ze(Te));pt!==r;)ft.push(pt),_e.test(t.charAt(Ce))?(pt=t.charAt(Ce),Ce++):(pt=r,Yt===0&&Ze(Te));ft!==r?(Tt=$,me=H(),$=me):(Ce=$,$=r)}else Ce=$,$=r;else Ce=$,$=r;return $}function wi(){var $,me;return $=Ce,t.substr(Ce,4)===Je?(me=Je,Ce+=4):(me=r,Yt===0&&Ze(He)),me!==r&&(Tt=$,me=x()),$=me,$}function gs(){var $,me;return $=Ce,t.substr(Ce,4)===w?(me=w,Ce+=4):(me=r,Yt===0&&Ze(S)),me!==r&&(Tt=$,me=y()),$=me,$===r&&($=Ce,t.substr(Ce,5)===F?(me=F,Ce+=5):(me=r,Yt===0&&Ze(z)),me!==r&&(Tt=$,me=X()),$=me),$}function ds(){var $,me,Le,ft;return Yt++,$=Ce,t.charCodeAt(Ce)===34?(me=ie,Ce++):(me=r,Yt===0&&Ze(Se)),me!==r?(t.charCodeAt(Ce)===34?(Le=ie,Ce++):(Le=r,Yt===0&&Ze(Se)),Le!==r?(Tt=$,me=Ne(),$=me):(Ce=$,$=r)):(Ce=$,$=r),$===r&&($=Ce,t.charCodeAt(Ce)===34?(me=ie,Ce++):(me=r,Yt===0&&Ze(Se)),me!==r?(Le=ms(),Le!==r?(t.charCodeAt(Ce)===34?(ft=ie,Ce++):(ft=r,Yt===0&&Ze(Se)),ft!==r?(Tt=$,me=ot(Le),$=me):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)),Yt--,$===r&&(me=r,Yt===0&&Ze(Z)),$}function ms(){var $,me,Le;if($=Ce,me=[],Le=_s(),Le!==r)for(;Le!==r;)me.push(Le),Le=_s();else me=r;return me!==r&&(Tt=$,me=dt(me)),$=me,$}function _s(){var $,me,Le,ft,pt,Rt;return jt.test(t.charAt(Ce))?($=t.charAt(Ce),Ce++):($=r,Yt===0&&Ze($t)),$===r&&($=Ce,t.substr(Ce,2)===xt?(me=xt,Ce+=2):(me=r,Yt===0&&Ze(an)),me!==r&&(Tt=$,me=Qr()),$=me,$===r&&($=Ce,t.substr(Ce,2)===mr?(me=mr,Ce+=2):(me=r,Yt===0&&Ze(xr)),me!==r&&(Tt=$,me=Wr()),$=me,$===r&&($=Ce,t.substr(Ce,2)===Vn?(me=Vn,Ce+=2):(me=r,Yt===0&&Ze(Ns)),me!==r&&(Tt=$,me=Ri()),$=me,$===r&&($=Ce,t.substr(Ce,2)===ps?(me=ps,Ce+=2):(me=r,Yt===0&&Ze(io)),me!==r&&(Tt=$,me=Si()),$=me,$===r&&($=Ce,t.substr(Ce,2)===Ls?(me=Ls,Ce+=2):(me=r,Yt===0&&Ze(so)),me!==r&&(Tt=$,me=cc()),$=me,$===r&&($=Ce,t.substr(Ce,2)===cu?(me=cu,Ce+=2):(me=r,Yt===0&&Ze(ap)),me!==r&&(Tt=$,me=lp()),$=me,$===r&&($=Ce,t.substr(Ce,2)===Ms?(me=Ms,Ce+=2):(me=r,Yt===0&&Ze(Dn)),me!==r&&(Tt=$,me=oo()),$=me,$===r&&($=Ce,t.substr(Ce,2)===Os?(me=Os,Ce+=2):(me=r,Yt===0&&Ze(ml)),me!==r&&(Tt=$,me=yl()),$=me,$===r&&($=Ce,t.substr(Ce,2)===ao?(me=ao,Ce+=2):(me=r,Yt===0&&Ze(Kn)),me!==r?(Le=Un(),Le!==r?(ft=Un(),ft!==r?(pt=Un(),pt!==r?(Rt=Un(),Rt!==r?(Tt=$,me=Mn(Le,ft,pt,Rt),$=me):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)):(Ce=$,$=r)))))))))),$}function Un(){var $;return Ni.test(t.charAt(Ce))?($=t.charAt(Ce),Ce++):($=r,Yt===0&&Ze(On)),$}function Pn(){var $,me;if(Yt++,$=[],tr.test(t.charAt(Ce))?(me=t.charAt(Ce),Ce++):(me=r,Yt===0&&Ze(Me)),me!==r)for(;me!==r;)$.push(me),tr.test(t.charAt(Ce))?(me=t.charAt(Ce),Ce++):(me=r,Yt===0&&Ze(Me));else $=r;return Yt--,$===r&&(me=r,Yt===0&&Ze(_i)),$}function ys(){var $,me;if(Yt++,$=[],Oa.test(t.charAt(Ce))?(me=t.charAt(Ce),Ce++):(me=r,Yt===0&&Ze(hr)),me!==r)for(;me!==r;)$.push(me),Oa.test(t.charAt(Ce))?(me=t.charAt(Ce),Ce++):(me=r,Yt===0&&Ze(hr));else $=r;return Yt--,$===r&&(me=r,Yt===0&&Ze(ii)),$}function We(){var $,me,Le,ft,pt,Rt;if($=Ce,me=tt(),me!==r){for(Le=[],ft=Ce,pt=Pn(),pt===r&&(pt=null),pt!==r?(Rt=tt(),Rt!==r?(pt=[pt,Rt],ft=pt):(Ce=ft,ft=r)):(Ce=ft,ft=r);ft!==r;)Le.push(ft),ft=Ce,pt=Pn(),pt===r&&(pt=null),pt!==r?(Rt=tt(),Rt!==r?(pt=[pt,Rt],ft=pt):(Ce=ft,ft=r)):(Ce=ft,ft=r);Le!==r?(me=[me,Le],$=me):(Ce=$,$=r)}else Ce=$,$=r;return $}function tt(){var $;return t.substr(Ce,2)===uc?($=uc,Ce+=2):($=r,Yt===0&&Ze(uu)),$===r&&(t.charCodeAt(Ce)===10?($=Ac,Ce++):($=r,Yt===0&&Ze(El)),$===r&&(t.charCodeAt(Ce)===13?($=vA,Ce++):($=r,Yt===0&&Ze(Au)))),$}let It=2,nr=0;if(Cl=a(),Cl!==r&&Ce===t.length)return Cl;throw Cl!==r&&Ce<t.length&&Ze(SA()),gc(fu,Hi<t.length?t.charAt(Hi):null,Hi<t.length?_o(Hi,Hi+1):_o(Hi,Hi))}$V.exports={SyntaxError:$g,parse:X6e}});function rK(t){return t.match(Z6e)?t:JSON.stringify(t)}function iK(t){return typeof t>"u"?!0:typeof t=="object"&&t!==null&&!Array.isArray(t)?Object.keys(t).every(e=>iK(t[e])):!1}function DR(t,e,r){if(t===null)return`null +`;if(typeof t=="number"||typeof t=="boolean")return`${t.toString()} +`;if(typeof t=="string")return`${rK(t)} +`;if(Array.isArray(t)){if(t.length===0)return`[] +`;let o=" ".repeat(e);return` +${t.map(n=>`${o}- ${DR(n,e+1,!1)}`).join("")}`}if(typeof t=="object"&&t){let[o,a]=t instanceof XD?[t.data,!1]:[t,!0],n=" ".repeat(e),u=Object.keys(o);a&&u.sort((p,h)=>{let E=tK.indexOf(p),I=tK.indexOf(h);return E===-1&&I===-1?p<h?-1:p>h?1:0:E!==-1&&I===-1?-1:E===-1&&I!==-1?1:E-I});let A=u.filter(p=>!iK(o[p])).map((p,h)=>{let E=o[p],I=rK(p),v=DR(E,e+1,!0),b=h>0||r?n:"",C=I.length>1024?`? ${I} +${b}:`:`${I}:`,T=v.startsWith(` +`)?v:` ${v}`;return`${b}${C}${T}`}).join(e===0?` +`:"")||` +`;return r?` +${A}`:`${A}`}throw new Error(`Unsupported value type (${t})`)}function Ba(t){try{let e=DR(t,0,!1);return e!==` +`?e:""}catch(e){throw e.location&&(e.message=e.message.replace(/(\.)?$/,` (line ${e.location.start.line}, column ${e.location.start.column})$1`)),e}}function $6e(t){return t.endsWith(` +`)||(t+=` +`),(0,nK.parse)(t)}function tje(t){if(eje.test(t))return $6e(t);let e=(0,ZD.safeLoad)(t,{schema:ZD.FAILSAFE_SCHEMA,json:!0});if(e==null)return{};if(typeof e!="object")throw new Error(`Expected an indexed object, got a ${typeof e} instead. Does your file follow Yaml's rules?`);if(Array.isArray(e))throw new Error("Expected an indexed object, got an array instead. Does your file follow Yaml's rules?");return e}function Vi(t){return tje(t)}var ZD,nK,Z6e,tK,XD,eje,sK=Et(()=>{ZD=$e(ZV()),nK=$e(eK()),Z6e=/^(?![-?:,\][{}#&*!|>'"%@` \t\r\n]).([ \t]*(?![,\][{}:# \t\r\n]).)*$/,tK=["__metadata","version","resolution","dependencies","peerDependencies","dependenciesMeta","peerDependenciesMeta","binaries"],XD=class{constructor(e){this.data=e}};Ba.PreserveOrdering=XD;eje=/^(#.*(\r?\n))*?#\s+yarn\s+lockfile\s+v1\r?\n/i});var tI={};Kt(tI,{parseResolution:()=>UD,parseShell:()=>LD,parseSyml:()=>Vi,stringifyArgument:()=>AR,stringifyArgumentSegment:()=>fR,stringifyArithmeticExpression:()=>OD,stringifyCommand:()=>uR,stringifyCommandChain:()=>cy,stringifyCommandChainThen:()=>cR,stringifyCommandLine:()=>MD,stringifyCommandLineThen:()=>lR,stringifyEnvSegment:()=>ND,stringifyRedirectArgument:()=>Kw,stringifyResolution:()=>_D,stringifyShell:()=>ly,stringifyShellLine:()=>ly,stringifySyml:()=>Ba,stringifyValueArgument:()=>Gg});var Nl=Et(()=>{iW();lW();sK()});var aK=_((Cbt,PR)=>{"use strict";var rje=t=>{let e=!1,r=!1,o=!1;for(let a=0;a<t.length;a++){let n=t[a];e&&/[a-zA-Z]/.test(n)&&n.toUpperCase()===n?(t=t.slice(0,a)+"-"+t.slice(a),e=!1,o=r,r=!0,a++):r&&o&&/[a-zA-Z]/.test(n)&&n.toLowerCase()===n?(t=t.slice(0,a-1)+"-"+t.slice(a-1),o=r,r=!1,e=!0):(e=n.toLowerCase()===n&&n.toUpperCase()!==n,o=r,r=n.toUpperCase()===n&&n.toLowerCase()!==n)}return t},oK=(t,e)=>{if(!(typeof t=="string"||Array.isArray(t)))throw new TypeError("Expected the input to be `string | string[]`");e=Object.assign({pascalCase:!1},e);let r=a=>e.pascalCase?a.charAt(0).toUpperCase()+a.slice(1):a;return Array.isArray(t)?t=t.map(a=>a.trim()).filter(a=>a.length).join("-"):t=t.trim(),t.length===0?"":t.length===1?e.pascalCase?t.toUpperCase():t.toLowerCase():(t!==t.toLowerCase()&&(t=rje(t)),t=t.replace(/^[_.\- ]+/,"").toLowerCase().replace(/[_.\- ]+(\w|$)/g,(a,n)=>n.toUpperCase()).replace(/\d+(\w|$)/g,a=>a.toUpperCase()),r(t))};PR.exports=oK;PR.exports.default=oK});var lK=_((wbt,nje)=>{nje.exports=[{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"SYSTEM_TEAMFOUNDATIONCOLLECTIONURI",pr:"SYSTEM_PULLREQUEST_PULLREQUESTID"},{name:"Appcircle",constant:"APPCIRCLE",env:"AC_APPCIRCLE"},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN"},{name:"Codefresh",constant:"CODEFRESH",env:"CF_BUILD_ID",pr:{any:["CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_ID"]}},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"GitHub Actions",constant:"GITHUB_ACTIONS",env:"GITHUB_ACTIONS",pr:{GITHUB_EVENT_NAME:"pull_request"}},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI",pr:"CI_MERGE_REQUEST_ID"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"LayerCI",constant:"LAYERCI",env:"LAYERCI",pr:"LAYERCI_PULL_REQUEST"},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Nevercode",constant:"NEVERCODE",env:"NEVERCODE",pr:{env:"NEVERCODE_PULL_REQUEST",ne:"false"}},{name:"Render",constant:"RENDER",env:"RENDER",pr:{IS_PULL_REQUEST:"true"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Screwdriver",constant:"SCREWDRIVER",env:"SCREWDRIVER",pr:{env:"SD_PULL_REQUEST",ne:"false"}},{name:"Shippable",constant:"SHIPPABLE",env:"SHIPPABLE",pr:{IS_PULL_REQUEST:"true"}},{name:"Solano CI",constant:"SOLANO",env:"TDDIUM",pr:"TDDIUM_PR_ID"},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}},{name:"Vercel",constant:"VERCEL",env:"NOW_BUILDER"},{name:"Visual Studio App Center",constant:"APPCENTER",env:"APPCENTER_BUILD_ID"}]});var ed=_(Xa=>{"use strict";var uK=lK(),ju=process.env;Object.defineProperty(Xa,"_vendors",{value:uK.map(function(t){return t.constant})});Xa.name=null;Xa.isPR=null;uK.forEach(function(t){let r=(Array.isArray(t.env)?t.env:[t.env]).every(function(o){return cK(o)});if(Xa[t.constant]=r,r)switch(Xa.name=t.name,typeof t.pr){case"string":Xa.isPR=!!ju[t.pr];break;case"object":"env"in t.pr?Xa.isPR=t.pr.env in ju&&ju[t.pr.env]!==t.pr.ne:"any"in t.pr?Xa.isPR=t.pr.any.some(function(o){return!!ju[o]}):Xa.isPR=cK(t.pr);break;default:Xa.isPR=null}});Xa.isCI=!!(ju.CI||ju.CONTINUOUS_INTEGRATION||ju.BUILD_NUMBER||ju.RUN_ID||Xa.name);function cK(t){return typeof t=="string"?!!ju[t]:Object.keys(t).every(function(e){return ju[e]===t[e]})}});var Hn,cn,td,SR,$D,AK,xR,bR,eP=Et(()=>{(function(t){t.StartOfInput="\0",t.EndOfInput="",t.EndOfPartialInput=""})(Hn||(Hn={}));(function(t){t[t.InitialNode=0]="InitialNode",t[t.SuccessNode=1]="SuccessNode",t[t.ErrorNode=2]="ErrorNode",t[t.CustomNode=3]="CustomNode"})(cn||(cn={}));td=-1,SR=/^(-h|--help)(?:=([0-9]+))?$/,$D=/^(--[a-z]+(?:-[a-z]+)*|-[a-zA-Z]+)$/,AK=/^-[a-zA-Z]{2,}$/,xR=/^([^=]+)=([\s\S]*)$/,bR=process.env.DEBUG_CLI==="1"});var it,my,tP,kR,rP=Et(()=>{eP();it=class extends Error{constructor(e){super(e),this.clipanion={type:"usage"},this.name="UsageError"}},my=class extends Error{constructor(e,r){if(super(),this.input=e,this.candidates=r,this.clipanion={type:"none"},this.name="UnknownSyntaxError",this.candidates.length===0)this.message="Command not found, but we're not sure what's the alternative.";else if(this.candidates.every(o=>o.reason!==null&&o.reason===r[0].reason)){let[{reason:o}]=this.candidates;this.message=`${o} + +${this.candidates.map(({usage:a})=>`$ ${a}`).join(` +`)}`}else if(this.candidates.length===1){let[{usage:o}]=this.candidates;this.message=`Command not found; did you mean: + +$ ${o} +${kR(e)}`}else this.message=`Command not found; did you mean one of: + +${this.candidates.map(({usage:o},a)=>`${`${a}.`.padStart(4)} ${o}`).join(` +`)} + +${kR(e)}`}},tP=class extends Error{constructor(e,r){super(),this.input=e,this.usages=r,this.clipanion={type:"none"},this.name="AmbiguousSyntaxError",this.message=`Cannot find which to pick amongst the following alternatives: + +${this.usages.map((o,a)=>`${`${a}.`.padStart(4)} ${o}`).join(` +`)} + +${kR(e)}`}},kR=t=>`While running ${t.filter(e=>e!==Hn.EndOfInput&&e!==Hn.EndOfPartialInput).map(e=>{let r=JSON.stringify(e);return e.match(/\s/)||e.length===0||r!==`"${e}"`?r:e}).join(" ")}`});function ije(t){let e=t.split(` +`),r=e.filter(a=>a.match(/\S/)),o=r.length>0?r.reduce((a,n)=>Math.min(a,n.length-n.trimStart().length),Number.MAX_VALUE):0;return e.map(a=>a.slice(o).trimRight()).join(` +`)}function Do(t,{format:e,paragraphs:r}){return t=t.replace(/\r\n?/g,` +`),t=ije(t),t=t.replace(/^\n+|\n+$/g,""),t=t.replace(/^(\s*)-([^\n]*?)\n+/gm,`$1-$2 + +`),t=t.replace(/\n(\n)?\n*/g,(o,a)=>a||" "),r&&(t=t.split(/\n/).map(o=>{let a=o.match(/^\s*[*-][\t ]+(.*)/);if(!a)return o.match(/(.{1,80})(?: |$)/g).join(` +`);let n=o.length-o.trimStart().length;return a[1].match(new RegExp(`(.{1,${78-n}})(?: |$)`,"g")).map((u,A)=>" ".repeat(n)+(A===0?"- ":" ")+u).join(` +`)}).join(` + +`)),t=t.replace(/(`+)((?:.|[\n])*?)\1/g,(o,a,n)=>e.code(a+n+a)),t=t.replace(/(\*\*)((?:.|[\n])*?)\1/g,(o,a,n)=>e.bold(a+n+a)),t?`${t} +`:""}var QR,fK,pK,FR=Et(()=>{QR=Array(80).fill("\u2501");for(let t=0;t<=24;++t)QR[QR.length-t]=`\x1B[38;5;${232+t}m\u2501`;fK={header:t=>`\x1B[1m\u2501\u2501\u2501 ${t}${t.length<80-5?` ${QR.slice(t.length+5).join("")}`:":"}\x1B[0m`,bold:t=>`\x1B[1m${t}\x1B[22m`,error:t=>`\x1B[31m\x1B[1m${t}\x1B[22m\x1B[39m`,code:t=>`\x1B[36m${t}\x1B[39m`},pK={header:t=>t,bold:t=>t,error:t=>t,code:t=>t}});function Vo(t){return{...t,[rI]:!0}}function qu(t,e){return typeof t>"u"?[t,e]:typeof t=="object"&&t!==null&&!Array.isArray(t)?[void 0,t]:[t,e]}function nP(t,{mergeName:e=!1}={}){let r=t.match(/^([^:]+): (.*)$/m);if(!r)return"validation failed";let[,o,a]=r;return e&&(a=a[0].toLowerCase()+a.slice(1)),a=o!=="."||!e?`${o.replace(/^\.(\[|$)/,"$1")}: ${a}`:`: ${a}`,a}function nI(t,e){return e.length===1?new it(`${t}${nP(e[0],{mergeName:!0})}`):new it(`${t}: +${e.map(r=>` +- ${nP(r)}`).join("")}`)}function rd(t,e,r){if(typeof r>"u")return e;let o=[],a=[],n=A=>{let p=e;return e=A,n.bind(null,p)};if(!r(e,{errors:o,coercions:a,coercion:n}))throw nI(`Invalid value for ${t}`,o);for(let[,A]of a)A();return e}var rI,yf=Et(()=>{rP();rI=Symbol("clipanion/isOption")});var Ko={};Kt(Ko,{KeyRelationship:()=>Gu,TypeAssertionError:()=>Wp,applyCascade:()=>oI,as:()=>Bje,assert:()=>Cje,assertWithErrors:()=>wje,cascade:()=>aP,fn:()=>vje,hasAtLeastOneKey:()=>UR,hasExactLength:()=>yK,hasForbiddenKeys:()=>qje,hasKeyRelationship:()=>lI,hasMaxLength:()=>Pje,hasMinLength:()=>Dje,hasMutuallyExclusiveKeys:()=>Gje,hasRequiredKeys:()=>jje,hasUniqueItems:()=>Sje,isArray:()=>iP,isAtLeast:()=>MR,isAtMost:()=>kje,isBase64:()=>Oje,isBoolean:()=>fje,isDate:()=>hje,isDict:()=>mje,isEnum:()=>Vs,isHexColor:()=>Mje,isISO8601:()=>Lje,isInExclusiveRange:()=>Fje,isInInclusiveRange:()=>Qje,isInstanceOf:()=>Eje,isInteger:()=>OR,isJSON:()=>Uje,isLiteral:()=>gK,isLowerCase:()=>Tje,isMap:()=>dje,isNegative:()=>xje,isNullable:()=>Hje,isNumber:()=>NR,isObject:()=>dK,isOneOf:()=>LR,isOptional:()=>_je,isPartial:()=>yje,isPayload:()=>pje,isPositive:()=>bje,isRecord:()=>oP,isSet:()=>gje,isString:()=>Ey,isTuple:()=>sP,isUUID4:()=>Nje,isUnknown:()=>RR,isUpperCase:()=>Rje,makeTrait:()=>mK,makeValidator:()=>Hr,matchesRegExp:()=>sI,softAssert:()=>Ije});function jn(t){return t===null?"null":t===void 0?"undefined":t===""?"an empty string":typeof t=="symbol"?`<${t.toString()}>`:Array.isArray(t)?"an array":JSON.stringify(t)}function yy(t,e){if(t.length===0)return"nothing";if(t.length===1)return jn(t[0]);let r=t.slice(0,-1),o=t[t.length-1],a=t.length>2?`, ${e} `:` ${e} `;return`${r.map(n=>jn(n)).join(", ")}${a}${jn(o)}`}function Yp(t,e){var r,o,a;return typeof e=="number"?`${(r=t?.p)!==null&&r!==void 0?r:"."}[${e}]`:sje.test(e)?`${(o=t?.p)!==null&&o!==void 0?o:""}.${e}`:`${(a=t?.p)!==null&&a!==void 0?a:"."}[${JSON.stringify(e)}]`}function TR(t,e,r){return t===1?e:r}function pr({errors:t,p:e}={},r){return t?.push(`${e??"."}: ${r}`),!1}function uje(t,e){return r=>{t[e]=r}}function Yu(t,e){return r=>{let o=t[e];return t[e]=r,Yu(t,e).bind(null,o)}}function iI(t,e,r){let o=()=>(t(r()),a),a=()=>(t(e),o);return o}function RR(){return Hr({test:(t,e)=>!0})}function gK(t){return Hr({test:(e,r)=>e!==t?pr(r,`Expected ${jn(t)} (got ${jn(e)})`):!0})}function Ey(){return Hr({test:(t,e)=>typeof t!="string"?pr(e,`Expected a string (got ${jn(t)})`):!0})}function Vs(t){let e=Array.isArray(t)?t:Object.values(t),r=e.every(a=>typeof a=="string"||typeof a=="number"),o=new Set(e);return o.size===1?gK([...o][0]):Hr({test:(a,n)=>o.has(a)?!0:r?pr(n,`Expected one of ${yy(e,"or")} (got ${jn(a)})`):pr(n,`Expected a valid enumeration value (got ${jn(a)})`)})}function fje(){return Hr({test:(t,e)=>{var r;if(typeof t!="boolean"){if(typeof e?.coercions<"u"){if(typeof e?.coercion>"u")return pr(e,"Unbound coercion result");let o=Aje.get(t);if(typeof o<"u")return e.coercions.push([(r=e.p)!==null&&r!==void 0?r:".",e.coercion.bind(null,o)]),!0}return pr(e,`Expected a boolean (got ${jn(t)})`)}return!0}})}function NR(){return Hr({test:(t,e)=>{var r;if(typeof t!="number"){if(typeof e?.coercions<"u"){if(typeof e?.coercion>"u")return pr(e,"Unbound coercion result");let o;if(typeof t=="string"){let a;try{a=JSON.parse(t)}catch{}if(typeof a=="number")if(JSON.stringify(a)===t)o=a;else return pr(e,`Received a number that can't be safely represented by the runtime (${t})`)}if(typeof o<"u")return e.coercions.push([(r=e.p)!==null&&r!==void 0?r:".",e.coercion.bind(null,o)]),!0}return pr(e,`Expected a number (got ${jn(t)})`)}return!0}})}function pje(t){return Hr({test:(e,r)=>{var o;if(typeof r?.coercions>"u")return pr(r,"The isPayload predicate can only be used with coercion enabled");if(typeof r.coercion>"u")return pr(r,"Unbound coercion result");if(typeof e!="string")return pr(r,`Expected a string (got ${jn(e)})`);let a;try{a=JSON.parse(e)}catch{return pr(r,`Expected a JSON string (got ${jn(e)})`)}let n={value:a};return t(a,Object.assign(Object.assign({},r),{coercion:Yu(n,"value")}))?(r.coercions.push([(o=r.p)!==null&&o!==void 0?o:".",r.coercion.bind(null,n.value)]),!0):!1}})}function hje(){return Hr({test:(t,e)=>{var r;if(!(t instanceof Date)){if(typeof e?.coercions<"u"){if(typeof e?.coercion>"u")return pr(e,"Unbound coercion result");let o;if(typeof t=="string"&&hK.test(t))o=new Date(t);else{let a;if(typeof t=="string"){let n;try{n=JSON.parse(t)}catch{}typeof n=="number"&&(a=n)}else typeof t=="number"&&(a=t);if(typeof a<"u")if(Number.isSafeInteger(a)||!Number.isSafeInteger(a*1e3))o=new Date(a*1e3);else return pr(e,`Received a timestamp that can't be safely represented by the runtime (${t})`)}if(typeof o<"u")return e.coercions.push([(r=e.p)!==null&&r!==void 0?r:".",e.coercion.bind(null,o)]),!0}return pr(e,`Expected a date (got ${jn(t)})`)}return!0}})}function iP(t,{delimiter:e}={}){return Hr({test:(r,o)=>{var a;let n=r;if(typeof r=="string"&&typeof e<"u"&&typeof o?.coercions<"u"){if(typeof o?.coercion>"u")return pr(o,"Unbound coercion result");r=r.split(e)}if(!Array.isArray(r))return pr(o,`Expected an array (got ${jn(r)})`);let u=!0;for(let A=0,p=r.length;A<p&&(u=t(r[A],Object.assign(Object.assign({},o),{p:Yp(o,A),coercion:Yu(r,A)}))&&u,!(!u&&o?.errors==null));++A);return r!==n&&o.coercions.push([(a=o.p)!==null&&a!==void 0?a:".",o.coercion.bind(null,r)]),u}})}function gje(t,{delimiter:e}={}){let r=iP(t,{delimiter:e});return Hr({test:(o,a)=>{var n,u;if(Object.getPrototypeOf(o).toString()==="[object Set]")if(typeof a?.coercions<"u"){if(typeof a?.coercion>"u")return pr(a,"Unbound coercion result");let A=[...o],p=[...o];if(!r(p,Object.assign(Object.assign({},a),{coercion:void 0})))return!1;let h=()=>p.some((E,I)=>E!==A[I])?new Set(p):o;return a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",iI(a.coercion,o,h)]),!0}else{let A=!0;for(let p of o)if(A=t(p,Object.assign({},a))&&A,!A&&a?.errors==null)break;return A}if(typeof a?.coercions<"u"){if(typeof a?.coercion>"u")return pr(a,"Unbound coercion result");let A={value:o};return r(o,Object.assign(Object.assign({},a),{coercion:Yu(A,"value")}))?(a.coercions.push([(u=a.p)!==null&&u!==void 0?u:".",iI(a.coercion,o,()=>new Set(A.value))]),!0):!1}return pr(a,`Expected a set (got ${jn(o)})`)}})}function dje(t,e){let r=iP(sP([t,e])),o=oP(e,{keys:t});return Hr({test:(a,n)=>{var u,A,p;if(Object.getPrototypeOf(a).toString()==="[object Map]")if(typeof n?.coercions<"u"){if(typeof n?.coercion>"u")return pr(n,"Unbound coercion result");let h=[...a],E=[...a];if(!r(E,Object.assign(Object.assign({},n),{coercion:void 0})))return!1;let I=()=>E.some((v,b)=>v[0]!==h[b][0]||v[1]!==h[b][1])?new Map(E):a;return n.coercions.push([(u=n.p)!==null&&u!==void 0?u:".",iI(n.coercion,a,I)]),!0}else{let h=!0;for(let[E,I]of a)if(h=t(E,Object.assign({},n))&&h,!h&&n?.errors==null||(h=e(I,Object.assign(Object.assign({},n),{p:Yp(n,E)}))&&h,!h&&n?.errors==null))break;return h}if(typeof n?.coercions<"u"){if(typeof n?.coercion>"u")return pr(n,"Unbound coercion result");let h={value:a};return Array.isArray(a)?r(a,Object.assign(Object.assign({},n),{coercion:void 0}))?(n.coercions.push([(A=n.p)!==null&&A!==void 0?A:".",iI(n.coercion,a,()=>new Map(h.value))]),!0):!1:o(a,Object.assign(Object.assign({},n),{coercion:Yu(h,"value")}))?(n.coercions.push([(p=n.p)!==null&&p!==void 0?p:".",iI(n.coercion,a,()=>new Map(Object.entries(h.value)))]),!0):!1}return pr(n,`Expected a map (got ${jn(a)})`)}})}function sP(t,{delimiter:e}={}){let r=yK(t.length);return Hr({test:(o,a)=>{var n;if(typeof o=="string"&&typeof e<"u"&&typeof a?.coercions<"u"){if(typeof a?.coercion>"u")return pr(a,"Unbound coercion result");o=o.split(e),a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",a.coercion.bind(null,o)])}if(!Array.isArray(o))return pr(a,`Expected a tuple (got ${jn(o)})`);let u=r(o,Object.assign({},a));for(let A=0,p=o.length;A<p&&A<t.length&&(u=t[A](o[A],Object.assign(Object.assign({},a),{p:Yp(a,A),coercion:Yu(o,A)}))&&u,!(!u&&a?.errors==null));++A);return u}})}function oP(t,{keys:e=null}={}){let r=iP(sP([e??Ey(),t]));return Hr({test:(o,a)=>{var n;if(Array.isArray(o)&&typeof a?.coercions<"u")return typeof a?.coercion>"u"?pr(a,"Unbound coercion result"):r(o,Object.assign(Object.assign({},a),{coercion:void 0}))?(o=Object.fromEntries(o),a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",a.coercion.bind(null,o)]),!0):!1;if(typeof o!="object"||o===null)return pr(a,`Expected an object (got ${jn(o)})`);let u=Object.keys(o),A=!0;for(let p=0,h=u.length;p<h&&(A||a?.errors!=null);++p){let E=u[p],I=o[E];if(E==="__proto__"||E==="constructor"){A=pr(Object.assign(Object.assign({},a),{p:Yp(a,E)}),"Unsafe property name");continue}if(e!==null&&!e(E,a)){A=!1;continue}if(!t(I,Object.assign(Object.assign({},a),{p:Yp(a,E),coercion:Yu(o,E)}))){A=!1;continue}}return A}})}function mje(t,e={}){return oP(t,e)}function dK(t,{extra:e=null}={}){let r=Object.keys(t),o=Hr({test:(a,n)=>{if(typeof a!="object"||a===null)return pr(n,`Expected an object (got ${jn(a)})`);let u=new Set([...r,...Object.keys(a)]),A={},p=!0;for(let h of u){if(h==="constructor"||h==="__proto__")p=pr(Object.assign(Object.assign({},n),{p:Yp(n,h)}),"Unsafe property name");else{let E=Object.prototype.hasOwnProperty.call(t,h)?t[h]:void 0,I=Object.prototype.hasOwnProperty.call(a,h)?a[h]:void 0;typeof E<"u"?p=E(I,Object.assign(Object.assign({},n),{p:Yp(n,h),coercion:Yu(a,h)}))&&p:e===null?p=pr(Object.assign(Object.assign({},n),{p:Yp(n,h)}),`Extraneous property (got ${jn(I)})`):Object.defineProperty(A,h,{enumerable:!0,get:()=>I,set:uje(a,h)})}if(!p&&n?.errors==null)break}return e!==null&&(p||n?.errors!=null)&&(p=e(A,n)&&p),p}});return Object.assign(o,{properties:t})}function yje(t){return dK(t,{extra:oP(RR())})}function mK(t){return()=>t}function Hr({test:t}){return mK(t)()}function Cje(t,e){if(!e(t))throw new Wp}function wje(t,e){let r=[];if(!e(t,{errors:r}))throw new Wp({errors:r})}function Ije(t,e){}function Bje(t,e,{coerce:r=!1,errors:o,throw:a}={}){let n=o?[]:void 0;if(!r){if(e(t,{errors:n}))return a?t:{value:t,errors:void 0};if(a)throw new Wp({errors:n});return{value:void 0,errors:n??!0}}let u={value:t},A=Yu(u,"value"),p=[];if(!e(t,{errors:n,coercion:A,coercions:p})){if(a)throw new Wp({errors:n});return{value:void 0,errors:n??!0}}for(let[,h]of p)h();return a?u.value:{value:u.value,errors:void 0}}function vje(t,e){let r=sP(t);return(...o)=>{if(!r(o))throw new Wp;return e(...o)}}function Dje(t){return Hr({test:(e,r)=>e.length>=t?!0:pr(r,`Expected to have a length of at least ${t} elements (got ${e.length})`)})}function Pje(t){return Hr({test:(e,r)=>e.length<=t?!0:pr(r,`Expected to have a length of at most ${t} elements (got ${e.length})`)})}function yK(t){return Hr({test:(e,r)=>e.length!==t?pr(r,`Expected to have a length of exactly ${t} elements (got ${e.length})`):!0})}function Sje({map:t}={}){return Hr({test:(e,r)=>{let o=new Set,a=new Set;for(let n=0,u=e.length;n<u;++n){let A=e[n],p=typeof t<"u"?t(A):A;if(o.has(p)){if(a.has(p))continue;pr(r,`Expected to contain unique elements; got a duplicate with ${jn(e)}`),a.add(p)}else o.add(p)}return a.size===0}})}function xje(){return Hr({test:(t,e)=>t<=0?!0:pr(e,`Expected to be negative (got ${t})`)})}function bje(){return Hr({test:(t,e)=>t>=0?!0:pr(e,`Expected to be positive (got ${t})`)})}function MR(t){return Hr({test:(e,r)=>e>=t?!0:pr(r,`Expected to be at least ${t} (got ${e})`)})}function kje(t){return Hr({test:(e,r)=>e<=t?!0:pr(r,`Expected to be at most ${t} (got ${e})`)})}function Qje(t,e){return Hr({test:(r,o)=>r>=t&&r<=e?!0:pr(o,`Expected to be in the [${t}; ${e}] range (got ${r})`)})}function Fje(t,e){return Hr({test:(r,o)=>r>=t&&r<e?!0:pr(o,`Expected to be in the [${t}; ${e}[ range (got ${r})`)})}function OR({unsafe:t=!1}={}){return Hr({test:(e,r)=>e!==Math.round(e)?pr(r,`Expected to be an integer (got ${e})`):!t&&!Number.isSafeInteger(e)?pr(r,`Expected to be a safe integer (got ${e})`):!0})}function sI(t){return Hr({test:(e,r)=>t.test(e)?!0:pr(r,`Expected to match the pattern ${t.toString()} (got ${jn(e)})`)})}function Tje(){return Hr({test:(t,e)=>t!==t.toLowerCase()?pr(e,`Expected to be all-lowercase (got ${t})`):!0})}function Rje(){return Hr({test:(t,e)=>t!==t.toUpperCase()?pr(e,`Expected to be all-uppercase (got ${t})`):!0})}function Nje(){return Hr({test:(t,e)=>cje.test(t)?!0:pr(e,`Expected to be a valid UUID v4 (got ${jn(t)})`)})}function Lje(){return Hr({test:(t,e)=>hK.test(t)?!0:pr(e,`Expected to be a valid ISO 8601 date string (got ${jn(t)})`)})}function Mje({alpha:t=!1}){return Hr({test:(e,r)=>(t?oje.test(e):aje.test(e))?!0:pr(r,`Expected to be a valid hexadecimal color string (got ${jn(e)})`)})}function Oje(){return Hr({test:(t,e)=>lje.test(t)?!0:pr(e,`Expected to be a valid base 64 string (got ${jn(t)})`)})}function Uje(t=RR()){return Hr({test:(e,r)=>{let o;try{o=JSON.parse(e)}catch{return pr(r,`Expected to be a valid JSON string (got ${jn(e)})`)}return t(o,r)}})}function aP(t,...e){let r=Array.isArray(e[0])?e[0]:e;return Hr({test:(o,a)=>{var n,u;let A={value:o},p=typeof a?.coercions<"u"?Yu(A,"value"):void 0,h=typeof a?.coercions<"u"?[]:void 0;if(!t(o,Object.assign(Object.assign({},a),{coercion:p,coercions:h})))return!1;let E=[];if(typeof h<"u")for(let[,I]of h)E.push(I());try{if(typeof a?.coercions<"u"){if(A.value!==o){if(typeof a?.coercion>"u")return pr(a,"Unbound coercion result");a.coercions.push([(n=a.p)!==null&&n!==void 0?n:".",a.coercion.bind(null,A.value)])}(u=a?.coercions)===null||u===void 0||u.push(...h)}return r.every(I=>I(A.value,a))}finally{for(let I of E)I()}}})}function oI(t,...e){let r=Array.isArray(e[0])?e[0]:e;return aP(t,r)}function _je(t){return Hr({test:(e,r)=>typeof e>"u"?!0:t(e,r)})}function Hje(t){return Hr({test:(e,r)=>e===null?!0:t(e,r)})}function jje(t,e){var r;let o=new Set(t),a=aI[(r=e?.missingIf)!==null&&r!==void 0?r:"missing"];return Hr({test:(n,u)=>{let A=new Set(Object.keys(n)),p=[];for(let h of o)a(A,h,n)||p.push(h);return p.length>0?pr(u,`Missing required ${TR(p.length,"property","properties")} ${yy(p,"and")}`):!0}})}function UR(t,e){var r;let o=new Set(t),a=aI[(r=e?.missingIf)!==null&&r!==void 0?r:"missing"];return Hr({test:(n,u)=>Object.keys(n).some(h=>a(o,h,n))?!0:pr(u,`Missing at least one property from ${yy(Array.from(o),"or")}`)})}function qje(t,e){var r;let o=new Set(t),a=aI[(r=e?.missingIf)!==null&&r!==void 0?r:"missing"];return Hr({test:(n,u)=>{let A=new Set(Object.keys(n)),p=[];for(let h of o)a(A,h,n)&&p.push(h);return p.length>0?pr(u,`Forbidden ${TR(p.length,"property","properties")} ${yy(p,"and")}`):!0}})}function Gje(t,e){var r;let o=new Set(t),a=aI[(r=e?.missingIf)!==null&&r!==void 0?r:"missing"];return Hr({test:(n,u)=>{let A=new Set(Object.keys(n)),p=[];for(let h of o)a(A,h,n)&&p.push(h);return p.length>1?pr(u,`Mutually exclusive properties ${yy(p,"and")}`):!0}})}function lI(t,e,r,o){var a,n;let u=new Set((a=o?.ignore)!==null&&a!==void 0?a:[]),A=aI[(n=o?.missingIf)!==null&&n!==void 0?n:"missing"],p=new Set(r),h=Yje[e],E=e===Gu.Forbids?"or":"and";return Hr({test:(I,v)=>{let b=new Set(Object.keys(I));if(!A(b,t,I)||u.has(I[t]))return!0;let C=[];for(let T of p)(A(b,T,I)&&!u.has(I[T]))!==h.expect&&C.push(T);return C.length>=1?pr(v,`Property "${t}" ${h.message} ${TR(C.length,"property","properties")} ${yy(C,E)}`):!0}})}var sje,oje,aje,lje,cje,hK,Aje,Eje,LR,Wp,aI,Gu,Yje,Za=Et(()=>{sje=/^[a-zA-Z_][a-zA-Z0-9_]*$/;oje=/^#[0-9a-f]{6}$/i,aje=/^#[0-9a-f]{6}([0-9a-f]{2})?$/i,lje=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,cje=/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}$/i,hK=/^(?:[1-9]\d{3}(-?)(?:(?:0[1-9]|1[0-2])\1(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])\1(?:29|30)|(?:0[13578]|1[02])(?:\1)31|00[1-9]|0[1-9]\d|[12]\d{2}|3(?:[0-5]\d|6[0-5]))|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)(?:(-?)02(?:\2)29|-?366))T(?:[01]\d|2[0-3])(:?)[0-5]\d(?:\3[0-5]\d)?(?:Z|[+-][01]\d(?:\3[0-5]\d)?)$/;Aje=new Map([["true",!0],["True",!0],["1",!0],[1,!0],["false",!1],["False",!1],["0",!1],[0,!1]]);Eje=t=>Hr({test:(e,r)=>e instanceof t?!0:pr(r,`Expected an instance of ${t.name} (got ${jn(e)})`)}),LR=(t,{exclusive:e=!1}={})=>Hr({test:(r,o)=>{var a,n,u;let A=[],p=typeof o?.errors<"u"?[]:void 0;for(let h=0,E=t.length;h<E;++h){let I=typeof o?.errors<"u"?[]:void 0,v=typeof o?.coercions<"u"?[]:void 0;if(t[h](r,Object.assign(Object.assign({},o),{errors:I,coercions:v,p:`${(a=o?.p)!==null&&a!==void 0?a:"."}#${h+1}`}))){if(A.push([`#${h+1}`,v]),!e)break}else p?.push(I[0])}if(A.length===1){let[,h]=A[0];return typeof h<"u"&&((n=o?.coercions)===null||n===void 0||n.push(...h)),!0}return A.length>1?pr(o,`Expected to match exactly a single predicate (matched ${A.join(", ")})`):(u=o?.errors)===null||u===void 0||u.push(...p),!1}});Wp=class extends Error{constructor({errors:e}={}){let r="Type mismatch";if(e&&e.length>0){r+=` +`;for(let o of e)r+=` +- ${o}`}super(r)}};aI={missing:(t,e)=>t.has(e),undefined:(t,e,r)=>t.has(e)&&typeof r[e]<"u",nil:(t,e,r)=>t.has(e)&&r[e]!=null,falsy:(t,e,r)=>t.has(e)&&!!r[e]};(function(t){t.Forbids="Forbids",t.Requires="Requires"})(Gu||(Gu={}));Yje={[Gu.Forbids]:{expect:!1,message:"forbids using"},[Gu.Requires]:{expect:!0,message:"requires using"}}});var nt,Vp=Et(()=>{yf();nt=class{constructor(){this.help=!1}static Usage(e){return e}async catch(e){throw e}async validateAndExecute(){let r=this.constructor.schema;if(Array.isArray(r)){let{isDict:a,isUnknown:n,applyCascade:u}=await Promise.resolve().then(()=>(Za(),Ko)),A=u(a(n()),r),p=[],h=[];if(!A(this,{errors:p,coercions:h}))throw nI("Invalid option schema",p);for(let[,I]of h)I()}else if(r!=null)throw new Error("Invalid command schema");let o=await this.execute();return typeof o<"u"?o:0}};nt.isOption=rI;nt.Default=[]});function va(t){bR&&console.log(t)}function CK(){let t={nodes:[]};for(let e=0;e<cn.CustomNode;++e)t.nodes.push($a());return t}function Wje(t){let e=CK(),r=[],o=e.nodes.length;for(let a of t){r.push(o);for(let n=0;n<a.nodes.length;++n)IK(n)||e.nodes.push(eqe(a.nodes[n],o));o+=a.nodes.length-cn.CustomNode+1}for(let a of r)Cy(e,cn.InitialNode,a);return e}function Mc(t,e){return t.nodes.push(e),t.nodes.length-1}function Vje(t){let e=new Set,r=o=>{if(e.has(o))return;e.add(o);let a=t.nodes[o];for(let u of Object.values(a.statics))for(let{to:A}of u)r(A);for(let[,{to:u}]of a.dynamics)r(u);for(let{to:u}of a.shortcuts)r(u);let n=new Set(a.shortcuts.map(({to:u})=>u));for(;a.shortcuts.length>0;){let{to:u}=a.shortcuts.shift(),A=t.nodes[u];for(let[p,h]of Object.entries(A.statics)){let E=Object.prototype.hasOwnProperty.call(a.statics,p)?a.statics[p]:a.statics[p]=[];for(let I of h)E.some(({to:v})=>I.to===v)||E.push(I)}for(let[p,h]of A.dynamics)a.dynamics.some(([E,{to:I}])=>p===E&&h.to===I)||a.dynamics.push([p,h]);for(let p of A.shortcuts)n.has(p.to)||(a.shortcuts.push(p),n.add(p.to))}};r(cn.InitialNode)}function Kje(t,{prefix:e=""}={}){if(bR){va(`${e}Nodes are:`);for(let r=0;r<t.nodes.length;++r)va(`${e} ${r}: ${JSON.stringify(t.nodes[r])}`)}}function Jje(t,e,r=!1){va(`Running a vm on ${JSON.stringify(e)}`);let o=[{node:cn.InitialNode,state:{candidateUsage:null,requiredOptions:[],errorMessage:null,ignoreOptions:!1,options:[],path:[],positionals:[],remainder:null,selectedIndex:null,partial:!1,tokens:[]}}];Kje(t,{prefix:" "});let a=[Hn.StartOfInput,...e];for(let n=0;n<a.length;++n){let u=a[n],A=u===Hn.EndOfInput||u===Hn.EndOfPartialInput,p=n-1;va(` Processing ${JSON.stringify(u)}`);let h=[];for(let{node:E,state:I}of o){va(` Current node is ${E}`);let v=t.nodes[E];if(E===cn.ErrorNode){h.push({node:E,state:I});continue}console.assert(v.shortcuts.length===0,"Shortcuts should have been eliminated by now");let b=Object.prototype.hasOwnProperty.call(v.statics,u);if(!r||n<a.length-1||b)if(b){let C=v.statics[u];for(let{to:T,reducer:L}of C)h.push({node:T,state:typeof L<"u"?lP(HR,L,I,u,p):I}),va(` Static transition to ${T} found`)}else va(" No static transition found");else{let C=!1;for(let T of Object.keys(v.statics))if(!!T.startsWith(u)){if(u===T)for(let{to:L,reducer:U}of v.statics[T])h.push({node:L,state:typeof U<"u"?lP(HR,U,I,u,p):I}),va(` Static transition to ${L} found`);else for(let{to:L}of v.statics[T])h.push({node:L,state:{...I,remainder:T.slice(u.length)}}),va(` Static transition to ${L} found (partial match)`);C=!0}C||va(" No partial static transition found")}if(!A)for(let[C,{to:T,reducer:L}]of v.dynamics)lP(tqe,C,I,u,p)&&(h.push({node:T,state:typeof L<"u"?lP(HR,L,I,u,p):I}),va(` Dynamic transition to ${T} found (via ${C})`))}if(h.length===0&&A&&e.length===1)return[{node:cn.InitialNode,state:EK}];if(h.length===0)throw new my(e,o.filter(({node:E})=>E!==cn.ErrorNode).map(({state:E})=>({usage:E.candidateUsage,reason:null})));if(h.every(({node:E})=>E===cn.ErrorNode))throw new my(e,h.map(({state:E})=>({usage:E.candidateUsage,reason:E.errorMessage})));o=Xje(h)}if(o.length>0){va(" Results:");for(let n of o)va(` - ${n.node} -> ${JSON.stringify(n.state)}`)}else va(" No results");return o}function zje(t,e,{endToken:r=Hn.EndOfInput}={}){let o=Jje(t,[...e,r]);return Zje(e,o.map(({state:a})=>a))}function Xje(t){let e=0;for(let{state:r}of t)r.path.length>e&&(e=r.path.length);return t.filter(({state:r})=>r.path.length===e)}function Zje(t,e){let r=e.filter(v=>v.selectedIndex!==null),o=r.filter(v=>!v.partial);if(o.length>0&&(r=o),r.length===0)throw new Error;let a=r.filter(v=>v.selectedIndex===td||v.requiredOptions.every(b=>b.some(C=>v.options.find(T=>T.name===C))));if(a.length===0)throw new my(t,r.map(v=>({usage:v.candidateUsage,reason:null})));let n=0;for(let v of a)v.path.length>n&&(n=v.path.length);let u=a.filter(v=>v.path.length===n),A=v=>v.positionals.filter(({extra:b})=>!b).length+v.options.length,p=u.map(v=>({state:v,positionalCount:A(v)})),h=0;for(let{positionalCount:v}of p)v>h&&(h=v);let E=p.filter(({positionalCount:v})=>v===h).map(({state:v})=>v),I=$je(E);if(I.length>1)throw new tP(t,I.map(v=>v.candidateUsage));return I[0]}function $je(t){let e=[],r=[];for(let o of t)o.selectedIndex===td?r.push(o):e.push(o);return r.length>0&&e.push({...EK,path:wK(...r.map(o=>o.path)),options:r.reduce((o,a)=>o.concat(a.options),[])}),e}function wK(t,e,...r){return e===void 0?Array.from(t):wK(t.filter((o,a)=>o===e[a]),...r)}function $a(){return{dynamics:[],shortcuts:[],statics:{}}}function IK(t){return t===cn.SuccessNode||t===cn.ErrorNode}function _R(t,e=0){return{to:IK(t.to)?t.to:t.to>=cn.CustomNode?t.to+e-cn.CustomNode+1:t.to+e,reducer:t.reducer}}function eqe(t,e=0){let r=$a();for(let[o,a]of t.dynamics)r.dynamics.push([o,_R(a,e)]);for(let o of t.shortcuts)r.shortcuts.push(_R(o,e));for(let[o,a]of Object.entries(t.statics))r.statics[o]=a.map(n=>_R(n,e));return r}function Ss(t,e,r,o,a){t.nodes[e].dynamics.push([r,{to:o,reducer:a}])}function Cy(t,e,r,o){t.nodes[e].shortcuts.push({to:r,reducer:o})}function Jo(t,e,r,o,a){(Object.prototype.hasOwnProperty.call(t.nodes[e].statics,r)?t.nodes[e].statics[r]:t.nodes[e].statics[r]=[]).push({to:o,reducer:a})}function lP(t,e,r,o,a){if(Array.isArray(e)){let[n,...u]=e;return t[n](r,o,a,...u)}else return t[e](r,o,a)}var EK,tqe,HR,el,jR,wy,cP=Et(()=>{eP();rP();EK={candidateUsage:null,requiredOptions:[],errorMessage:null,ignoreOptions:!1,path:[],positionals:[],options:[],remainder:null,selectedIndex:td,partial:!1,tokens:[]};tqe={always:()=>!0,isOptionLike:(t,e)=>!t.ignoreOptions&&e!=="-"&&e.startsWith("-"),isNotOptionLike:(t,e)=>t.ignoreOptions||e==="-"||!e.startsWith("-"),isOption:(t,e,r,o)=>!t.ignoreOptions&&e===o,isBatchOption:(t,e,r,o)=>!t.ignoreOptions&&AK.test(e)&&[...e.slice(1)].every(a=>o.has(`-${a}`)),isBoundOption:(t,e,r,o,a)=>{let n=e.match(xR);return!t.ignoreOptions&&!!n&&$D.test(n[1])&&o.has(n[1])&&a.filter(u=>u.nameSet.includes(n[1])).every(u=>u.allowBinding)},isNegatedOption:(t,e,r,o)=>!t.ignoreOptions&&e===`--no-${o.slice(2)}`,isHelp:(t,e)=>!t.ignoreOptions&&SR.test(e),isUnsupportedOption:(t,e,r,o)=>!t.ignoreOptions&&e.startsWith("-")&&$D.test(e)&&!o.has(e),isInvalidOption:(t,e)=>!t.ignoreOptions&&e.startsWith("-")&&!$D.test(e)},HR={setCandidateState:(t,e,r,o)=>({...t,...o}),setSelectedIndex:(t,e,r,o)=>({...t,selectedIndex:o}),setPartialIndex:(t,e,r,o)=>({...t,selectedIndex:o,partial:!0}),pushBatch:(t,e,r,o)=>{let a=t.options.slice(),n=t.tokens.slice();for(let u=1;u<e.length;++u){let A=o.get(`-${e[u]}`),p=u===1?[0,2]:[u,u+1];a.push({name:A,value:!0}),n.push({segmentIndex:r,type:"option",option:A,slice:p})}return{...t,options:a,tokens:n}},pushBound:(t,e,r)=>{let[,o,a]=e.match(xR),n=t.options.concat({name:o,value:a}),u=t.tokens.concat([{segmentIndex:r,type:"option",slice:[0,o.length],option:o},{segmentIndex:r,type:"assign",slice:[o.length,o.length+1]},{segmentIndex:r,type:"value",slice:[o.length+1,o.length+a.length+1]}]);return{...t,options:n,tokens:u}},pushPath:(t,e,r)=>{let o=t.path.concat(e),a=t.tokens.concat({segmentIndex:r,type:"path"});return{...t,path:o,tokens:a}},pushPositional:(t,e,r)=>{let o=t.positionals.concat({value:e,extra:!1}),a=t.tokens.concat({segmentIndex:r,type:"positional"});return{...t,positionals:o,tokens:a}},pushExtra:(t,e,r)=>{let o=t.positionals.concat({value:e,extra:!0}),a=t.tokens.concat({segmentIndex:r,type:"positional"});return{...t,positionals:o,tokens:a}},pushExtraNoLimits:(t,e,r)=>{let o=t.positionals.concat({value:e,extra:el}),a=t.tokens.concat({segmentIndex:r,type:"positional"});return{...t,positionals:o,tokens:a}},pushTrue:(t,e,r,o)=>{let a=t.options.concat({name:o,value:!0}),n=t.tokens.concat({segmentIndex:r,type:"option",option:o});return{...t,options:a,tokens:n}},pushFalse:(t,e,r,o)=>{let a=t.options.concat({name:o,value:!1}),n=t.tokens.concat({segmentIndex:r,type:"option",option:o});return{...t,options:a,tokens:n}},pushUndefined:(t,e,r,o)=>{let a=t.options.concat({name:e,value:void 0}),n=t.tokens.concat({segmentIndex:r,type:"option",option:e});return{...t,options:a,tokens:n}},pushStringValue:(t,e,r)=>{var o;let a=t.options[t.options.length-1],n=t.options.slice(),u=t.tokens.concat({segmentIndex:r,type:"value"});return a.value=((o=a.value)!==null&&o!==void 0?o:[]).concat([e]),{...t,options:n,tokens:u}},setStringValue:(t,e,r)=>{let o=t.options[t.options.length-1],a=t.options.slice(),n=t.tokens.concat({segmentIndex:r,type:"value"});return o.value=e,{...t,options:a,tokens:n}},inhibateOptions:t=>({...t,ignoreOptions:!0}),useHelp:(t,e,r,o)=>{let[,,a]=e.match(SR);return typeof a<"u"?{...t,options:[{name:"-c",value:String(o)},{name:"-i",value:a}]}:{...t,options:[{name:"-c",value:String(o)}]}},setError:(t,e,r,o)=>e===Hn.EndOfInput||e===Hn.EndOfPartialInput?{...t,errorMessage:`${o}.`}:{...t,errorMessage:`${o} ("${e}").`},setOptionArityError:(t,e)=>{let r=t.options[t.options.length-1];return{...t,errorMessage:`Not enough arguments to option ${r.name}.`}}},el=Symbol(),jR=class{constructor(e,r){this.allOptionNames=new Map,this.arity={leading:[],trailing:[],extra:[],proxy:!1},this.options=[],this.paths=[],this.cliIndex=e,this.cliOpts=r}addPath(e){this.paths.push(e)}setArity({leading:e=this.arity.leading,trailing:r=this.arity.trailing,extra:o=this.arity.extra,proxy:a=this.arity.proxy}){Object.assign(this.arity,{leading:e,trailing:r,extra:o,proxy:a})}addPositional({name:e="arg",required:r=!0}={}){if(!r&&this.arity.extra===el)throw new Error("Optional parameters cannot be declared when using .rest() or .proxy()");if(!r&&this.arity.trailing.length>0)throw new Error("Optional parameters cannot be declared after the required trailing positional arguments");!r&&this.arity.extra!==el?this.arity.extra.push(e):this.arity.extra!==el&&this.arity.extra.length===0?this.arity.leading.push(e):this.arity.trailing.push(e)}addRest({name:e="arg",required:r=0}={}){if(this.arity.extra===el)throw new Error("Infinite lists cannot be declared multiple times in the same command");if(this.arity.trailing.length>0)throw new Error("Infinite lists cannot be declared after the required trailing positional arguments");for(let o=0;o<r;++o)this.addPositional({name:e});this.arity.extra=el}addProxy({required:e=0}={}){this.addRest({required:e}),this.arity.proxy=!0}addOption({names:e,description:r,arity:o=0,hidden:a=!1,required:n=!1,allowBinding:u=!0}){if(!u&&o>1)throw new Error("The arity cannot be higher than 1 when the option only supports the --arg=value syntax");if(!Number.isInteger(o))throw new Error(`The arity must be an integer, got ${o}`);if(o<0)throw new Error(`The arity must be positive, got ${o}`);let A=e.reduce((p,h)=>h.length>p.length?h:p,"");for(let p of e)this.allOptionNames.set(p,A);this.options.push({preferredName:A,nameSet:e,description:r,arity:o,hidden:a,required:n,allowBinding:u})}setContext(e){this.context=e}usage({detailed:e=!0,inlineOptions:r=!0}={}){let o=[this.cliOpts.binaryName],a=[];if(this.paths.length>0&&o.push(...this.paths[0]),e){for(let{preferredName:u,nameSet:A,arity:p,hidden:h,description:E,required:I}of this.options){if(h)continue;let v=[];for(let C=0;C<p;++C)v.push(` #${C}`);let b=`${A.join(",")}${v.join("")}`;!r&&E?a.push({preferredName:u,nameSet:A,definition:b,description:E,required:I}):o.push(I?`<${b}>`:`[${b}]`)}o.push(...this.arity.leading.map(u=>`<${u}>`)),this.arity.extra===el?o.push("..."):o.push(...this.arity.extra.map(u=>`[${u}]`)),o.push(...this.arity.trailing.map(u=>`<${u}>`))}return{usage:o.join(" "),options:a}}compile(){if(typeof this.context>"u")throw new Error("Assertion failed: No context attached");let e=CK(),r=cn.InitialNode,o=this.usage().usage,a=this.options.filter(A=>A.required).map(A=>A.nameSet);r=Mc(e,$a()),Jo(e,cn.InitialNode,Hn.StartOfInput,r,["setCandidateState",{candidateUsage:o,requiredOptions:a}]);let n=this.arity.proxy?"always":"isNotOptionLike",u=this.paths.length>0?this.paths:[[]];for(let A of u){let p=r;if(A.length>0){let v=Mc(e,$a());Cy(e,p,v),this.registerOptions(e,v),p=v}for(let v=0;v<A.length;++v){let b=Mc(e,$a());Jo(e,p,A[v],b,"pushPath"),p=b}if(this.arity.leading.length>0||!this.arity.proxy){let v=Mc(e,$a());Ss(e,p,"isHelp",v,["useHelp",this.cliIndex]),Ss(e,v,"always",v,"pushExtra"),Jo(e,v,Hn.EndOfInput,cn.SuccessNode,["setSelectedIndex",td]),this.registerOptions(e,p)}this.arity.leading.length>0&&(Jo(e,p,Hn.EndOfInput,cn.ErrorNode,["setError","Not enough positional arguments"]),Jo(e,p,Hn.EndOfPartialInput,cn.SuccessNode,["setPartialIndex",this.cliIndex]));let h=p;for(let v=0;v<this.arity.leading.length;++v){let b=Mc(e,$a());(!this.arity.proxy||v+1!==this.arity.leading.length)&&this.registerOptions(e,b),(this.arity.trailing.length>0||v+1!==this.arity.leading.length)&&(Jo(e,b,Hn.EndOfInput,cn.ErrorNode,["setError","Not enough positional arguments"]),Jo(e,b,Hn.EndOfPartialInput,cn.SuccessNode,["setPartialIndex",this.cliIndex])),Ss(e,h,"isNotOptionLike",b,"pushPositional"),h=b}let E=h;if(this.arity.extra===el||this.arity.extra.length>0){let v=Mc(e,$a());if(Cy(e,h,v),this.arity.extra===el){let b=Mc(e,$a());this.arity.proxy||this.registerOptions(e,b),Ss(e,h,n,b,"pushExtraNoLimits"),Ss(e,b,n,b,"pushExtraNoLimits"),Cy(e,b,v)}else for(let b=0;b<this.arity.extra.length;++b){let C=Mc(e,$a());(!this.arity.proxy||b>0)&&this.registerOptions(e,C),Ss(e,E,n,C,"pushExtra"),Cy(e,C,v),E=C}E=v}this.arity.trailing.length>0&&(Jo(e,E,Hn.EndOfInput,cn.ErrorNode,["setError","Not enough positional arguments"]),Jo(e,E,Hn.EndOfPartialInput,cn.SuccessNode,["setPartialIndex",this.cliIndex]));let I=E;for(let v=0;v<this.arity.trailing.length;++v){let b=Mc(e,$a());this.arity.proxy||this.registerOptions(e,b),v+1<this.arity.trailing.length&&(Jo(e,b,Hn.EndOfInput,cn.ErrorNode,["setError","Not enough positional arguments"]),Jo(e,b,Hn.EndOfPartialInput,cn.SuccessNode,["setPartialIndex",this.cliIndex])),Ss(e,I,"isNotOptionLike",b,"pushPositional"),I=b}Ss(e,I,n,cn.ErrorNode,["setError","Extraneous positional argument"]),Jo(e,I,Hn.EndOfInput,cn.SuccessNode,["setSelectedIndex",this.cliIndex]),Jo(e,I,Hn.EndOfPartialInput,cn.SuccessNode,["setSelectedIndex",this.cliIndex])}return{machine:e,context:this.context}}registerOptions(e,r){Ss(e,r,["isOption","--"],r,"inhibateOptions"),Ss(e,r,["isBatchOption",this.allOptionNames],r,["pushBatch",this.allOptionNames]),Ss(e,r,["isBoundOption",this.allOptionNames,this.options],r,"pushBound"),Ss(e,r,["isUnsupportedOption",this.allOptionNames],cn.ErrorNode,["setError","Unsupported option name"]),Ss(e,r,["isInvalidOption"],cn.ErrorNode,["setError","Invalid option name"]);for(let o of this.options)if(o.arity===0)for(let a of o.nameSet)Ss(e,r,["isOption",a],r,["pushTrue",o.preferredName]),a.startsWith("--")&&!a.startsWith("--no-")&&Ss(e,r,["isNegatedOption",a],r,["pushFalse",o.preferredName]);else{let a=Mc(e,$a());for(let n of o.nameSet)Ss(e,r,["isOption",n],a,["pushUndefined",o.preferredName]);for(let n=0;n<o.arity;++n){let u=Mc(e,$a());Jo(e,a,Hn.EndOfInput,cn.ErrorNode,"setOptionArityError"),Jo(e,a,Hn.EndOfPartialInput,cn.ErrorNode,"setOptionArityError"),Ss(e,a,"isOptionLike",cn.ErrorNode,"setOptionArityError");let A=o.arity===1?"setStringValue":"pushStringValue";Ss(e,a,"isNotOptionLike",u,A),a=u}Cy(e,a,r)}}},wy=class{constructor({binaryName:e="..."}={}){this.builders=[],this.opts={binaryName:e}}static build(e,r={}){return new wy(r).commands(e).compile()}getBuilderByIndex(e){if(!(e>=0&&e<this.builders.length))throw new Error(`Assertion failed: Out-of-bound command index (${e})`);return this.builders[e]}commands(e){for(let r of e)r(this.command());return this}command(){let e=new jR(this.builders.length,this.opts);return this.builders.push(e),e}compile(){let e=[],r=[];for(let a of this.builders){let{machine:n,context:u}=a.compile();e.push(n),r.push(u)}let o=Wje(e);return Vje(o),{machine:o,contexts:r,process:(a,{partial:n}={})=>{let u=n?Hn.EndOfPartialInput:Hn.EndOfInput;return zje(o,a,{endToken:u})}}}}});function vK(){return uP.default&&"getColorDepth"in uP.default.WriteStream.prototype?uP.default.WriteStream.prototype.getColorDepth():process.env.FORCE_COLOR==="0"?1:process.env.FORCE_COLOR==="1"||typeof process.stdout<"u"&&process.stdout.isTTY?8:1}function DK(t){let e=BK;if(typeof e>"u"){if(t.stdout===process.stdout&&t.stderr===process.stderr)return null;let{AsyncLocalStorage:r}=Be("async_hooks");e=BK=new r;let o=process.stdout._write;process.stdout._write=function(n,u,A){let p=e.getStore();return typeof p>"u"?o.call(this,n,u,A):p.stdout.write(n,u,A)};let a=process.stderr._write;process.stderr._write=function(n,u,A){let p=e.getStore();return typeof p>"u"?a.call(this,n,u,A):p.stderr.write(n,u,A)}}return r=>e.run(t,r)}var uP,BK,PK=Et(()=>{uP=$e(Be("tty"),1)});var Iy,SK=Et(()=>{Vp();Iy=class extends nt{constructor(e){super(),this.contexts=e,this.commands=[]}static from(e,r){let o=new Iy(r);o.path=e.path;for(let a of e.options)switch(a.name){case"-c":o.commands.push(Number(a.value));break;case"-i":o.index=Number(a.value);break}return o}async execute(){let e=this.commands;if(typeof this.index<"u"&&this.index>=0&&this.index<e.length&&(e=[e[this.index]]),e.length===0)this.context.stdout.write(this.cli.usage());else if(e.length===1)this.context.stdout.write(this.cli.usage(this.contexts[e[0]].commandClass,{detailed:!0}));else if(e.length>1){this.context.stdout.write(`Multiple commands match your selection: +`),this.context.stdout.write(` +`);let r=0;for(let o of this.commands)this.context.stdout.write(this.cli.usage(this.contexts[o].commandClass,{prefix:`${r++}. `.padStart(5)}));this.context.stdout.write(` +`),this.context.stdout.write(`Run again with -h=<index> to see the longer details of any of those commands. +`)}}}});async function kK(...t){let{resolvedOptions:e,resolvedCommandClasses:r,resolvedArgv:o,resolvedContext:a}=FK(t);return as.from(r,e).runExit(o,a)}async function QK(...t){let{resolvedOptions:e,resolvedCommandClasses:r,resolvedArgv:o,resolvedContext:a}=FK(t);return as.from(r,e).run(o,a)}function FK(t){let e,r,o,a;switch(typeof process<"u"&&typeof process.argv<"u"&&(o=process.argv.slice(2)),t.length){case 1:r=t[0];break;case 2:t[0]&&t[0].prototype instanceof nt||Array.isArray(t[0])?(r=t[0],Array.isArray(t[1])?o=t[1]:a=t[1]):(e=t[0],r=t[1]);break;case 3:Array.isArray(t[2])?(e=t[0],r=t[1],o=t[2]):t[0]&&t[0].prototype instanceof nt||Array.isArray(t[0])?(r=t[0],o=t[1],a=t[2]):(e=t[0],r=t[1],a=t[2]);break;default:e=t[0],r=t[1],o=t[2],a=t[3];break}if(typeof o>"u")throw new Error("The argv parameter must be provided when running Clipanion outside of a Node context");return{resolvedOptions:e,resolvedCommandClasses:r,resolvedArgv:o,resolvedContext:a}}function bK(t){return t()}var xK,as,TK=Et(()=>{eP();cP();FR();PK();Vp();SK();xK=Symbol("clipanion/errorCommand");as=class{constructor({binaryLabel:e,binaryName:r="...",binaryVersion:o,enableCapture:a=!1,enableColors:n}={}){this.registrations=new Map,this.builder=new wy({binaryName:r}),this.binaryLabel=e,this.binaryName=r,this.binaryVersion=o,this.enableCapture=a,this.enableColors=n}static from(e,r={}){let o=new as(r),a=Array.isArray(e)?e:[e];for(let n of a)o.register(n);return o}register(e){var r;let o=new Map,a=new e;for(let p in a){let h=a[p];typeof h=="object"&&h!==null&&h[nt.isOption]&&o.set(p,h)}let n=this.builder.command(),u=n.cliIndex,A=(r=e.paths)!==null&&r!==void 0?r:a.paths;if(typeof A<"u")for(let p of A)n.addPath(p);this.registrations.set(e,{specs:o,builder:n,index:u});for(let[p,{definition:h}]of o.entries())h(n,p);n.setContext({commandClass:e})}process(e,r){let{input:o,context:a,partial:n}=typeof e=="object"&&Array.isArray(e)?{input:e,context:r}:e,{contexts:u,process:A}=this.builder.compile(),p=A(o,{partial:n}),h={...as.defaultContext,...a};switch(p.selectedIndex){case td:{let E=Iy.from(p,u);return E.context=h,E.tokens=p.tokens,E}default:{let{commandClass:E}=u[p.selectedIndex],I=this.registrations.get(E);if(typeof I>"u")throw new Error("Assertion failed: Expected the command class to have been registered.");let v=new E;v.context=h,v.tokens=p.tokens,v.path=p.path;try{for(let[b,{transformer:C}]of I.specs.entries())v[b]=C(I.builder,b,p,h);return v}catch(b){throw b[xK]=v,b}}break}}async run(e,r){var o,a;let n,u={...as.defaultContext,...r},A=(o=this.enableColors)!==null&&o!==void 0?o:u.colorDepth>1;if(!Array.isArray(e))n=e;else try{n=this.process(e,u)}catch(E){return u.stdout.write(this.error(E,{colored:A})),1}if(n.help)return u.stdout.write(this.usage(n,{colored:A,detailed:!0})),0;n.context=u,n.cli={binaryLabel:this.binaryLabel,binaryName:this.binaryName,binaryVersion:this.binaryVersion,enableCapture:this.enableCapture,enableColors:this.enableColors,definitions:()=>this.definitions(),definition:E=>this.definition(E),error:(E,I)=>this.error(E,I),format:E=>this.format(E),process:(E,I)=>this.process(E,{...u,...I}),run:(E,I)=>this.run(E,{...u,...I}),usage:(E,I)=>this.usage(E,I)};let p=this.enableCapture&&(a=DK(u))!==null&&a!==void 0?a:bK,h;try{h=await p(()=>n.validateAndExecute().catch(E=>n.catch(E).then(()=>0)))}catch(E){return u.stdout.write(this.error(E,{colored:A,command:n})),1}return h}async runExit(e,r){process.exitCode=await this.run(e,r)}definition(e,{colored:r=!1}={}){if(!e.usage)return null;let{usage:o}=this.getUsageByRegistration(e,{detailed:!1}),{usage:a,options:n}=this.getUsageByRegistration(e,{detailed:!0,inlineOptions:!1}),u=typeof e.usage.category<"u"?Do(e.usage.category,{format:this.format(r),paragraphs:!1}):void 0,A=typeof e.usage.description<"u"?Do(e.usage.description,{format:this.format(r),paragraphs:!1}):void 0,p=typeof e.usage.details<"u"?Do(e.usage.details,{format:this.format(r),paragraphs:!0}):void 0,h=typeof e.usage.examples<"u"?e.usage.examples.map(([E,I])=>[Do(E,{format:this.format(r),paragraphs:!1}),I.replace(/\$0/g,this.binaryName)]):void 0;return{path:o,usage:a,category:u,description:A,details:p,examples:h,options:n}}definitions({colored:e=!1}={}){let r=[];for(let o of this.registrations.keys()){let a=this.definition(o,{colored:e});!a||r.push(a)}return r}usage(e=null,{colored:r,detailed:o=!1,prefix:a="$ "}={}){var n;if(e===null){for(let p of this.registrations.keys()){let h=p.paths,E=typeof p.usage<"u";if(!h||h.length===0||h.length===1&&h[0].length===0||((n=h?.some(b=>b.length===0))!==null&&n!==void 0?n:!1))if(e){e=null;break}else e=p;else if(E){e=null;continue}}e&&(o=!0)}let u=e!==null&&e instanceof nt?e.constructor:e,A="";if(u)if(o){let{description:p="",details:h="",examples:E=[]}=u.usage||{};p!==""&&(A+=Do(p,{format:this.format(r),paragraphs:!1}).replace(/^./,b=>b.toUpperCase()),A+=` +`),(h!==""||E.length>0)&&(A+=`${this.format(r).header("Usage")} +`,A+=` +`);let{usage:I,options:v}=this.getUsageByRegistration(u,{inlineOptions:!1});if(A+=`${this.format(r).bold(a)}${I} +`,v.length>0){A+=` +`,A+=`${this.format(r).header("Options")} +`;let b=v.reduce((C,T)=>Math.max(C,T.definition.length),0);A+=` +`;for(let{definition:C,description:T}of v)A+=` ${this.format(r).bold(C.padEnd(b))} ${Do(T,{format:this.format(r),paragraphs:!1})}`}if(h!==""&&(A+=` +`,A+=`${this.format(r).header("Details")} +`,A+=` +`,A+=Do(h,{format:this.format(r),paragraphs:!0})),E.length>0){A+=` +`,A+=`${this.format(r).header("Examples")} +`;for(let[b,C]of E)A+=` +`,A+=Do(b,{format:this.format(r),paragraphs:!1}),A+=`${C.replace(/^/m,` ${this.format(r).bold(a)}`).replace(/\$0/g,this.binaryName)} +`}}else{let{usage:p}=this.getUsageByRegistration(u);A+=`${this.format(r).bold(a)}${p} +`}else{let p=new Map;for(let[v,{index:b}]of this.registrations.entries()){if(typeof v.usage>"u")continue;let C=typeof v.usage.category<"u"?Do(v.usage.category,{format:this.format(r),paragraphs:!1}):null,T=p.get(C);typeof T>"u"&&p.set(C,T=[]);let{usage:L}=this.getUsageByIndex(b);T.push({commandClass:v,usage:L})}let h=Array.from(p.keys()).sort((v,b)=>v===null?-1:b===null?1:v.localeCompare(b,"en",{usage:"sort",caseFirst:"upper"})),E=typeof this.binaryLabel<"u",I=typeof this.binaryVersion<"u";E||I?(E&&I?A+=`${this.format(r).header(`${this.binaryLabel} - ${this.binaryVersion}`)} + +`:E?A+=`${this.format(r).header(`${this.binaryLabel}`)} +`:A+=`${this.format(r).header(`${this.binaryVersion}`)} +`,A+=` ${this.format(r).bold(a)}${this.binaryName} <command> +`):A+=`${this.format(r).bold(a)}${this.binaryName} <command> +`;for(let v of h){let b=p.get(v).slice().sort((T,L)=>T.usage.localeCompare(L.usage,"en",{usage:"sort",caseFirst:"upper"})),C=v!==null?v.trim():"General commands";A+=` +`,A+=`${this.format(r).header(`${C}`)} +`;for(let{commandClass:T,usage:L}of b){let U=T.usage.description||"undocumented";A+=` +`,A+=` ${this.format(r).bold(L)} +`,A+=` ${Do(U,{format:this.format(r),paragraphs:!1})}`}}A+=` +`,A+=Do("You can also print more details about any of these commands by calling them with the `-h,--help` flag right after the command name.",{format:this.format(r),paragraphs:!0})}return A}error(e,r){var o,{colored:a,command:n=(o=e[xK])!==null&&o!==void 0?o:null}=r===void 0?{}:r;(!e||typeof e!="object"||!("stack"in e))&&(e=new Error(`Execution failed with a non-error rejection (rejected value: ${JSON.stringify(e)})`));let u="",A=e.name.replace(/([a-z])([A-Z])/g,"$1 $2");A==="Error"&&(A="Internal Error"),u+=`${this.format(a).error(A)}: ${e.message} +`;let p=e.clipanion;return typeof p<"u"?p.type==="usage"&&(u+=` +`,u+=this.usage(n)):e.stack&&(u+=`${e.stack.replace(/^.*\n/,"")} +`),u}format(e){var r;return((r=e??this.enableColors)!==null&&r!==void 0?r:as.defaultContext.colorDepth>1)?fK:pK}getUsageByRegistration(e,r){let o=this.registrations.get(e);if(typeof o>"u")throw new Error("Assertion failed: Unregistered command");return this.getUsageByIndex(o.index,r)}getUsageByIndex(e,r){return this.builder.getBuilderByIndex(e).usage(r)}};as.defaultContext={env:process.env,stdin:process.stdin,stdout:process.stdout,stderr:process.stderr,colorDepth:vK()}});var cI,RK=Et(()=>{Vp();cI=class extends nt{async execute(){this.context.stdout.write(`${JSON.stringify(this.cli.definitions(),null,2)} +`)}};cI.paths=[["--clipanion=definitions"]]});var uI,NK=Et(()=>{Vp();uI=class extends nt{async execute(){this.context.stdout.write(this.cli.usage())}};uI.paths=[["-h"],["--help"]]});function AP(t={}){return Vo({definition(e,r){var o;e.addProxy({name:(o=t.name)!==null&&o!==void 0?o:r,required:t.required})},transformer(e,r,o){return o.positionals.map(({value:a})=>a)}})}var qR=Et(()=>{yf()});var AI,LK=Et(()=>{Vp();qR();AI=class extends nt{constructor(){super(...arguments),this.args=AP()}async execute(){this.context.stdout.write(`${JSON.stringify(this.cli.process(this.args).tokens,null,2)} +`)}};AI.paths=[["--clipanion=tokens"]]});var fI,MK=Et(()=>{Vp();fI=class extends nt{async execute(){var e;this.context.stdout.write(`${(e=this.cli.binaryVersion)!==null&&e!==void 0?e:"<unknown>"} +`)}};fI.paths=[["-v"],["--version"]]});var GR={};Kt(GR,{DefinitionsCommand:()=>cI,HelpCommand:()=>uI,TokensCommand:()=>AI,VersionCommand:()=>fI});var OK=Et(()=>{RK();NK();LK();MK()});function UK(t,e,r){let[o,a]=qu(e,r??{}),{arity:n=1}=a,u=t.split(","),A=new Set(u);return Vo({definition(p){p.addOption({names:u,arity:n,hidden:a?.hidden,description:a?.description,required:a.required})},transformer(p,h,E){let I,v=typeof o<"u"?[...o]:void 0;for(let{name:b,value:C}of E.options)!A.has(b)||(I=b,v=v??[],v.push(C));return typeof v<"u"?rd(I??h,v,a.validator):v}})}var _K=Et(()=>{yf()});function HK(t,e,r){let[o,a]=qu(e,r??{}),n=t.split(","),u=new Set(n);return Vo({definition(A){A.addOption({names:n,allowBinding:!1,arity:0,hidden:a.hidden,description:a.description,required:a.required})},transformer(A,p,h){let E=o;for(let{name:I,value:v}of h.options)!u.has(I)||(E=v);return E}})}var jK=Et(()=>{yf()});function qK(t,e,r){let[o,a]=qu(e,r??{}),n=t.split(","),u=new Set(n);return Vo({definition(A){A.addOption({names:n,allowBinding:!1,arity:0,hidden:a.hidden,description:a.description,required:a.required})},transformer(A,p,h){let E=o;for(let{name:I,value:v}of h.options)!u.has(I)||(E??(E=0),v?E+=1:E=0);return E}})}var GK=Et(()=>{yf()});function YK(t={}){return Vo({definition(e,r){var o;e.addRest({name:(o=t.name)!==null&&o!==void 0?o:r,required:t.required})},transformer(e,r,o){let a=u=>{let A=o.positionals[u];return A.extra===el||A.extra===!1&&u<e.arity.leading.length},n=0;for(;n<o.positionals.length&&a(n);)n+=1;return o.positionals.splice(0,n).map(({value:u})=>u)}})}var WK=Et(()=>{cP();yf()});function rqe(t,e,r){let[o,a]=qu(e,r??{}),{arity:n=1}=a,u=t.split(","),A=new Set(u);return Vo({definition(p){p.addOption({names:u,arity:a.tolerateBoolean?0:n,hidden:a.hidden,description:a.description,required:a.required})},transformer(p,h,E,I){let v,b=o;typeof a.env<"u"&&I.env[a.env]&&(v=a.env,b=I.env[a.env]);for(let{name:C,value:T}of E.options)!A.has(C)||(v=C,b=T);return typeof b=="string"?rd(v??h,b,a.validator):b}})}function nqe(t={}){let{required:e=!0}=t;return Vo({definition(r,o){var a;r.addPositional({name:(a=t.name)!==null&&a!==void 0?a:o,required:t.required})},transformer(r,o,a){var n;for(let u=0;u<a.positionals.length;++u){if(a.positionals[u].extra===el||e&&a.positionals[u].extra===!0||!e&&a.positionals[u].extra===!1)continue;let[A]=a.positionals.splice(u,1);return rd((n=t.name)!==null&&n!==void 0?n:o,A.value,t.validator)}}})}function VK(t,...e){return typeof t=="string"?rqe(t,...e):nqe(t)}var KK=Et(()=>{cP();yf()});var ge={};Kt(ge,{Array:()=>UK,Boolean:()=>HK,Counter:()=>qK,Proxy:()=>AP,Rest:()=>YK,String:()=>VK,applyValidator:()=>rd,cleanValidationError:()=>nP,formatError:()=>nI,isOptionSymbol:()=>rI,makeCommandOption:()=>Vo,rerouteArguments:()=>qu});var JK=Et(()=>{yf();qR();_K();jK();GK();WK();KK()});var pI={};Kt(pI,{Builtins:()=>GR,Cli:()=>as,Command:()=>nt,Option:()=>ge,UsageError:()=>it,formatMarkdownish:()=>Do,run:()=>QK,runExit:()=>kK});var qt=Et(()=>{rP();FR();Vp();TK();OK();JK()});var zK=_((xkt,iqe)=>{iqe.exports={name:"dotenv",version:"16.3.1",description:"Loads environment variables from .env file",main:"lib/main.js",types:"lib/main.d.ts",exports:{".":{types:"./lib/main.d.ts",require:"./lib/main.js",default:"./lib/main.js"},"./config":"./config.js","./config.js":"./config.js","./lib/env-options":"./lib/env-options.js","./lib/env-options.js":"./lib/env-options.js","./lib/cli-options":"./lib/cli-options.js","./lib/cli-options.js":"./lib/cli-options.js","./package.json":"./package.json"},scripts:{"dts-check":"tsc --project tests/types/tsconfig.json",lint:"standard","lint-readme":"standard-markdown",pretest:"npm run lint && npm run dts-check",test:"tap tests/*.js --100 -Rspec",prerelease:"npm test",release:"standard-version"},repository:{type:"git",url:"git://github.com/motdotla/dotenv.git"},funding:"https://github.com/motdotla/dotenv?sponsor=1",keywords:["dotenv","env",".env","environment","variables","config","settings"],readmeFilename:"README.md",license:"BSD-2-Clause",devDependencies:{"@definitelytyped/dtslint":"^0.0.133","@types/node":"^18.11.3",decache:"^4.6.1",sinon:"^14.0.1",standard:"^17.0.0","standard-markdown":"^7.1.0","standard-version":"^9.5.0",tap:"^16.3.0",tar:"^6.1.11",typescript:"^4.8.4"},engines:{node:">=12"},browser:{fs:!1}}});var eJ=_((bkt,Ef)=>{var XK=Be("fs"),WR=Be("path"),sqe=Be("os"),oqe=Be("crypto"),aqe=zK(),VR=aqe.version,lqe=/(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;function cqe(t){let e={},r=t.toString();r=r.replace(/\r\n?/mg,` +`);let o;for(;(o=lqe.exec(r))!=null;){let a=o[1],n=o[2]||"";n=n.trim();let u=n[0];n=n.replace(/^(['"`])([\s\S]*)\1$/mg,"$2"),u==='"'&&(n=n.replace(/\\n/g,` +`),n=n.replace(/\\r/g,"\r")),e[a]=n}return e}function uqe(t){let e=$K(t),r=xs.configDotenv({path:e});if(!r.parsed)throw new Error(`MISSING_DATA: Cannot parse ${e} for an unknown reason`);let o=ZK(t).split(","),a=o.length,n;for(let u=0;u<a;u++)try{let A=o[u].trim(),p=pqe(r,A);n=xs.decrypt(p.ciphertext,p.key);break}catch(A){if(u+1>=a)throw A}return xs.parse(n)}function Aqe(t){console.log(`[dotenv@${VR}][INFO] ${t}`)}function fqe(t){console.log(`[dotenv@${VR}][WARN] ${t}`)}function YR(t){console.log(`[dotenv@${VR}][DEBUG] ${t}`)}function ZK(t){return t&&t.DOTENV_KEY&&t.DOTENV_KEY.length>0?t.DOTENV_KEY:process.env.DOTENV_KEY&&process.env.DOTENV_KEY.length>0?process.env.DOTENV_KEY:""}function pqe(t,e){let r;try{r=new URL(e)}catch(A){throw A.code==="ERR_INVALID_URL"?new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenv.org/vault/.env.vault?environment=development"):A}let o=r.password;if(!o)throw new Error("INVALID_DOTENV_KEY: Missing key part");let a=r.searchParams.get("environment");if(!a)throw new Error("INVALID_DOTENV_KEY: Missing environment part");let n=`DOTENV_VAULT_${a.toUpperCase()}`,u=t.parsed[n];if(!u)throw new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${n} in your .env.vault file.`);return{ciphertext:u,key:o}}function $K(t){let e=WR.resolve(process.cwd(),".env");return t&&t.path&&t.path.length>0&&(e=t.path),e.endsWith(".vault")?e:`${e}.vault`}function hqe(t){return t[0]==="~"?WR.join(sqe.homedir(),t.slice(1)):t}function gqe(t){Aqe("Loading env from encrypted .env.vault");let e=xs._parseVault(t),r=process.env;return t&&t.processEnv!=null&&(r=t.processEnv),xs.populate(r,e,t),{parsed:e}}function dqe(t){let e=WR.resolve(process.cwd(),".env"),r="utf8",o=Boolean(t&&t.debug);t&&(t.path!=null&&(e=hqe(t.path)),t.encoding!=null&&(r=t.encoding));try{let a=xs.parse(XK.readFileSync(e,{encoding:r})),n=process.env;return t&&t.processEnv!=null&&(n=t.processEnv),xs.populate(n,a,t),{parsed:a}}catch(a){return o&&YR(`Failed to load ${e} ${a.message}`),{error:a}}}function mqe(t){let e=$K(t);return ZK(t).length===0?xs.configDotenv(t):XK.existsSync(e)?xs._configVault(t):(fqe(`You set DOTENV_KEY but you are missing a .env.vault file at ${e}. Did you forget to build it?`),xs.configDotenv(t))}function yqe(t,e){let r=Buffer.from(e.slice(-64),"hex"),o=Buffer.from(t,"base64"),a=o.slice(0,12),n=o.slice(-16);o=o.slice(12,-16);try{let u=oqe.createDecipheriv("aes-256-gcm",r,a);return u.setAuthTag(n),`${u.update(o)}${u.final()}`}catch(u){let A=u instanceof RangeError,p=u.message==="Invalid key length",h=u.message==="Unsupported state or unable to authenticate data";if(A||p){let E="INVALID_DOTENV_KEY: It must be 64 characters long (or more)";throw new Error(E)}else if(h){let E="DECRYPTION_FAILED: Please check your DOTENV_KEY";throw new Error(E)}else throw console.error("Error: ",u.code),console.error("Error: ",u.message),u}}function Eqe(t,e,r={}){let o=Boolean(r&&r.debug),a=Boolean(r&&r.override);if(typeof e!="object")throw new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");for(let n of Object.keys(e))Object.prototype.hasOwnProperty.call(t,n)?(a===!0&&(t[n]=e[n]),o&&YR(a===!0?`"${n}" is already defined and WAS overwritten`:`"${n}" is already defined and was NOT overwritten`)):t[n]=e[n]}var xs={configDotenv:dqe,_configVault:gqe,_parseVault:uqe,config:mqe,decrypt:yqe,parse:cqe,populate:Eqe};Ef.exports.configDotenv=xs.configDotenv;Ef.exports._configVault=xs._configVault;Ef.exports._parseVault=xs._parseVault;Ef.exports.config=xs.config;Ef.exports.decrypt=xs.decrypt;Ef.exports.parse=xs.parse;Ef.exports.populate=xs.populate;Ef.exports=xs});var rJ=_((kkt,tJ)=>{"use strict";tJ.exports=(t,...e)=>new Promise(r=>{r(t(...e))})});var nd=_((Qkt,KR)=>{"use strict";var Cqe=rJ(),nJ=t=>{if(t<1)throw new TypeError("Expected `concurrency` to be a number from 1 and up");let e=[],r=0,o=()=>{r--,e.length>0&&e.shift()()},a=(A,p,...h)=>{r++;let E=Cqe(A,...h);p(E),E.then(o,o)},n=(A,p,...h)=>{r<t?a(A,p,...h):e.push(a.bind(null,A,p,...h))},u=(A,...p)=>new Promise(h=>n(A,h,...p));return Object.defineProperties(u,{activeCount:{get:()=>r},pendingCount:{get:()=>e.length}}),u};KR.exports=nJ;KR.exports.default=nJ});function Wu(t){return`YN${t.toString(10).padStart(4,"0")}`}function fP(t){let e=Number(t.slice(2));if(typeof wr[e]>"u")throw new Error(`Unknown message name: "${t}"`);return e}var wr,pP=Et(()=>{wr=(Me=>(Me[Me.UNNAMED=0]="UNNAMED",Me[Me.EXCEPTION=1]="EXCEPTION",Me[Me.MISSING_PEER_DEPENDENCY=2]="MISSING_PEER_DEPENDENCY",Me[Me.CYCLIC_DEPENDENCIES=3]="CYCLIC_DEPENDENCIES",Me[Me.DISABLED_BUILD_SCRIPTS=4]="DISABLED_BUILD_SCRIPTS",Me[Me.BUILD_DISABLED=5]="BUILD_DISABLED",Me[Me.SOFT_LINK_BUILD=6]="SOFT_LINK_BUILD",Me[Me.MUST_BUILD=7]="MUST_BUILD",Me[Me.MUST_REBUILD=8]="MUST_REBUILD",Me[Me.BUILD_FAILED=9]="BUILD_FAILED",Me[Me.RESOLVER_NOT_FOUND=10]="RESOLVER_NOT_FOUND",Me[Me.FETCHER_NOT_FOUND=11]="FETCHER_NOT_FOUND",Me[Me.LINKER_NOT_FOUND=12]="LINKER_NOT_FOUND",Me[Me.FETCH_NOT_CACHED=13]="FETCH_NOT_CACHED",Me[Me.YARN_IMPORT_FAILED=14]="YARN_IMPORT_FAILED",Me[Me.REMOTE_INVALID=15]="REMOTE_INVALID",Me[Me.REMOTE_NOT_FOUND=16]="REMOTE_NOT_FOUND",Me[Me.RESOLUTION_PACK=17]="RESOLUTION_PACK",Me[Me.CACHE_CHECKSUM_MISMATCH=18]="CACHE_CHECKSUM_MISMATCH",Me[Me.UNUSED_CACHE_ENTRY=19]="UNUSED_CACHE_ENTRY",Me[Me.MISSING_LOCKFILE_ENTRY=20]="MISSING_LOCKFILE_ENTRY",Me[Me.WORKSPACE_NOT_FOUND=21]="WORKSPACE_NOT_FOUND",Me[Me.TOO_MANY_MATCHING_WORKSPACES=22]="TOO_MANY_MATCHING_WORKSPACES",Me[Me.CONSTRAINTS_MISSING_DEPENDENCY=23]="CONSTRAINTS_MISSING_DEPENDENCY",Me[Me.CONSTRAINTS_INCOMPATIBLE_DEPENDENCY=24]="CONSTRAINTS_INCOMPATIBLE_DEPENDENCY",Me[Me.CONSTRAINTS_EXTRANEOUS_DEPENDENCY=25]="CONSTRAINTS_EXTRANEOUS_DEPENDENCY",Me[Me.CONSTRAINTS_INVALID_DEPENDENCY=26]="CONSTRAINTS_INVALID_DEPENDENCY",Me[Me.CANT_SUGGEST_RESOLUTIONS=27]="CANT_SUGGEST_RESOLUTIONS",Me[Me.FROZEN_LOCKFILE_EXCEPTION=28]="FROZEN_LOCKFILE_EXCEPTION",Me[Me.CROSS_DRIVE_VIRTUAL_LOCAL=29]="CROSS_DRIVE_VIRTUAL_LOCAL",Me[Me.FETCH_FAILED=30]="FETCH_FAILED",Me[Me.DANGEROUS_NODE_MODULES=31]="DANGEROUS_NODE_MODULES",Me[Me.NODE_GYP_INJECTED=32]="NODE_GYP_INJECTED",Me[Me.AUTHENTICATION_NOT_FOUND=33]="AUTHENTICATION_NOT_FOUND",Me[Me.INVALID_CONFIGURATION_KEY=34]="INVALID_CONFIGURATION_KEY",Me[Me.NETWORK_ERROR=35]="NETWORK_ERROR",Me[Me.LIFECYCLE_SCRIPT=36]="LIFECYCLE_SCRIPT",Me[Me.CONSTRAINTS_MISSING_FIELD=37]="CONSTRAINTS_MISSING_FIELD",Me[Me.CONSTRAINTS_INCOMPATIBLE_FIELD=38]="CONSTRAINTS_INCOMPATIBLE_FIELD",Me[Me.CONSTRAINTS_EXTRANEOUS_FIELD=39]="CONSTRAINTS_EXTRANEOUS_FIELD",Me[Me.CONSTRAINTS_INVALID_FIELD=40]="CONSTRAINTS_INVALID_FIELD",Me[Me.AUTHENTICATION_INVALID=41]="AUTHENTICATION_INVALID",Me[Me.PROLOG_UNKNOWN_ERROR=42]="PROLOG_UNKNOWN_ERROR",Me[Me.PROLOG_SYNTAX_ERROR=43]="PROLOG_SYNTAX_ERROR",Me[Me.PROLOG_EXISTENCE_ERROR=44]="PROLOG_EXISTENCE_ERROR",Me[Me.STACK_OVERFLOW_RESOLUTION=45]="STACK_OVERFLOW_RESOLUTION",Me[Me.AUTOMERGE_FAILED_TO_PARSE=46]="AUTOMERGE_FAILED_TO_PARSE",Me[Me.AUTOMERGE_IMMUTABLE=47]="AUTOMERGE_IMMUTABLE",Me[Me.AUTOMERGE_SUCCESS=48]="AUTOMERGE_SUCCESS",Me[Me.AUTOMERGE_REQUIRED=49]="AUTOMERGE_REQUIRED",Me[Me.DEPRECATED_CLI_SETTINGS=50]="DEPRECATED_CLI_SETTINGS",Me[Me.PLUGIN_NAME_NOT_FOUND=51]="PLUGIN_NAME_NOT_FOUND",Me[Me.INVALID_PLUGIN_REFERENCE=52]="INVALID_PLUGIN_REFERENCE",Me[Me.CONSTRAINTS_AMBIGUITY=53]="CONSTRAINTS_AMBIGUITY",Me[Me.CACHE_OUTSIDE_PROJECT=54]="CACHE_OUTSIDE_PROJECT",Me[Me.IMMUTABLE_INSTALL=55]="IMMUTABLE_INSTALL",Me[Me.IMMUTABLE_CACHE=56]="IMMUTABLE_CACHE",Me[Me.INVALID_MANIFEST=57]="INVALID_MANIFEST",Me[Me.PACKAGE_PREPARATION_FAILED=58]="PACKAGE_PREPARATION_FAILED",Me[Me.INVALID_RANGE_PEER_DEPENDENCY=59]="INVALID_RANGE_PEER_DEPENDENCY",Me[Me.INCOMPATIBLE_PEER_DEPENDENCY=60]="INCOMPATIBLE_PEER_DEPENDENCY",Me[Me.DEPRECATED_PACKAGE=61]="DEPRECATED_PACKAGE",Me[Me.INCOMPATIBLE_OS=62]="INCOMPATIBLE_OS",Me[Me.INCOMPATIBLE_CPU=63]="INCOMPATIBLE_CPU",Me[Me.FROZEN_ARTIFACT_EXCEPTION=64]="FROZEN_ARTIFACT_EXCEPTION",Me[Me.TELEMETRY_NOTICE=65]="TELEMETRY_NOTICE",Me[Me.PATCH_HUNK_FAILED=66]="PATCH_HUNK_FAILED",Me[Me.INVALID_CONFIGURATION_VALUE=67]="INVALID_CONFIGURATION_VALUE",Me[Me.UNUSED_PACKAGE_EXTENSION=68]="UNUSED_PACKAGE_EXTENSION",Me[Me.REDUNDANT_PACKAGE_EXTENSION=69]="REDUNDANT_PACKAGE_EXTENSION",Me[Me.AUTO_NM_SUCCESS=70]="AUTO_NM_SUCCESS",Me[Me.NM_CANT_INSTALL_EXTERNAL_SOFT_LINK=71]="NM_CANT_INSTALL_EXTERNAL_SOFT_LINK",Me[Me.NM_PRESERVE_SYMLINKS_REQUIRED=72]="NM_PRESERVE_SYMLINKS_REQUIRED",Me[Me.UPDATE_LOCKFILE_ONLY_SKIP_LINK=73]="UPDATE_LOCKFILE_ONLY_SKIP_LINK",Me[Me.NM_HARDLINKS_MODE_DOWNGRADED=74]="NM_HARDLINKS_MODE_DOWNGRADED",Me[Me.PROLOG_INSTANTIATION_ERROR=75]="PROLOG_INSTANTIATION_ERROR",Me[Me.INCOMPATIBLE_ARCHITECTURE=76]="INCOMPATIBLE_ARCHITECTURE",Me[Me.GHOST_ARCHITECTURE=77]="GHOST_ARCHITECTURE",Me[Me.RESOLUTION_MISMATCH=78]="RESOLUTION_MISMATCH",Me[Me.PROLOG_LIMIT_EXCEEDED=79]="PROLOG_LIMIT_EXCEEDED",Me[Me.NETWORK_DISABLED=80]="NETWORK_DISABLED",Me[Me.NETWORK_UNSAFE_HTTP=81]="NETWORK_UNSAFE_HTTP",Me[Me.RESOLUTION_FAILED=82]="RESOLUTION_FAILED",Me[Me.AUTOMERGE_GIT_ERROR=83]="AUTOMERGE_GIT_ERROR",Me[Me.CONSTRAINTS_CHECK_FAILED=84]="CONSTRAINTS_CHECK_FAILED",Me[Me.UPDATED_RESOLUTION_RECORD=85]="UPDATED_RESOLUTION_RECORD",Me[Me.EXPLAIN_PEER_DEPENDENCIES_CTA=86]="EXPLAIN_PEER_DEPENDENCIES_CTA",Me[Me.MIGRATION_SUCCESS=87]="MIGRATION_SUCCESS",Me[Me.VERSION_NOTICE=88]="VERSION_NOTICE",Me[Me.TIPS_NOTICE=89]="TIPS_NOTICE",Me[Me.OFFLINE_MODE_ENABLED=90]="OFFLINE_MODE_ENABLED",Me))(wr||{})});var hI=_((Tkt,iJ)=>{var wqe="2.0.0",Iqe=Number.MAX_SAFE_INTEGER||9007199254740991,Bqe=16,vqe=256-6,Dqe=["major","premajor","minor","preminor","patch","prepatch","prerelease"];iJ.exports={MAX_LENGTH:256,MAX_SAFE_COMPONENT_LENGTH:Bqe,MAX_SAFE_BUILD_LENGTH:vqe,MAX_SAFE_INTEGER:Iqe,RELEASE_TYPES:Dqe,SEMVER_SPEC_VERSION:wqe,FLAG_INCLUDE_PRERELEASE:1,FLAG_LOOSE:2}});var gI=_((Rkt,sJ)=>{var Pqe=typeof process=="object"&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...t)=>console.error("SEMVER",...t):()=>{};sJ.exports=Pqe});var By=_((Cf,oJ)=>{var{MAX_SAFE_COMPONENT_LENGTH:JR,MAX_SAFE_BUILD_LENGTH:Sqe,MAX_LENGTH:xqe}=hI(),bqe=gI();Cf=oJ.exports={};var kqe=Cf.re=[],Qqe=Cf.safeRe=[],lr=Cf.src=[],cr=Cf.t={},Fqe=0,zR="[a-zA-Z0-9-]",Tqe=[["\\s",1],["\\d",xqe],[zR,Sqe]],Rqe=t=>{for(let[e,r]of Tqe)t=t.split(`${e}*`).join(`${e}{0,${r}}`).split(`${e}+`).join(`${e}{1,${r}}`);return t},Jr=(t,e,r)=>{let o=Rqe(e),a=Fqe++;bqe(t,a,e),cr[t]=a,lr[a]=e,kqe[a]=new RegExp(e,r?"g":void 0),Qqe[a]=new RegExp(o,r?"g":void 0)};Jr("NUMERICIDENTIFIER","0|[1-9]\\d*");Jr("NUMERICIDENTIFIERLOOSE","\\d+");Jr("NONNUMERICIDENTIFIER",`\\d*[a-zA-Z-]${zR}*`);Jr("MAINVERSION",`(${lr[cr.NUMERICIDENTIFIER]})\\.(${lr[cr.NUMERICIDENTIFIER]})\\.(${lr[cr.NUMERICIDENTIFIER]})`);Jr("MAINVERSIONLOOSE",`(${lr[cr.NUMERICIDENTIFIERLOOSE]})\\.(${lr[cr.NUMERICIDENTIFIERLOOSE]})\\.(${lr[cr.NUMERICIDENTIFIERLOOSE]})`);Jr("PRERELEASEIDENTIFIER",`(?:${lr[cr.NUMERICIDENTIFIER]}|${lr[cr.NONNUMERICIDENTIFIER]})`);Jr("PRERELEASEIDENTIFIERLOOSE",`(?:${lr[cr.NUMERICIDENTIFIERLOOSE]}|${lr[cr.NONNUMERICIDENTIFIER]})`);Jr("PRERELEASE",`(?:-(${lr[cr.PRERELEASEIDENTIFIER]}(?:\\.${lr[cr.PRERELEASEIDENTIFIER]})*))`);Jr("PRERELEASELOOSE",`(?:-?(${lr[cr.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${lr[cr.PRERELEASEIDENTIFIERLOOSE]})*))`);Jr("BUILDIDENTIFIER",`${zR}+`);Jr("BUILD",`(?:\\+(${lr[cr.BUILDIDENTIFIER]}(?:\\.${lr[cr.BUILDIDENTIFIER]})*))`);Jr("FULLPLAIN",`v?${lr[cr.MAINVERSION]}${lr[cr.PRERELEASE]}?${lr[cr.BUILD]}?`);Jr("FULL",`^${lr[cr.FULLPLAIN]}$`);Jr("LOOSEPLAIN",`[v=\\s]*${lr[cr.MAINVERSIONLOOSE]}${lr[cr.PRERELEASELOOSE]}?${lr[cr.BUILD]}?`);Jr("LOOSE",`^${lr[cr.LOOSEPLAIN]}$`);Jr("GTLT","((?:<|>)?=?)");Jr("XRANGEIDENTIFIERLOOSE",`${lr[cr.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);Jr("XRANGEIDENTIFIER",`${lr[cr.NUMERICIDENTIFIER]}|x|X|\\*`);Jr("XRANGEPLAIN",`[v=\\s]*(${lr[cr.XRANGEIDENTIFIER]})(?:\\.(${lr[cr.XRANGEIDENTIFIER]})(?:\\.(${lr[cr.XRANGEIDENTIFIER]})(?:${lr[cr.PRERELEASE]})?${lr[cr.BUILD]}?)?)?`);Jr("XRANGEPLAINLOOSE",`[v=\\s]*(${lr[cr.XRANGEIDENTIFIERLOOSE]})(?:\\.(${lr[cr.XRANGEIDENTIFIERLOOSE]})(?:\\.(${lr[cr.XRANGEIDENTIFIERLOOSE]})(?:${lr[cr.PRERELEASELOOSE]})?${lr[cr.BUILD]}?)?)?`);Jr("XRANGE",`^${lr[cr.GTLT]}\\s*${lr[cr.XRANGEPLAIN]}$`);Jr("XRANGELOOSE",`^${lr[cr.GTLT]}\\s*${lr[cr.XRANGEPLAINLOOSE]}$`);Jr("COERCE",`(^|[^\\d])(\\d{1,${JR}})(?:\\.(\\d{1,${JR}}))?(?:\\.(\\d{1,${JR}}))?(?:$|[^\\d])`);Jr("COERCERTL",lr[cr.COERCE],!0);Jr("LONETILDE","(?:~>?)");Jr("TILDETRIM",`(\\s*)${lr[cr.LONETILDE]}\\s+`,!0);Cf.tildeTrimReplace="$1~";Jr("TILDE",`^${lr[cr.LONETILDE]}${lr[cr.XRANGEPLAIN]}$`);Jr("TILDELOOSE",`^${lr[cr.LONETILDE]}${lr[cr.XRANGEPLAINLOOSE]}$`);Jr("LONECARET","(?:\\^)");Jr("CARETTRIM",`(\\s*)${lr[cr.LONECARET]}\\s+`,!0);Cf.caretTrimReplace="$1^";Jr("CARET",`^${lr[cr.LONECARET]}${lr[cr.XRANGEPLAIN]}$`);Jr("CARETLOOSE",`^${lr[cr.LONECARET]}${lr[cr.XRANGEPLAINLOOSE]}$`);Jr("COMPARATORLOOSE",`^${lr[cr.GTLT]}\\s*(${lr[cr.LOOSEPLAIN]})$|^$`);Jr("COMPARATOR",`^${lr[cr.GTLT]}\\s*(${lr[cr.FULLPLAIN]})$|^$`);Jr("COMPARATORTRIM",`(\\s*)${lr[cr.GTLT]}\\s*(${lr[cr.LOOSEPLAIN]}|${lr[cr.XRANGEPLAIN]})`,!0);Cf.comparatorTrimReplace="$1$2$3";Jr("HYPHENRANGE",`^\\s*(${lr[cr.XRANGEPLAIN]})\\s+-\\s+(${lr[cr.XRANGEPLAIN]})\\s*$`);Jr("HYPHENRANGELOOSE",`^\\s*(${lr[cr.XRANGEPLAINLOOSE]})\\s+-\\s+(${lr[cr.XRANGEPLAINLOOSE]})\\s*$`);Jr("STAR","(<|>)?=?\\s*\\*");Jr("GTE0","^\\s*>=\\s*0\\.0\\.0\\s*$");Jr("GTE0PRE","^\\s*>=\\s*0\\.0\\.0-0\\s*$")});var hP=_((Nkt,aJ)=>{var Nqe=Object.freeze({loose:!0}),Lqe=Object.freeze({}),Mqe=t=>t?typeof t!="object"?Nqe:t:Lqe;aJ.exports=Mqe});var XR=_((Lkt,uJ)=>{var lJ=/^[0-9]+$/,cJ=(t,e)=>{let r=lJ.test(t),o=lJ.test(e);return r&&o&&(t=+t,e=+e),t===e?0:r&&!o?-1:o&&!r?1:t<e?-1:1},Oqe=(t,e)=>cJ(e,t);uJ.exports={compareIdentifiers:cJ,rcompareIdentifiers:Oqe}});var Po=_((Mkt,hJ)=>{var gP=gI(),{MAX_LENGTH:AJ,MAX_SAFE_INTEGER:dP}=hI(),{safeRe:fJ,t:pJ}=By(),Uqe=hP(),{compareIdentifiers:vy}=XR(),tl=class{constructor(e,r){if(r=Uqe(r),e instanceof tl){if(e.loose===!!r.loose&&e.includePrerelease===!!r.includePrerelease)return e;e=e.version}else if(typeof e!="string")throw new TypeError(`Invalid version. Must be a string. Got type "${typeof e}".`);if(e.length>AJ)throw new TypeError(`version is longer than ${AJ} characters`);gP("SemVer",e,r),this.options=r,this.loose=!!r.loose,this.includePrerelease=!!r.includePrerelease;let o=e.trim().match(r.loose?fJ[pJ.LOOSE]:fJ[pJ.FULL]);if(!o)throw new TypeError(`Invalid Version: ${e}`);if(this.raw=e,this.major=+o[1],this.minor=+o[2],this.patch=+o[3],this.major>dP||this.major<0)throw new TypeError("Invalid major version");if(this.minor>dP||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>dP||this.patch<0)throw new TypeError("Invalid patch version");o[4]?this.prerelease=o[4].split(".").map(a=>{if(/^[0-9]+$/.test(a)){let n=+a;if(n>=0&&n<dP)return n}return a}):this.prerelease=[],this.build=o[5]?o[5].split("."):[],this.format()}format(){return this.version=`${this.major}.${this.minor}.${this.patch}`,this.prerelease.length&&(this.version+=`-${this.prerelease.join(".")}`),this.version}toString(){return this.version}compare(e){if(gP("SemVer.compare",this.version,this.options,e),!(e instanceof tl)){if(typeof e=="string"&&e===this.version)return 0;e=new tl(e,this.options)}return e.version===this.version?0:this.compareMain(e)||this.comparePre(e)}compareMain(e){return e instanceof tl||(e=new tl(e,this.options)),vy(this.major,e.major)||vy(this.minor,e.minor)||vy(this.patch,e.patch)}comparePre(e){if(e instanceof tl||(e=new tl(e,this.options)),this.prerelease.length&&!e.prerelease.length)return-1;if(!this.prerelease.length&&e.prerelease.length)return 1;if(!this.prerelease.length&&!e.prerelease.length)return 0;let r=0;do{let o=this.prerelease[r],a=e.prerelease[r];if(gP("prerelease compare",r,o,a),o===void 0&&a===void 0)return 0;if(a===void 0)return 1;if(o===void 0)return-1;if(o===a)continue;return vy(o,a)}while(++r)}compareBuild(e){e instanceof tl||(e=new tl(e,this.options));let r=0;do{let o=this.build[r],a=e.build[r];if(gP("prerelease compare",r,o,a),o===void 0&&a===void 0)return 0;if(a===void 0)return 1;if(o===void 0)return-1;if(o===a)continue;return vy(o,a)}while(++r)}inc(e,r,o){switch(e){case"premajor":this.prerelease.length=0,this.patch=0,this.minor=0,this.major++,this.inc("pre",r,o);break;case"preminor":this.prerelease.length=0,this.patch=0,this.minor++,this.inc("pre",r,o);break;case"prepatch":this.prerelease.length=0,this.inc("patch",r,o),this.inc("pre",r,o);break;case"prerelease":this.prerelease.length===0&&this.inc("patch",r,o),this.inc("pre",r,o);break;case"major":(this.minor!==0||this.patch!==0||this.prerelease.length===0)&&this.major++,this.minor=0,this.patch=0,this.prerelease=[];break;case"minor":(this.patch!==0||this.prerelease.length===0)&&this.minor++,this.patch=0,this.prerelease=[];break;case"patch":this.prerelease.length===0&&this.patch++,this.prerelease=[];break;case"pre":{let a=Number(o)?1:0;if(!r&&o===!1)throw new Error("invalid increment argument: identifier is empty");if(this.prerelease.length===0)this.prerelease=[a];else{let n=this.prerelease.length;for(;--n>=0;)typeof this.prerelease[n]=="number"&&(this.prerelease[n]++,n=-2);if(n===-1){if(r===this.prerelease.join(".")&&o===!1)throw new Error("invalid increment argument: identifier already exists");this.prerelease.push(a)}}if(r){let n=[r,a];o===!1&&(n=[r]),vy(this.prerelease[0],r)===0?isNaN(this.prerelease[1])&&(this.prerelease=n):this.prerelease=n}break}default:throw new Error(`invalid increment argument: ${e}`)}return this.raw=this.format(),this.build.length&&(this.raw+=`+${this.build.join(".")}`),this}};hJ.exports=tl});var id=_((Okt,dJ)=>{var gJ=Po(),_qe=(t,e,r=!1)=>{if(t instanceof gJ)return t;try{return new gJ(t,e)}catch(o){if(!r)return null;throw o}};dJ.exports=_qe});var yJ=_((Ukt,mJ)=>{var Hqe=id(),jqe=(t,e)=>{let r=Hqe(t,e);return r?r.version:null};mJ.exports=jqe});var CJ=_((_kt,EJ)=>{var qqe=id(),Gqe=(t,e)=>{let r=qqe(t.trim().replace(/^[=v]+/,""),e);return r?r.version:null};EJ.exports=Gqe});var BJ=_((Hkt,IJ)=>{var wJ=Po(),Yqe=(t,e,r,o,a)=>{typeof r=="string"&&(a=o,o=r,r=void 0);try{return new wJ(t instanceof wJ?t.version:t,r).inc(e,o,a).version}catch{return null}};IJ.exports=Yqe});var PJ=_((jkt,DJ)=>{var vJ=id(),Wqe=(t,e)=>{let r=vJ(t,null,!0),o=vJ(e,null,!0),a=r.compare(o);if(a===0)return null;let n=a>0,u=n?r:o,A=n?o:r,p=!!u.prerelease.length;if(!!A.prerelease.length&&!p)return!A.patch&&!A.minor?"major":u.patch?"patch":u.minor?"minor":"major";let E=p?"pre":"";return r.major!==o.major?E+"major":r.minor!==o.minor?E+"minor":r.patch!==o.patch?E+"patch":"prerelease"};DJ.exports=Wqe});var xJ=_((qkt,SJ)=>{var Vqe=Po(),Kqe=(t,e)=>new Vqe(t,e).major;SJ.exports=Kqe});var kJ=_((Gkt,bJ)=>{var Jqe=Po(),zqe=(t,e)=>new Jqe(t,e).minor;bJ.exports=zqe});var FJ=_((Ykt,QJ)=>{var Xqe=Po(),Zqe=(t,e)=>new Xqe(t,e).patch;QJ.exports=Zqe});var RJ=_((Wkt,TJ)=>{var $qe=id(),eGe=(t,e)=>{let r=$qe(t,e);return r&&r.prerelease.length?r.prerelease:null};TJ.exports=eGe});var Ll=_((Vkt,LJ)=>{var NJ=Po(),tGe=(t,e,r)=>new NJ(t,r).compare(new NJ(e,r));LJ.exports=tGe});var OJ=_((Kkt,MJ)=>{var rGe=Ll(),nGe=(t,e,r)=>rGe(e,t,r);MJ.exports=nGe});var _J=_((Jkt,UJ)=>{var iGe=Ll(),sGe=(t,e)=>iGe(t,e,!0);UJ.exports=sGe});var mP=_((zkt,jJ)=>{var HJ=Po(),oGe=(t,e,r)=>{let o=new HJ(t,r),a=new HJ(e,r);return o.compare(a)||o.compareBuild(a)};jJ.exports=oGe});var GJ=_((Xkt,qJ)=>{var aGe=mP(),lGe=(t,e)=>t.sort((r,o)=>aGe(r,o,e));qJ.exports=lGe});var WJ=_((Zkt,YJ)=>{var cGe=mP(),uGe=(t,e)=>t.sort((r,o)=>cGe(o,r,e));YJ.exports=uGe});var dI=_(($kt,VJ)=>{var AGe=Ll(),fGe=(t,e,r)=>AGe(t,e,r)>0;VJ.exports=fGe});var yP=_((eQt,KJ)=>{var pGe=Ll(),hGe=(t,e,r)=>pGe(t,e,r)<0;KJ.exports=hGe});var ZR=_((tQt,JJ)=>{var gGe=Ll(),dGe=(t,e,r)=>gGe(t,e,r)===0;JJ.exports=dGe});var $R=_((rQt,zJ)=>{var mGe=Ll(),yGe=(t,e,r)=>mGe(t,e,r)!==0;zJ.exports=yGe});var EP=_((nQt,XJ)=>{var EGe=Ll(),CGe=(t,e,r)=>EGe(t,e,r)>=0;XJ.exports=CGe});var CP=_((iQt,ZJ)=>{var wGe=Ll(),IGe=(t,e,r)=>wGe(t,e,r)<=0;ZJ.exports=IGe});var eN=_((sQt,$J)=>{var BGe=ZR(),vGe=$R(),DGe=dI(),PGe=EP(),SGe=yP(),xGe=CP(),bGe=(t,e,r,o)=>{switch(e){case"===":return typeof t=="object"&&(t=t.version),typeof r=="object"&&(r=r.version),t===r;case"!==":return typeof t=="object"&&(t=t.version),typeof r=="object"&&(r=r.version),t!==r;case"":case"=":case"==":return BGe(t,r,o);case"!=":return vGe(t,r,o);case">":return DGe(t,r,o);case">=":return PGe(t,r,o);case"<":return SGe(t,r,o);case"<=":return xGe(t,r,o);default:throw new TypeError(`Invalid operator: ${e}`)}};$J.exports=bGe});var tz=_((oQt,ez)=>{var kGe=Po(),QGe=id(),{safeRe:wP,t:IP}=By(),FGe=(t,e)=>{if(t instanceof kGe)return t;if(typeof t=="number"&&(t=String(t)),typeof t!="string")return null;e=e||{};let r=null;if(!e.rtl)r=t.match(wP[IP.COERCE]);else{let o;for(;(o=wP[IP.COERCERTL].exec(t))&&(!r||r.index+r[0].length!==t.length);)(!r||o.index+o[0].length!==r.index+r[0].length)&&(r=o),wP[IP.COERCERTL].lastIndex=o.index+o[1].length+o[2].length;wP[IP.COERCERTL].lastIndex=-1}return r===null?null:QGe(`${r[2]}.${r[3]||"0"}.${r[4]||"0"}`,e)};ez.exports=FGe});var nz=_((aQt,rz)=>{"use strict";rz.exports=function(t){t.prototype[Symbol.iterator]=function*(){for(let e=this.head;e;e=e.next)yield e.value}}});var BP=_((lQt,iz)=>{"use strict";iz.exports=Cn;Cn.Node=sd;Cn.create=Cn;function Cn(t){var e=this;if(e instanceof Cn||(e=new Cn),e.tail=null,e.head=null,e.length=0,t&&typeof t.forEach=="function")t.forEach(function(a){e.push(a)});else if(arguments.length>0)for(var r=0,o=arguments.length;r<o;r++)e.push(arguments[r]);return e}Cn.prototype.removeNode=function(t){if(t.list!==this)throw new Error("removing node which does not belong to this list");var e=t.next,r=t.prev;return e&&(e.prev=r),r&&(r.next=e),t===this.head&&(this.head=e),t===this.tail&&(this.tail=r),t.list.length--,t.next=null,t.prev=null,t.list=null,e};Cn.prototype.unshiftNode=function(t){if(t!==this.head){t.list&&t.list.removeNode(t);var e=this.head;t.list=this,t.next=e,e&&(e.prev=t),this.head=t,this.tail||(this.tail=t),this.length++}};Cn.prototype.pushNode=function(t){if(t!==this.tail){t.list&&t.list.removeNode(t);var e=this.tail;t.list=this,t.prev=e,e&&(e.next=t),this.tail=t,this.head||(this.head=t),this.length++}};Cn.prototype.push=function(){for(var t=0,e=arguments.length;t<e;t++)RGe(this,arguments[t]);return this.length};Cn.prototype.unshift=function(){for(var t=0,e=arguments.length;t<e;t++)NGe(this,arguments[t]);return this.length};Cn.prototype.pop=function(){if(!!this.tail){var t=this.tail.value;return this.tail=this.tail.prev,this.tail?this.tail.next=null:this.head=null,this.length--,t}};Cn.prototype.shift=function(){if(!!this.head){var t=this.head.value;return this.head=this.head.next,this.head?this.head.prev=null:this.tail=null,this.length--,t}};Cn.prototype.forEach=function(t,e){e=e||this;for(var r=this.head,o=0;r!==null;o++)t.call(e,r.value,o,this),r=r.next};Cn.prototype.forEachReverse=function(t,e){e=e||this;for(var r=this.tail,o=this.length-1;r!==null;o--)t.call(e,r.value,o,this),r=r.prev};Cn.prototype.get=function(t){for(var e=0,r=this.head;r!==null&&e<t;e++)r=r.next;if(e===t&&r!==null)return r.value};Cn.prototype.getReverse=function(t){for(var e=0,r=this.tail;r!==null&&e<t;e++)r=r.prev;if(e===t&&r!==null)return r.value};Cn.prototype.map=function(t,e){e=e||this;for(var r=new Cn,o=this.head;o!==null;)r.push(t.call(e,o.value,this)),o=o.next;return r};Cn.prototype.mapReverse=function(t,e){e=e||this;for(var r=new Cn,o=this.tail;o!==null;)r.push(t.call(e,o.value,this)),o=o.prev;return r};Cn.prototype.reduce=function(t,e){var r,o=this.head;if(arguments.length>1)r=e;else if(this.head)o=this.head.next,r=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var a=0;o!==null;a++)r=t(r,o.value,a),o=o.next;return r};Cn.prototype.reduceReverse=function(t,e){var r,o=this.tail;if(arguments.length>1)r=e;else if(this.tail)o=this.tail.prev,r=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(var a=this.length-1;o!==null;a--)r=t(r,o.value,a),o=o.prev;return r};Cn.prototype.toArray=function(){for(var t=new Array(this.length),e=0,r=this.head;r!==null;e++)t[e]=r.value,r=r.next;return t};Cn.prototype.toArrayReverse=function(){for(var t=new Array(this.length),e=0,r=this.tail;r!==null;e++)t[e]=r.value,r=r.prev;return t};Cn.prototype.slice=function(t,e){e=e||this.length,e<0&&(e+=this.length),t=t||0,t<0&&(t+=this.length);var r=new Cn;if(e<t||e<0)return r;t<0&&(t=0),e>this.length&&(e=this.length);for(var o=0,a=this.head;a!==null&&o<t;o++)a=a.next;for(;a!==null&&o<e;o++,a=a.next)r.push(a.value);return r};Cn.prototype.sliceReverse=function(t,e){e=e||this.length,e<0&&(e+=this.length),t=t||0,t<0&&(t+=this.length);var r=new Cn;if(e<t||e<0)return r;t<0&&(t=0),e>this.length&&(e=this.length);for(var o=this.length,a=this.tail;a!==null&&o>e;o--)a=a.prev;for(;a!==null&&o>t;o--,a=a.prev)r.push(a.value);return r};Cn.prototype.splice=function(t,e,...r){t>this.length&&(t=this.length-1),t<0&&(t=this.length+t);for(var o=0,a=this.head;a!==null&&o<t;o++)a=a.next;for(var n=[],o=0;a&&o<e;o++)n.push(a.value),a=this.removeNode(a);a===null&&(a=this.tail),a!==this.head&&a!==this.tail&&(a=a.prev);for(var o=0;o<r.length;o++)a=TGe(this,a,r[o]);return n};Cn.prototype.reverse=function(){for(var t=this.head,e=this.tail,r=t;r!==null;r=r.prev){var o=r.prev;r.prev=r.next,r.next=o}return this.head=e,this.tail=t,this};function TGe(t,e,r){var o=e===t.head?new sd(r,null,e,t):new sd(r,e,e.next,t);return o.next===null&&(t.tail=o),o.prev===null&&(t.head=o),t.length++,o}function RGe(t,e){t.tail=new sd(e,t.tail,null,t),t.head||(t.head=t.tail),t.length++}function NGe(t,e){t.head=new sd(e,null,t.head,t),t.tail||(t.tail=t.head),t.length++}function sd(t,e,r,o){if(!(this instanceof sd))return new sd(t,e,r,o);this.list=o,this.value=t,e?(e.next=this,this.prev=e):this.prev=null,r?(r.prev=this,this.next=r):this.next=null}try{nz()(Cn)}catch{}});var cz=_((cQt,lz)=>{"use strict";var LGe=BP(),od=Symbol("max"),If=Symbol("length"),Dy=Symbol("lengthCalculator"),yI=Symbol("allowStale"),ad=Symbol("maxAge"),wf=Symbol("dispose"),sz=Symbol("noDisposeOnSet"),bs=Symbol("lruList"),Oc=Symbol("cache"),az=Symbol("updateAgeOnGet"),tN=()=>1,nN=class{constructor(e){if(typeof e=="number"&&(e={max:e}),e||(e={}),e.max&&(typeof e.max!="number"||e.max<0))throw new TypeError("max must be a non-negative number");let r=this[od]=e.max||1/0,o=e.length||tN;if(this[Dy]=typeof o!="function"?tN:o,this[yI]=e.stale||!1,e.maxAge&&typeof e.maxAge!="number")throw new TypeError("maxAge must be a number");this[ad]=e.maxAge||0,this[wf]=e.dispose,this[sz]=e.noDisposeOnSet||!1,this[az]=e.updateAgeOnGet||!1,this.reset()}set max(e){if(typeof e!="number"||e<0)throw new TypeError("max must be a non-negative number");this[od]=e||1/0,mI(this)}get max(){return this[od]}set allowStale(e){this[yI]=!!e}get allowStale(){return this[yI]}set maxAge(e){if(typeof e!="number")throw new TypeError("maxAge must be a non-negative number");this[ad]=e,mI(this)}get maxAge(){return this[ad]}set lengthCalculator(e){typeof e!="function"&&(e=tN),e!==this[Dy]&&(this[Dy]=e,this[If]=0,this[bs].forEach(r=>{r.length=this[Dy](r.value,r.key),this[If]+=r.length})),mI(this)}get lengthCalculator(){return this[Dy]}get length(){return this[If]}get itemCount(){return this[bs].length}rforEach(e,r){r=r||this;for(let o=this[bs].tail;o!==null;){let a=o.prev;oz(this,e,o,r),o=a}}forEach(e,r){r=r||this;for(let o=this[bs].head;o!==null;){let a=o.next;oz(this,e,o,r),o=a}}keys(){return this[bs].toArray().map(e=>e.key)}values(){return this[bs].toArray().map(e=>e.value)}reset(){this[wf]&&this[bs]&&this[bs].length&&this[bs].forEach(e=>this[wf](e.key,e.value)),this[Oc]=new Map,this[bs]=new LGe,this[If]=0}dump(){return this[bs].map(e=>vP(this,e)?!1:{k:e.key,v:e.value,e:e.now+(e.maxAge||0)}).toArray().filter(e=>e)}dumpLru(){return this[bs]}set(e,r,o){if(o=o||this[ad],o&&typeof o!="number")throw new TypeError("maxAge must be a number");let a=o?Date.now():0,n=this[Dy](r,e);if(this[Oc].has(e)){if(n>this[od])return Py(this,this[Oc].get(e)),!1;let p=this[Oc].get(e).value;return this[wf]&&(this[sz]||this[wf](e,p.value)),p.now=a,p.maxAge=o,p.value=r,this[If]+=n-p.length,p.length=n,this.get(e),mI(this),!0}let u=new iN(e,r,n,a,o);return u.length>this[od]?(this[wf]&&this[wf](e,r),!1):(this[If]+=u.length,this[bs].unshift(u),this[Oc].set(e,this[bs].head),mI(this),!0)}has(e){if(!this[Oc].has(e))return!1;let r=this[Oc].get(e).value;return!vP(this,r)}get(e){return rN(this,e,!0)}peek(e){return rN(this,e,!1)}pop(){let e=this[bs].tail;return e?(Py(this,e),e.value):null}del(e){Py(this,this[Oc].get(e))}load(e){this.reset();let r=Date.now();for(let o=e.length-1;o>=0;o--){let a=e[o],n=a.e||0;if(n===0)this.set(a.k,a.v);else{let u=n-r;u>0&&this.set(a.k,a.v,u)}}}prune(){this[Oc].forEach((e,r)=>rN(this,r,!1))}},rN=(t,e,r)=>{let o=t[Oc].get(e);if(o){let a=o.value;if(vP(t,a)){if(Py(t,o),!t[yI])return}else r&&(t[az]&&(o.value.now=Date.now()),t[bs].unshiftNode(o));return a.value}},vP=(t,e)=>{if(!e||!e.maxAge&&!t[ad])return!1;let r=Date.now()-e.now;return e.maxAge?r>e.maxAge:t[ad]&&r>t[ad]},mI=t=>{if(t[If]>t[od])for(let e=t[bs].tail;t[If]>t[od]&&e!==null;){let r=e.prev;Py(t,e),e=r}},Py=(t,e)=>{if(e){let r=e.value;t[wf]&&t[wf](r.key,r.value),t[If]-=r.length,t[Oc].delete(r.key),t[bs].removeNode(e)}},iN=class{constructor(e,r,o,a,n){this.key=e,this.value=r,this.length=o,this.now=a,this.maxAge=n||0}},oz=(t,e,r,o)=>{let a=r.value;vP(t,a)&&(Py(t,r),t[yI]||(a=void 0)),a&&e.call(o,a.value,a.key,t)};lz.exports=nN});var Ml=_((uQt,pz)=>{var ld=class{constructor(e,r){if(r=OGe(r),e instanceof ld)return e.loose===!!r.loose&&e.includePrerelease===!!r.includePrerelease?e:new ld(e.raw,r);if(e instanceof sN)return this.raw=e.value,this.set=[[e]],this.format(),this;if(this.options=r,this.loose=!!r.loose,this.includePrerelease=!!r.includePrerelease,this.raw=e.trim().split(/\s+/).join(" "),this.set=this.raw.split("||").map(o=>this.parseRange(o.trim())).filter(o=>o.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${this.raw}`);if(this.set.length>1){let o=this.set[0];if(this.set=this.set.filter(a=>!Az(a[0])),this.set.length===0)this.set=[o];else if(this.set.length>1){for(let a of this.set)if(a.length===1&&YGe(a[0])){this.set=[a];break}}}this.format()}format(){return this.range=this.set.map(e=>e.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange(e){let o=((this.options.includePrerelease&&qGe)|(this.options.loose&&GGe))+":"+e,a=uz.get(o);if(a)return a;let n=this.options.loose,u=n?Da[zo.HYPHENRANGELOOSE]:Da[zo.HYPHENRANGE];e=e.replace(u,t5e(this.options.includePrerelease)),ci("hyphen replace",e),e=e.replace(Da[zo.COMPARATORTRIM],_Ge),ci("comparator trim",e),e=e.replace(Da[zo.TILDETRIM],HGe),ci("tilde trim",e),e=e.replace(Da[zo.CARETTRIM],jGe),ci("caret trim",e);let A=e.split(" ").map(I=>WGe(I,this.options)).join(" ").split(/\s+/).map(I=>e5e(I,this.options));n&&(A=A.filter(I=>(ci("loose invalid filter",I,this.options),!!I.match(Da[zo.COMPARATORLOOSE])))),ci("range list",A);let p=new Map,h=A.map(I=>new sN(I,this.options));for(let I of h){if(Az(I))return[I];p.set(I.value,I)}p.size>1&&p.has("")&&p.delete("");let E=[...p.values()];return uz.set(o,E),E}intersects(e,r){if(!(e instanceof ld))throw new TypeError("a Range is required");return this.set.some(o=>fz(o,r)&&e.set.some(a=>fz(a,r)&&o.every(n=>a.every(u=>n.intersects(u,r)))))}test(e){if(!e)return!1;if(typeof e=="string")try{e=new UGe(e,this.options)}catch{return!1}for(let r=0;r<this.set.length;r++)if(r5e(this.set[r],e,this.options))return!0;return!1}};pz.exports=ld;var MGe=cz(),uz=new MGe({max:1e3}),OGe=hP(),sN=EI(),ci=gI(),UGe=Po(),{safeRe:Da,t:zo,comparatorTrimReplace:_Ge,tildeTrimReplace:HGe,caretTrimReplace:jGe}=By(),{FLAG_INCLUDE_PRERELEASE:qGe,FLAG_LOOSE:GGe}=hI(),Az=t=>t.value==="<0.0.0-0",YGe=t=>t.value==="",fz=(t,e)=>{let r=!0,o=t.slice(),a=o.pop();for(;r&&o.length;)r=o.every(n=>a.intersects(n,e)),a=o.pop();return r},WGe=(t,e)=>(ci("comp",t,e),t=JGe(t,e),ci("caret",t),t=VGe(t,e),ci("tildes",t),t=XGe(t,e),ci("xrange",t),t=$Ge(t,e),ci("stars",t),t),Xo=t=>!t||t.toLowerCase()==="x"||t==="*",VGe=(t,e)=>t.trim().split(/\s+/).map(r=>KGe(r,e)).join(" "),KGe=(t,e)=>{let r=e.loose?Da[zo.TILDELOOSE]:Da[zo.TILDE];return t.replace(r,(o,a,n,u,A)=>{ci("tilde",t,o,a,n,u,A);let p;return Xo(a)?p="":Xo(n)?p=`>=${a}.0.0 <${+a+1}.0.0-0`:Xo(u)?p=`>=${a}.${n}.0 <${a}.${+n+1}.0-0`:A?(ci("replaceTilde pr",A),p=`>=${a}.${n}.${u}-${A} <${a}.${+n+1}.0-0`):p=`>=${a}.${n}.${u} <${a}.${+n+1}.0-0`,ci("tilde return",p),p})},JGe=(t,e)=>t.trim().split(/\s+/).map(r=>zGe(r,e)).join(" "),zGe=(t,e)=>{ci("caret",t,e);let r=e.loose?Da[zo.CARETLOOSE]:Da[zo.CARET],o=e.includePrerelease?"-0":"";return t.replace(r,(a,n,u,A,p)=>{ci("caret",t,a,n,u,A,p);let h;return Xo(n)?h="":Xo(u)?h=`>=${n}.0.0${o} <${+n+1}.0.0-0`:Xo(A)?n==="0"?h=`>=${n}.${u}.0${o} <${n}.${+u+1}.0-0`:h=`>=${n}.${u}.0${o} <${+n+1}.0.0-0`:p?(ci("replaceCaret pr",p),n==="0"?u==="0"?h=`>=${n}.${u}.${A}-${p} <${n}.${u}.${+A+1}-0`:h=`>=${n}.${u}.${A}-${p} <${n}.${+u+1}.0-0`:h=`>=${n}.${u}.${A}-${p} <${+n+1}.0.0-0`):(ci("no pr"),n==="0"?u==="0"?h=`>=${n}.${u}.${A}${o} <${n}.${u}.${+A+1}-0`:h=`>=${n}.${u}.${A}${o} <${n}.${+u+1}.0-0`:h=`>=${n}.${u}.${A} <${+n+1}.0.0-0`),ci("caret return",h),h})},XGe=(t,e)=>(ci("replaceXRanges",t,e),t.split(/\s+/).map(r=>ZGe(r,e)).join(" ")),ZGe=(t,e)=>{t=t.trim();let r=e.loose?Da[zo.XRANGELOOSE]:Da[zo.XRANGE];return t.replace(r,(o,a,n,u,A,p)=>{ci("xRange",t,o,a,n,u,A,p);let h=Xo(n),E=h||Xo(u),I=E||Xo(A),v=I;return a==="="&&v&&(a=""),p=e.includePrerelease?"-0":"",h?a===">"||a==="<"?o="<0.0.0-0":o="*":a&&v?(E&&(u=0),A=0,a===">"?(a=">=",E?(n=+n+1,u=0,A=0):(u=+u+1,A=0)):a==="<="&&(a="<",E?n=+n+1:u=+u+1),a==="<"&&(p="-0"),o=`${a+n}.${u}.${A}${p}`):E?o=`>=${n}.0.0${p} <${+n+1}.0.0-0`:I&&(o=`>=${n}.${u}.0${p} <${n}.${+u+1}.0-0`),ci("xRange return",o),o})},$Ge=(t,e)=>(ci("replaceStars",t,e),t.trim().replace(Da[zo.STAR],"")),e5e=(t,e)=>(ci("replaceGTE0",t,e),t.trim().replace(Da[e.includePrerelease?zo.GTE0PRE:zo.GTE0],"")),t5e=t=>(e,r,o,a,n,u,A,p,h,E,I,v,b)=>(Xo(o)?r="":Xo(a)?r=`>=${o}.0.0${t?"-0":""}`:Xo(n)?r=`>=${o}.${a}.0${t?"-0":""}`:u?r=`>=${r}`:r=`>=${r}${t?"-0":""}`,Xo(h)?p="":Xo(E)?p=`<${+h+1}.0.0-0`:Xo(I)?p=`<${h}.${+E+1}.0-0`:v?p=`<=${h}.${E}.${I}-${v}`:t?p=`<${h}.${E}.${+I+1}-0`:p=`<=${p}`,`${r} ${p}`.trim()),r5e=(t,e,r)=>{for(let o=0;o<t.length;o++)if(!t[o].test(e))return!1;if(e.prerelease.length&&!r.includePrerelease){for(let o=0;o<t.length;o++)if(ci(t[o].semver),t[o].semver!==sN.ANY&&t[o].semver.prerelease.length>0){let a=t[o].semver;if(a.major===e.major&&a.minor===e.minor&&a.patch===e.patch)return!0}return!1}return!0}});var EI=_((AQt,Ez)=>{var CI=Symbol("SemVer ANY"),Sy=class{static get ANY(){return CI}constructor(e,r){if(r=hz(r),e instanceof Sy){if(e.loose===!!r.loose)return e;e=e.value}e=e.trim().split(/\s+/).join(" "),aN("comparator",e,r),this.options=r,this.loose=!!r.loose,this.parse(e),this.semver===CI?this.value="":this.value=this.operator+this.semver.version,aN("comp",this)}parse(e){let r=this.options.loose?gz[dz.COMPARATORLOOSE]:gz[dz.COMPARATOR],o=e.match(r);if(!o)throw new TypeError(`Invalid comparator: ${e}`);this.operator=o[1]!==void 0?o[1]:"",this.operator==="="&&(this.operator=""),o[2]?this.semver=new mz(o[2],this.options.loose):this.semver=CI}toString(){return this.value}test(e){if(aN("Comparator.test",e,this.options.loose),this.semver===CI||e===CI)return!0;if(typeof e=="string")try{e=new mz(e,this.options)}catch{return!1}return oN(e,this.operator,this.semver,this.options)}intersects(e,r){if(!(e instanceof Sy))throw new TypeError("a Comparator is required");return this.operator===""?this.value===""?!0:new yz(e.value,r).test(this.value):e.operator===""?e.value===""?!0:new yz(this.value,r).test(e.semver):(r=hz(r),r.includePrerelease&&(this.value==="<0.0.0-0"||e.value==="<0.0.0-0")||!r.includePrerelease&&(this.value.startsWith("<0.0.0")||e.value.startsWith("<0.0.0"))?!1:!!(this.operator.startsWith(">")&&e.operator.startsWith(">")||this.operator.startsWith("<")&&e.operator.startsWith("<")||this.semver.version===e.semver.version&&this.operator.includes("=")&&e.operator.includes("=")||oN(this.semver,"<",e.semver,r)&&this.operator.startsWith(">")&&e.operator.startsWith("<")||oN(this.semver,">",e.semver,r)&&this.operator.startsWith("<")&&e.operator.startsWith(">")))}};Ez.exports=Sy;var hz=hP(),{safeRe:gz,t:dz}=By(),oN=eN(),aN=gI(),mz=Po(),yz=Ml()});var wI=_((fQt,Cz)=>{var n5e=Ml(),i5e=(t,e,r)=>{try{e=new n5e(e,r)}catch{return!1}return e.test(t)};Cz.exports=i5e});var Iz=_((pQt,wz)=>{var s5e=Ml(),o5e=(t,e)=>new s5e(t,e).set.map(r=>r.map(o=>o.value).join(" ").trim().split(" "));wz.exports=o5e});var vz=_((hQt,Bz)=>{var a5e=Po(),l5e=Ml(),c5e=(t,e,r)=>{let o=null,a=null,n=null;try{n=new l5e(e,r)}catch{return null}return t.forEach(u=>{n.test(u)&&(!o||a.compare(u)===-1)&&(o=u,a=new a5e(o,r))}),o};Bz.exports=c5e});var Pz=_((gQt,Dz)=>{var u5e=Po(),A5e=Ml(),f5e=(t,e,r)=>{let o=null,a=null,n=null;try{n=new A5e(e,r)}catch{return null}return t.forEach(u=>{n.test(u)&&(!o||a.compare(u)===1)&&(o=u,a=new u5e(o,r))}),o};Dz.exports=f5e});var bz=_((dQt,xz)=>{var lN=Po(),p5e=Ml(),Sz=dI(),h5e=(t,e)=>{t=new p5e(t,e);let r=new lN("0.0.0");if(t.test(r)||(r=new lN("0.0.0-0"),t.test(r)))return r;r=null;for(let o=0;o<t.set.length;++o){let a=t.set[o],n=null;a.forEach(u=>{let A=new lN(u.semver.version);switch(u.operator){case">":A.prerelease.length===0?A.patch++:A.prerelease.push(0),A.raw=A.format();case"":case">=":(!n||Sz(A,n))&&(n=A);break;case"<":case"<=":break;default:throw new Error(`Unexpected operation: ${u.operator}`)}}),n&&(!r||Sz(r,n))&&(r=n)}return r&&t.test(r)?r:null};xz.exports=h5e});var Qz=_((mQt,kz)=>{var g5e=Ml(),d5e=(t,e)=>{try{return new g5e(t,e).range||"*"}catch{return null}};kz.exports=d5e});var DP=_((yQt,Nz)=>{var m5e=Po(),Rz=EI(),{ANY:y5e}=Rz,E5e=Ml(),C5e=wI(),Fz=dI(),Tz=yP(),w5e=CP(),I5e=EP(),B5e=(t,e,r,o)=>{t=new m5e(t,o),e=new E5e(e,o);let a,n,u,A,p;switch(r){case">":a=Fz,n=w5e,u=Tz,A=">",p=">=";break;case"<":a=Tz,n=I5e,u=Fz,A="<",p="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(C5e(t,e,o))return!1;for(let h=0;h<e.set.length;++h){let E=e.set[h],I=null,v=null;if(E.forEach(b=>{b.semver===y5e&&(b=new Rz(">=0.0.0")),I=I||b,v=v||b,a(b.semver,I.semver,o)?I=b:u(b.semver,v.semver,o)&&(v=b)}),I.operator===A||I.operator===p||(!v.operator||v.operator===A)&&n(t,v.semver))return!1;if(v.operator===p&&u(t,v.semver))return!1}return!0};Nz.exports=B5e});var Mz=_((EQt,Lz)=>{var v5e=DP(),D5e=(t,e,r)=>v5e(t,e,">",r);Lz.exports=D5e});var Uz=_((CQt,Oz)=>{var P5e=DP(),S5e=(t,e,r)=>P5e(t,e,"<",r);Oz.exports=S5e});var jz=_((wQt,Hz)=>{var _z=Ml(),x5e=(t,e,r)=>(t=new _z(t,r),e=new _z(e,r),t.intersects(e,r));Hz.exports=x5e});var Gz=_((IQt,qz)=>{var b5e=wI(),k5e=Ll();qz.exports=(t,e,r)=>{let o=[],a=null,n=null,u=t.sort((E,I)=>k5e(E,I,r));for(let E of u)b5e(E,e,r)?(n=E,a||(a=E)):(n&&o.push([a,n]),n=null,a=null);a&&o.push([a,null]);let A=[];for(let[E,I]of o)E===I?A.push(E):!I&&E===u[0]?A.push("*"):I?E===u[0]?A.push(`<=${I}`):A.push(`${E} - ${I}`):A.push(`>=${E}`);let p=A.join(" || "),h=typeof e.raw=="string"?e.raw:String(e);return p.length<h.length?p:e}});var zz=_((BQt,Jz)=>{var Yz=Ml(),uN=EI(),{ANY:cN}=uN,II=wI(),AN=Ll(),Q5e=(t,e,r={})=>{if(t===e)return!0;t=new Yz(t,r),e=new Yz(e,r);let o=!1;e:for(let a of t.set){for(let n of e.set){let u=T5e(a,n,r);if(o=o||u!==null,u)continue e}if(o)return!1}return!0},F5e=[new uN(">=0.0.0-0")],Wz=[new uN(">=0.0.0")],T5e=(t,e,r)=>{if(t===e)return!0;if(t.length===1&&t[0].semver===cN){if(e.length===1&&e[0].semver===cN)return!0;r.includePrerelease?t=F5e:t=Wz}if(e.length===1&&e[0].semver===cN){if(r.includePrerelease)return!0;e=Wz}let o=new Set,a,n;for(let b of t)b.operator===">"||b.operator===">="?a=Vz(a,b,r):b.operator==="<"||b.operator==="<="?n=Kz(n,b,r):o.add(b.semver);if(o.size>1)return null;let u;if(a&&n){if(u=AN(a.semver,n.semver,r),u>0)return null;if(u===0&&(a.operator!==">="||n.operator!=="<="))return null}for(let b of o){if(a&&!II(b,String(a),r)||n&&!II(b,String(n),r))return null;for(let C of e)if(!II(b,String(C),r))return!1;return!0}let A,p,h,E,I=n&&!r.includePrerelease&&n.semver.prerelease.length?n.semver:!1,v=a&&!r.includePrerelease&&a.semver.prerelease.length?a.semver:!1;I&&I.prerelease.length===1&&n.operator==="<"&&I.prerelease[0]===0&&(I=!1);for(let b of e){if(E=E||b.operator===">"||b.operator===">=",h=h||b.operator==="<"||b.operator==="<=",a){if(v&&b.semver.prerelease&&b.semver.prerelease.length&&b.semver.major===v.major&&b.semver.minor===v.minor&&b.semver.patch===v.patch&&(v=!1),b.operator===">"||b.operator===">="){if(A=Vz(a,b,r),A===b&&A!==a)return!1}else if(a.operator===">="&&!II(a.semver,String(b),r))return!1}if(n){if(I&&b.semver.prerelease&&b.semver.prerelease.length&&b.semver.major===I.major&&b.semver.minor===I.minor&&b.semver.patch===I.patch&&(I=!1),b.operator==="<"||b.operator==="<="){if(p=Kz(n,b,r),p===b&&p!==n)return!1}else if(n.operator==="<="&&!II(n.semver,String(b),r))return!1}if(!b.operator&&(n||a)&&u!==0)return!1}return!(a&&h&&!n&&u!==0||n&&E&&!a&&u!==0||v||I)},Vz=(t,e,r)=>{if(!t)return e;let o=AN(t.semver,e.semver,r);return o>0?t:o<0||e.operator===">"&&t.operator===">="?e:t},Kz=(t,e,r)=>{if(!t)return e;let o=AN(t.semver,e.semver,r);return o<0?t:o>0||e.operator==="<"&&t.operator==="<="?e:t};Jz.exports=Q5e});var zn=_((vQt,$z)=>{var fN=By(),Xz=hI(),R5e=Po(),Zz=XR(),N5e=id(),L5e=yJ(),M5e=CJ(),O5e=BJ(),U5e=PJ(),_5e=xJ(),H5e=kJ(),j5e=FJ(),q5e=RJ(),G5e=Ll(),Y5e=OJ(),W5e=_J(),V5e=mP(),K5e=GJ(),J5e=WJ(),z5e=dI(),X5e=yP(),Z5e=ZR(),$5e=$R(),e9e=EP(),t9e=CP(),r9e=eN(),n9e=tz(),i9e=EI(),s9e=Ml(),o9e=wI(),a9e=Iz(),l9e=vz(),c9e=Pz(),u9e=bz(),A9e=Qz(),f9e=DP(),p9e=Mz(),h9e=Uz(),g9e=jz(),d9e=Gz(),m9e=zz();$z.exports={parse:N5e,valid:L5e,clean:M5e,inc:O5e,diff:U5e,major:_5e,minor:H5e,patch:j5e,prerelease:q5e,compare:G5e,rcompare:Y5e,compareLoose:W5e,compareBuild:V5e,sort:K5e,rsort:J5e,gt:z5e,lt:X5e,eq:Z5e,neq:$5e,gte:e9e,lte:t9e,cmp:r9e,coerce:n9e,Comparator:i9e,Range:s9e,satisfies:o9e,toComparators:a9e,maxSatisfying:l9e,minSatisfying:c9e,minVersion:u9e,validRange:A9e,outside:f9e,gtr:p9e,ltr:h9e,intersects:g9e,simplifyRange:d9e,subset:m9e,SemVer:R5e,re:fN.re,src:fN.src,tokens:fN.t,SEMVER_SPEC_VERSION:Xz.SEMVER_SPEC_VERSION,RELEASE_TYPES:Xz.RELEASE_TYPES,compareIdentifiers:Zz.compareIdentifiers,rcompareIdentifiers:Zz.rcompareIdentifiers}});var tX=_((DQt,eX)=>{"use strict";function y9e(t,e){function r(){this.constructor=t}r.prototype=e.prototype,t.prototype=new r}function cd(t,e,r,o){this.message=t,this.expected=e,this.found=r,this.location=o,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,cd)}y9e(cd,Error);cd.buildMessage=function(t,e){var r={literal:function(h){return'"'+a(h.text)+'"'},class:function(h){var E="",I;for(I=0;I<h.parts.length;I++)E+=h.parts[I]instanceof Array?n(h.parts[I][0])+"-"+n(h.parts[I][1]):n(h.parts[I]);return"["+(h.inverted?"^":"")+E+"]"},any:function(h){return"any character"},end:function(h){return"end of input"},other:function(h){return h.description}};function o(h){return h.charCodeAt(0).toString(16).toUpperCase()}function a(h){return h.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(E){return"\\x0"+o(E)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(E){return"\\x"+o(E)})}function n(h){return h.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(E){return"\\x0"+o(E)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(E){return"\\x"+o(E)})}function u(h){return r[h.type](h)}function A(h){var E=new Array(h.length),I,v;for(I=0;I<h.length;I++)E[I]=u(h[I]);if(E.sort(),E.length>0){for(I=1,v=1;I<E.length;I++)E[I-1]!==E[I]&&(E[v]=E[I],v++);E.length=v}switch(E.length){case 1:return E[0];case 2:return E[0]+" or "+E[1];default:return E.slice(0,-1).join(", ")+", or "+E[E.length-1]}}function p(h){return h?'"'+a(h)+'"':"end of input"}return"Expected "+A(t)+" but "+p(e)+" found."};function E9e(t,e){e=e!==void 0?e:{};var r={},o={Expression:y},a=y,n="|",u=Re("|",!1),A="&",p=Re("&",!1),h="^",E=Re("^",!1),I=function(Z,ie){return!!ie.reduce((Se,Ne)=>{switch(Ne[1]){case"|":return Se|Ne[3];case"&":return Se&Ne[3];case"^":return Se^Ne[3]}},Z)},v="!",b=Re("!",!1),C=function(Z){return!Z},T="(",L=Re("(",!1),U=")",J=Re(")",!1),te=function(Z){return Z},le=/^[^ \t\n\r()!|&\^]/,pe=Qe([" "," ",` +`,"\r","(",")","!","|","&","^"],!0,!1),Ae=function(Z){return e.queryPattern.test(Z)},ye=function(Z){return e.checkFn(Z)},ae=Te("whitespace"),we=/^[ \t\n\r]/,Pe=Qe([" "," ",` +`,"\r"],!1,!1),g=0,Ee=0,De=[{line:1,column:1}],ce=0,ne=[],ee=0,Ie;if("startRule"in e){if(!(e.startRule in o))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');a=o[e.startRule]}function ke(){return t.substring(Ee,g)}function ht(){return He(Ee,g)}function H(Z,ie){throw ie=ie!==void 0?ie:He(Ee,g),S([Te(Z)],t.substring(Ee,g),ie)}function lt(Z,ie){throw ie=ie!==void 0?ie:He(Ee,g),w(Z,ie)}function Re(Z,ie){return{type:"literal",text:Z,ignoreCase:ie}}function Qe(Z,ie,Se){return{type:"class",parts:Z,inverted:ie,ignoreCase:Se}}function be(){return{type:"any"}}function _e(){return{type:"end"}}function Te(Z){return{type:"other",description:Z}}function Je(Z){var ie=De[Z],Se;if(ie)return ie;for(Se=Z-1;!De[Se];)Se--;for(ie=De[Se],ie={line:ie.line,column:ie.column};Se<Z;)t.charCodeAt(Se)===10?(ie.line++,ie.column=1):ie.column++,Se++;return De[Z]=ie,ie}function He(Z,ie){var Se=Je(Z),Ne=Je(ie);return{start:{offset:Z,line:Se.line,column:Se.column},end:{offset:ie,line:Ne.line,column:Ne.column}}}function x(Z){g<ce||(g>ce&&(ce=g,ne=[]),ne.push(Z))}function w(Z,ie){return new cd(Z,null,null,ie)}function S(Z,ie,Se){return new cd(cd.buildMessage(Z,ie),Z,ie,Se)}function y(){var Z,ie,Se,Ne,ot,dt,jt,$t;if(Z=g,ie=F(),ie!==r){for(Se=[],Ne=g,ot=X(),ot!==r?(t.charCodeAt(g)===124?(dt=n,g++):(dt=r,ee===0&&x(u)),dt===r&&(t.charCodeAt(g)===38?(dt=A,g++):(dt=r,ee===0&&x(p)),dt===r&&(t.charCodeAt(g)===94?(dt=h,g++):(dt=r,ee===0&&x(E)))),dt!==r?(jt=X(),jt!==r?($t=F(),$t!==r?(ot=[ot,dt,jt,$t],Ne=ot):(g=Ne,Ne=r)):(g=Ne,Ne=r)):(g=Ne,Ne=r)):(g=Ne,Ne=r);Ne!==r;)Se.push(Ne),Ne=g,ot=X(),ot!==r?(t.charCodeAt(g)===124?(dt=n,g++):(dt=r,ee===0&&x(u)),dt===r&&(t.charCodeAt(g)===38?(dt=A,g++):(dt=r,ee===0&&x(p)),dt===r&&(t.charCodeAt(g)===94?(dt=h,g++):(dt=r,ee===0&&x(E)))),dt!==r?(jt=X(),jt!==r?($t=F(),$t!==r?(ot=[ot,dt,jt,$t],Ne=ot):(g=Ne,Ne=r)):(g=Ne,Ne=r)):(g=Ne,Ne=r)):(g=Ne,Ne=r);Se!==r?(Ee=Z,ie=I(ie,Se),Z=ie):(g=Z,Z=r)}else g=Z,Z=r;return Z}function F(){var Z,ie,Se,Ne,ot,dt;return Z=g,t.charCodeAt(g)===33?(ie=v,g++):(ie=r,ee===0&&x(b)),ie!==r?(Se=F(),Se!==r?(Ee=Z,ie=C(Se),Z=ie):(g=Z,Z=r)):(g=Z,Z=r),Z===r&&(Z=g,t.charCodeAt(g)===40?(ie=T,g++):(ie=r,ee===0&&x(L)),ie!==r?(Se=X(),Se!==r?(Ne=y(),Ne!==r?(ot=X(),ot!==r?(t.charCodeAt(g)===41?(dt=U,g++):(dt=r,ee===0&&x(J)),dt!==r?(Ee=Z,ie=te(Ne),Z=ie):(g=Z,Z=r)):(g=Z,Z=r)):(g=Z,Z=r)):(g=Z,Z=r)):(g=Z,Z=r),Z===r&&(Z=z())),Z}function z(){var Z,ie,Se,Ne,ot;if(Z=g,ie=X(),ie!==r){if(Se=g,Ne=[],le.test(t.charAt(g))?(ot=t.charAt(g),g++):(ot=r,ee===0&&x(pe)),ot!==r)for(;ot!==r;)Ne.push(ot),le.test(t.charAt(g))?(ot=t.charAt(g),g++):(ot=r,ee===0&&x(pe));else Ne=r;Ne!==r?Se=t.substring(Se,g):Se=Ne,Se!==r?(Ee=g,Ne=Ae(Se),Ne?Ne=void 0:Ne=r,Ne!==r?(Ee=Z,ie=ye(Se),Z=ie):(g=Z,Z=r)):(g=Z,Z=r)}else g=Z,Z=r;return Z}function X(){var Z,ie;for(ee++,Z=[],we.test(t.charAt(g))?(ie=t.charAt(g),g++):(ie=r,ee===0&&x(Pe));ie!==r;)Z.push(ie),we.test(t.charAt(g))?(ie=t.charAt(g),g++):(ie=r,ee===0&&x(Pe));return ee--,Z===r&&(ie=r,ee===0&&x(ae)),Z}if(Ie=a(),Ie!==r&&g===t.length)return Ie;throw Ie!==r&&g<t.length&&x(_e()),S(ne,ce<t.length?t.charAt(ce):null,ce<t.length?He(ce,ce+1):He(ce,ce))}eX.exports={SyntaxError:cd,parse:E9e}});var rX=_(PP=>{var{parse:C9e}=tX();PP.makeParser=(t=/[a-z]+/)=>(e,r)=>C9e(e,{queryPattern:t,checkFn:r});PP.parse=PP.makeParser()});var iX=_((SQt,nX)=>{"use strict";nX.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}});var pN=_((xQt,oX)=>{var BI=iX(),sX={};for(let t of Object.keys(BI))sX[BI[t]]=t;var Ar={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};oX.exports=Ar;for(let t of Object.keys(Ar)){if(!("channels"in Ar[t]))throw new Error("missing channels property: "+t);if(!("labels"in Ar[t]))throw new Error("missing channel labels property: "+t);if(Ar[t].labels.length!==Ar[t].channels)throw new Error("channel and label counts mismatch: "+t);let{channels:e,labels:r}=Ar[t];delete Ar[t].channels,delete Ar[t].labels,Object.defineProperty(Ar[t],"channels",{value:e}),Object.defineProperty(Ar[t],"labels",{value:r})}Ar.rgb.hsl=function(t){let e=t[0]/255,r=t[1]/255,o=t[2]/255,a=Math.min(e,r,o),n=Math.max(e,r,o),u=n-a,A,p;n===a?A=0:e===n?A=(r-o)/u:r===n?A=2+(o-e)/u:o===n&&(A=4+(e-r)/u),A=Math.min(A*60,360),A<0&&(A+=360);let h=(a+n)/2;return n===a?p=0:h<=.5?p=u/(n+a):p=u/(2-n-a),[A,p*100,h*100]};Ar.rgb.hsv=function(t){let e,r,o,a,n,u=t[0]/255,A=t[1]/255,p=t[2]/255,h=Math.max(u,A,p),E=h-Math.min(u,A,p),I=function(v){return(h-v)/6/E+1/2};return E===0?(a=0,n=0):(n=E/h,e=I(u),r=I(A),o=I(p),u===h?a=o-r:A===h?a=1/3+e-o:p===h&&(a=2/3+r-e),a<0?a+=1:a>1&&(a-=1)),[a*360,n*100,h*100]};Ar.rgb.hwb=function(t){let e=t[0],r=t[1],o=t[2],a=Ar.rgb.hsl(t)[0],n=1/255*Math.min(e,Math.min(r,o));return o=1-1/255*Math.max(e,Math.max(r,o)),[a,n*100,o*100]};Ar.rgb.cmyk=function(t){let e=t[0]/255,r=t[1]/255,o=t[2]/255,a=Math.min(1-e,1-r,1-o),n=(1-e-a)/(1-a)||0,u=(1-r-a)/(1-a)||0,A=(1-o-a)/(1-a)||0;return[n*100,u*100,A*100,a*100]};function w9e(t,e){return(t[0]-e[0])**2+(t[1]-e[1])**2+(t[2]-e[2])**2}Ar.rgb.keyword=function(t){let e=sX[t];if(e)return e;let r=1/0,o;for(let a of Object.keys(BI)){let n=BI[a],u=w9e(t,n);u<r&&(r=u,o=a)}return o};Ar.keyword.rgb=function(t){return BI[t]};Ar.rgb.xyz=function(t){let e=t[0]/255,r=t[1]/255,o=t[2]/255;e=e>.04045?((e+.055)/1.055)**2.4:e/12.92,r=r>.04045?((r+.055)/1.055)**2.4:r/12.92,o=o>.04045?((o+.055)/1.055)**2.4:o/12.92;let a=e*.4124+r*.3576+o*.1805,n=e*.2126+r*.7152+o*.0722,u=e*.0193+r*.1192+o*.9505;return[a*100,n*100,u*100]};Ar.rgb.lab=function(t){let e=Ar.rgb.xyz(t),r=e[0],o=e[1],a=e[2];r/=95.047,o/=100,a/=108.883,r=r>.008856?r**(1/3):7.787*r+16/116,o=o>.008856?o**(1/3):7.787*o+16/116,a=a>.008856?a**(1/3):7.787*a+16/116;let n=116*o-16,u=500*(r-o),A=200*(o-a);return[n,u,A]};Ar.hsl.rgb=function(t){let e=t[0]/360,r=t[1]/100,o=t[2]/100,a,n,u;if(r===0)return u=o*255,[u,u,u];o<.5?a=o*(1+r):a=o+r-o*r;let A=2*o-a,p=[0,0,0];for(let h=0;h<3;h++)n=e+1/3*-(h-1),n<0&&n++,n>1&&n--,6*n<1?u=A+(a-A)*6*n:2*n<1?u=a:3*n<2?u=A+(a-A)*(2/3-n)*6:u=A,p[h]=u*255;return p};Ar.hsl.hsv=function(t){let e=t[0],r=t[1]/100,o=t[2]/100,a=r,n=Math.max(o,.01);o*=2,r*=o<=1?o:2-o,a*=n<=1?n:2-n;let u=(o+r)/2,A=o===0?2*a/(n+a):2*r/(o+r);return[e,A*100,u*100]};Ar.hsv.rgb=function(t){let e=t[0]/60,r=t[1]/100,o=t[2]/100,a=Math.floor(e)%6,n=e-Math.floor(e),u=255*o*(1-r),A=255*o*(1-r*n),p=255*o*(1-r*(1-n));switch(o*=255,a){case 0:return[o,p,u];case 1:return[A,o,u];case 2:return[u,o,p];case 3:return[u,A,o];case 4:return[p,u,o];case 5:return[o,u,A]}};Ar.hsv.hsl=function(t){let e=t[0],r=t[1]/100,o=t[2]/100,a=Math.max(o,.01),n,u;u=(2-r)*o;let A=(2-r)*a;return n=r*a,n/=A<=1?A:2-A,n=n||0,u/=2,[e,n*100,u*100]};Ar.hwb.rgb=function(t){let e=t[0]/360,r=t[1]/100,o=t[2]/100,a=r+o,n;a>1&&(r/=a,o/=a);let u=Math.floor(6*e),A=1-o;n=6*e-u,(u&1)!==0&&(n=1-n);let p=r+n*(A-r),h,E,I;switch(u){default:case 6:case 0:h=A,E=p,I=r;break;case 1:h=p,E=A,I=r;break;case 2:h=r,E=A,I=p;break;case 3:h=r,E=p,I=A;break;case 4:h=p,E=r,I=A;break;case 5:h=A,E=r,I=p;break}return[h*255,E*255,I*255]};Ar.cmyk.rgb=function(t){let e=t[0]/100,r=t[1]/100,o=t[2]/100,a=t[3]/100,n=1-Math.min(1,e*(1-a)+a),u=1-Math.min(1,r*(1-a)+a),A=1-Math.min(1,o*(1-a)+a);return[n*255,u*255,A*255]};Ar.xyz.rgb=function(t){let e=t[0]/100,r=t[1]/100,o=t[2]/100,a,n,u;return a=e*3.2406+r*-1.5372+o*-.4986,n=e*-.9689+r*1.8758+o*.0415,u=e*.0557+r*-.204+o*1.057,a=a>.0031308?1.055*a**(1/2.4)-.055:a*12.92,n=n>.0031308?1.055*n**(1/2.4)-.055:n*12.92,u=u>.0031308?1.055*u**(1/2.4)-.055:u*12.92,a=Math.min(Math.max(0,a),1),n=Math.min(Math.max(0,n),1),u=Math.min(Math.max(0,u),1),[a*255,n*255,u*255]};Ar.xyz.lab=function(t){let e=t[0],r=t[1],o=t[2];e/=95.047,r/=100,o/=108.883,e=e>.008856?e**(1/3):7.787*e+16/116,r=r>.008856?r**(1/3):7.787*r+16/116,o=o>.008856?o**(1/3):7.787*o+16/116;let a=116*r-16,n=500*(e-r),u=200*(r-o);return[a,n,u]};Ar.lab.xyz=function(t){let e=t[0],r=t[1],o=t[2],a,n,u;n=(e+16)/116,a=r/500+n,u=n-o/200;let A=n**3,p=a**3,h=u**3;return n=A>.008856?A:(n-16/116)/7.787,a=p>.008856?p:(a-16/116)/7.787,u=h>.008856?h:(u-16/116)/7.787,a*=95.047,n*=100,u*=108.883,[a,n,u]};Ar.lab.lch=function(t){let e=t[0],r=t[1],o=t[2],a;a=Math.atan2(o,r)*360/2/Math.PI,a<0&&(a+=360);let u=Math.sqrt(r*r+o*o);return[e,u,a]};Ar.lch.lab=function(t){let e=t[0],r=t[1],a=t[2]/360*2*Math.PI,n=r*Math.cos(a),u=r*Math.sin(a);return[e,n,u]};Ar.rgb.ansi16=function(t,e=null){let[r,o,a]=t,n=e===null?Ar.rgb.hsv(t)[2]:e;if(n=Math.round(n/50),n===0)return 30;let u=30+(Math.round(a/255)<<2|Math.round(o/255)<<1|Math.round(r/255));return n===2&&(u+=60),u};Ar.hsv.ansi16=function(t){return Ar.rgb.ansi16(Ar.hsv.rgb(t),t[2])};Ar.rgb.ansi256=function(t){let e=t[0],r=t[1],o=t[2];return e===r&&r===o?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(r/255*5)+Math.round(o/255*5)};Ar.ansi16.rgb=function(t){let e=t%10;if(e===0||e===7)return t>50&&(e+=3.5),e=e/10.5*255,[e,e,e];let r=(~~(t>50)+1)*.5,o=(e&1)*r*255,a=(e>>1&1)*r*255,n=(e>>2&1)*r*255;return[o,a,n]};Ar.ansi256.rgb=function(t){if(t>=232){let n=(t-232)*10+8;return[n,n,n]}t-=16;let e,r=Math.floor(t/36)/5*255,o=Math.floor((e=t%36)/6)/5*255,a=e%6/5*255;return[r,o,a]};Ar.rgb.hex=function(t){let r=(((Math.round(t[0])&255)<<16)+((Math.round(t[1])&255)<<8)+(Math.round(t[2])&255)).toString(16).toUpperCase();return"000000".substring(r.length)+r};Ar.hex.rgb=function(t){let e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];let r=e[0];e[0].length===3&&(r=r.split("").map(A=>A+A).join(""));let o=parseInt(r,16),a=o>>16&255,n=o>>8&255,u=o&255;return[a,n,u]};Ar.rgb.hcg=function(t){let e=t[0]/255,r=t[1]/255,o=t[2]/255,a=Math.max(Math.max(e,r),o),n=Math.min(Math.min(e,r),o),u=a-n,A,p;return u<1?A=n/(1-u):A=0,u<=0?p=0:a===e?p=(r-o)/u%6:a===r?p=2+(o-e)/u:p=4+(e-r)/u,p/=6,p%=1,[p*360,u*100,A*100]};Ar.hsl.hcg=function(t){let e=t[1]/100,r=t[2]/100,o=r<.5?2*e*r:2*e*(1-r),a=0;return o<1&&(a=(r-.5*o)/(1-o)),[t[0],o*100,a*100]};Ar.hsv.hcg=function(t){let e=t[1]/100,r=t[2]/100,o=e*r,a=0;return o<1&&(a=(r-o)/(1-o)),[t[0],o*100,a*100]};Ar.hcg.rgb=function(t){let e=t[0]/360,r=t[1]/100,o=t[2]/100;if(r===0)return[o*255,o*255,o*255];let a=[0,0,0],n=e%1*6,u=n%1,A=1-u,p=0;switch(Math.floor(n)){case 0:a[0]=1,a[1]=u,a[2]=0;break;case 1:a[0]=A,a[1]=1,a[2]=0;break;case 2:a[0]=0,a[1]=1,a[2]=u;break;case 3:a[0]=0,a[1]=A,a[2]=1;break;case 4:a[0]=u,a[1]=0,a[2]=1;break;default:a[0]=1,a[1]=0,a[2]=A}return p=(1-r)*o,[(r*a[0]+p)*255,(r*a[1]+p)*255,(r*a[2]+p)*255]};Ar.hcg.hsv=function(t){let e=t[1]/100,r=t[2]/100,o=e+r*(1-e),a=0;return o>0&&(a=e/o),[t[0],a*100,o*100]};Ar.hcg.hsl=function(t){let e=t[1]/100,o=t[2]/100*(1-e)+.5*e,a=0;return o>0&&o<.5?a=e/(2*o):o>=.5&&o<1&&(a=e/(2*(1-o))),[t[0],a*100,o*100]};Ar.hcg.hwb=function(t){let e=t[1]/100,r=t[2]/100,o=e+r*(1-e);return[t[0],(o-e)*100,(1-o)*100]};Ar.hwb.hcg=function(t){let e=t[1]/100,o=1-t[2]/100,a=o-e,n=0;return a<1&&(n=(o-a)/(1-a)),[t[0],a*100,n*100]};Ar.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]};Ar.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]};Ar.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]};Ar.gray.hsl=function(t){return[0,0,t[0]]};Ar.gray.hsv=Ar.gray.hsl;Ar.gray.hwb=function(t){return[0,100,t[0]]};Ar.gray.cmyk=function(t){return[0,0,0,t[0]]};Ar.gray.lab=function(t){return[t[0],0,0]};Ar.gray.hex=function(t){let e=Math.round(t[0]/100*255)&255,o=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(o.length)+o};Ar.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}});var lX=_((bQt,aX)=>{var SP=pN();function I9e(){let t={},e=Object.keys(SP);for(let r=e.length,o=0;o<r;o++)t[e[o]]={distance:-1,parent:null};return t}function B9e(t){let e=I9e(),r=[t];for(e[t].distance=0;r.length;){let o=r.pop(),a=Object.keys(SP[o]);for(let n=a.length,u=0;u<n;u++){let A=a[u],p=e[A];p.distance===-1&&(p.distance=e[o].distance+1,p.parent=o,r.unshift(A))}}return e}function v9e(t,e){return function(r){return e(t(r))}}function D9e(t,e){let r=[e[t].parent,t],o=SP[e[t].parent][t],a=e[t].parent;for(;e[a].parent;)r.unshift(e[a].parent),o=v9e(SP[e[a].parent][a],o),a=e[a].parent;return o.conversion=r,o}aX.exports=function(t){let e=B9e(t),r={},o=Object.keys(e);for(let a=o.length,n=0;n<a;n++){let u=o[n];e[u].parent!==null&&(r[u]=D9e(u,e))}return r}});var uX=_((kQt,cX)=>{var hN=pN(),P9e=lX(),xy={},S9e=Object.keys(hN);function x9e(t){let e=function(...r){let o=r[0];return o==null?o:(o.length>1&&(r=o),t(r))};return"conversion"in t&&(e.conversion=t.conversion),e}function b9e(t){let e=function(...r){let o=r[0];if(o==null)return o;o.length>1&&(r=o);let a=t(r);if(typeof a=="object")for(let n=a.length,u=0;u<n;u++)a[u]=Math.round(a[u]);return a};return"conversion"in t&&(e.conversion=t.conversion),e}S9e.forEach(t=>{xy[t]={},Object.defineProperty(xy[t],"channels",{value:hN[t].channels}),Object.defineProperty(xy[t],"labels",{value:hN[t].labels});let e=P9e(t);Object.keys(e).forEach(o=>{let a=e[o];xy[t][o]=b9e(a),xy[t][o].raw=x9e(a)})});cX.exports=xy});var vI=_((QQt,gX)=>{"use strict";var AX=(t,e)=>(...r)=>`\x1B[${t(...r)+e}m`,fX=(t,e)=>(...r)=>{let o=t(...r);return`\x1B[${38+e};5;${o}m`},pX=(t,e)=>(...r)=>{let o=t(...r);return`\x1B[${38+e};2;${o[0]};${o[1]};${o[2]}m`},xP=t=>t,hX=(t,e,r)=>[t,e,r],by=(t,e,r)=>{Object.defineProperty(t,e,{get:()=>{let o=r();return Object.defineProperty(t,e,{value:o,enumerable:!0,configurable:!0}),o},enumerable:!0,configurable:!0})},gN,ky=(t,e,r,o)=>{gN===void 0&&(gN=uX());let a=o?10:0,n={};for(let[u,A]of Object.entries(gN)){let p=u==="ansi16"?"ansi":u;u===e?n[p]=t(r,a):typeof A=="object"&&(n[p]=t(A[e],a))}return n};function k9e(){let t=new Map,e={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};e.color.gray=e.color.blackBright,e.bgColor.bgGray=e.bgColor.bgBlackBright,e.color.grey=e.color.blackBright,e.bgColor.bgGrey=e.bgColor.bgBlackBright;for(let[r,o]of Object.entries(e)){for(let[a,n]of Object.entries(o))e[a]={open:`\x1B[${n[0]}m`,close:`\x1B[${n[1]}m`},o[a]=e[a],t.set(n[0],n[1]);Object.defineProperty(e,r,{value:o,enumerable:!1})}return Object.defineProperty(e,"codes",{value:t,enumerable:!1}),e.color.close="\x1B[39m",e.bgColor.close="\x1B[49m",by(e.color,"ansi",()=>ky(AX,"ansi16",xP,!1)),by(e.color,"ansi256",()=>ky(fX,"ansi256",xP,!1)),by(e.color,"ansi16m",()=>ky(pX,"rgb",hX,!1)),by(e.bgColor,"ansi",()=>ky(AX,"ansi16",xP,!0)),by(e.bgColor,"ansi256",()=>ky(fX,"ansi256",xP,!0)),by(e.bgColor,"ansi16m",()=>ky(pX,"rgb",hX,!0)),e}Object.defineProperty(gX,"exports",{enumerable:!0,get:k9e})});var mX=_((FQt,dX)=>{"use strict";dX.exports=(t,e=process.argv)=>{let r=t.startsWith("-")?"":t.length===1?"-":"--",o=e.indexOf(r+t),a=e.indexOf("--");return o!==-1&&(a===-1||o<a)}});var yN=_((TQt,EX)=>{"use strict";var Q9e=Be("os"),yX=Be("tty"),Ol=mX(),{env:ls}=process,Kp;Ol("no-color")||Ol("no-colors")||Ol("color=false")||Ol("color=never")?Kp=0:(Ol("color")||Ol("colors")||Ol("color=true")||Ol("color=always"))&&(Kp=1);"FORCE_COLOR"in ls&&(ls.FORCE_COLOR==="true"?Kp=1:ls.FORCE_COLOR==="false"?Kp=0:Kp=ls.FORCE_COLOR.length===0?1:Math.min(parseInt(ls.FORCE_COLOR,10),3));function dN(t){return t===0?!1:{level:t,hasBasic:!0,has256:t>=2,has16m:t>=3}}function mN(t,e){if(Kp===0)return 0;if(Ol("color=16m")||Ol("color=full")||Ol("color=truecolor"))return 3;if(Ol("color=256"))return 2;if(t&&!e&&Kp===void 0)return 0;let r=Kp||0;if(ls.TERM==="dumb")return r;if(process.platform==="win32"){let o=Q9e.release().split(".");return Number(o[0])>=10&&Number(o[2])>=10586?Number(o[2])>=14931?3:2:1}if("CI"in ls)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some(o=>o in ls)||ls.CI_NAME==="codeship"?1:r;if("TEAMCITY_VERSION"in ls)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(ls.TEAMCITY_VERSION)?1:0;if("GITHUB_ACTIONS"in ls)return 1;if(ls.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in ls){let o=parseInt((ls.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(ls.TERM_PROGRAM){case"iTerm.app":return o>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(ls.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(ls.TERM)||"COLORTERM"in ls?1:r}function F9e(t){let e=mN(t,t&&t.isTTY);return dN(e)}EX.exports={supportsColor:F9e,stdout:dN(mN(!0,yX.isatty(1))),stderr:dN(mN(!0,yX.isatty(2)))}});var wX=_((RQt,CX)=>{"use strict";var T9e=(t,e,r)=>{let o=t.indexOf(e);if(o===-1)return t;let a=e.length,n=0,u="";do u+=t.substr(n,o-n)+e+r,n=o+a,o=t.indexOf(e,n);while(o!==-1);return u+=t.substr(n),u},R9e=(t,e,r,o)=>{let a=0,n="";do{let u=t[o-1]==="\r";n+=t.substr(a,(u?o-1:o)-a)+e+(u?`\r +`:` +`)+r,a=o+1,o=t.indexOf(` +`,a)}while(o!==-1);return n+=t.substr(a),n};CX.exports={stringReplaceAll:T9e,stringEncaseCRLFWithFirstIndex:R9e}});var PX=_((NQt,DX)=>{"use strict";var N9e=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,IX=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,L9e=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,M9e=/\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.)|([^\\])/gi,O9e=new Map([["n",` +`],["r","\r"],["t"," "],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e","\x1B"],["a","\x07"]]);function vX(t){let e=t[0]==="u",r=t[1]==="{";return e&&!r&&t.length===5||t[0]==="x"&&t.length===3?String.fromCharCode(parseInt(t.slice(1),16)):e&&r?String.fromCodePoint(parseInt(t.slice(2,-1),16)):O9e.get(t)||t}function U9e(t,e){let r=[],o=e.trim().split(/\s*,\s*/g),a;for(let n of o){let u=Number(n);if(!Number.isNaN(u))r.push(u);else if(a=n.match(L9e))r.push(a[2].replace(M9e,(A,p,h)=>p?vX(p):h));else throw new Error(`Invalid Chalk template style argument: ${n} (in style '${t}')`)}return r}function _9e(t){IX.lastIndex=0;let e=[],r;for(;(r=IX.exec(t))!==null;){let o=r[1];if(r[2]){let a=U9e(o,r[2]);e.push([o].concat(a))}else e.push([o])}return e}function BX(t,e){let r={};for(let a of e)for(let n of a.styles)r[n[0]]=a.inverse?null:n.slice(1);let o=t;for(let[a,n]of Object.entries(r))if(!!Array.isArray(n)){if(!(a in o))throw new Error(`Unknown Chalk style: ${a}`);o=n.length>0?o[a](...n):o[a]}return o}DX.exports=(t,e)=>{let r=[],o=[],a=[];if(e.replace(N9e,(n,u,A,p,h,E)=>{if(u)a.push(vX(u));else if(p){let I=a.join("");a=[],o.push(r.length===0?I:BX(t,r)(I)),r.push({inverse:A,styles:_9e(p)})}else if(h){if(r.length===0)throw new Error("Found extraneous } in Chalk template literal");o.push(BX(t,r)(a.join(""))),a=[],r.pop()}else a.push(E)}),o.push(a.join("")),r.length>0){let n=`Chalk template literal is missing ${r.length} closing bracket${r.length===1?"":"s"} (\`}\`)`;throw new Error(n)}return o.join("")}});var vN=_((LQt,kX)=>{"use strict";var DI=vI(),{stdout:CN,stderr:wN}=yN(),{stringReplaceAll:H9e,stringEncaseCRLFWithFirstIndex:j9e}=wX(),SX=["ansi","ansi","ansi256","ansi16m"],Qy=Object.create(null),q9e=(t,e={})=>{if(e.level>3||e.level<0)throw new Error("The `level` option should be an integer from 0 to 3");let r=CN?CN.level:0;t.level=e.level===void 0?r:e.level},IN=class{constructor(e){return xX(e)}},xX=t=>{let e={};return q9e(e,t),e.template=(...r)=>W9e(e.template,...r),Object.setPrototypeOf(e,bP.prototype),Object.setPrototypeOf(e.template,e),e.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},e.template.Instance=IN,e.template};function bP(t){return xX(t)}for(let[t,e]of Object.entries(DI))Qy[t]={get(){let r=kP(this,BN(e.open,e.close,this._styler),this._isEmpty);return Object.defineProperty(this,t,{value:r}),r}};Qy.visible={get(){let t=kP(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:t}),t}};var bX=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(let t of bX)Qy[t]={get(){let{level:e}=this;return function(...r){let o=BN(DI.color[SX[e]][t](...r),DI.color.close,this._styler);return kP(this,o,this._isEmpty)}}};for(let t of bX){let e="bg"+t[0].toUpperCase()+t.slice(1);Qy[e]={get(){let{level:r}=this;return function(...o){let a=BN(DI.bgColor[SX[r]][t](...o),DI.bgColor.close,this._styler);return kP(this,a,this._isEmpty)}}}}var G9e=Object.defineProperties(()=>{},{...Qy,level:{enumerable:!0,get(){return this._generator.level},set(t){this._generator.level=t}}}),BN=(t,e,r)=>{let o,a;return r===void 0?(o=t,a=e):(o=r.openAll+t,a=e+r.closeAll),{open:t,close:e,openAll:o,closeAll:a,parent:r}},kP=(t,e,r)=>{let o=(...a)=>Y9e(o,a.length===1?""+a[0]:a.join(" "));return o.__proto__=G9e,o._generator=t,o._styler=e,o._isEmpty=r,o},Y9e=(t,e)=>{if(t.level<=0||!e)return t._isEmpty?"":e;let r=t._styler;if(r===void 0)return e;let{openAll:o,closeAll:a}=r;if(e.indexOf("\x1B")!==-1)for(;r!==void 0;)e=H9e(e,r.close,r.open),r=r.parent;let n=e.indexOf(` +`);return n!==-1&&(e=j9e(e,a,o,n)),o+e+a},EN,W9e=(t,...e)=>{let[r]=e;if(!Array.isArray(r))return e.join(" ");let o=e.slice(1),a=[r.raw[0]];for(let n=1;n<r.length;n++)a.push(String(o[n-1]).replace(/[{}\\]/g,"\\$&"),String(r.raw[n]));return EN===void 0&&(EN=PX()),EN(t,a.join(""))};Object.defineProperties(bP.prototype,Qy);var PI=bP();PI.supportsColor=CN;PI.stderr=bP({level:wN?wN.level:0});PI.stderr.supportsColor=wN;PI.Level={None:0,Basic:1,Ansi256:2,TrueColor:3,0:"None",1:"Basic",2:"Ansi256",3:"TrueColor"};kX.exports=PI});var QP=_(Ul=>{"use strict";Ul.isInteger=t=>typeof t=="number"?Number.isInteger(t):typeof t=="string"&&t.trim()!==""?Number.isInteger(Number(t)):!1;Ul.find=(t,e)=>t.nodes.find(r=>r.type===e);Ul.exceedsLimit=(t,e,r=1,o)=>o===!1||!Ul.isInteger(t)||!Ul.isInteger(e)?!1:(Number(e)-Number(t))/Number(r)>=o;Ul.escapeNode=(t,e=0,r)=>{let o=t.nodes[e];!o||(r&&o.type===r||o.type==="open"||o.type==="close")&&o.escaped!==!0&&(o.value="\\"+o.value,o.escaped=!0)};Ul.encloseBrace=t=>t.type!=="brace"?!1:t.commas>>0+t.ranges>>0===0?(t.invalid=!0,!0):!1;Ul.isInvalidBrace=t=>t.type!=="brace"?!1:t.invalid===!0||t.dollar?!0:t.commas>>0+t.ranges>>0===0||t.open!==!0||t.close!==!0?(t.invalid=!0,!0):!1;Ul.isOpenOrClose=t=>t.type==="open"||t.type==="close"?!0:t.open===!0||t.close===!0;Ul.reduce=t=>t.reduce((e,r)=>(r.type==="text"&&e.push(r.value),r.type==="range"&&(r.type="text"),e),[]);Ul.flatten=(...t)=>{let e=[],r=o=>{for(let a=0;a<o.length;a++){let n=o[a];Array.isArray(n)?r(n,e):n!==void 0&&e.push(n)}return e};return r(t),e}});var FP=_((OQt,FX)=>{"use strict";var QX=QP();FX.exports=(t,e={})=>{let r=(o,a={})=>{let n=e.escapeInvalid&&QX.isInvalidBrace(a),u=o.invalid===!0&&e.escapeInvalid===!0,A="";if(o.value)return(n||u)&&QX.isOpenOrClose(o)?"\\"+o.value:o.value;if(o.value)return o.value;if(o.nodes)for(let p of o.nodes)A+=r(p);return A};return r(t)}});var RX=_((UQt,TX)=>{"use strict";TX.exports=function(t){return typeof t=="number"?t-t===0:typeof t=="string"&&t.trim()!==""?Number.isFinite?Number.isFinite(+t):isFinite(+t):!1}});var qX=_((_Qt,jX)=>{"use strict";var NX=RX(),ud=(t,e,r)=>{if(NX(t)===!1)throw new TypeError("toRegexRange: expected the first argument to be a number");if(e===void 0||t===e)return String(t);if(NX(e)===!1)throw new TypeError("toRegexRange: expected the second argument to be a number.");let o={relaxZeros:!0,...r};typeof o.strictZeros=="boolean"&&(o.relaxZeros=o.strictZeros===!1);let a=String(o.relaxZeros),n=String(o.shorthand),u=String(o.capture),A=String(o.wrap),p=t+":"+e+"="+a+n+u+A;if(ud.cache.hasOwnProperty(p))return ud.cache[p].result;let h=Math.min(t,e),E=Math.max(t,e);if(Math.abs(h-E)===1){let T=t+"|"+e;return o.capture?`(${T})`:o.wrap===!1?T:`(?:${T})`}let I=HX(t)||HX(e),v={min:t,max:e,a:h,b:E},b=[],C=[];if(I&&(v.isPadded=I,v.maxLen=String(v.max).length),h<0){let T=E<0?Math.abs(E):1;C=LX(T,Math.abs(h),v,o),h=v.a=0}return E>=0&&(b=LX(h,E,v,o)),v.negatives=C,v.positives=b,v.result=V9e(C,b,o),o.capture===!0?v.result=`(${v.result})`:o.wrap!==!1&&b.length+C.length>1&&(v.result=`(?:${v.result})`),ud.cache[p]=v,v.result};function V9e(t,e,r){let o=DN(t,e,"-",!1,r)||[],a=DN(e,t,"",!1,r)||[],n=DN(t,e,"-?",!0,r)||[];return o.concat(n).concat(a).join("|")}function K9e(t,e){let r=1,o=1,a=OX(t,r),n=new Set([e]);for(;t<=a&&a<=e;)n.add(a),r+=1,a=OX(t,r);for(a=UX(e+1,o)-1;t<a&&a<=e;)n.add(a),o+=1,a=UX(e+1,o)-1;return n=[...n],n.sort(X9e),n}function J9e(t,e,r){if(t===e)return{pattern:t,count:[],digits:0};let o=z9e(t,e),a=o.length,n="",u=0;for(let A=0;A<a;A++){let[p,h]=o[A];p===h?n+=p:p!=="0"||h!=="9"?n+=Z9e(p,h,r):u++}return u&&(n+=r.shorthand===!0?"\\d":"[0-9]"),{pattern:n,count:[u],digits:a}}function LX(t,e,r,o){let a=K9e(t,e),n=[],u=t,A;for(let p=0;p<a.length;p++){let h=a[p],E=J9e(String(u),String(h),o),I="";if(!r.isPadded&&A&&A.pattern===E.pattern){A.count.length>1&&A.count.pop(),A.count.push(E.count[0]),A.string=A.pattern+_X(A.count),u=h+1;continue}r.isPadded&&(I=$9e(h,r,o)),E.string=I+E.pattern+_X(E.count),n.push(E),u=h+1,A=E}return n}function DN(t,e,r,o,a){let n=[];for(let u of t){let{string:A}=u;!o&&!MX(e,"string",A)&&n.push(r+A),o&&MX(e,"string",A)&&n.push(r+A)}return n}function z9e(t,e){let r=[];for(let o=0;o<t.length;o++)r.push([t[o],e[o]]);return r}function X9e(t,e){return t>e?1:e>t?-1:0}function MX(t,e,r){return t.some(o=>o[e]===r)}function OX(t,e){return Number(String(t).slice(0,-e)+"9".repeat(e))}function UX(t,e){return t-t%Math.pow(10,e)}function _X(t){let[e=0,r=""]=t;return r||e>1?`{${e+(r?","+r:"")}}`:""}function Z9e(t,e,r){return`[${t}${e-t===1?"":"-"}${e}]`}function HX(t){return/^-?(0+)\d/.test(t)}function $9e(t,e,r){if(!e.isPadded)return t;let o=Math.abs(e.maxLen-String(t).length),a=r.relaxZeros!==!1;switch(o){case 0:return"";case 1:return a?"0?":"0";case 2:return a?"0{0,2}":"00";default:return a?`0{0,${o}}`:`0{${o}}`}}ud.cache={};ud.clearCache=()=>ud.cache={};jX.exports=ud});var xN=_((HQt,XX)=>{"use strict";var e7e=Be("util"),WX=qX(),GX=t=>t!==null&&typeof t=="object"&&!Array.isArray(t),t7e=t=>e=>t===!0?Number(e):String(e),PN=t=>typeof t=="number"||typeof t=="string"&&t!=="",SI=t=>Number.isInteger(+t),SN=t=>{let e=`${t}`,r=-1;if(e[0]==="-"&&(e=e.slice(1)),e==="0")return!1;for(;e[++r]==="0";);return r>0},r7e=(t,e,r)=>typeof t=="string"||typeof e=="string"?!0:r.stringify===!0,n7e=(t,e,r)=>{if(e>0){let o=t[0]==="-"?"-":"";o&&(t=t.slice(1)),t=o+t.padStart(o?e-1:e,"0")}return r===!1?String(t):t},YX=(t,e)=>{let r=t[0]==="-"?"-":"";for(r&&(t=t.slice(1),e--);t.length<e;)t="0"+t;return r?"-"+t:t},i7e=(t,e)=>{t.negatives.sort((u,A)=>u<A?-1:u>A?1:0),t.positives.sort((u,A)=>u<A?-1:u>A?1:0);let r=e.capture?"":"?:",o="",a="",n;return t.positives.length&&(o=t.positives.join("|")),t.negatives.length&&(a=`-(${r}${t.negatives.join("|")})`),o&&a?n=`${o}|${a}`:n=o||a,e.wrap?`(${r}${n})`:n},VX=(t,e,r,o)=>{if(r)return WX(t,e,{wrap:!1,...o});let a=String.fromCharCode(t);if(t===e)return a;let n=String.fromCharCode(e);return`[${a}-${n}]`},KX=(t,e,r)=>{if(Array.isArray(t)){let o=r.wrap===!0,a=r.capture?"":"?:";return o?`(${a}${t.join("|")})`:t.join("|")}return WX(t,e,r)},JX=(...t)=>new RangeError("Invalid range arguments: "+e7e.inspect(...t)),zX=(t,e,r)=>{if(r.strictRanges===!0)throw JX([t,e]);return[]},s7e=(t,e)=>{if(e.strictRanges===!0)throw new TypeError(`Expected step "${t}" to be a number`);return[]},o7e=(t,e,r=1,o={})=>{let a=Number(t),n=Number(e);if(!Number.isInteger(a)||!Number.isInteger(n)){if(o.strictRanges===!0)throw JX([t,e]);return[]}a===0&&(a=0),n===0&&(n=0);let u=a>n,A=String(t),p=String(e),h=String(r);r=Math.max(Math.abs(r),1);let E=SN(A)||SN(p)||SN(h),I=E?Math.max(A.length,p.length,h.length):0,v=E===!1&&r7e(t,e,o)===!1,b=o.transform||t7e(v);if(o.toRegex&&r===1)return VX(YX(t,I),YX(e,I),!0,o);let C={negatives:[],positives:[]},T=J=>C[J<0?"negatives":"positives"].push(Math.abs(J)),L=[],U=0;for(;u?a>=n:a<=n;)o.toRegex===!0&&r>1?T(a):L.push(n7e(b(a,U),I,v)),a=u?a-r:a+r,U++;return o.toRegex===!0?r>1?i7e(C,o):KX(L,null,{wrap:!1,...o}):L},a7e=(t,e,r=1,o={})=>{if(!SI(t)&&t.length>1||!SI(e)&&e.length>1)return zX(t,e,o);let a=o.transform||(v=>String.fromCharCode(v)),n=`${t}`.charCodeAt(0),u=`${e}`.charCodeAt(0),A=n>u,p=Math.min(n,u),h=Math.max(n,u);if(o.toRegex&&r===1)return VX(p,h,!1,o);let E=[],I=0;for(;A?n>=u:n<=u;)E.push(a(n,I)),n=A?n-r:n+r,I++;return o.toRegex===!0?KX(E,null,{wrap:!1,options:o}):E},TP=(t,e,r,o={})=>{if(e==null&&PN(t))return[t];if(!PN(t)||!PN(e))return zX(t,e,o);if(typeof r=="function")return TP(t,e,1,{transform:r});if(GX(r))return TP(t,e,0,r);let a={...o};return a.capture===!0&&(a.wrap=!0),r=r||a.step||1,SI(r)?SI(t)&&SI(e)?o7e(t,e,r,a):a7e(t,e,Math.max(Math.abs(r),1),a):r!=null&&!GX(r)?s7e(r,a):TP(t,e,1,r)};XX.exports=TP});var eZ=_((jQt,$X)=>{"use strict";var l7e=xN(),ZX=QP(),c7e=(t,e={})=>{let r=(o,a={})=>{let n=ZX.isInvalidBrace(a),u=o.invalid===!0&&e.escapeInvalid===!0,A=n===!0||u===!0,p=e.escapeInvalid===!0?"\\":"",h="";if(o.isOpen===!0||o.isClose===!0)return p+o.value;if(o.type==="open")return A?p+o.value:"(";if(o.type==="close")return A?p+o.value:")";if(o.type==="comma")return o.prev.type==="comma"?"":A?o.value:"|";if(o.value)return o.value;if(o.nodes&&o.ranges>0){let E=ZX.reduce(o.nodes),I=l7e(...E,{...e,wrap:!1,toRegex:!0});if(I.length!==0)return E.length>1&&I.length>1?`(${I})`:I}if(o.nodes)for(let E of o.nodes)h+=r(E,o);return h};return r(t)};$X.exports=c7e});var nZ=_((qQt,rZ)=>{"use strict";var u7e=xN(),tZ=FP(),Fy=QP(),Ad=(t="",e="",r=!1)=>{let o=[];if(t=[].concat(t),e=[].concat(e),!e.length)return t;if(!t.length)return r?Fy.flatten(e).map(a=>`{${a}}`):e;for(let a of t)if(Array.isArray(a))for(let n of a)o.push(Ad(n,e,r));else for(let n of e)r===!0&&typeof n=="string"&&(n=`{${n}}`),o.push(Array.isArray(n)?Ad(a,n,r):a+n);return Fy.flatten(o)},A7e=(t,e={})=>{let r=e.rangeLimit===void 0?1e3:e.rangeLimit,o=(a,n={})=>{a.queue=[];let u=n,A=n.queue;for(;u.type!=="brace"&&u.type!=="root"&&u.parent;)u=u.parent,A=u.queue;if(a.invalid||a.dollar){A.push(Ad(A.pop(),tZ(a,e)));return}if(a.type==="brace"&&a.invalid!==!0&&a.nodes.length===2){A.push(Ad(A.pop(),["{}"]));return}if(a.nodes&&a.ranges>0){let I=Fy.reduce(a.nodes);if(Fy.exceedsLimit(...I,e.step,r))throw new RangeError("expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.");let v=u7e(...I,e);v.length===0&&(v=tZ(a,e)),A.push(Ad(A.pop(),v)),a.nodes=[];return}let p=Fy.encloseBrace(a),h=a.queue,E=a;for(;E.type!=="brace"&&E.type!=="root"&&E.parent;)E=E.parent,h=E.queue;for(let I=0;I<a.nodes.length;I++){let v=a.nodes[I];if(v.type==="comma"&&a.type==="brace"){I===1&&h.push(""),h.push("");continue}if(v.type==="close"){A.push(Ad(A.pop(),h,p));continue}if(v.value&&v.type!=="open"){h.push(Ad(h.pop(),v.value));continue}v.nodes&&o(v,a)}return h};return Fy.flatten(o(t))};rZ.exports=A7e});var sZ=_((GQt,iZ)=>{"use strict";iZ.exports={MAX_LENGTH:1024*64,CHAR_0:"0",CHAR_9:"9",CHAR_UPPERCASE_A:"A",CHAR_LOWERCASE_A:"a",CHAR_UPPERCASE_Z:"Z",CHAR_LOWERCASE_Z:"z",CHAR_LEFT_PARENTHESES:"(",CHAR_RIGHT_PARENTHESES:")",CHAR_ASTERISK:"*",CHAR_AMPERSAND:"&",CHAR_AT:"@",CHAR_BACKSLASH:"\\",CHAR_BACKTICK:"`",CHAR_CARRIAGE_RETURN:"\r",CHAR_CIRCUMFLEX_ACCENT:"^",CHAR_COLON:":",CHAR_COMMA:",",CHAR_DOLLAR:"$",CHAR_DOT:".",CHAR_DOUBLE_QUOTE:'"',CHAR_EQUAL:"=",CHAR_EXCLAMATION_MARK:"!",CHAR_FORM_FEED:"\f",CHAR_FORWARD_SLASH:"/",CHAR_HASH:"#",CHAR_HYPHEN_MINUS:"-",CHAR_LEFT_ANGLE_BRACKET:"<",CHAR_LEFT_CURLY_BRACE:"{",CHAR_LEFT_SQUARE_BRACKET:"[",CHAR_LINE_FEED:` +`,CHAR_NO_BREAK_SPACE:"\xA0",CHAR_PERCENT:"%",CHAR_PLUS:"+",CHAR_QUESTION_MARK:"?",CHAR_RIGHT_ANGLE_BRACKET:">",CHAR_RIGHT_CURLY_BRACE:"}",CHAR_RIGHT_SQUARE_BRACKET:"]",CHAR_SEMICOLON:";",CHAR_SINGLE_QUOTE:"'",CHAR_SPACE:" ",CHAR_TAB:" ",CHAR_UNDERSCORE:"_",CHAR_VERTICAL_LINE:"|",CHAR_ZERO_WIDTH_NOBREAK_SPACE:"\uFEFF"}});var uZ=_((YQt,cZ)=>{"use strict";var f7e=FP(),{MAX_LENGTH:oZ,CHAR_BACKSLASH:bN,CHAR_BACKTICK:p7e,CHAR_COMMA:h7e,CHAR_DOT:g7e,CHAR_LEFT_PARENTHESES:d7e,CHAR_RIGHT_PARENTHESES:m7e,CHAR_LEFT_CURLY_BRACE:y7e,CHAR_RIGHT_CURLY_BRACE:E7e,CHAR_LEFT_SQUARE_BRACKET:aZ,CHAR_RIGHT_SQUARE_BRACKET:lZ,CHAR_DOUBLE_QUOTE:C7e,CHAR_SINGLE_QUOTE:w7e,CHAR_NO_BREAK_SPACE:I7e,CHAR_ZERO_WIDTH_NOBREAK_SPACE:B7e}=sZ(),v7e=(t,e={})=>{if(typeof t!="string")throw new TypeError("Expected a string");let r=e||{},o=typeof r.maxLength=="number"?Math.min(oZ,r.maxLength):oZ;if(t.length>o)throw new SyntaxError(`Input length (${t.length}), exceeds max characters (${o})`);let a={type:"root",input:t,nodes:[]},n=[a],u=a,A=a,p=0,h=t.length,E=0,I=0,v,b={},C=()=>t[E++],T=L=>{if(L.type==="text"&&A.type==="dot"&&(A.type="text"),A&&A.type==="text"&&L.type==="text"){A.value+=L.value;return}return u.nodes.push(L),L.parent=u,L.prev=A,A=L,L};for(T({type:"bos"});E<h;)if(u=n[n.length-1],v=C(),!(v===B7e||v===I7e)){if(v===bN){T({type:"text",value:(e.keepEscaping?v:"")+C()});continue}if(v===lZ){T({type:"text",value:"\\"+v});continue}if(v===aZ){p++;let L=!0,U;for(;E<h&&(U=C());){if(v+=U,U===aZ){p++;continue}if(U===bN){v+=C();continue}if(U===lZ&&(p--,p===0))break}T({type:"text",value:v});continue}if(v===d7e){u=T({type:"paren",nodes:[]}),n.push(u),T({type:"text",value:v});continue}if(v===m7e){if(u.type!=="paren"){T({type:"text",value:v});continue}u=n.pop(),T({type:"text",value:v}),u=n[n.length-1];continue}if(v===C7e||v===w7e||v===p7e){let L=v,U;for(e.keepQuotes!==!0&&(v="");E<h&&(U=C());){if(U===bN){v+=U+C();continue}if(U===L){e.keepQuotes===!0&&(v+=U);break}v+=U}T({type:"text",value:v});continue}if(v===y7e){I++;let U={type:"brace",open:!0,close:!1,dollar:A.value&&A.value.slice(-1)==="$"||u.dollar===!0,depth:I,commas:0,ranges:0,nodes:[]};u=T(U),n.push(u),T({type:"open",value:v});continue}if(v===E7e){if(u.type!=="brace"){T({type:"text",value:v});continue}let L="close";u=n.pop(),u.close=!0,T({type:L,value:v}),I--,u=n[n.length-1];continue}if(v===h7e&&I>0){if(u.ranges>0){u.ranges=0;let L=u.nodes.shift();u.nodes=[L,{type:"text",value:f7e(u)}]}T({type:"comma",value:v}),u.commas++;continue}if(v===g7e&&I>0&&u.commas===0){let L=u.nodes;if(I===0||L.length===0){T({type:"text",value:v});continue}if(A.type==="dot"){if(u.range=[],A.value+=v,A.type="range",u.nodes.length!==3&&u.nodes.length!==5){u.invalid=!0,u.ranges=0,A.type="text";continue}u.ranges++,u.args=[];continue}if(A.type==="range"){L.pop();let U=L[L.length-1];U.value+=A.value+v,A=U,u.ranges--;continue}T({type:"dot",value:v});continue}T({type:"text",value:v})}do if(u=n.pop(),u.type!=="root"){u.nodes.forEach(J=>{J.nodes||(J.type==="open"&&(J.isOpen=!0),J.type==="close"&&(J.isClose=!0),J.nodes||(J.type="text"),J.invalid=!0)});let L=n[n.length-1],U=L.nodes.indexOf(u);L.nodes.splice(U,1,...u.nodes)}while(n.length>0);return T({type:"eos"}),a};cZ.exports=v7e});var pZ=_((WQt,fZ)=>{"use strict";var AZ=FP(),D7e=eZ(),P7e=nZ(),S7e=uZ(),rl=(t,e={})=>{let r=[];if(Array.isArray(t))for(let o of t){let a=rl.create(o,e);Array.isArray(a)?r.push(...a):r.push(a)}else r=[].concat(rl.create(t,e));return e&&e.expand===!0&&e.nodupes===!0&&(r=[...new Set(r)]),r};rl.parse=(t,e={})=>S7e(t,e);rl.stringify=(t,e={})=>AZ(typeof t=="string"?rl.parse(t,e):t,e);rl.compile=(t,e={})=>(typeof t=="string"&&(t=rl.parse(t,e)),D7e(t,e));rl.expand=(t,e={})=>{typeof t=="string"&&(t=rl.parse(t,e));let r=P7e(t,e);return e.noempty===!0&&(r=r.filter(Boolean)),e.nodupes===!0&&(r=[...new Set(r)]),r};rl.create=(t,e={})=>t===""||t.length<3?[t]:e.expand!==!0?rl.compile(t,e):rl.expand(t,e);fZ.exports=rl});var xI=_((VQt,yZ)=>{"use strict";var x7e=Be("path"),Vu="\\\\/",hZ=`[^${Vu}]`,Bf="\\.",b7e="\\+",k7e="\\?",RP="\\/",Q7e="(?=.)",gZ="[^/]",kN=`(?:${RP}|$)`,dZ=`(?:^|${RP})`,QN=`${Bf}{1,2}${kN}`,F7e=`(?!${Bf})`,T7e=`(?!${dZ}${QN})`,R7e=`(?!${Bf}{0,1}${kN})`,N7e=`(?!${QN})`,L7e=`[^.${RP}]`,M7e=`${gZ}*?`,mZ={DOT_LITERAL:Bf,PLUS_LITERAL:b7e,QMARK_LITERAL:k7e,SLASH_LITERAL:RP,ONE_CHAR:Q7e,QMARK:gZ,END_ANCHOR:kN,DOTS_SLASH:QN,NO_DOT:F7e,NO_DOTS:T7e,NO_DOT_SLASH:R7e,NO_DOTS_SLASH:N7e,QMARK_NO_DOT:L7e,STAR:M7e,START_ANCHOR:dZ},O7e={...mZ,SLASH_LITERAL:`[${Vu}]`,QMARK:hZ,STAR:`${hZ}*?`,DOTS_SLASH:`${Bf}{1,2}(?:[${Vu}]|$)`,NO_DOT:`(?!${Bf})`,NO_DOTS:`(?!(?:^|[${Vu}])${Bf}{1,2}(?:[${Vu}]|$))`,NO_DOT_SLASH:`(?!${Bf}{0,1}(?:[${Vu}]|$))`,NO_DOTS_SLASH:`(?!${Bf}{1,2}(?:[${Vu}]|$))`,QMARK_NO_DOT:`[^.${Vu}]`,START_ANCHOR:`(?:^|[${Vu}])`,END_ANCHOR:`(?:[${Vu}]|$)`},U7e={alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"};yZ.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:U7e,REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:x7e.sep,extglobChars(t){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${t.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(t){return t===!0?O7e:mZ}}});var bI=_(Pa=>{"use strict";var _7e=Be("path"),H7e=process.platform==="win32",{REGEX_BACKSLASH:j7e,REGEX_REMOVE_BACKSLASH:q7e,REGEX_SPECIAL_CHARS:G7e,REGEX_SPECIAL_CHARS_GLOBAL:Y7e}=xI();Pa.isObject=t=>t!==null&&typeof t=="object"&&!Array.isArray(t);Pa.hasRegexChars=t=>G7e.test(t);Pa.isRegexChar=t=>t.length===1&&Pa.hasRegexChars(t);Pa.escapeRegex=t=>t.replace(Y7e,"\\$1");Pa.toPosixSlashes=t=>t.replace(j7e,"/");Pa.removeBackslashes=t=>t.replace(q7e,e=>e==="\\"?"":e);Pa.supportsLookbehinds=()=>{let t=process.version.slice(1).split(".").map(Number);return t.length===3&&t[0]>=9||t[0]===8&&t[1]>=10};Pa.isWindows=t=>t&&typeof t.windows=="boolean"?t.windows:H7e===!0||_7e.sep==="\\";Pa.escapeLast=(t,e,r)=>{let o=t.lastIndexOf(e,r);return o===-1?t:t[o-1]==="\\"?Pa.escapeLast(t,e,o-1):`${t.slice(0,o)}\\${t.slice(o)}`};Pa.removePrefix=(t,e={})=>{let r=t;return r.startsWith("./")&&(r=r.slice(2),e.prefix="./"),r};Pa.wrapOutput=(t,e={},r={})=>{let o=r.contains?"":"^",a=r.contains?"":"$",n=`${o}(?:${t})${a}`;return e.negated===!0&&(n=`(?:^(?!${n}).*$)`),n}});var PZ=_((JQt,DZ)=>{"use strict";var EZ=bI(),{CHAR_ASTERISK:FN,CHAR_AT:W7e,CHAR_BACKWARD_SLASH:kI,CHAR_COMMA:V7e,CHAR_DOT:TN,CHAR_EXCLAMATION_MARK:RN,CHAR_FORWARD_SLASH:vZ,CHAR_LEFT_CURLY_BRACE:NN,CHAR_LEFT_PARENTHESES:LN,CHAR_LEFT_SQUARE_BRACKET:K7e,CHAR_PLUS:J7e,CHAR_QUESTION_MARK:CZ,CHAR_RIGHT_CURLY_BRACE:z7e,CHAR_RIGHT_PARENTHESES:wZ,CHAR_RIGHT_SQUARE_BRACKET:X7e}=xI(),IZ=t=>t===vZ||t===kI,BZ=t=>{t.isPrefix!==!0&&(t.depth=t.isGlobstar?1/0:1)},Z7e=(t,e)=>{let r=e||{},o=t.length-1,a=r.parts===!0||r.scanToEnd===!0,n=[],u=[],A=[],p=t,h=-1,E=0,I=0,v=!1,b=!1,C=!1,T=!1,L=!1,U=!1,J=!1,te=!1,le=!1,pe=!1,Ae=0,ye,ae,we={value:"",depth:0,isGlob:!1},Pe=()=>h>=o,g=()=>p.charCodeAt(h+1),Ee=()=>(ye=ae,p.charCodeAt(++h));for(;h<o;){ae=Ee();let Ie;if(ae===kI){J=we.backslashes=!0,ae=Ee(),ae===NN&&(U=!0);continue}if(U===!0||ae===NN){for(Ae++;Pe()!==!0&&(ae=Ee());){if(ae===kI){J=we.backslashes=!0,Ee();continue}if(ae===NN){Ae++;continue}if(U!==!0&&ae===TN&&(ae=Ee())===TN){if(v=we.isBrace=!0,C=we.isGlob=!0,pe=!0,a===!0)continue;break}if(U!==!0&&ae===V7e){if(v=we.isBrace=!0,C=we.isGlob=!0,pe=!0,a===!0)continue;break}if(ae===z7e&&(Ae--,Ae===0)){U=!1,v=we.isBrace=!0,pe=!0;break}}if(a===!0)continue;break}if(ae===vZ){if(n.push(h),u.push(we),we={value:"",depth:0,isGlob:!1},pe===!0)continue;if(ye===TN&&h===E+1){E+=2;continue}I=h+1;continue}if(r.noext!==!0&&(ae===J7e||ae===W7e||ae===FN||ae===CZ||ae===RN)===!0&&g()===LN){if(C=we.isGlob=!0,T=we.isExtglob=!0,pe=!0,ae===RN&&h===E&&(le=!0),a===!0){for(;Pe()!==!0&&(ae=Ee());){if(ae===kI){J=we.backslashes=!0,ae=Ee();continue}if(ae===wZ){C=we.isGlob=!0,pe=!0;break}}continue}break}if(ae===FN){if(ye===FN&&(L=we.isGlobstar=!0),C=we.isGlob=!0,pe=!0,a===!0)continue;break}if(ae===CZ){if(C=we.isGlob=!0,pe=!0,a===!0)continue;break}if(ae===K7e){for(;Pe()!==!0&&(Ie=Ee());){if(Ie===kI){J=we.backslashes=!0,Ee();continue}if(Ie===X7e){b=we.isBracket=!0,C=we.isGlob=!0,pe=!0;break}}if(a===!0)continue;break}if(r.nonegate!==!0&&ae===RN&&h===E){te=we.negated=!0,E++;continue}if(r.noparen!==!0&&ae===LN){if(C=we.isGlob=!0,a===!0){for(;Pe()!==!0&&(ae=Ee());){if(ae===LN){J=we.backslashes=!0,ae=Ee();continue}if(ae===wZ){pe=!0;break}}continue}break}if(C===!0){if(pe=!0,a===!0)continue;break}}r.noext===!0&&(T=!1,C=!1);let De=p,ce="",ne="";E>0&&(ce=p.slice(0,E),p=p.slice(E),I-=E),De&&C===!0&&I>0?(De=p.slice(0,I),ne=p.slice(I)):C===!0?(De="",ne=p):De=p,De&&De!==""&&De!=="/"&&De!==p&&IZ(De.charCodeAt(De.length-1))&&(De=De.slice(0,-1)),r.unescape===!0&&(ne&&(ne=EZ.removeBackslashes(ne)),De&&J===!0&&(De=EZ.removeBackslashes(De)));let ee={prefix:ce,input:t,start:E,base:De,glob:ne,isBrace:v,isBracket:b,isGlob:C,isExtglob:T,isGlobstar:L,negated:te,negatedExtglob:le};if(r.tokens===!0&&(ee.maxDepth=0,IZ(ae)||u.push(we),ee.tokens=u),r.parts===!0||r.tokens===!0){let Ie;for(let ke=0;ke<n.length;ke++){let ht=Ie?Ie+1:E,H=n[ke],lt=t.slice(ht,H);r.tokens&&(ke===0&&E!==0?(u[ke].isPrefix=!0,u[ke].value=ce):u[ke].value=lt,BZ(u[ke]),ee.maxDepth+=u[ke].depth),(ke!==0||lt!=="")&&A.push(lt),Ie=H}if(Ie&&Ie+1<t.length){let ke=t.slice(Ie+1);A.push(ke),r.tokens&&(u[u.length-1].value=ke,BZ(u[u.length-1]),ee.maxDepth+=u[u.length-1].depth)}ee.slashes=n,ee.parts=A}return ee};DZ.exports=Z7e});var bZ=_((zQt,xZ)=>{"use strict";var NP=xI(),nl=bI(),{MAX_LENGTH:LP,POSIX_REGEX_SOURCE:$7e,REGEX_NON_SPECIAL_CHARS:eYe,REGEX_SPECIAL_CHARS_BACKREF:tYe,REPLACEMENTS:SZ}=NP,rYe=(t,e)=>{if(typeof e.expandRange=="function")return e.expandRange(...t,e);t.sort();let r=`[${t.join("-")}]`;try{new RegExp(r)}catch{return t.map(a=>nl.escapeRegex(a)).join("..")}return r},Ty=(t,e)=>`Missing ${t}: "${e}" - use "\\\\${e}" to match literal characters`,MN=(t,e)=>{if(typeof t!="string")throw new TypeError("Expected a string");t=SZ[t]||t;let r={...e},o=typeof r.maxLength=="number"?Math.min(LP,r.maxLength):LP,a=t.length;if(a>o)throw new SyntaxError(`Input length: ${a}, exceeds maximum allowed length: ${o}`);let n={type:"bos",value:"",output:r.prepend||""},u=[n],A=r.capture?"":"?:",p=nl.isWindows(e),h=NP.globChars(p),E=NP.extglobChars(h),{DOT_LITERAL:I,PLUS_LITERAL:v,SLASH_LITERAL:b,ONE_CHAR:C,DOTS_SLASH:T,NO_DOT:L,NO_DOT_SLASH:U,NO_DOTS_SLASH:J,QMARK:te,QMARK_NO_DOT:le,STAR:pe,START_ANCHOR:Ae}=h,ye=x=>`(${A}(?:(?!${Ae}${x.dot?T:I}).)*?)`,ae=r.dot?"":L,we=r.dot?te:le,Pe=r.bash===!0?ye(r):pe;r.capture&&(Pe=`(${Pe})`),typeof r.noext=="boolean"&&(r.noextglob=r.noext);let g={input:t,index:-1,start:0,dot:r.dot===!0,consumed:"",output:"",prefix:"",backtrack:!1,negated:!1,brackets:0,braces:0,parens:0,quotes:0,globstar:!1,tokens:u};t=nl.removePrefix(t,g),a=t.length;let Ee=[],De=[],ce=[],ne=n,ee,Ie=()=>g.index===a-1,ke=g.peek=(x=1)=>t[g.index+x],ht=g.advance=()=>t[++g.index]||"",H=()=>t.slice(g.index+1),lt=(x="",w=0)=>{g.consumed+=x,g.index+=w},Re=x=>{g.output+=x.output!=null?x.output:x.value,lt(x.value)},Qe=()=>{let x=1;for(;ke()==="!"&&(ke(2)!=="("||ke(3)==="?");)ht(),g.start++,x++;return x%2===0?!1:(g.negated=!0,g.start++,!0)},be=x=>{g[x]++,ce.push(x)},_e=x=>{g[x]--,ce.pop()},Te=x=>{if(ne.type==="globstar"){let w=g.braces>0&&(x.type==="comma"||x.type==="brace"),S=x.extglob===!0||Ee.length&&(x.type==="pipe"||x.type==="paren");x.type!=="slash"&&x.type!=="paren"&&!w&&!S&&(g.output=g.output.slice(0,-ne.output.length),ne.type="star",ne.value="*",ne.output=Pe,g.output+=ne.output)}if(Ee.length&&x.type!=="paren"&&(Ee[Ee.length-1].inner+=x.value),(x.value||x.output)&&Re(x),ne&&ne.type==="text"&&x.type==="text"){ne.value+=x.value,ne.output=(ne.output||"")+x.value;return}x.prev=ne,u.push(x),ne=x},Je=(x,w)=>{let S={...E[w],conditions:1,inner:""};S.prev=ne,S.parens=g.parens,S.output=g.output;let y=(r.capture?"(":"")+S.open;be("parens"),Te({type:x,value:w,output:g.output?"":C}),Te({type:"paren",extglob:!0,value:ht(),output:y}),Ee.push(S)},He=x=>{let w=x.close+(r.capture?")":""),S;if(x.type==="negate"){let y=Pe;if(x.inner&&x.inner.length>1&&x.inner.includes("/")&&(y=ye(r)),(y!==Pe||Ie()||/^\)+$/.test(H()))&&(w=x.close=`)$))${y}`),x.inner.includes("*")&&(S=H())&&/^\.[^\\/.]+$/.test(S)){let F=MN(S,{...e,fastpaths:!1}).output;w=x.close=`)${F})${y})`}x.prev.type==="bos"&&(g.negatedExtglob=!0)}Te({type:"paren",extglob:!0,value:ee,output:w}),_e("parens")};if(r.fastpaths!==!1&&!/(^[*!]|[/()[\]{}"])/.test(t)){let x=!1,w=t.replace(tYe,(S,y,F,z,X,Z)=>z==="\\"?(x=!0,S):z==="?"?y?y+z+(X?te.repeat(X.length):""):Z===0?we+(X?te.repeat(X.length):""):te.repeat(F.length):z==="."?I.repeat(F.length):z==="*"?y?y+z+(X?Pe:""):Pe:y?S:`\\${S}`);return x===!0&&(r.unescape===!0?w=w.replace(/\\/g,""):w=w.replace(/\\+/g,S=>S.length%2===0?"\\\\":S?"\\":"")),w===t&&r.contains===!0?(g.output=t,g):(g.output=nl.wrapOutput(w,g,e),g)}for(;!Ie();){if(ee=ht(),ee==="\0")continue;if(ee==="\\"){let S=ke();if(S==="/"&&r.bash!==!0||S==="."||S===";")continue;if(!S){ee+="\\",Te({type:"text",value:ee});continue}let y=/^\\+/.exec(H()),F=0;if(y&&y[0].length>2&&(F=y[0].length,g.index+=F,F%2!==0&&(ee+="\\")),r.unescape===!0?ee=ht():ee+=ht(),g.brackets===0){Te({type:"text",value:ee});continue}}if(g.brackets>0&&(ee!=="]"||ne.value==="["||ne.value==="[^")){if(r.posix!==!1&&ee===":"){let S=ne.value.slice(1);if(S.includes("[")&&(ne.posix=!0,S.includes(":"))){let y=ne.value.lastIndexOf("["),F=ne.value.slice(0,y),z=ne.value.slice(y+2),X=$7e[z];if(X){ne.value=F+X,g.backtrack=!0,ht(),!n.output&&u.indexOf(ne)===1&&(n.output=C);continue}}}(ee==="["&&ke()!==":"||ee==="-"&&ke()==="]")&&(ee=`\\${ee}`),ee==="]"&&(ne.value==="["||ne.value==="[^")&&(ee=`\\${ee}`),r.posix===!0&&ee==="!"&&ne.value==="["&&(ee="^"),ne.value+=ee,Re({value:ee});continue}if(g.quotes===1&&ee!=='"'){ee=nl.escapeRegex(ee),ne.value+=ee,Re({value:ee});continue}if(ee==='"'){g.quotes=g.quotes===1?0:1,r.keepQuotes===!0&&Te({type:"text",value:ee});continue}if(ee==="("){be("parens"),Te({type:"paren",value:ee});continue}if(ee===")"){if(g.parens===0&&r.strictBrackets===!0)throw new SyntaxError(Ty("opening","("));let S=Ee[Ee.length-1];if(S&&g.parens===S.parens+1){He(Ee.pop());continue}Te({type:"paren",value:ee,output:g.parens?")":"\\)"}),_e("parens");continue}if(ee==="["){if(r.nobracket===!0||!H().includes("]")){if(r.nobracket!==!0&&r.strictBrackets===!0)throw new SyntaxError(Ty("closing","]"));ee=`\\${ee}`}else be("brackets");Te({type:"bracket",value:ee});continue}if(ee==="]"){if(r.nobracket===!0||ne&&ne.type==="bracket"&&ne.value.length===1){Te({type:"text",value:ee,output:`\\${ee}`});continue}if(g.brackets===0){if(r.strictBrackets===!0)throw new SyntaxError(Ty("opening","["));Te({type:"text",value:ee,output:`\\${ee}`});continue}_e("brackets");let S=ne.value.slice(1);if(ne.posix!==!0&&S[0]==="^"&&!S.includes("/")&&(ee=`/${ee}`),ne.value+=ee,Re({value:ee}),r.literalBrackets===!1||nl.hasRegexChars(S))continue;let y=nl.escapeRegex(ne.value);if(g.output=g.output.slice(0,-ne.value.length),r.literalBrackets===!0){g.output+=y,ne.value=y;continue}ne.value=`(${A}${y}|${ne.value})`,g.output+=ne.value;continue}if(ee==="{"&&r.nobrace!==!0){be("braces");let S={type:"brace",value:ee,output:"(",outputIndex:g.output.length,tokensIndex:g.tokens.length};De.push(S),Te(S);continue}if(ee==="}"){let S=De[De.length-1];if(r.nobrace===!0||!S){Te({type:"text",value:ee,output:ee});continue}let y=")";if(S.dots===!0){let F=u.slice(),z=[];for(let X=F.length-1;X>=0&&(u.pop(),F[X].type!=="brace");X--)F[X].type!=="dots"&&z.unshift(F[X].value);y=rYe(z,r),g.backtrack=!0}if(S.comma!==!0&&S.dots!==!0){let F=g.output.slice(0,S.outputIndex),z=g.tokens.slice(S.tokensIndex);S.value=S.output="\\{",ee=y="\\}",g.output=F;for(let X of z)g.output+=X.output||X.value}Te({type:"brace",value:ee,output:y}),_e("braces"),De.pop();continue}if(ee==="|"){Ee.length>0&&Ee[Ee.length-1].conditions++,Te({type:"text",value:ee});continue}if(ee===","){let S=ee,y=De[De.length-1];y&&ce[ce.length-1]==="braces"&&(y.comma=!0,S="|"),Te({type:"comma",value:ee,output:S});continue}if(ee==="/"){if(ne.type==="dot"&&g.index===g.start+1){g.start=g.index+1,g.consumed="",g.output="",u.pop(),ne=n;continue}Te({type:"slash",value:ee,output:b});continue}if(ee==="."){if(g.braces>0&&ne.type==="dot"){ne.value==="."&&(ne.output=I);let S=De[De.length-1];ne.type="dots",ne.output+=ee,ne.value+=ee,S.dots=!0;continue}if(g.braces+g.parens===0&&ne.type!=="bos"&&ne.type!=="slash"){Te({type:"text",value:ee,output:I});continue}Te({type:"dot",value:ee,output:I});continue}if(ee==="?"){if(!(ne&&ne.value==="(")&&r.noextglob!==!0&&ke()==="("&&ke(2)!=="?"){Je("qmark",ee);continue}if(ne&&ne.type==="paren"){let y=ke(),F=ee;if(y==="<"&&!nl.supportsLookbehinds())throw new Error("Node.js v10 or higher is required for regex lookbehinds");(ne.value==="("&&!/[!=<:]/.test(y)||y==="<"&&!/<([!=]|\w+>)/.test(H()))&&(F=`\\${ee}`),Te({type:"text",value:ee,output:F});continue}if(r.dot!==!0&&(ne.type==="slash"||ne.type==="bos")){Te({type:"qmark",value:ee,output:le});continue}Te({type:"qmark",value:ee,output:te});continue}if(ee==="!"){if(r.noextglob!==!0&&ke()==="("&&(ke(2)!=="?"||!/[!=<:]/.test(ke(3)))){Je("negate",ee);continue}if(r.nonegate!==!0&&g.index===0){Qe();continue}}if(ee==="+"){if(r.noextglob!==!0&&ke()==="("&&ke(2)!=="?"){Je("plus",ee);continue}if(ne&&ne.value==="("||r.regex===!1){Te({type:"plus",value:ee,output:v});continue}if(ne&&(ne.type==="bracket"||ne.type==="paren"||ne.type==="brace")||g.parens>0){Te({type:"plus",value:ee});continue}Te({type:"plus",value:v});continue}if(ee==="@"){if(r.noextglob!==!0&&ke()==="("&&ke(2)!=="?"){Te({type:"at",extglob:!0,value:ee,output:""});continue}Te({type:"text",value:ee});continue}if(ee!=="*"){(ee==="$"||ee==="^")&&(ee=`\\${ee}`);let S=eYe.exec(H());S&&(ee+=S[0],g.index+=S[0].length),Te({type:"text",value:ee});continue}if(ne&&(ne.type==="globstar"||ne.star===!0)){ne.type="star",ne.star=!0,ne.value+=ee,ne.output=Pe,g.backtrack=!0,g.globstar=!0,lt(ee);continue}let x=H();if(r.noextglob!==!0&&/^\([^?]/.test(x)){Je("star",ee);continue}if(ne.type==="star"){if(r.noglobstar===!0){lt(ee);continue}let S=ne.prev,y=S.prev,F=S.type==="slash"||S.type==="bos",z=y&&(y.type==="star"||y.type==="globstar");if(r.bash===!0&&(!F||x[0]&&x[0]!=="/")){Te({type:"star",value:ee,output:""});continue}let X=g.braces>0&&(S.type==="comma"||S.type==="brace"),Z=Ee.length&&(S.type==="pipe"||S.type==="paren");if(!F&&S.type!=="paren"&&!X&&!Z){Te({type:"star",value:ee,output:""});continue}for(;x.slice(0,3)==="/**";){let ie=t[g.index+4];if(ie&&ie!=="/")break;x=x.slice(3),lt("/**",3)}if(S.type==="bos"&&Ie()){ne.type="globstar",ne.value+=ee,ne.output=ye(r),g.output=ne.output,g.globstar=!0,lt(ee);continue}if(S.type==="slash"&&S.prev.type!=="bos"&&!z&&Ie()){g.output=g.output.slice(0,-(S.output+ne.output).length),S.output=`(?:${S.output}`,ne.type="globstar",ne.output=ye(r)+(r.strictSlashes?")":"|$)"),ne.value+=ee,g.globstar=!0,g.output+=S.output+ne.output,lt(ee);continue}if(S.type==="slash"&&S.prev.type!=="bos"&&x[0]==="/"){let ie=x[1]!==void 0?"|$":"";g.output=g.output.slice(0,-(S.output+ne.output).length),S.output=`(?:${S.output}`,ne.type="globstar",ne.output=`${ye(r)}${b}|${b}${ie})`,ne.value+=ee,g.output+=S.output+ne.output,g.globstar=!0,lt(ee+ht()),Te({type:"slash",value:"/",output:""});continue}if(S.type==="bos"&&x[0]==="/"){ne.type="globstar",ne.value+=ee,ne.output=`(?:^|${b}|${ye(r)}${b})`,g.output=ne.output,g.globstar=!0,lt(ee+ht()),Te({type:"slash",value:"/",output:""});continue}g.output=g.output.slice(0,-ne.output.length),ne.type="globstar",ne.output=ye(r),ne.value+=ee,g.output+=ne.output,g.globstar=!0,lt(ee);continue}let w={type:"star",value:ee,output:Pe};if(r.bash===!0){w.output=".*?",(ne.type==="bos"||ne.type==="slash")&&(w.output=ae+w.output),Te(w);continue}if(ne&&(ne.type==="bracket"||ne.type==="paren")&&r.regex===!0){w.output=ee,Te(w);continue}(g.index===g.start||ne.type==="slash"||ne.type==="dot")&&(ne.type==="dot"?(g.output+=U,ne.output+=U):r.dot===!0?(g.output+=J,ne.output+=J):(g.output+=ae,ne.output+=ae),ke()!=="*"&&(g.output+=C,ne.output+=C)),Te(w)}for(;g.brackets>0;){if(r.strictBrackets===!0)throw new SyntaxError(Ty("closing","]"));g.output=nl.escapeLast(g.output,"["),_e("brackets")}for(;g.parens>0;){if(r.strictBrackets===!0)throw new SyntaxError(Ty("closing",")"));g.output=nl.escapeLast(g.output,"("),_e("parens")}for(;g.braces>0;){if(r.strictBrackets===!0)throw new SyntaxError(Ty("closing","}"));g.output=nl.escapeLast(g.output,"{"),_e("braces")}if(r.strictSlashes!==!0&&(ne.type==="star"||ne.type==="bracket")&&Te({type:"maybe_slash",value:"",output:`${b}?`}),g.backtrack===!0){g.output="";for(let x of g.tokens)g.output+=x.output!=null?x.output:x.value,x.suffix&&(g.output+=x.suffix)}return g};MN.fastpaths=(t,e)=>{let r={...e},o=typeof r.maxLength=="number"?Math.min(LP,r.maxLength):LP,a=t.length;if(a>o)throw new SyntaxError(`Input length: ${a}, exceeds maximum allowed length: ${o}`);t=SZ[t]||t;let n=nl.isWindows(e),{DOT_LITERAL:u,SLASH_LITERAL:A,ONE_CHAR:p,DOTS_SLASH:h,NO_DOT:E,NO_DOTS:I,NO_DOTS_SLASH:v,STAR:b,START_ANCHOR:C}=NP.globChars(n),T=r.dot?I:E,L=r.dot?v:E,U=r.capture?"":"?:",J={negated:!1,prefix:""},te=r.bash===!0?".*?":b;r.capture&&(te=`(${te})`);let le=ae=>ae.noglobstar===!0?te:`(${U}(?:(?!${C}${ae.dot?h:u}).)*?)`,pe=ae=>{switch(ae){case"*":return`${T}${p}${te}`;case".*":return`${u}${p}${te}`;case"*.*":return`${T}${te}${u}${p}${te}`;case"*/*":return`${T}${te}${A}${p}${L}${te}`;case"**":return T+le(r);case"**/*":return`(?:${T}${le(r)}${A})?${L}${p}${te}`;case"**/*.*":return`(?:${T}${le(r)}${A})?${L}${te}${u}${p}${te}`;case"**/.*":return`(?:${T}${le(r)}${A})?${u}${p}${te}`;default:{let we=/^(.*?)\.(\w+)$/.exec(ae);if(!we)return;let Pe=pe(we[1]);return Pe?Pe+u+we[2]:void 0}}},Ae=nl.removePrefix(t,J),ye=pe(Ae);return ye&&r.strictSlashes!==!0&&(ye+=`${A}?`),ye};xZ.exports=MN});var QZ=_((XQt,kZ)=>{"use strict";var nYe=Be("path"),iYe=PZ(),ON=bZ(),UN=bI(),sYe=xI(),oYe=t=>t&&typeof t=="object"&&!Array.isArray(t),Oi=(t,e,r=!1)=>{if(Array.isArray(t)){let E=t.map(v=>Oi(v,e,r));return v=>{for(let b of E){let C=b(v);if(C)return C}return!1}}let o=oYe(t)&&t.tokens&&t.input;if(t===""||typeof t!="string"&&!o)throw new TypeError("Expected pattern to be a non-empty string");let a=e||{},n=UN.isWindows(e),u=o?Oi.compileRe(t,e):Oi.makeRe(t,e,!1,!0),A=u.state;delete u.state;let p=()=>!1;if(a.ignore){let E={...e,ignore:null,onMatch:null,onResult:null};p=Oi(a.ignore,E,r)}let h=(E,I=!1)=>{let{isMatch:v,match:b,output:C}=Oi.test(E,u,e,{glob:t,posix:n}),T={glob:t,state:A,regex:u,posix:n,input:E,output:C,match:b,isMatch:v};return typeof a.onResult=="function"&&a.onResult(T),v===!1?(T.isMatch=!1,I?T:!1):p(E)?(typeof a.onIgnore=="function"&&a.onIgnore(T),T.isMatch=!1,I?T:!1):(typeof a.onMatch=="function"&&a.onMatch(T),I?T:!0)};return r&&(h.state=A),h};Oi.test=(t,e,r,{glob:o,posix:a}={})=>{if(typeof t!="string")throw new TypeError("Expected input to be a string");if(t==="")return{isMatch:!1,output:""};let n=r||{},u=n.format||(a?UN.toPosixSlashes:null),A=t===o,p=A&&u?u(t):t;return A===!1&&(p=u?u(t):t,A=p===o),(A===!1||n.capture===!0)&&(n.matchBase===!0||n.basename===!0?A=Oi.matchBase(t,e,r,a):A=e.exec(p)),{isMatch:Boolean(A),match:A,output:p}};Oi.matchBase=(t,e,r,o=UN.isWindows(r))=>(e instanceof RegExp?e:Oi.makeRe(e,r)).test(nYe.basename(t));Oi.isMatch=(t,e,r)=>Oi(e,r)(t);Oi.parse=(t,e)=>Array.isArray(t)?t.map(r=>Oi.parse(r,e)):ON(t,{...e,fastpaths:!1});Oi.scan=(t,e)=>iYe(t,e);Oi.compileRe=(t,e,r=!1,o=!1)=>{if(r===!0)return t.output;let a=e||{},n=a.contains?"":"^",u=a.contains?"":"$",A=`${n}(?:${t.output})${u}`;t&&t.negated===!0&&(A=`^(?!${A}).*$`);let p=Oi.toRegex(A,e);return o===!0&&(p.state=t),p};Oi.makeRe=(t,e={},r=!1,o=!1)=>{if(!t||typeof t!="string")throw new TypeError("Expected a non-empty string");let a={negated:!1,fastpaths:!0};return e.fastpaths!==!1&&(t[0]==="."||t[0]==="*")&&(a.output=ON.fastpaths(t,e)),a.output||(a=ON(t,e)),Oi.compileRe(a,e,r,o)};Oi.toRegex=(t,e)=>{try{let r=e||{};return new RegExp(t,r.flags||(r.nocase?"i":""))}catch(r){if(e&&e.debug===!0)throw r;return/$^/}};Oi.constants=sYe;kZ.exports=Oi});var TZ=_((ZQt,FZ)=>{"use strict";FZ.exports=QZ()});var Zo=_(($Qt,MZ)=>{"use strict";var NZ=Be("util"),LZ=pZ(),Ku=TZ(),_N=bI(),RZ=t=>t===""||t==="./",yi=(t,e,r)=>{e=[].concat(e),t=[].concat(t);let o=new Set,a=new Set,n=new Set,u=0,A=E=>{n.add(E.output),r&&r.onResult&&r.onResult(E)};for(let E=0;E<e.length;E++){let I=Ku(String(e[E]),{...r,onResult:A},!0),v=I.state.negated||I.state.negatedExtglob;v&&u++;for(let b of t){let C=I(b,!0);!(v?!C.isMatch:C.isMatch)||(v?o.add(C.output):(o.delete(C.output),a.add(C.output)))}}let h=(u===e.length?[...n]:[...a]).filter(E=>!o.has(E));if(r&&h.length===0){if(r.failglob===!0)throw new Error(`No matches found for "${e.join(", ")}"`);if(r.nonull===!0||r.nullglob===!0)return r.unescape?e.map(E=>E.replace(/\\/g,"")):e}return h};yi.match=yi;yi.matcher=(t,e)=>Ku(t,e);yi.isMatch=(t,e,r)=>Ku(e,r)(t);yi.any=yi.isMatch;yi.not=(t,e,r={})=>{e=[].concat(e).map(String);let o=new Set,a=[],n=A=>{r.onResult&&r.onResult(A),a.push(A.output)},u=new Set(yi(t,e,{...r,onResult:n}));for(let A of a)u.has(A)||o.add(A);return[...o]};yi.contains=(t,e,r)=>{if(typeof t!="string")throw new TypeError(`Expected a string: "${NZ.inspect(t)}"`);if(Array.isArray(e))return e.some(o=>yi.contains(t,o,r));if(typeof e=="string"){if(RZ(t)||RZ(e))return!1;if(t.includes(e)||t.startsWith("./")&&t.slice(2).includes(e))return!0}return yi.isMatch(t,e,{...r,contains:!0})};yi.matchKeys=(t,e,r)=>{if(!_N.isObject(t))throw new TypeError("Expected the first argument to be an object");let o=yi(Object.keys(t),e,r),a={};for(let n of o)a[n]=t[n];return a};yi.some=(t,e,r)=>{let o=[].concat(t);for(let a of[].concat(e)){let n=Ku(String(a),r);if(o.some(u=>n(u)))return!0}return!1};yi.every=(t,e,r)=>{let o=[].concat(t);for(let a of[].concat(e)){let n=Ku(String(a),r);if(!o.every(u=>n(u)))return!1}return!0};yi.all=(t,e,r)=>{if(typeof t!="string")throw new TypeError(`Expected a string: "${NZ.inspect(t)}"`);return[].concat(e).every(o=>Ku(o,r)(t))};yi.capture=(t,e,r)=>{let o=_N.isWindows(r),n=Ku.makeRe(String(t),{...r,capture:!0}).exec(o?_N.toPosixSlashes(e):e);if(n)return n.slice(1).map(u=>u===void 0?"":u)};yi.makeRe=(...t)=>Ku.makeRe(...t);yi.scan=(...t)=>Ku.scan(...t);yi.parse=(t,e)=>{let r=[];for(let o of[].concat(t||[]))for(let a of LZ(String(o),e))r.push(Ku.parse(a,e));return r};yi.braces=(t,e)=>{if(typeof t!="string")throw new TypeError("Expected a string");return e&&e.nobrace===!0||!/\{.*\}/.test(t)?[t]:LZ(t,e)};yi.braceExpand=(t,e)=>{if(typeof t!="string")throw new TypeError("Expected a string");return yi.braces(t,{...e,expand:!0})};MZ.exports=yi});var UZ=_((eFt,OZ)=>{"use strict";OZ.exports=({onlyFirst:t=!1}={})=>{let e=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(e,t?void 0:"g")}});var MP=_((tFt,_Z)=>{"use strict";var aYe=UZ();_Z.exports=t=>typeof t=="string"?t.replace(aYe(),""):t});var jZ=_((rFt,HZ)=>{function lYe(){this.__data__=[],this.size=0}HZ.exports=lYe});var Ry=_((nFt,qZ)=>{function cYe(t,e){return t===e||t!==t&&e!==e}qZ.exports=cYe});var QI=_((iFt,GZ)=>{var uYe=Ry();function AYe(t,e){for(var r=t.length;r--;)if(uYe(t[r][0],e))return r;return-1}GZ.exports=AYe});var WZ=_((sFt,YZ)=>{var fYe=QI(),pYe=Array.prototype,hYe=pYe.splice;function gYe(t){var e=this.__data__,r=fYe(e,t);if(r<0)return!1;var o=e.length-1;return r==o?e.pop():hYe.call(e,r,1),--this.size,!0}YZ.exports=gYe});var KZ=_((oFt,VZ)=>{var dYe=QI();function mYe(t){var e=this.__data__,r=dYe(e,t);return r<0?void 0:e[r][1]}VZ.exports=mYe});var zZ=_((aFt,JZ)=>{var yYe=QI();function EYe(t){return yYe(this.__data__,t)>-1}JZ.exports=EYe});var ZZ=_((lFt,XZ)=>{var CYe=QI();function wYe(t,e){var r=this.__data__,o=CYe(r,t);return o<0?(++this.size,r.push([t,e])):r[o][1]=e,this}XZ.exports=wYe});var FI=_((cFt,$Z)=>{var IYe=jZ(),BYe=WZ(),vYe=KZ(),DYe=zZ(),PYe=ZZ();function Ny(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e<r;){var o=t[e];this.set(o[0],o[1])}}Ny.prototype.clear=IYe;Ny.prototype.delete=BYe;Ny.prototype.get=vYe;Ny.prototype.has=DYe;Ny.prototype.set=PYe;$Z.exports=Ny});var t$=_((uFt,e$)=>{var SYe=FI();function xYe(){this.__data__=new SYe,this.size=0}e$.exports=xYe});var n$=_((AFt,r$)=>{function bYe(t){var e=this.__data__,r=e.delete(t);return this.size=e.size,r}r$.exports=bYe});var s$=_((fFt,i$)=>{function kYe(t){return this.__data__.get(t)}i$.exports=kYe});var a$=_((pFt,o$)=>{function QYe(t){return this.__data__.has(t)}o$.exports=QYe});var HN=_((hFt,l$)=>{var FYe=typeof global=="object"&&global&&global.Object===Object&&global;l$.exports=FYe});var _l=_((gFt,c$)=>{var TYe=HN(),RYe=typeof self=="object"&&self&&self.Object===Object&&self,NYe=TYe||RYe||Function("return this")();c$.exports=NYe});var fd=_((dFt,u$)=>{var LYe=_l(),MYe=LYe.Symbol;u$.exports=MYe});var h$=_((mFt,p$)=>{var A$=fd(),f$=Object.prototype,OYe=f$.hasOwnProperty,UYe=f$.toString,TI=A$?A$.toStringTag:void 0;function _Ye(t){var e=OYe.call(t,TI),r=t[TI];try{t[TI]=void 0;var o=!0}catch{}var a=UYe.call(t);return o&&(e?t[TI]=r:delete t[TI]),a}p$.exports=_Ye});var d$=_((yFt,g$)=>{var HYe=Object.prototype,jYe=HYe.toString;function qYe(t){return jYe.call(t)}g$.exports=qYe});var pd=_((EFt,E$)=>{var m$=fd(),GYe=h$(),YYe=d$(),WYe="[object Null]",VYe="[object Undefined]",y$=m$?m$.toStringTag:void 0;function KYe(t){return t==null?t===void 0?VYe:WYe:y$&&y$ in Object(t)?GYe(t):YYe(t)}E$.exports=KYe});var il=_((CFt,C$)=>{function JYe(t){var e=typeof t;return t!=null&&(e=="object"||e=="function")}C$.exports=JYe});var OP=_((wFt,w$)=>{var zYe=pd(),XYe=il(),ZYe="[object AsyncFunction]",$Ye="[object Function]",eWe="[object GeneratorFunction]",tWe="[object Proxy]";function rWe(t){if(!XYe(t))return!1;var e=zYe(t);return e==$Ye||e==eWe||e==ZYe||e==tWe}w$.exports=rWe});var B$=_((IFt,I$)=>{var nWe=_l(),iWe=nWe["__core-js_shared__"];I$.exports=iWe});var P$=_((BFt,D$)=>{var jN=B$(),v$=function(){var t=/[^.]+$/.exec(jN&&jN.keys&&jN.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}();function sWe(t){return!!v$&&v$ in t}D$.exports=sWe});var qN=_((vFt,S$)=>{var oWe=Function.prototype,aWe=oWe.toString;function lWe(t){if(t!=null){try{return aWe.call(t)}catch{}try{return t+""}catch{}}return""}S$.exports=lWe});var b$=_((DFt,x$)=>{var cWe=OP(),uWe=P$(),AWe=il(),fWe=qN(),pWe=/[\\^$.*+?()[\]{}|]/g,hWe=/^\[object .+?Constructor\]$/,gWe=Function.prototype,dWe=Object.prototype,mWe=gWe.toString,yWe=dWe.hasOwnProperty,EWe=RegExp("^"+mWe.call(yWe).replace(pWe,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function CWe(t){if(!AWe(t)||uWe(t))return!1;var e=cWe(t)?EWe:hWe;return e.test(fWe(t))}x$.exports=CWe});var Q$=_((PFt,k$)=>{function wWe(t,e){return t?.[e]}k$.exports=wWe});var Jp=_((SFt,F$)=>{var IWe=b$(),BWe=Q$();function vWe(t,e){var r=BWe(t,e);return IWe(r)?r:void 0}F$.exports=vWe});var UP=_((xFt,T$)=>{var DWe=Jp(),PWe=_l(),SWe=DWe(PWe,"Map");T$.exports=SWe});var RI=_((bFt,R$)=>{var xWe=Jp(),bWe=xWe(Object,"create");R$.exports=bWe});var M$=_((kFt,L$)=>{var N$=RI();function kWe(){this.__data__=N$?N$(null):{},this.size=0}L$.exports=kWe});var U$=_((QFt,O$)=>{function QWe(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e}O$.exports=QWe});var H$=_((FFt,_$)=>{var FWe=RI(),TWe="__lodash_hash_undefined__",RWe=Object.prototype,NWe=RWe.hasOwnProperty;function LWe(t){var e=this.__data__;if(FWe){var r=e[t];return r===TWe?void 0:r}return NWe.call(e,t)?e[t]:void 0}_$.exports=LWe});var q$=_((TFt,j$)=>{var MWe=RI(),OWe=Object.prototype,UWe=OWe.hasOwnProperty;function _We(t){var e=this.__data__;return MWe?e[t]!==void 0:UWe.call(e,t)}j$.exports=_We});var Y$=_((RFt,G$)=>{var HWe=RI(),jWe="__lodash_hash_undefined__";function qWe(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=HWe&&e===void 0?jWe:e,this}G$.exports=qWe});var V$=_((NFt,W$)=>{var GWe=M$(),YWe=U$(),WWe=H$(),VWe=q$(),KWe=Y$();function Ly(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e<r;){var o=t[e];this.set(o[0],o[1])}}Ly.prototype.clear=GWe;Ly.prototype.delete=YWe;Ly.prototype.get=WWe;Ly.prototype.has=VWe;Ly.prototype.set=KWe;W$.exports=Ly});var z$=_((LFt,J$)=>{var K$=V$(),JWe=FI(),zWe=UP();function XWe(){this.size=0,this.__data__={hash:new K$,map:new(zWe||JWe),string:new K$}}J$.exports=XWe});var Z$=_((MFt,X$)=>{function ZWe(t){var e=typeof t;return e=="string"||e=="number"||e=="symbol"||e=="boolean"?t!=="__proto__":t===null}X$.exports=ZWe});var NI=_((OFt,$$)=>{var $We=Z$();function eVe(t,e){var r=t.__data__;return $We(e)?r[typeof e=="string"?"string":"hash"]:r.map}$$.exports=eVe});var tee=_((UFt,eee)=>{var tVe=NI();function rVe(t){var e=tVe(this,t).delete(t);return this.size-=e?1:0,e}eee.exports=rVe});var nee=_((_Ft,ree)=>{var nVe=NI();function iVe(t){return nVe(this,t).get(t)}ree.exports=iVe});var see=_((HFt,iee)=>{var sVe=NI();function oVe(t){return sVe(this,t).has(t)}iee.exports=oVe});var aee=_((jFt,oee)=>{var aVe=NI();function lVe(t,e){var r=aVe(this,t),o=r.size;return r.set(t,e),this.size+=r.size==o?0:1,this}oee.exports=lVe});var _P=_((qFt,lee)=>{var cVe=z$(),uVe=tee(),AVe=nee(),fVe=see(),pVe=aee();function My(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e<r;){var o=t[e];this.set(o[0],o[1])}}My.prototype.clear=cVe;My.prototype.delete=uVe;My.prototype.get=AVe;My.prototype.has=fVe;My.prototype.set=pVe;lee.exports=My});var uee=_((GFt,cee)=>{var hVe=FI(),gVe=UP(),dVe=_P(),mVe=200;function yVe(t,e){var r=this.__data__;if(r instanceof hVe){var o=r.__data__;if(!gVe||o.length<mVe-1)return o.push([t,e]),this.size=++r.size,this;r=this.__data__=new dVe(o)}return r.set(t,e),this.size=r.size,this}cee.exports=yVe});var HP=_((YFt,Aee)=>{var EVe=FI(),CVe=t$(),wVe=n$(),IVe=s$(),BVe=a$(),vVe=uee();function Oy(t){var e=this.__data__=new EVe(t);this.size=e.size}Oy.prototype.clear=CVe;Oy.prototype.delete=wVe;Oy.prototype.get=IVe;Oy.prototype.has=BVe;Oy.prototype.set=vVe;Aee.exports=Oy});var pee=_((WFt,fee)=>{var DVe="__lodash_hash_undefined__";function PVe(t){return this.__data__.set(t,DVe),this}fee.exports=PVe});var gee=_((VFt,hee)=>{function SVe(t){return this.__data__.has(t)}hee.exports=SVe});var mee=_((KFt,dee)=>{var xVe=_P(),bVe=pee(),kVe=gee();function jP(t){var e=-1,r=t==null?0:t.length;for(this.__data__=new xVe;++e<r;)this.add(t[e])}jP.prototype.add=jP.prototype.push=bVe;jP.prototype.has=kVe;dee.exports=jP});var Eee=_((JFt,yee)=>{function QVe(t,e){for(var r=-1,o=t==null?0:t.length;++r<o;)if(e(t[r],r,t))return!0;return!1}yee.exports=QVe});var wee=_((zFt,Cee)=>{function FVe(t,e){return t.has(e)}Cee.exports=FVe});var GN=_((XFt,Iee)=>{var TVe=mee(),RVe=Eee(),NVe=wee(),LVe=1,MVe=2;function OVe(t,e,r,o,a,n){var u=r&LVe,A=t.length,p=e.length;if(A!=p&&!(u&&p>A))return!1;var h=n.get(t),E=n.get(e);if(h&&E)return h==e&&E==t;var I=-1,v=!0,b=r&MVe?new TVe:void 0;for(n.set(t,e),n.set(e,t);++I<A;){var C=t[I],T=e[I];if(o)var L=u?o(T,C,I,e,t,n):o(C,T,I,t,e,n);if(L!==void 0){if(L)continue;v=!1;break}if(b){if(!RVe(e,function(U,J){if(!NVe(b,J)&&(C===U||a(C,U,r,o,n)))return b.push(J)})){v=!1;break}}else if(!(C===T||a(C,T,r,o,n))){v=!1;break}}return n.delete(t),n.delete(e),v}Iee.exports=OVe});var YN=_((ZFt,Bee)=>{var UVe=_l(),_Ve=UVe.Uint8Array;Bee.exports=_Ve});var Dee=_(($Ft,vee)=>{function HVe(t){var e=-1,r=Array(t.size);return t.forEach(function(o,a){r[++e]=[a,o]}),r}vee.exports=HVe});var See=_((eTt,Pee)=>{function jVe(t){var e=-1,r=Array(t.size);return t.forEach(function(o){r[++e]=o}),r}Pee.exports=jVe});var Fee=_((tTt,Qee)=>{var xee=fd(),bee=YN(),qVe=Ry(),GVe=GN(),YVe=Dee(),WVe=See(),VVe=1,KVe=2,JVe="[object Boolean]",zVe="[object Date]",XVe="[object Error]",ZVe="[object Map]",$Ve="[object Number]",eKe="[object RegExp]",tKe="[object Set]",rKe="[object String]",nKe="[object Symbol]",iKe="[object ArrayBuffer]",sKe="[object DataView]",kee=xee?xee.prototype:void 0,WN=kee?kee.valueOf:void 0;function oKe(t,e,r,o,a,n,u){switch(r){case sKe:if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)return!1;t=t.buffer,e=e.buffer;case iKe:return!(t.byteLength!=e.byteLength||!n(new bee(t),new bee(e)));case JVe:case zVe:case $Ve:return qVe(+t,+e);case XVe:return t.name==e.name&&t.message==e.message;case eKe:case rKe:return t==e+"";case ZVe:var A=YVe;case tKe:var p=o&VVe;if(A||(A=WVe),t.size!=e.size&&!p)return!1;var h=u.get(t);if(h)return h==e;o|=KVe,u.set(t,e);var E=GVe(A(t),A(e),o,a,n,u);return u.delete(t),E;case nKe:if(WN)return WN.call(t)==WN.call(e)}return!1}Qee.exports=oKe});var qP=_((rTt,Tee)=>{function aKe(t,e){for(var r=-1,o=e.length,a=t.length;++r<o;)t[a+r]=e[r];return t}Tee.exports=aKe});var Hl=_((nTt,Ree)=>{var lKe=Array.isArray;Ree.exports=lKe});var VN=_((iTt,Nee)=>{var cKe=qP(),uKe=Hl();function AKe(t,e,r){var o=e(t);return uKe(t)?o:cKe(o,r(t))}Nee.exports=AKe});var Mee=_((sTt,Lee)=>{function fKe(t,e){for(var r=-1,o=t==null?0:t.length,a=0,n=[];++r<o;){var u=t[r];e(u,r,t)&&(n[a++]=u)}return n}Lee.exports=fKe});var KN=_((oTt,Oee)=>{function pKe(){return[]}Oee.exports=pKe});var GP=_((aTt,_ee)=>{var hKe=Mee(),gKe=KN(),dKe=Object.prototype,mKe=dKe.propertyIsEnumerable,Uee=Object.getOwnPropertySymbols,yKe=Uee?function(t){return t==null?[]:(t=Object(t),hKe(Uee(t),function(e){return mKe.call(t,e)}))}:gKe;_ee.exports=yKe});var jee=_((lTt,Hee)=>{function EKe(t,e){for(var r=-1,o=Array(t);++r<t;)o[r]=e(r);return o}Hee.exports=EKe});var Ju=_((cTt,qee)=>{function CKe(t){return t!=null&&typeof t=="object"}qee.exports=CKe});var Yee=_((uTt,Gee)=>{var wKe=pd(),IKe=Ju(),BKe="[object Arguments]";function vKe(t){return IKe(t)&&wKe(t)==BKe}Gee.exports=vKe});var LI=_((ATt,Kee)=>{var Wee=Yee(),DKe=Ju(),Vee=Object.prototype,PKe=Vee.hasOwnProperty,SKe=Vee.propertyIsEnumerable,xKe=Wee(function(){return arguments}())?Wee:function(t){return DKe(t)&&PKe.call(t,"callee")&&!SKe.call(t,"callee")};Kee.exports=xKe});var zee=_((fTt,Jee)=>{function bKe(){return!1}Jee.exports=bKe});var OI=_((MI,Uy)=>{var kKe=_l(),QKe=zee(),$ee=typeof MI=="object"&&MI&&!MI.nodeType&&MI,Xee=$ee&&typeof Uy=="object"&&Uy&&!Uy.nodeType&&Uy,FKe=Xee&&Xee.exports===$ee,Zee=FKe?kKe.Buffer:void 0,TKe=Zee?Zee.isBuffer:void 0,RKe=TKe||QKe;Uy.exports=RKe});var UI=_((pTt,ete)=>{var NKe=9007199254740991,LKe=/^(?:0|[1-9]\d*)$/;function MKe(t,e){var r=typeof t;return e=e??NKe,!!e&&(r=="number"||r!="symbol"&&LKe.test(t))&&t>-1&&t%1==0&&t<e}ete.exports=MKe});var YP=_((hTt,tte)=>{var OKe=9007199254740991;function UKe(t){return typeof t=="number"&&t>-1&&t%1==0&&t<=OKe}tte.exports=UKe});var nte=_((gTt,rte)=>{var _Ke=pd(),HKe=YP(),jKe=Ju(),qKe="[object Arguments]",GKe="[object Array]",YKe="[object Boolean]",WKe="[object Date]",VKe="[object Error]",KKe="[object Function]",JKe="[object Map]",zKe="[object Number]",XKe="[object Object]",ZKe="[object RegExp]",$Ke="[object Set]",eJe="[object String]",tJe="[object WeakMap]",rJe="[object ArrayBuffer]",nJe="[object DataView]",iJe="[object Float32Array]",sJe="[object Float64Array]",oJe="[object Int8Array]",aJe="[object Int16Array]",lJe="[object Int32Array]",cJe="[object Uint8Array]",uJe="[object Uint8ClampedArray]",AJe="[object Uint16Array]",fJe="[object Uint32Array]",ui={};ui[iJe]=ui[sJe]=ui[oJe]=ui[aJe]=ui[lJe]=ui[cJe]=ui[uJe]=ui[AJe]=ui[fJe]=!0;ui[qKe]=ui[GKe]=ui[rJe]=ui[YKe]=ui[nJe]=ui[WKe]=ui[VKe]=ui[KKe]=ui[JKe]=ui[zKe]=ui[XKe]=ui[ZKe]=ui[$Ke]=ui[eJe]=ui[tJe]=!1;function pJe(t){return jKe(t)&&HKe(t.length)&&!!ui[_Ke(t)]}rte.exports=pJe});var WP=_((dTt,ite)=>{function hJe(t){return function(e){return t(e)}}ite.exports=hJe});var VP=_((_I,_y)=>{var gJe=HN(),ste=typeof _I=="object"&&_I&&!_I.nodeType&&_I,HI=ste&&typeof _y=="object"&&_y&&!_y.nodeType&&_y,dJe=HI&&HI.exports===ste,JN=dJe&&gJe.process,mJe=function(){try{var t=HI&&HI.require&&HI.require("util").types;return t||JN&&JN.binding&&JN.binding("util")}catch{}}();_y.exports=mJe});var KP=_((mTt,lte)=>{var yJe=nte(),EJe=WP(),ote=VP(),ate=ote&&ote.isTypedArray,CJe=ate?EJe(ate):yJe;lte.exports=CJe});var zN=_((yTt,cte)=>{var wJe=jee(),IJe=LI(),BJe=Hl(),vJe=OI(),DJe=UI(),PJe=KP(),SJe=Object.prototype,xJe=SJe.hasOwnProperty;function bJe(t,e){var r=BJe(t),o=!r&&IJe(t),a=!r&&!o&&vJe(t),n=!r&&!o&&!a&&PJe(t),u=r||o||a||n,A=u?wJe(t.length,String):[],p=A.length;for(var h in t)(e||xJe.call(t,h))&&!(u&&(h=="length"||a&&(h=="offset"||h=="parent")||n&&(h=="buffer"||h=="byteLength"||h=="byteOffset")||DJe(h,p)))&&A.push(h);return A}cte.exports=bJe});var JP=_((ETt,ute)=>{var kJe=Object.prototype;function QJe(t){var e=t&&t.constructor,r=typeof e=="function"&&e.prototype||kJe;return t===r}ute.exports=QJe});var XN=_((CTt,Ate)=>{function FJe(t,e){return function(r){return t(e(r))}}Ate.exports=FJe});var pte=_((wTt,fte)=>{var TJe=XN(),RJe=TJe(Object.keys,Object);fte.exports=RJe});var gte=_((ITt,hte)=>{var NJe=JP(),LJe=pte(),MJe=Object.prototype,OJe=MJe.hasOwnProperty;function UJe(t){if(!NJe(t))return LJe(t);var e=[];for(var r in Object(t))OJe.call(t,r)&&r!="constructor"&&e.push(r);return e}hte.exports=UJe});var jI=_((BTt,dte)=>{var _Je=OP(),HJe=YP();function jJe(t){return t!=null&&HJe(t.length)&&!_Je(t)}dte.exports=jJe});var zP=_((vTt,mte)=>{var qJe=zN(),GJe=gte(),YJe=jI();function WJe(t){return YJe(t)?qJe(t):GJe(t)}mte.exports=WJe});var ZN=_((DTt,yte)=>{var VJe=VN(),KJe=GP(),JJe=zP();function zJe(t){return VJe(t,JJe,KJe)}yte.exports=zJe});var wte=_((PTt,Cte)=>{var Ete=ZN(),XJe=1,ZJe=Object.prototype,$Je=ZJe.hasOwnProperty;function eze(t,e,r,o,a,n){var u=r&XJe,A=Ete(t),p=A.length,h=Ete(e),E=h.length;if(p!=E&&!u)return!1;for(var I=p;I--;){var v=A[I];if(!(u?v in e:$Je.call(e,v)))return!1}var b=n.get(t),C=n.get(e);if(b&&C)return b==e&&C==t;var T=!0;n.set(t,e),n.set(e,t);for(var L=u;++I<p;){v=A[I];var U=t[v],J=e[v];if(o)var te=u?o(J,U,v,e,t,n):o(U,J,v,t,e,n);if(!(te===void 0?U===J||a(U,J,r,o,n):te)){T=!1;break}L||(L=v=="constructor")}if(T&&!L){var le=t.constructor,pe=e.constructor;le!=pe&&"constructor"in t&&"constructor"in e&&!(typeof le=="function"&&le instanceof le&&typeof pe=="function"&&pe instanceof pe)&&(T=!1)}return n.delete(t),n.delete(e),T}Cte.exports=eze});var Bte=_((STt,Ite)=>{var tze=Jp(),rze=_l(),nze=tze(rze,"DataView");Ite.exports=nze});var Dte=_((xTt,vte)=>{var ize=Jp(),sze=_l(),oze=ize(sze,"Promise");vte.exports=oze});var Ste=_((bTt,Pte)=>{var aze=Jp(),lze=_l(),cze=aze(lze,"Set");Pte.exports=cze});var bte=_((kTt,xte)=>{var uze=Jp(),Aze=_l(),fze=uze(Aze,"WeakMap");xte.exports=fze});var qI=_((QTt,Lte)=>{var $N=Bte(),eL=UP(),tL=Dte(),rL=Ste(),nL=bte(),Nte=pd(),Hy=qN(),kte="[object Map]",pze="[object Object]",Qte="[object Promise]",Fte="[object Set]",Tte="[object WeakMap]",Rte="[object DataView]",hze=Hy($N),gze=Hy(eL),dze=Hy(tL),mze=Hy(rL),yze=Hy(nL),hd=Nte;($N&&hd(new $N(new ArrayBuffer(1)))!=Rte||eL&&hd(new eL)!=kte||tL&&hd(tL.resolve())!=Qte||rL&&hd(new rL)!=Fte||nL&&hd(new nL)!=Tte)&&(hd=function(t){var e=Nte(t),r=e==pze?t.constructor:void 0,o=r?Hy(r):"";if(o)switch(o){case hze:return Rte;case gze:return kte;case dze:return Qte;case mze:return Fte;case yze:return Tte}return e});Lte.exports=hd});var Gte=_((FTt,qte)=>{var iL=HP(),Eze=GN(),Cze=Fee(),wze=wte(),Mte=qI(),Ote=Hl(),Ute=OI(),Ize=KP(),Bze=1,_te="[object Arguments]",Hte="[object Array]",XP="[object Object]",vze=Object.prototype,jte=vze.hasOwnProperty;function Dze(t,e,r,o,a,n){var u=Ote(t),A=Ote(e),p=u?Hte:Mte(t),h=A?Hte:Mte(e);p=p==_te?XP:p,h=h==_te?XP:h;var E=p==XP,I=h==XP,v=p==h;if(v&&Ute(t)){if(!Ute(e))return!1;u=!0,E=!1}if(v&&!E)return n||(n=new iL),u||Ize(t)?Eze(t,e,r,o,a,n):Cze(t,e,p,r,o,a,n);if(!(r&Bze)){var b=E&&jte.call(t,"__wrapped__"),C=I&&jte.call(e,"__wrapped__");if(b||C){var T=b?t.value():t,L=C?e.value():e;return n||(n=new iL),a(T,L,r,o,n)}}return v?(n||(n=new iL),wze(t,e,r,o,a,n)):!1}qte.exports=Dze});var Kte=_((TTt,Vte)=>{var Pze=Gte(),Yte=Ju();function Wte(t,e,r,o,a){return t===e?!0:t==null||e==null||!Yte(t)&&!Yte(e)?t!==t&&e!==e:Pze(t,e,r,o,Wte,a)}Vte.exports=Wte});var zte=_((RTt,Jte)=>{var Sze=Kte();function xze(t,e){return Sze(t,e)}Jte.exports=xze});var sL=_((NTt,Xte)=>{var bze=Jp(),kze=function(){try{var t=bze(Object,"defineProperty");return t({},"",{}),t}catch{}}();Xte.exports=kze});var ZP=_((LTt,$te)=>{var Zte=sL();function Qze(t,e,r){e=="__proto__"&&Zte?Zte(t,e,{configurable:!0,enumerable:!0,value:r,writable:!0}):t[e]=r}$te.exports=Qze});var oL=_((MTt,ere)=>{var Fze=ZP(),Tze=Ry();function Rze(t,e,r){(r!==void 0&&!Tze(t[e],r)||r===void 0&&!(e in t))&&Fze(t,e,r)}ere.exports=Rze});var rre=_((OTt,tre)=>{function Nze(t){return function(e,r,o){for(var a=-1,n=Object(e),u=o(e),A=u.length;A--;){var p=u[t?A:++a];if(r(n[p],p,n)===!1)break}return e}}tre.exports=Nze});var ire=_((UTt,nre)=>{var Lze=rre(),Mze=Lze();nre.exports=Mze});var aL=_((GI,jy)=>{var Oze=_l(),lre=typeof GI=="object"&&GI&&!GI.nodeType&&GI,sre=lre&&typeof jy=="object"&&jy&&!jy.nodeType&&jy,Uze=sre&&sre.exports===lre,ore=Uze?Oze.Buffer:void 0,are=ore?ore.allocUnsafe:void 0;function _ze(t,e){if(e)return t.slice();var r=t.length,o=are?are(r):new t.constructor(r);return t.copy(o),o}jy.exports=_ze});var $P=_((_Tt,ure)=>{var cre=YN();function Hze(t){var e=new t.constructor(t.byteLength);return new cre(e).set(new cre(t)),e}ure.exports=Hze});var lL=_((HTt,Are)=>{var jze=$P();function qze(t,e){var r=e?jze(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.length)}Are.exports=qze});var eS=_((jTt,fre)=>{function Gze(t,e){var r=-1,o=t.length;for(e||(e=Array(o));++r<o;)e[r]=t[r];return e}fre.exports=Gze});var gre=_((qTt,hre)=>{var Yze=il(),pre=Object.create,Wze=function(){function t(){}return function(e){if(!Yze(e))return{};if(pre)return pre(e);t.prototype=e;var r=new t;return t.prototype=void 0,r}}();hre.exports=Wze});var tS=_((GTt,dre)=>{var Vze=XN(),Kze=Vze(Object.getPrototypeOf,Object);dre.exports=Kze});var cL=_((YTt,mre)=>{var Jze=gre(),zze=tS(),Xze=JP();function Zze(t){return typeof t.constructor=="function"&&!Xze(t)?Jze(zze(t)):{}}mre.exports=Zze});var Ere=_((WTt,yre)=>{var $ze=jI(),eXe=Ju();function tXe(t){return eXe(t)&&$ze(t)}yre.exports=tXe});var uL=_((VTt,wre)=>{var rXe=pd(),nXe=tS(),iXe=Ju(),sXe="[object Object]",oXe=Function.prototype,aXe=Object.prototype,Cre=oXe.toString,lXe=aXe.hasOwnProperty,cXe=Cre.call(Object);function uXe(t){if(!iXe(t)||rXe(t)!=sXe)return!1;var e=nXe(t);if(e===null)return!0;var r=lXe.call(e,"constructor")&&e.constructor;return typeof r=="function"&&r instanceof r&&Cre.call(r)==cXe}wre.exports=uXe});var AL=_((KTt,Ire)=>{function AXe(t,e){if(!(e==="constructor"&&typeof t[e]=="function")&&e!="__proto__")return t[e]}Ire.exports=AXe});var rS=_((JTt,Bre)=>{var fXe=ZP(),pXe=Ry(),hXe=Object.prototype,gXe=hXe.hasOwnProperty;function dXe(t,e,r){var o=t[e];(!(gXe.call(t,e)&&pXe(o,r))||r===void 0&&!(e in t))&&fXe(t,e,r)}Bre.exports=dXe});var gd=_((zTt,vre)=>{var mXe=rS(),yXe=ZP();function EXe(t,e,r,o){var a=!r;r||(r={});for(var n=-1,u=e.length;++n<u;){var A=e[n],p=o?o(r[A],t[A],A,r,t):void 0;p===void 0&&(p=t[A]),a?yXe(r,A,p):mXe(r,A,p)}return r}vre.exports=EXe});var Pre=_((XTt,Dre)=>{function CXe(t){var e=[];if(t!=null)for(var r in Object(t))e.push(r);return e}Dre.exports=CXe});var xre=_((ZTt,Sre)=>{var wXe=il(),IXe=JP(),BXe=Pre(),vXe=Object.prototype,DXe=vXe.hasOwnProperty;function PXe(t){if(!wXe(t))return BXe(t);var e=IXe(t),r=[];for(var o in t)o=="constructor"&&(e||!DXe.call(t,o))||r.push(o);return r}Sre.exports=PXe});var qy=_(($Tt,bre)=>{var SXe=zN(),xXe=xre(),bXe=jI();function kXe(t){return bXe(t)?SXe(t,!0):xXe(t)}bre.exports=kXe});var Qre=_((eRt,kre)=>{var QXe=gd(),FXe=qy();function TXe(t){return QXe(t,FXe(t))}kre.exports=TXe});var Mre=_((tRt,Lre)=>{var Fre=oL(),RXe=aL(),NXe=lL(),LXe=eS(),MXe=cL(),Tre=LI(),Rre=Hl(),OXe=Ere(),UXe=OI(),_Xe=OP(),HXe=il(),jXe=uL(),qXe=KP(),Nre=AL(),GXe=Qre();function YXe(t,e,r,o,a,n,u){var A=Nre(t,r),p=Nre(e,r),h=u.get(p);if(h){Fre(t,r,h);return}var E=n?n(A,p,r+"",t,e,u):void 0,I=E===void 0;if(I){var v=Rre(p),b=!v&&UXe(p),C=!v&&!b&&qXe(p);E=p,v||b||C?Rre(A)?E=A:OXe(A)?E=LXe(A):b?(I=!1,E=RXe(p,!0)):C?(I=!1,E=NXe(p,!0)):E=[]:jXe(p)||Tre(p)?(E=A,Tre(A)?E=GXe(A):(!HXe(A)||_Xe(A))&&(E=MXe(p))):I=!1}I&&(u.set(p,E),a(E,p,o,n,u),u.delete(p)),Fre(t,r,E)}Lre.exports=YXe});var _re=_((rRt,Ure)=>{var WXe=HP(),VXe=oL(),KXe=ire(),JXe=Mre(),zXe=il(),XXe=qy(),ZXe=AL();function Ore(t,e,r,o,a){t!==e&&KXe(e,function(n,u){if(a||(a=new WXe),zXe(n))JXe(t,e,u,r,Ore,o,a);else{var A=o?o(ZXe(t,u),n,u+"",t,e,a):void 0;A===void 0&&(A=n),VXe(t,u,A)}},XXe)}Ure.exports=Ore});var fL=_((nRt,Hre)=>{function $Xe(t){return t}Hre.exports=$Xe});var qre=_((iRt,jre)=>{function eZe(t,e,r){switch(r.length){case 0:return t.call(e);case 1:return t.call(e,r[0]);case 2:return t.call(e,r[0],r[1]);case 3:return t.call(e,r[0],r[1],r[2])}return t.apply(e,r)}jre.exports=eZe});var pL=_((sRt,Yre)=>{var tZe=qre(),Gre=Math.max;function rZe(t,e,r){return e=Gre(e===void 0?t.length-1:e,0),function(){for(var o=arguments,a=-1,n=Gre(o.length-e,0),u=Array(n);++a<n;)u[a]=o[e+a];a=-1;for(var A=Array(e+1);++a<e;)A[a]=o[a];return A[e]=r(u),tZe(t,this,A)}}Yre.exports=rZe});var Vre=_((oRt,Wre)=>{function nZe(t){return function(){return t}}Wre.exports=nZe});var zre=_((aRt,Jre)=>{var iZe=Vre(),Kre=sL(),sZe=fL(),oZe=Kre?function(t,e){return Kre(t,"toString",{configurable:!0,enumerable:!1,value:iZe(e),writable:!0})}:sZe;Jre.exports=oZe});var Zre=_((lRt,Xre)=>{var aZe=800,lZe=16,cZe=Date.now;function uZe(t){var e=0,r=0;return function(){var o=cZe(),a=lZe-(o-r);if(r=o,a>0){if(++e>=aZe)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}Xre.exports=uZe});var hL=_((cRt,$re)=>{var AZe=zre(),fZe=Zre(),pZe=fZe(AZe);$re.exports=pZe});var tne=_((uRt,ene)=>{var hZe=fL(),gZe=pL(),dZe=hL();function mZe(t,e){return dZe(gZe(t,e,hZe),t+"")}ene.exports=mZe});var nne=_((ARt,rne)=>{var yZe=Ry(),EZe=jI(),CZe=UI(),wZe=il();function IZe(t,e,r){if(!wZe(r))return!1;var o=typeof e;return(o=="number"?EZe(r)&&CZe(e,r.length):o=="string"&&e in r)?yZe(r[e],t):!1}rne.exports=IZe});var sne=_((fRt,ine)=>{var BZe=tne(),vZe=nne();function DZe(t){return BZe(function(e,r){var o=-1,a=r.length,n=a>1?r[a-1]:void 0,u=a>2?r[2]:void 0;for(n=t.length>3&&typeof n=="function"?(a--,n):void 0,u&&vZe(r[0],r[1],u)&&(n=a<3?void 0:n,a=1),e=Object(e);++o<a;){var A=r[o];A&&t(e,A,o,n)}return e})}ine.exports=DZe});var ane=_((pRt,one)=>{var PZe=_re(),SZe=sne(),xZe=SZe(function(t,e,r,o){PZe(t,e,r,o)});one.exports=xZe});var je={};Kt(je,{AsyncActions:()=>mL,BufferStream:()=>dL,CachingStrategy:()=>Ene,DefaultStream:()=>yL,allSettledSafe:()=>Uc,assertNever:()=>CL,bufferStream:()=>Vy,buildIgnorePattern:()=>NZe,convertMapsToIndexableObjects:()=>iS,dynamicRequire:()=>vf,escapeRegExp:()=>kZe,getArrayWithDefault:()=>Gy,getFactoryWithDefault:()=>ol,getMapWithDefault:()=>Yy,getSetWithDefault:()=>dd,groupBy:()=>BL,isIndexableObject:()=>gL,isPathLike:()=>LZe,isTaggedYarnVersion:()=>bZe,makeDeferred:()=>dne,mapAndFilter:()=>sl,mapAndFind:()=>WI,mergeIntoTarget:()=>wne,overrideType:()=>QZe,parseBoolean:()=>VI,parseInt:()=>Ky,parseOptionalBoolean:()=>Cne,plural:()=>nS,prettifyAsyncErrors:()=>Wy,prettifySyncErrors:()=>wL,releaseAfterUseAsync:()=>TZe,replaceEnvVariables:()=>sS,sortMap:()=>ks,toMerged:()=>MZe,tryParseOptionalBoolean:()=>IL,validateEnum:()=>FZe});function bZe(t){return!!(pne.default.valid(t)&&t.match(/^[^-]+(-rc\.[0-9]+)?$/))}function nS(t,{one:e,more:r,zero:o=r}){return t===0?o:t===1?e:r}function kZe(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function QZe(t){}function CL(t){throw new Error(`Assertion failed: Unexpected object '${t}'`)}function FZe(t,e){let r=Object.values(t);if(!r.includes(e))throw new it(`Invalid value for enumeration: ${JSON.stringify(e)} (expected one of ${r.map(o=>JSON.stringify(o)).join(", ")})`);return e}function sl(t,e){let r=[];for(let o of t){let a=e(o);a!==hne&&r.push(a)}return r}function WI(t,e){for(let r of t){let o=e(r);if(o!==gne)return o}}function gL(t){return typeof t=="object"&&t!==null}async function Uc(t){let e=await Promise.allSettled(t),r=[];for(let o of e){if(o.status==="rejected")throw o.reason;r.push(o.value)}return r}function iS(t){if(t instanceof Map&&(t=Object.fromEntries(t)),gL(t))for(let e of Object.keys(t)){let r=t[e];gL(r)&&(t[e]=iS(r))}return t}function ol(t,e,r){let o=t.get(e);return typeof o>"u"&&t.set(e,o=r()),o}function Gy(t,e){let r=t.get(e);return typeof r>"u"&&t.set(e,r=[]),r}function dd(t,e){let r=t.get(e);return typeof r>"u"&&t.set(e,r=new Set),r}function Yy(t,e){let r=t.get(e);return typeof r>"u"&&t.set(e,r=new Map),r}async function TZe(t,e){if(e==null)return await t();try{return await t()}finally{await e()}}async function Wy(t,e){try{return await t()}catch(r){throw r.message=e(r.message),r}}function wL(t,e){try{return t()}catch(r){throw r.message=e(r.message),r}}async function Vy(t){return await new Promise((e,r)=>{let o=[];t.on("error",a=>{r(a)}),t.on("data",a=>{o.push(a)}),t.on("end",()=>{e(Buffer.concat(o))})})}function dne(){let t,e;return{promise:new Promise((o,a)=>{t=o,e=a}),resolve:t,reject:e}}function mne(t){return YI(ue.fromPortablePath(t))}function yne(path){let physicalPath=ue.fromPortablePath(path),currentCacheEntry=YI.cache[physicalPath];delete YI.cache[physicalPath];let result;try{result=mne(physicalPath);let freshCacheEntry=YI.cache[physicalPath],dynamicModule=eval("module"),freshCacheIndex=dynamicModule.children.indexOf(freshCacheEntry);freshCacheIndex!==-1&&dynamicModule.children.splice(freshCacheIndex,1)}finally{YI.cache[physicalPath]=currentCacheEntry}return result}function RZe(t){let e=lne.get(t),r=oe.statSync(t);if(e?.mtime===r.mtimeMs)return e.instance;let o=yne(t);return lne.set(t,{mtime:r.mtimeMs,instance:o}),o}function vf(t,{cachingStrategy:e=2}={}){switch(e){case 0:return yne(t);case 1:return RZe(t);case 2:return mne(t);default:throw new Error("Unsupported caching strategy")}}function ks(t,e){let r=Array.from(t);Array.isArray(e)||(e=[e]);let o=[];for(let n of e)o.push(r.map(u=>n(u)));let a=r.map((n,u)=>u);return a.sort((n,u)=>{for(let A of o){let p=A[n]<A[u]?-1:A[n]>A[u]?1:0;if(p!==0)return p}return 0}),a.map(n=>r[n])}function NZe(t){return t.length===0?null:t.map(e=>`(${Ane.default.makeRe(e,{windows:!1,dot:!0}).source})`).join("|")}function sS(t,{env:e}){let r=/\${(?<variableName>[\d\w_]+)(?<colon>:)?(?:-(?<fallback>[^}]*))?}/g;return t.replace(r,(...o)=>{let{variableName:a,colon:n,fallback:u}=o[o.length-1],A=Object.hasOwn(e,a),p=e[a];if(p||A&&!n)return p;if(u!=null)return u;throw new it(`Environment variable not found (${a})`)})}function VI(t){switch(t){case"true":case"1":case 1:case!0:return!0;case"false":case"0":case 0:case!1:return!1;default:throw new Error(`Couldn't parse "${t}" as a boolean`)}}function Cne(t){return typeof t>"u"?t:VI(t)}function IL(t){try{return Cne(t)}catch{return null}}function LZe(t){return!!(ue.isAbsolute(t)||t.match(/^(\.{1,2}|~)\//))}function wne(t,...e){let r=u=>({value:u}),o=r(t),a=e.map(u=>r(u)),{value:n}=(0,une.default)(o,...a,(u,A)=>{if(Array.isArray(u)&&Array.isArray(A)){for(let p of A)u.find(h=>(0,cne.default)(h,p))||u.push(p);return u}});return n}function MZe(...t){return wne({},...t)}function BL(t,e){let r=Object.create(null);for(let o of t){let a=o[e];r[a]??=[],r[a].push(o)}return r}function Ky(t){return typeof t=="string"?Number.parseInt(t,10):t}var cne,une,Ane,fne,pne,EL,hne,gne,dL,mL,yL,YI,lne,Ene,jl=Et(()=>{Pt();qt();cne=$e(zte()),une=$e(ane()),Ane=$e(Zo()),fne=$e(nd()),pne=$e(zn()),EL=Be("stream");hne=Symbol();sl.skip=hne;gne=Symbol();WI.skip=gne;dL=class extends EL.Transform{constructor(){super(...arguments);this.chunks=[]}_transform(r,o,a){if(o!=="buffer"||!Buffer.isBuffer(r))throw new Error("Assertion failed: BufferStream only accept buffers");this.chunks.push(r),a(null,null)}_flush(r){r(null,Buffer.concat(this.chunks))}};mL=class{constructor(e){this.deferred=new Map;this.promises=new Map;this.limit=(0,fne.default)(e)}set(e,r){let o=this.deferred.get(e);typeof o>"u"&&this.deferred.set(e,o=dne());let a=this.limit(()=>r());return this.promises.set(e,a),a.then(()=>{this.promises.get(e)===a&&o.resolve()},n=>{this.promises.get(e)===a&&o.reject(n)}),o.promise}reduce(e,r){let o=this.promises.get(e)??Promise.resolve();this.set(e,()=>r(o))}async wait(){await Promise.all(this.promises.values())}},yL=class extends EL.Transform{constructor(r=Buffer.alloc(0)){super();this.active=!0;this.ifEmpty=r}_transform(r,o,a){if(o!=="buffer"||!Buffer.isBuffer(r))throw new Error("Assertion failed: DefaultStream only accept buffers");this.active=!1,a(null,r)}_flush(r){this.active&&this.ifEmpty.length>0?r(null,this.ifEmpty):r(null)}},YI=eval("require");lne=new Map;Ene=(o=>(o[o.NoCache=0]="NoCache",o[o.FsTime=1]="FsTime",o[o.Node=2]="Node",o))(Ene||{})});var Jy,vL,DL,Ine=Et(()=>{Jy=(r=>(r.HARD="HARD",r.SOFT="SOFT",r))(Jy||{}),vL=(o=>(o.Dependency="Dependency",o.PeerDependency="PeerDependency",o.PeerDependencyMeta="PeerDependencyMeta",o))(vL||{}),DL=(o=>(o.Inactive="inactive",o.Redundant="redundant",o.Active="active",o))(DL||{})});var de={};Kt(de,{LogLevel:()=>uS,Style:()=>aS,Type:()=>yt,addLogFilterSupport:()=>zI,applyColor:()=>Ks,applyHyperlink:()=>Xy,applyStyle:()=>md,json:()=>yd,jsonOrPretty:()=>_Ze,mark:()=>kL,pretty:()=>Ot,prettyField:()=>zu,prettyList:()=>bL,prettyTruncatedLocatorList:()=>cS,stripAnsi:()=>zy.default,supportsColor:()=>lS,supportsHyperlinks:()=>xL,tuple:()=>_c});function Bne(t){let e=["KiB","MiB","GiB","TiB"],r=e.length;for(;r>1&&t<1024**r;)r-=1;let o=1024**r;return`${Math.floor(t*100/o)/100} ${e[r-1]}`}function _c(t,e){return[e,t]}function md(t,e,r){return t.get("enableColors")&&r&2&&(e=JI.default.bold(e)),e}function Ks(t,e,r){if(!t.get("enableColors"))return e;let o=OZe.get(r);if(o===null)return e;let a=typeof o>"u"?r:SL.level>=3?o[0]:o[1],n=typeof a=="number"?PL.ansi256(a):a.startsWith("#")?PL.hex(a):PL[a];if(typeof n!="function")throw new Error(`Invalid format type ${a}`);return n(e)}function Xy(t,e,r){return t.get("enableHyperlinks")?UZe?`\x1B]8;;${r}\x1B\\${e}\x1B]8;;\x1B\\`:`\x1B]8;;${r}\x07${e}\x1B]8;;\x07`:e}function Ot(t,e,r){if(e===null)return Ks(t,"null",yt.NULL);if(Object.hasOwn(oS,r))return oS[r].pretty(t,e);if(typeof e!="string")throw new Error(`Assertion failed: Expected the value to be a string, got ${typeof e}`);return Ks(t,e,r)}function bL(t,e,r,{separator:o=", "}={}){return[...e].map(a=>Ot(t,a,r)).join(o)}function yd(t,e){if(t===null)return null;if(Object.hasOwn(oS,e))return oS[e].json(t);if(typeof t!="string")throw new Error(`Assertion failed: Expected the value to be a string, got ${typeof t}`);return t}function _Ze(t,e,[r,o]){return t?yd(r,o):Ot(e,r,o)}function kL(t){return{Check:Ks(t,"\u2713","green"),Cross:Ks(t,"\u2718","red"),Question:Ks(t,"?","cyan")}}function zu(t,{label:e,value:[r,o]}){return`${Ot(t,e,yt.CODE)}: ${Ot(t,r,o)}`}function cS(t,e,r){let o=[],a=[...e],n=r;for(;a.length>0;){let h=a[0],E=`${jr(t,h)}, `,I=QL(h).length+2;if(o.length>0&&n<I)break;o.push([E,I]),n-=I,a.shift()}if(a.length===0)return o.map(([h])=>h).join("").slice(0,-2);let u="X".repeat(a.length.toString().length),A=`and ${u} more.`,p=a.length;for(;o.length>1&&n<A.length;)n+=o[o.length-1][1],p+=1,o.pop();return[o.map(([h])=>h).join(""),A.replace(u,Ot(t,p,yt.NUMBER))].join("")}function zI(t,{configuration:e}){let r=e.get("logFilters"),o=new Map,a=new Map,n=[];for(let I of r){let v=I.get("level");if(typeof v>"u")continue;let b=I.get("code");typeof b<"u"&&o.set(b,v);let C=I.get("text");typeof C<"u"&&a.set(C,v);let T=I.get("pattern");typeof T<"u"&&n.push([vne.default.matcher(T,{contains:!0}),v])}n.reverse();let u=(I,v,b)=>{if(I===null||I===0)return b;let C=a.size>0||n.length>0?(0,zy.default)(v):v;if(a.size>0){let T=a.get(C);if(typeof T<"u")return T??b}if(n.length>0){for(let[T,L]of n)if(T(C))return L??b}if(o.size>0){let T=o.get(Wu(I));if(typeof T<"u")return T??b}return b},A=t.reportInfo,p=t.reportWarning,h=t.reportError,E=function(I,v,b,C){switch(u(v,b,C)){case"info":A.call(I,v,b);break;case"warning":p.call(I,v??0,b);break;case"error":h.call(I,v??0,b);break}};t.reportInfo=function(...I){return E(this,...I,"info")},t.reportWarning=function(...I){return E(this,...I,"warning")},t.reportError=function(...I){return E(this,...I,"error")}}var JI,KI,vne,zy,Dne,yt,aS,SL,lS,xL,PL,OZe,So,oS,UZe,uS,ql=Et(()=>{Pt();JI=$e(vN()),KI=$e(ed());qt();vne=$e(Zo()),zy=$e(MP()),Dne=Be("util");pP();xo();yt={NO_HINT:"NO_HINT",ID:"ID",NULL:"NULL",SCOPE:"SCOPE",NAME:"NAME",RANGE:"RANGE",REFERENCE:"REFERENCE",NUMBER:"NUMBER",PATH:"PATH",URL:"URL",ADDED:"ADDED",REMOVED:"REMOVED",CODE:"CODE",INSPECT:"INSPECT",DURATION:"DURATION",SIZE:"SIZE",SIZE_DIFF:"SIZE_DIFF",IDENT:"IDENT",DESCRIPTOR:"DESCRIPTOR",LOCATOR:"LOCATOR",RESOLUTION:"RESOLUTION",DEPENDENT:"DEPENDENT",PACKAGE_EXTENSION:"PACKAGE_EXTENSION",SETTING:"SETTING",MARKDOWN:"MARKDOWN",MARKDOWN_INLINE:"MARKDOWN_INLINE"},aS=(e=>(e[e.BOLD=2]="BOLD",e))(aS||{}),SL=KI.default.GITHUB_ACTIONS?{level:2}:JI.default.supportsColor?{level:JI.default.supportsColor.level}:{level:0},lS=SL.level!==0,xL=lS&&!KI.default.GITHUB_ACTIONS&&!KI.default.CIRCLE&&!KI.default.GITLAB,PL=new JI.default.Instance(SL),OZe=new Map([[yt.NO_HINT,null],[yt.NULL,["#a853b5",129]],[yt.SCOPE,["#d75f00",166]],[yt.NAME,["#d7875f",173]],[yt.RANGE,["#00afaf",37]],[yt.REFERENCE,["#87afff",111]],[yt.NUMBER,["#ffd700",220]],[yt.PATH,["#d75fd7",170]],[yt.URL,["#d75fd7",170]],[yt.ADDED,["#5faf00",70]],[yt.REMOVED,["#ff3131",160]],[yt.CODE,["#87afff",111]],[yt.SIZE,["#ffd700",220]]]),So=t=>t;oS={[yt.ID]:So({pretty:(t,e)=>typeof e=="number"?Ks(t,`${e}`,yt.NUMBER):Ks(t,e,yt.CODE),json:t=>t}),[yt.INSPECT]:So({pretty:(t,e)=>(0,Dne.inspect)(e,{depth:1/0,colors:t.get("enableColors"),compact:!0,breakLength:1/0}),json:t=>t}),[yt.NUMBER]:So({pretty:(t,e)=>Ks(t,`${e}`,yt.NUMBER),json:t=>t}),[yt.IDENT]:So({pretty:(t,e)=>cs(t,e),json:t=>fn(t)}),[yt.LOCATOR]:So({pretty:(t,e)=>jr(t,e),json:t=>xa(t)}),[yt.DESCRIPTOR]:So({pretty:(t,e)=>qn(t,e),json:t=>Sa(t)}),[yt.RESOLUTION]:So({pretty:(t,{descriptor:e,locator:r})=>XI(t,e,r),json:({descriptor:t,locator:e})=>({descriptor:Sa(t),locator:e!==null?xa(e):null})}),[yt.DEPENDENT]:So({pretty:(t,{locator:e,descriptor:r})=>FL(t,e,r),json:({locator:t,descriptor:e})=>({locator:xa(t),descriptor:Sa(e)})}),[yt.PACKAGE_EXTENSION]:So({pretty:(t,e)=>{switch(e.type){case"Dependency":return`${cs(t,e.parentDescriptor)} \u27A4 ${Ks(t,"dependencies",yt.CODE)} \u27A4 ${cs(t,e.descriptor)}`;case"PeerDependency":return`${cs(t,e.parentDescriptor)} \u27A4 ${Ks(t,"peerDependencies",yt.CODE)} \u27A4 ${cs(t,e.descriptor)}`;case"PeerDependencyMeta":return`${cs(t,e.parentDescriptor)} \u27A4 ${Ks(t,"peerDependenciesMeta",yt.CODE)} \u27A4 ${cs(t,Js(e.selector))} \u27A4 ${Ks(t,e.key,yt.CODE)}`;default:throw new Error(`Assertion failed: Unsupported package extension type: ${e.type}`)}},json:t=>{switch(t.type){case"Dependency":return`${fn(t.parentDescriptor)} > ${fn(t.descriptor)}`;case"PeerDependency":return`${fn(t.parentDescriptor)} >> ${fn(t.descriptor)}`;case"PeerDependencyMeta":return`${fn(t.parentDescriptor)} >> ${t.selector} / ${t.key}`;default:throw new Error(`Assertion failed: Unsupported package extension type: ${t.type}`)}}}),[yt.SETTING]:So({pretty:(t,e)=>(t.get(e),Xy(t,Ks(t,e,yt.CODE),`https://yarnpkg.com/configuration/yarnrc#${e}`)),json:t=>t}),[yt.DURATION]:So({pretty:(t,e)=>{if(e>1e3*60){let r=Math.floor(e/1e3/60),o=Math.ceil((e-r*60*1e3)/1e3);return o===0?`${r}m`:`${r}m ${o}s`}else{let r=Math.floor(e/1e3),o=e-r*1e3;return o===0?`${r}s`:`${r}s ${o}ms`}},json:t=>t}),[yt.SIZE]:So({pretty:(t,e)=>Ks(t,Bne(e),yt.NUMBER),json:t=>t}),[yt.SIZE_DIFF]:So({pretty:(t,e)=>{let r=e>=0?"+":"-",o=r==="+"?yt.REMOVED:yt.ADDED;return Ks(t,`${r} ${Bne(Math.max(Math.abs(e),1))}`,o)},json:t=>t}),[yt.PATH]:So({pretty:(t,e)=>Ks(t,ue.fromPortablePath(e),yt.PATH),json:t=>ue.fromPortablePath(t)}),[yt.MARKDOWN]:So({pretty:(t,{text:e,format:r,paragraphs:o})=>Do(e,{format:r,paragraphs:o}),json:({text:t})=>t}),[yt.MARKDOWN_INLINE]:So({pretty:(t,e)=>(e=e.replace(/(`+)((?:.|[\n])*?)\1/g,(r,o,a)=>Ot(t,o+a+o,yt.CODE)),e=e.replace(/(\*\*)((?:.|[\n])*?)\1/g,(r,o,a)=>md(t,a,2)),e),json:t=>t})};UZe=!!process.env.KONSOLE_VERSION;uS=(a=>(a.Error="error",a.Warning="warning",a.Info="info",a.Discard="discard",a))(uS||{})});var Pne=_(Zy=>{"use strict";Object.defineProperty(Zy,"__esModule",{value:!0});Zy.splitWhen=Zy.flatten=void 0;function HZe(t){return t.reduce((e,r)=>[].concat(e,r),[])}Zy.flatten=HZe;function jZe(t,e){let r=[[]],o=0;for(let a of t)e(a)?(o++,r[o]=[]):r[o].push(a);return r}Zy.splitWhen=jZe});var Sne=_(AS=>{"use strict";Object.defineProperty(AS,"__esModule",{value:!0});AS.isEnoentCodeError=void 0;function qZe(t){return t.code==="ENOENT"}AS.isEnoentCodeError=qZe});var xne=_(fS=>{"use strict";Object.defineProperty(fS,"__esModule",{value:!0});fS.createDirentFromStats=void 0;var TL=class{constructor(e,r){this.name=e,this.isBlockDevice=r.isBlockDevice.bind(r),this.isCharacterDevice=r.isCharacterDevice.bind(r),this.isDirectory=r.isDirectory.bind(r),this.isFIFO=r.isFIFO.bind(r),this.isFile=r.isFile.bind(r),this.isSocket=r.isSocket.bind(r),this.isSymbolicLink=r.isSymbolicLink.bind(r)}};function GZe(t,e){return new TL(t,e)}fS.createDirentFromStats=GZe});var bne=_(Xu=>{"use strict";Object.defineProperty(Xu,"__esModule",{value:!0});Xu.removeLeadingDotSegment=Xu.escape=Xu.makeAbsolute=Xu.unixify=void 0;var YZe=Be("path"),WZe=2,VZe=/(\\?)([()*?[\]{|}]|^!|[!+@](?=\())/g;function KZe(t){return t.replace(/\\/g,"/")}Xu.unixify=KZe;function JZe(t,e){return YZe.resolve(t,e)}Xu.makeAbsolute=JZe;function zZe(t){return t.replace(VZe,"\\$2")}Xu.escape=zZe;function XZe(t){if(t.charAt(0)==="."){let e=t.charAt(1);if(e==="/"||e==="\\")return t.slice(WZe)}return t}Xu.removeLeadingDotSegment=XZe});var Qne=_((xRt,kne)=>{kne.exports=function(e){if(typeof e!="string"||e==="")return!1;for(var r;r=/(\\).|([@?!+*]\(.*\))/g.exec(e);){if(r[2])return!0;e=e.slice(r.index+r[0].length)}return!1}});var Rne=_((bRt,Tne)=>{var ZZe=Qne(),Fne={"{":"}","(":")","[":"]"},$Ze=function(t){if(t[0]==="!")return!0;for(var e=0,r=-2,o=-2,a=-2,n=-2,u=-2;e<t.length;){if(t[e]==="*"||t[e+1]==="?"&&/[\].+)]/.test(t[e])||o!==-1&&t[e]==="["&&t[e+1]!=="]"&&(o<e&&(o=t.indexOf("]",e)),o>e&&(u===-1||u>o||(u=t.indexOf("\\",e),u===-1||u>o)))||a!==-1&&t[e]==="{"&&t[e+1]!=="}"&&(a=t.indexOf("}",e),a>e&&(u=t.indexOf("\\",e),u===-1||u>a))||n!==-1&&t[e]==="("&&t[e+1]==="?"&&/[:!=]/.test(t[e+2])&&t[e+3]!==")"&&(n=t.indexOf(")",e),n>e&&(u=t.indexOf("\\",e),u===-1||u>n))||r!==-1&&t[e]==="("&&t[e+1]!=="|"&&(r<e&&(r=t.indexOf("|",e)),r!==-1&&t[r+1]!==")"&&(n=t.indexOf(")",r),n>r&&(u=t.indexOf("\\",r),u===-1||u>n))))return!0;if(t[e]==="\\"){var A=t[e+1];e+=2;var p=Fne[A];if(p){var h=t.indexOf(p,e);h!==-1&&(e=h+1)}if(t[e]==="!")return!0}else e++}return!1},e$e=function(t){if(t[0]==="!")return!0;for(var e=0;e<t.length;){if(/[*?{}()[\]]/.test(t[e]))return!0;if(t[e]==="\\"){var r=t[e+1];e+=2;var o=Fne[r];if(o){var a=t.indexOf(o,e);a!==-1&&(e=a+1)}if(t[e]==="!")return!0}else e++}return!1};Tne.exports=function(e,r){if(typeof e!="string"||e==="")return!1;if(ZZe(e))return!0;var o=$Ze;return r&&r.strict===!1&&(o=e$e),o(e)}});var Lne=_((kRt,Nne)=>{"use strict";var t$e=Rne(),r$e=Be("path").posix.dirname,n$e=Be("os").platform()==="win32",RL="/",i$e=/\\/g,s$e=/[\{\[].*[\}\]]$/,o$e=/(^|[^\\])([\{\[]|\([^\)]+$)/,a$e=/\\([\!\*\?\|\[\]\(\)\{\}])/g;Nne.exports=function(e,r){var o=Object.assign({flipBackslashes:!0},r);o.flipBackslashes&&n$e&&e.indexOf(RL)<0&&(e=e.replace(i$e,RL)),s$e.test(e)&&(e+=RL),e+="a";do e=r$e(e);while(t$e(e)||o$e.test(e));return e.replace(a$e,"$1")}});var Gne=_(qr=>{"use strict";Object.defineProperty(qr,"__esModule",{value:!0});qr.matchAny=qr.convertPatternsToRe=qr.makeRe=qr.getPatternParts=qr.expandBraceExpansion=qr.expandPatternsWithBraceExpansion=qr.isAffectDepthOfReadingPattern=qr.endsWithSlashGlobStar=qr.hasGlobStar=qr.getBaseDirectory=qr.isPatternRelatedToParentDirectory=qr.getPatternsOutsideCurrentDirectory=qr.getPatternsInsideCurrentDirectory=qr.getPositivePatterns=qr.getNegativePatterns=qr.isPositivePattern=qr.isNegativePattern=qr.convertToNegativePattern=qr.convertToPositivePattern=qr.isDynamicPattern=qr.isStaticPattern=void 0;var l$e=Be("path"),c$e=Lne(),NL=Zo(),Mne="**",u$e="\\",A$e=/[*?]|^!/,f$e=/\[[^[]*]/,p$e=/(?:^|[^!*+?@])\([^(]*\|[^|]*\)/,h$e=/[!*+?@]\([^(]*\)/,g$e=/,|\.\./;function One(t,e={}){return!Une(t,e)}qr.isStaticPattern=One;function Une(t,e={}){return t===""?!1:!!(e.caseSensitiveMatch===!1||t.includes(u$e)||A$e.test(t)||f$e.test(t)||p$e.test(t)||e.extglob!==!1&&h$e.test(t)||e.braceExpansion!==!1&&d$e(t))}qr.isDynamicPattern=Une;function d$e(t){let e=t.indexOf("{");if(e===-1)return!1;let r=t.indexOf("}",e+1);if(r===-1)return!1;let o=t.slice(e,r);return g$e.test(o)}function m$e(t){return pS(t)?t.slice(1):t}qr.convertToPositivePattern=m$e;function y$e(t){return"!"+t}qr.convertToNegativePattern=y$e;function pS(t){return t.startsWith("!")&&t[1]!=="("}qr.isNegativePattern=pS;function _ne(t){return!pS(t)}qr.isPositivePattern=_ne;function E$e(t){return t.filter(pS)}qr.getNegativePatterns=E$e;function C$e(t){return t.filter(_ne)}qr.getPositivePatterns=C$e;function w$e(t){return t.filter(e=>!LL(e))}qr.getPatternsInsideCurrentDirectory=w$e;function I$e(t){return t.filter(LL)}qr.getPatternsOutsideCurrentDirectory=I$e;function LL(t){return t.startsWith("..")||t.startsWith("./..")}qr.isPatternRelatedToParentDirectory=LL;function B$e(t){return c$e(t,{flipBackslashes:!1})}qr.getBaseDirectory=B$e;function v$e(t){return t.includes(Mne)}qr.hasGlobStar=v$e;function Hne(t){return t.endsWith("/"+Mne)}qr.endsWithSlashGlobStar=Hne;function D$e(t){let e=l$e.basename(t);return Hne(t)||One(e)}qr.isAffectDepthOfReadingPattern=D$e;function P$e(t){return t.reduce((e,r)=>e.concat(jne(r)),[])}qr.expandPatternsWithBraceExpansion=P$e;function jne(t){return NL.braces(t,{expand:!0,nodupes:!0})}qr.expandBraceExpansion=jne;function S$e(t,e){let{parts:r}=NL.scan(t,Object.assign(Object.assign({},e),{parts:!0}));return r.length===0&&(r=[t]),r[0].startsWith("/")&&(r[0]=r[0].slice(1),r.unshift("")),r}qr.getPatternParts=S$e;function qne(t,e){return NL.makeRe(t,e)}qr.makeRe=qne;function x$e(t,e){return t.map(r=>qne(r,e))}qr.convertPatternsToRe=x$e;function b$e(t,e){return e.some(r=>r.test(t))}qr.matchAny=b$e});var Kne=_((FRt,Vne)=>{"use strict";var k$e=Be("stream"),Yne=k$e.PassThrough,Q$e=Array.prototype.slice;Vne.exports=F$e;function F$e(){let t=[],e=Q$e.call(arguments),r=!1,o=e[e.length-1];o&&!Array.isArray(o)&&o.pipe==null?e.pop():o={};let a=o.end!==!1,n=o.pipeError===!0;o.objectMode==null&&(o.objectMode=!0),o.highWaterMark==null&&(o.highWaterMark=64*1024);let u=Yne(o);function A(){for(let E=0,I=arguments.length;E<I;E++)t.push(Wne(arguments[E],o));return p(),this}function p(){if(r)return;r=!0;let E=t.shift();if(!E){process.nextTick(h);return}Array.isArray(E)||(E=[E]);let I=E.length+1;function v(){--I>0||(r=!1,p())}function b(C){function T(){C.removeListener("merge2UnpipeEnd",T),C.removeListener("end",T),n&&C.removeListener("error",L),v()}function L(U){u.emit("error",U)}if(C._readableState.endEmitted)return v();C.on("merge2UnpipeEnd",T),C.on("end",T),n&&C.on("error",L),C.pipe(u,{end:!1}),C.resume()}for(let C=0;C<E.length;C++)b(E[C]);v()}function h(){r=!1,u.emit("queueDrain"),a&&u.end()}return u.setMaxListeners(0),u.add=A,u.on("unpipe",function(E){E.emit("merge2UnpipeEnd")}),e.length&&A.apply(null,e),u}function Wne(t,e){if(Array.isArray(t))for(let r=0,o=t.length;r<o;r++)t[r]=Wne(t[r],e);else{if(!t._readableState&&t.pipe&&(t=t.pipe(Yne(e))),!t._readableState||!t.pause||!t.pipe)throw new Error("Only readable stream can be merged.");t.pause()}return t}});var zne=_(hS=>{"use strict";Object.defineProperty(hS,"__esModule",{value:!0});hS.merge=void 0;var T$e=Kne();function R$e(t){let e=T$e(t);return t.forEach(r=>{r.once("error",o=>e.emit("error",o))}),e.once("close",()=>Jne(t)),e.once("end",()=>Jne(t)),e}hS.merge=R$e;function Jne(t){t.forEach(e=>e.emit("close"))}});var Xne=_($y=>{"use strict";Object.defineProperty($y,"__esModule",{value:!0});$y.isEmpty=$y.isString=void 0;function N$e(t){return typeof t=="string"}$y.isString=N$e;function L$e(t){return t===""}$y.isEmpty=L$e});var Df=_(bo=>{"use strict";Object.defineProperty(bo,"__esModule",{value:!0});bo.string=bo.stream=bo.pattern=bo.path=bo.fs=bo.errno=bo.array=void 0;var M$e=Pne();bo.array=M$e;var O$e=Sne();bo.errno=O$e;var U$e=xne();bo.fs=U$e;var _$e=bne();bo.path=_$e;var H$e=Gne();bo.pattern=H$e;var j$e=zne();bo.stream=j$e;var q$e=Xne();bo.string=q$e});var eie=_(ko=>{"use strict";Object.defineProperty(ko,"__esModule",{value:!0});ko.convertPatternGroupToTask=ko.convertPatternGroupsToTasks=ko.groupPatternsByBaseDirectory=ko.getNegativePatternsAsPositive=ko.getPositivePatterns=ko.convertPatternsToTasks=ko.generate=void 0;var Pf=Df();function G$e(t,e){let r=Zne(t),o=$ne(t,e.ignore),a=r.filter(p=>Pf.pattern.isStaticPattern(p,e)),n=r.filter(p=>Pf.pattern.isDynamicPattern(p,e)),u=ML(a,o,!1),A=ML(n,o,!0);return u.concat(A)}ko.generate=G$e;function ML(t,e,r){let o=[],a=Pf.pattern.getPatternsOutsideCurrentDirectory(t),n=Pf.pattern.getPatternsInsideCurrentDirectory(t),u=OL(a),A=OL(n);return o.push(...UL(u,e,r)),"."in A?o.push(_L(".",n,e,r)):o.push(...UL(A,e,r)),o}ko.convertPatternsToTasks=ML;function Zne(t){return Pf.pattern.getPositivePatterns(t)}ko.getPositivePatterns=Zne;function $ne(t,e){return Pf.pattern.getNegativePatterns(t).concat(e).map(Pf.pattern.convertToPositivePattern)}ko.getNegativePatternsAsPositive=$ne;function OL(t){let e={};return t.reduce((r,o)=>{let a=Pf.pattern.getBaseDirectory(o);return a in r?r[a].push(o):r[a]=[o],r},e)}ko.groupPatternsByBaseDirectory=OL;function UL(t,e,r){return Object.keys(t).map(o=>_L(o,t[o],e,r))}ko.convertPatternGroupsToTasks=UL;function _L(t,e,r,o){return{dynamic:o,positive:e,negative:r,base:t,patterns:[].concat(e,r.map(Pf.pattern.convertToNegativePattern))}}ko.convertPatternGroupToTask=_L});var rie=_(eE=>{"use strict";Object.defineProperty(eE,"__esModule",{value:!0});eE.removeDuplicateSlashes=eE.transform=void 0;var Y$e=/(?!^)\/{2,}/g;function W$e(t){return t.map(e=>tie(e))}eE.transform=W$e;function tie(t){return t.replace(Y$e,"/")}eE.removeDuplicateSlashes=tie});var iie=_(gS=>{"use strict";Object.defineProperty(gS,"__esModule",{value:!0});gS.read=void 0;function V$e(t,e,r){e.fs.lstat(t,(o,a)=>{if(o!==null){nie(r,o);return}if(!a.isSymbolicLink()||!e.followSymbolicLink){HL(r,a);return}e.fs.stat(t,(n,u)=>{if(n!==null){if(e.throwErrorOnBrokenSymbolicLink){nie(r,n);return}HL(r,a);return}e.markSymbolicLink&&(u.isSymbolicLink=()=>!0),HL(r,u)})})}gS.read=V$e;function nie(t,e){t(e)}function HL(t,e){t(null,e)}});var sie=_(dS=>{"use strict";Object.defineProperty(dS,"__esModule",{value:!0});dS.read=void 0;function K$e(t,e){let r=e.fs.lstatSync(t);if(!r.isSymbolicLink()||!e.followSymbolicLink)return r;try{let o=e.fs.statSync(t);return e.markSymbolicLink&&(o.isSymbolicLink=()=>!0),o}catch(o){if(!e.throwErrorOnBrokenSymbolicLink)return r;throw o}}dS.read=K$e});var oie=_(zp=>{"use strict";Object.defineProperty(zp,"__esModule",{value:!0});zp.createFileSystemAdapter=zp.FILE_SYSTEM_ADAPTER=void 0;var mS=Be("fs");zp.FILE_SYSTEM_ADAPTER={lstat:mS.lstat,stat:mS.stat,lstatSync:mS.lstatSync,statSync:mS.statSync};function J$e(t){return t===void 0?zp.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},zp.FILE_SYSTEM_ADAPTER),t)}zp.createFileSystemAdapter=J$e});var aie=_(qL=>{"use strict";Object.defineProperty(qL,"__esModule",{value:!0});var z$e=oie(),jL=class{constructor(e={}){this._options=e,this.followSymbolicLink=this._getValue(this._options.followSymbolicLink,!0),this.fs=z$e.createFileSystemAdapter(this._options.fs),this.markSymbolicLink=this._getValue(this._options.markSymbolicLink,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0)}_getValue(e,r){return e??r}};qL.default=jL});var Ed=_(Xp=>{"use strict";Object.defineProperty(Xp,"__esModule",{value:!0});Xp.statSync=Xp.stat=Xp.Settings=void 0;var lie=iie(),X$e=sie(),YL=aie();Xp.Settings=YL.default;function Z$e(t,e,r){if(typeof e=="function"){lie.read(t,WL(),e);return}lie.read(t,WL(e),r)}Xp.stat=Z$e;function $$e(t,e){let r=WL(e);return X$e.read(t,r)}Xp.statSync=$$e;function WL(t={}){return t instanceof YL.default?t:new YL.default(t)}});var uie=_((qRt,cie)=>{cie.exports=eet;function eet(t,e){var r,o,a,n=!0;Array.isArray(t)?(r=[],o=t.length):(a=Object.keys(t),r={},o=a.length);function u(p){function h(){e&&e(p,r),e=null}n?process.nextTick(h):h()}function A(p,h,E){r[p]=E,(--o===0||h)&&u(h)}o?a?a.forEach(function(p){t[p](function(h,E){A(p,h,E)})}):t.forEach(function(p,h){p(function(E,I){A(h,E,I)})}):u(null),n=!1}});var VL=_(ES=>{"use strict";Object.defineProperty(ES,"__esModule",{value:!0});ES.IS_SUPPORT_READDIR_WITH_FILE_TYPES=void 0;var yS=process.versions.node.split(".");if(yS[0]===void 0||yS[1]===void 0)throw new Error(`Unexpected behavior. The 'process.versions.node' variable has invalid value: ${process.versions.node}`);var Aie=Number.parseInt(yS[0],10),tet=Number.parseInt(yS[1],10),fie=10,ret=10,net=Aie>fie,iet=Aie===fie&&tet>=ret;ES.IS_SUPPORT_READDIR_WITH_FILE_TYPES=net||iet});var pie=_(CS=>{"use strict";Object.defineProperty(CS,"__esModule",{value:!0});CS.createDirentFromStats=void 0;var KL=class{constructor(e,r){this.name=e,this.isBlockDevice=r.isBlockDevice.bind(r),this.isCharacterDevice=r.isCharacterDevice.bind(r),this.isDirectory=r.isDirectory.bind(r),this.isFIFO=r.isFIFO.bind(r),this.isFile=r.isFile.bind(r),this.isSocket=r.isSocket.bind(r),this.isSymbolicLink=r.isSymbolicLink.bind(r)}};function set(t,e){return new KL(t,e)}CS.createDirentFromStats=set});var JL=_(wS=>{"use strict";Object.defineProperty(wS,"__esModule",{value:!0});wS.fs=void 0;var oet=pie();wS.fs=oet});var zL=_(IS=>{"use strict";Object.defineProperty(IS,"__esModule",{value:!0});IS.joinPathSegments=void 0;function aet(t,e,r){return t.endsWith(r)?t+e:t+r+e}IS.joinPathSegments=aet});var Eie=_(Zp=>{"use strict";Object.defineProperty(Zp,"__esModule",{value:!0});Zp.readdir=Zp.readdirWithFileTypes=Zp.read=void 0;var cet=Ed(),hie=uie(),uet=VL(),gie=JL(),die=zL();function Aet(t,e,r){if(!e.stats&&uet.IS_SUPPORT_READDIR_WITH_FILE_TYPES){mie(t,e,r);return}yie(t,e,r)}Zp.read=Aet;function mie(t,e,r){e.fs.readdir(t,{withFileTypes:!0},(o,a)=>{if(o!==null){BS(r,o);return}let n=a.map(A=>({dirent:A,name:A.name,path:die.joinPathSegments(t,A.name,e.pathSegmentSeparator)}));if(!e.followSymbolicLinks){XL(r,n);return}let u=n.map(A=>fet(A,e));hie(u,(A,p)=>{if(A!==null){BS(r,A);return}XL(r,p)})})}Zp.readdirWithFileTypes=mie;function fet(t,e){return r=>{if(!t.dirent.isSymbolicLink()){r(null,t);return}e.fs.stat(t.path,(o,a)=>{if(o!==null){if(e.throwErrorOnBrokenSymbolicLink){r(o);return}r(null,t);return}t.dirent=gie.fs.createDirentFromStats(t.name,a),r(null,t)})}}function yie(t,e,r){e.fs.readdir(t,(o,a)=>{if(o!==null){BS(r,o);return}let n=a.map(u=>{let A=die.joinPathSegments(t,u,e.pathSegmentSeparator);return p=>{cet.stat(A,e.fsStatSettings,(h,E)=>{if(h!==null){p(h);return}let I={name:u,path:A,dirent:gie.fs.createDirentFromStats(u,E)};e.stats&&(I.stats=E),p(null,I)})}});hie(n,(u,A)=>{if(u!==null){BS(r,u);return}XL(r,A)})})}Zp.readdir=yie;function BS(t,e){t(e)}function XL(t,e){t(null,e)}});var vie=_($p=>{"use strict";Object.defineProperty($p,"__esModule",{value:!0});$p.readdir=$p.readdirWithFileTypes=$p.read=void 0;var pet=Ed(),het=VL(),Cie=JL(),wie=zL();function get(t,e){return!e.stats&&het.IS_SUPPORT_READDIR_WITH_FILE_TYPES?Iie(t,e):Bie(t,e)}$p.read=get;function Iie(t,e){return e.fs.readdirSync(t,{withFileTypes:!0}).map(o=>{let a={dirent:o,name:o.name,path:wie.joinPathSegments(t,o.name,e.pathSegmentSeparator)};if(a.dirent.isSymbolicLink()&&e.followSymbolicLinks)try{let n=e.fs.statSync(a.path);a.dirent=Cie.fs.createDirentFromStats(a.name,n)}catch(n){if(e.throwErrorOnBrokenSymbolicLink)throw n}return a})}$p.readdirWithFileTypes=Iie;function Bie(t,e){return e.fs.readdirSync(t).map(o=>{let a=wie.joinPathSegments(t,o,e.pathSegmentSeparator),n=pet.statSync(a,e.fsStatSettings),u={name:o,path:a,dirent:Cie.fs.createDirentFromStats(o,n)};return e.stats&&(u.stats=n),u})}$p.readdir=Bie});var Die=_(eh=>{"use strict";Object.defineProperty(eh,"__esModule",{value:!0});eh.createFileSystemAdapter=eh.FILE_SYSTEM_ADAPTER=void 0;var tE=Be("fs");eh.FILE_SYSTEM_ADAPTER={lstat:tE.lstat,stat:tE.stat,lstatSync:tE.lstatSync,statSync:tE.statSync,readdir:tE.readdir,readdirSync:tE.readdirSync};function det(t){return t===void 0?eh.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},eh.FILE_SYSTEM_ADAPTER),t)}eh.createFileSystemAdapter=det});var Pie=_($L=>{"use strict";Object.defineProperty($L,"__esModule",{value:!0});var met=Be("path"),yet=Ed(),Eet=Die(),ZL=class{constructor(e={}){this._options=e,this.followSymbolicLinks=this._getValue(this._options.followSymbolicLinks,!1),this.fs=Eet.createFileSystemAdapter(this._options.fs),this.pathSegmentSeparator=this._getValue(this._options.pathSegmentSeparator,met.sep),this.stats=this._getValue(this._options.stats,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0),this.fsStatSettings=new yet.Settings({followSymbolicLink:this.followSymbolicLinks,fs:this.fs,throwErrorOnBrokenSymbolicLink:this.throwErrorOnBrokenSymbolicLink})}_getValue(e,r){return e??r}};$L.default=ZL});var vS=_(th=>{"use strict";Object.defineProperty(th,"__esModule",{value:!0});th.Settings=th.scandirSync=th.scandir=void 0;var Sie=Eie(),Cet=vie(),eM=Pie();th.Settings=eM.default;function wet(t,e,r){if(typeof e=="function"){Sie.read(t,tM(),e);return}Sie.read(t,tM(e),r)}th.scandir=wet;function Iet(t,e){let r=tM(e);return Cet.read(t,r)}th.scandirSync=Iet;function tM(t={}){return t instanceof eM.default?t:new eM.default(t)}});var bie=_(($Rt,xie)=>{"use strict";function Bet(t){var e=new t,r=e;function o(){var n=e;return n.next?e=n.next:(e=new t,r=e),n.next=null,n}function a(n){r.next=n,r=n}return{get:o,release:a}}xie.exports=Bet});var Qie=_((eNt,rM)=>{"use strict";var vet=bie();function kie(t,e,r){if(typeof t=="function"&&(r=e,e=t,t=null),r<1)throw new Error("fastqueue concurrency must be greater than 1");var o=vet(Det),a=null,n=null,u=0,A=null,p={push:T,drain:Gl,saturated:Gl,pause:E,paused:!1,concurrency:r,running:h,resume:b,idle:C,length:I,getQueue:v,unshift:L,empty:Gl,kill:J,killAndDrain:te,error:le};return p;function h(){return u}function E(){p.paused=!0}function I(){for(var pe=a,Ae=0;pe;)pe=pe.next,Ae++;return Ae}function v(){for(var pe=a,Ae=[];pe;)Ae.push(pe.value),pe=pe.next;return Ae}function b(){if(!!p.paused){p.paused=!1;for(var pe=0;pe<p.concurrency;pe++)u++,U()}}function C(){return u===0&&p.length()===0}function T(pe,Ae){var ye=o.get();ye.context=t,ye.release=U,ye.value=pe,ye.callback=Ae||Gl,ye.errorHandler=A,u===p.concurrency||p.paused?n?(n.next=ye,n=ye):(a=ye,n=ye,p.saturated()):(u++,e.call(t,ye.value,ye.worked))}function L(pe,Ae){var ye=o.get();ye.context=t,ye.release=U,ye.value=pe,ye.callback=Ae||Gl,u===p.concurrency||p.paused?a?(ye.next=a,a=ye):(a=ye,n=ye,p.saturated()):(u++,e.call(t,ye.value,ye.worked))}function U(pe){pe&&o.release(pe);var Ae=a;Ae?p.paused?u--:(n===a&&(n=null),a=Ae.next,Ae.next=null,e.call(t,Ae.value,Ae.worked),n===null&&p.empty()):--u===0&&p.drain()}function J(){a=null,n=null,p.drain=Gl}function te(){a=null,n=null,p.drain(),p.drain=Gl}function le(pe){A=pe}}function Gl(){}function Det(){this.value=null,this.callback=Gl,this.next=null,this.release=Gl,this.context=null,this.errorHandler=null;var t=this;this.worked=function(r,o){var a=t.callback,n=t.errorHandler,u=t.value;t.value=null,t.callback=Gl,t.errorHandler&&n(r,u),a.call(t.context,r,o),t.release(t)}}function Pet(t,e,r){typeof t=="function"&&(r=e,e=t,t=null);function o(E,I){e.call(this,E).then(function(v){I(null,v)},I)}var a=kie(t,o,r),n=a.push,u=a.unshift;return a.push=A,a.unshift=p,a.drained=h,a;function A(E){var I=new Promise(function(v,b){n(E,function(C,T){if(C){b(C);return}v(T)})});return I.catch(Gl),I}function p(E){var I=new Promise(function(v,b){u(E,function(C,T){if(C){b(C);return}v(T)})});return I.catch(Gl),I}function h(){var E=a.drain,I=new Promise(function(v){a.drain=function(){E(),v()}});return I}}rM.exports=kie;rM.exports.promise=Pet});var DS=_(Zu=>{"use strict";Object.defineProperty(Zu,"__esModule",{value:!0});Zu.joinPathSegments=Zu.replacePathSegmentSeparator=Zu.isAppliedFilter=Zu.isFatalError=void 0;function xet(t,e){return t.errorFilter===null?!0:!t.errorFilter(e)}Zu.isFatalError=xet;function bet(t,e){return t===null||t(e)}Zu.isAppliedFilter=bet;function ket(t,e){return t.split(/[/\\]/).join(e)}Zu.replacePathSegmentSeparator=ket;function Qet(t,e,r){return t===""?e:t.endsWith(r)?t+e:t+r+e}Zu.joinPathSegments=Qet});var sM=_(iM=>{"use strict";Object.defineProperty(iM,"__esModule",{value:!0});var Fet=DS(),nM=class{constructor(e,r){this._root=e,this._settings=r,this._root=Fet.replacePathSegmentSeparator(e,r.pathSegmentSeparator)}};iM.default=nM});var lM=_(aM=>{"use strict";Object.defineProperty(aM,"__esModule",{value:!0});var Tet=Be("events"),Ret=vS(),Net=Qie(),PS=DS(),Let=sM(),oM=class extends Let.default{constructor(e,r){super(e,r),this._settings=r,this._scandir=Ret.scandir,this._emitter=new Tet.EventEmitter,this._queue=Net(this._worker.bind(this),this._settings.concurrency),this._isFatalError=!1,this._isDestroyed=!1,this._queue.drain=()=>{this._isFatalError||this._emitter.emit("end")}}read(){return this._isFatalError=!1,this._isDestroyed=!1,setImmediate(()=>{this._pushToQueue(this._root,this._settings.basePath)}),this._emitter}get isDestroyed(){return this._isDestroyed}destroy(){if(this._isDestroyed)throw new Error("The reader is already destroyed");this._isDestroyed=!0,this._queue.killAndDrain()}onEntry(e){this._emitter.on("entry",e)}onError(e){this._emitter.once("error",e)}onEnd(e){this._emitter.once("end",e)}_pushToQueue(e,r){let o={directory:e,base:r};this._queue.push(o,a=>{a!==null&&this._handleError(a)})}_worker(e,r){this._scandir(e.directory,this._settings.fsScandirSettings,(o,a)=>{if(o!==null){r(o,void 0);return}for(let n of a)this._handleEntry(n,e.base);r(null,void 0)})}_handleError(e){this._isDestroyed||!PS.isFatalError(this._settings,e)||(this._isFatalError=!0,this._isDestroyed=!0,this._emitter.emit("error",e))}_handleEntry(e,r){if(this._isDestroyed||this._isFatalError)return;let o=e.path;r!==void 0&&(e.path=PS.joinPathSegments(r,e.name,this._settings.pathSegmentSeparator)),PS.isAppliedFilter(this._settings.entryFilter,e)&&this._emitEntry(e),e.dirent.isDirectory()&&PS.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(o,r===void 0?void 0:e.path)}_emitEntry(e){this._emitter.emit("entry",e)}};aM.default=oM});var Fie=_(uM=>{"use strict";Object.defineProperty(uM,"__esModule",{value:!0});var Met=lM(),cM=class{constructor(e,r){this._root=e,this._settings=r,this._reader=new Met.default(this._root,this._settings),this._storage=[]}read(e){this._reader.onError(r=>{Oet(e,r)}),this._reader.onEntry(r=>{this._storage.push(r)}),this._reader.onEnd(()=>{Uet(e,this._storage)}),this._reader.read()}};uM.default=cM;function Oet(t,e){t(e)}function Uet(t,e){t(null,e)}});var Tie=_(fM=>{"use strict";Object.defineProperty(fM,"__esModule",{value:!0});var _et=Be("stream"),Het=lM(),AM=class{constructor(e,r){this._root=e,this._settings=r,this._reader=new Het.default(this._root,this._settings),this._stream=new _et.Readable({objectMode:!0,read:()=>{},destroy:()=>{this._reader.isDestroyed||this._reader.destroy()}})}read(){return this._reader.onError(e=>{this._stream.emit("error",e)}),this._reader.onEntry(e=>{this._stream.push(e)}),this._reader.onEnd(()=>{this._stream.push(null)}),this._reader.read(),this._stream}};fM.default=AM});var Rie=_(hM=>{"use strict";Object.defineProperty(hM,"__esModule",{value:!0});var jet=vS(),SS=DS(),qet=sM(),pM=class extends qet.default{constructor(){super(...arguments),this._scandir=jet.scandirSync,this._storage=[],this._queue=new Set}read(){return this._pushToQueue(this._root,this._settings.basePath),this._handleQueue(),this._storage}_pushToQueue(e,r){this._queue.add({directory:e,base:r})}_handleQueue(){for(let e of this._queue.values())this._handleDirectory(e.directory,e.base)}_handleDirectory(e,r){try{let o=this._scandir(e,this._settings.fsScandirSettings);for(let a of o)this._handleEntry(a,r)}catch(o){this._handleError(o)}}_handleError(e){if(!!SS.isFatalError(this._settings,e))throw e}_handleEntry(e,r){let o=e.path;r!==void 0&&(e.path=SS.joinPathSegments(r,e.name,this._settings.pathSegmentSeparator)),SS.isAppliedFilter(this._settings.entryFilter,e)&&this._pushToStorage(e),e.dirent.isDirectory()&&SS.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(o,r===void 0?void 0:e.path)}_pushToStorage(e){this._storage.push(e)}};hM.default=pM});var Nie=_(dM=>{"use strict";Object.defineProperty(dM,"__esModule",{value:!0});var Get=Rie(),gM=class{constructor(e,r){this._root=e,this._settings=r,this._reader=new Get.default(this._root,this._settings)}read(){return this._reader.read()}};dM.default=gM});var Lie=_(yM=>{"use strict";Object.defineProperty(yM,"__esModule",{value:!0});var Yet=Be("path"),Wet=vS(),mM=class{constructor(e={}){this._options=e,this.basePath=this._getValue(this._options.basePath,void 0),this.concurrency=this._getValue(this._options.concurrency,Number.POSITIVE_INFINITY),this.deepFilter=this._getValue(this._options.deepFilter,null),this.entryFilter=this._getValue(this._options.entryFilter,null),this.errorFilter=this._getValue(this._options.errorFilter,null),this.pathSegmentSeparator=this._getValue(this._options.pathSegmentSeparator,Yet.sep),this.fsScandirSettings=new Wet.Settings({followSymbolicLinks:this._options.followSymbolicLinks,fs:this._options.fs,pathSegmentSeparator:this._options.pathSegmentSeparator,stats:this._options.stats,throwErrorOnBrokenSymbolicLink:this._options.throwErrorOnBrokenSymbolicLink})}_getValue(e,r){return e??r}};yM.default=mM});var bS=_($u=>{"use strict";Object.defineProperty($u,"__esModule",{value:!0});$u.Settings=$u.walkStream=$u.walkSync=$u.walk=void 0;var Mie=Fie(),Vet=Tie(),Ket=Nie(),EM=Lie();$u.Settings=EM.default;function Jet(t,e,r){if(typeof e=="function"){new Mie.default(t,xS()).read(e);return}new Mie.default(t,xS(e)).read(r)}$u.walk=Jet;function zet(t,e){let r=xS(e);return new Ket.default(t,r).read()}$u.walkSync=zet;function Xet(t,e){let r=xS(e);return new Vet.default(t,r).read()}$u.walkStream=Xet;function xS(t={}){return t instanceof EM.default?t:new EM.default(t)}});var kS=_(wM=>{"use strict";Object.defineProperty(wM,"__esModule",{value:!0});var Zet=Be("path"),$et=Ed(),Oie=Df(),CM=class{constructor(e){this._settings=e,this._fsStatSettings=new $et.Settings({followSymbolicLink:this._settings.followSymbolicLinks,fs:this._settings.fs,throwErrorOnBrokenSymbolicLink:this._settings.followSymbolicLinks})}_getFullEntryPath(e){return Zet.resolve(this._settings.cwd,e)}_makeEntry(e,r){let o={name:r,path:r,dirent:Oie.fs.createDirentFromStats(r,e)};return this._settings.stats&&(o.stats=e),o}_isFatalError(e){return!Oie.errno.isEnoentCodeError(e)&&!this._settings.suppressErrors}};wM.default=CM});var vM=_(BM=>{"use strict";Object.defineProperty(BM,"__esModule",{value:!0});var ett=Be("stream"),ttt=Ed(),rtt=bS(),ntt=kS(),IM=class extends ntt.default{constructor(){super(...arguments),this._walkStream=rtt.walkStream,this._stat=ttt.stat}dynamic(e,r){return this._walkStream(e,r)}static(e,r){let o=e.map(this._getFullEntryPath,this),a=new ett.PassThrough({objectMode:!0});a._write=(n,u,A)=>this._getEntry(o[n],e[n],r).then(p=>{p!==null&&r.entryFilter(p)&&a.push(p),n===o.length-1&&a.end(),A()}).catch(A);for(let n=0;n<o.length;n++)a.write(n);return a}_getEntry(e,r,o){return this._getStat(e).then(a=>this._makeEntry(a,r)).catch(a=>{if(o.errorFilter(a))return null;throw a})}_getStat(e){return new Promise((r,o)=>{this._stat(e,this._fsStatSettings,(a,n)=>a===null?r(n):o(a))})}};BM.default=IM});var Uie=_(PM=>{"use strict";Object.defineProperty(PM,"__esModule",{value:!0});var itt=bS(),stt=kS(),ott=vM(),DM=class extends stt.default{constructor(){super(...arguments),this._walkAsync=itt.walk,this._readerStream=new ott.default(this._settings)}dynamic(e,r){return new Promise((o,a)=>{this._walkAsync(e,r,(n,u)=>{n===null?o(u):a(n)})})}async static(e,r){let o=[],a=this._readerStream.static(e,r);return new Promise((n,u)=>{a.once("error",u),a.on("data",A=>o.push(A)),a.once("end",()=>n(o))})}};PM.default=DM});var _ie=_(xM=>{"use strict";Object.defineProperty(xM,"__esModule",{value:!0});var rE=Df(),SM=class{constructor(e,r,o){this._patterns=e,this._settings=r,this._micromatchOptions=o,this._storage=[],this._fillStorage()}_fillStorage(){let e=rE.pattern.expandPatternsWithBraceExpansion(this._patterns);for(let r of e){let o=this._getPatternSegments(r),a=this._splitSegmentsIntoSections(o);this._storage.push({complete:a.length<=1,pattern:r,segments:o,sections:a})}}_getPatternSegments(e){return rE.pattern.getPatternParts(e,this._micromatchOptions).map(o=>rE.pattern.isDynamicPattern(o,this._settings)?{dynamic:!0,pattern:o,patternRe:rE.pattern.makeRe(o,this._micromatchOptions)}:{dynamic:!1,pattern:o})}_splitSegmentsIntoSections(e){return rE.array.splitWhen(e,r=>r.dynamic&&rE.pattern.hasGlobStar(r.pattern))}};xM.default=SM});var Hie=_(kM=>{"use strict";Object.defineProperty(kM,"__esModule",{value:!0});var att=_ie(),bM=class extends att.default{match(e){let r=e.split("/"),o=r.length,a=this._storage.filter(n=>!n.complete||n.segments.length>o);for(let n of a){let u=n.sections[0];if(!n.complete&&o>u.length||r.every((p,h)=>{let E=n.segments[h];return!!(E.dynamic&&E.patternRe.test(p)||!E.dynamic&&E.pattern===p)}))return!0}return!1}};kM.default=bM});var jie=_(FM=>{"use strict";Object.defineProperty(FM,"__esModule",{value:!0});var QS=Df(),ltt=Hie(),QM=class{constructor(e,r){this._settings=e,this._micromatchOptions=r}getFilter(e,r,o){let a=this._getMatcher(r),n=this._getNegativePatternsRe(o);return u=>this._filter(e,u,a,n)}_getMatcher(e){return new ltt.default(e,this._settings,this._micromatchOptions)}_getNegativePatternsRe(e){let r=e.filter(QS.pattern.isAffectDepthOfReadingPattern);return QS.pattern.convertPatternsToRe(r,this._micromatchOptions)}_filter(e,r,o,a){if(this._isSkippedByDeep(e,r.path)||this._isSkippedSymbolicLink(r))return!1;let n=QS.path.removeLeadingDotSegment(r.path);return this._isSkippedByPositivePatterns(n,o)?!1:this._isSkippedByNegativePatterns(n,a)}_isSkippedByDeep(e,r){return this._settings.deep===1/0?!1:this._getEntryLevel(e,r)>=this._settings.deep}_getEntryLevel(e,r){let o=r.split("/").length;if(e==="")return o;let a=e.split("/").length;return o-a}_isSkippedSymbolicLink(e){return!this._settings.followSymbolicLinks&&e.dirent.isSymbolicLink()}_isSkippedByPositivePatterns(e,r){return!this._settings.baseNameMatch&&!r.match(e)}_isSkippedByNegativePatterns(e,r){return!QS.pattern.matchAny(e,r)}};FM.default=QM});var qie=_(RM=>{"use strict";Object.defineProperty(RM,"__esModule",{value:!0});var Cd=Df(),TM=class{constructor(e,r){this._settings=e,this._micromatchOptions=r,this.index=new Map}getFilter(e,r){let o=Cd.pattern.convertPatternsToRe(e,this._micromatchOptions),a=Cd.pattern.convertPatternsToRe(r,this._micromatchOptions);return n=>this._filter(n,o,a)}_filter(e,r,o){if(this._settings.unique&&this._isDuplicateEntry(e)||this._onlyFileFilter(e)||this._onlyDirectoryFilter(e)||this._isSkippedByAbsoluteNegativePatterns(e.path,o))return!1;let a=this._settings.baseNameMatch?e.name:e.path,n=e.dirent.isDirectory(),u=this._isMatchToPatterns(a,r,n)&&!this._isMatchToPatterns(e.path,o,n);return this._settings.unique&&u&&this._createIndexRecord(e),u}_isDuplicateEntry(e){return this.index.has(e.path)}_createIndexRecord(e){this.index.set(e.path,void 0)}_onlyFileFilter(e){return this._settings.onlyFiles&&!e.dirent.isFile()}_onlyDirectoryFilter(e){return this._settings.onlyDirectories&&!e.dirent.isDirectory()}_isSkippedByAbsoluteNegativePatterns(e,r){if(!this._settings.absolute)return!1;let o=Cd.path.makeAbsolute(this._settings.cwd,e);return Cd.pattern.matchAny(o,r)}_isMatchToPatterns(e,r,o){let a=Cd.path.removeLeadingDotSegment(e),n=Cd.pattern.matchAny(a,r);return!n&&o?Cd.pattern.matchAny(a+"/",r):n}};RM.default=TM});var Gie=_(LM=>{"use strict";Object.defineProperty(LM,"__esModule",{value:!0});var ctt=Df(),NM=class{constructor(e){this._settings=e}getFilter(){return e=>this._isNonFatalError(e)}_isNonFatalError(e){return ctt.errno.isEnoentCodeError(e)||this._settings.suppressErrors}};LM.default=NM});var Wie=_(OM=>{"use strict";Object.defineProperty(OM,"__esModule",{value:!0});var Yie=Df(),MM=class{constructor(e){this._settings=e}getTransformer(){return e=>this._transform(e)}_transform(e){let r=e.path;return this._settings.absolute&&(r=Yie.path.makeAbsolute(this._settings.cwd,r),r=Yie.path.unixify(r)),this._settings.markDirectories&&e.dirent.isDirectory()&&(r+="/"),this._settings.objectMode?Object.assign(Object.assign({},e),{path:r}):r}};OM.default=MM});var TS=_(_M=>{"use strict";Object.defineProperty(_M,"__esModule",{value:!0});var utt=Be("path"),Att=jie(),ftt=qie(),ptt=Gie(),htt=Wie(),UM=class{constructor(e){this._settings=e,this.errorFilter=new ptt.default(this._settings),this.entryFilter=new ftt.default(this._settings,this._getMicromatchOptions()),this.deepFilter=new Att.default(this._settings,this._getMicromatchOptions()),this.entryTransformer=new htt.default(this._settings)}_getRootDirectory(e){return utt.resolve(this._settings.cwd,e.base)}_getReaderOptions(e){let r=e.base==="."?"":e.base;return{basePath:r,pathSegmentSeparator:"/",concurrency:this._settings.concurrency,deepFilter:this.deepFilter.getFilter(r,e.positive,e.negative),entryFilter:this.entryFilter.getFilter(e.positive,e.negative),errorFilter:this.errorFilter.getFilter(),followSymbolicLinks:this._settings.followSymbolicLinks,fs:this._settings.fs,stats:this._settings.stats,throwErrorOnBrokenSymbolicLink:this._settings.throwErrorOnBrokenSymbolicLink,transform:this.entryTransformer.getTransformer()}}_getMicromatchOptions(){return{dot:this._settings.dot,matchBase:this._settings.baseNameMatch,nobrace:!this._settings.braceExpansion,nocase:!this._settings.caseSensitiveMatch,noext:!this._settings.extglob,noglobstar:!this._settings.globstar,posix:!0,strictSlashes:!1}}};_M.default=UM});var Vie=_(jM=>{"use strict";Object.defineProperty(jM,"__esModule",{value:!0});var gtt=Uie(),dtt=TS(),HM=class extends dtt.default{constructor(){super(...arguments),this._reader=new gtt.default(this._settings)}async read(e){let r=this._getRootDirectory(e),o=this._getReaderOptions(e);return(await this.api(r,e,o)).map(n=>o.transform(n))}api(e,r,o){return r.dynamic?this._reader.dynamic(e,o):this._reader.static(r.patterns,o)}};jM.default=HM});var Kie=_(GM=>{"use strict";Object.defineProperty(GM,"__esModule",{value:!0});var mtt=Be("stream"),ytt=vM(),Ett=TS(),qM=class extends Ett.default{constructor(){super(...arguments),this._reader=new ytt.default(this._settings)}read(e){let r=this._getRootDirectory(e),o=this._getReaderOptions(e),a=this.api(r,e,o),n=new mtt.Readable({objectMode:!0,read:()=>{}});return a.once("error",u=>n.emit("error",u)).on("data",u=>n.emit("data",o.transform(u))).once("end",()=>n.emit("end")),n.once("close",()=>a.destroy()),n}api(e,r,o){return r.dynamic?this._reader.dynamic(e,o):this._reader.static(r.patterns,o)}};GM.default=qM});var Jie=_(WM=>{"use strict";Object.defineProperty(WM,"__esModule",{value:!0});var Ctt=Ed(),wtt=bS(),Itt=kS(),YM=class extends Itt.default{constructor(){super(...arguments),this._walkSync=wtt.walkSync,this._statSync=Ctt.statSync}dynamic(e,r){return this._walkSync(e,r)}static(e,r){let o=[];for(let a of e){let n=this._getFullEntryPath(a),u=this._getEntry(n,a,r);u===null||!r.entryFilter(u)||o.push(u)}return o}_getEntry(e,r,o){try{let a=this._getStat(e);return this._makeEntry(a,r)}catch(a){if(o.errorFilter(a))return null;throw a}}_getStat(e){return this._statSync(e,this._fsStatSettings)}};WM.default=YM});var zie=_(KM=>{"use strict";Object.defineProperty(KM,"__esModule",{value:!0});var Btt=Jie(),vtt=TS(),VM=class extends vtt.default{constructor(){super(...arguments),this._reader=new Btt.default(this._settings)}read(e){let r=this._getRootDirectory(e),o=this._getReaderOptions(e);return this.api(r,e,o).map(o.transform)}api(e,r,o){return r.dynamic?this._reader.dynamic(e,o):this._reader.static(r.patterns,o)}};KM.default=VM});var Xie=_(iE=>{"use strict";Object.defineProperty(iE,"__esModule",{value:!0});iE.DEFAULT_FILE_SYSTEM_ADAPTER=void 0;var nE=Be("fs"),Dtt=Be("os"),Ptt=Math.max(Dtt.cpus().length,1);iE.DEFAULT_FILE_SYSTEM_ADAPTER={lstat:nE.lstat,lstatSync:nE.lstatSync,stat:nE.stat,statSync:nE.statSync,readdir:nE.readdir,readdirSync:nE.readdirSync};var JM=class{constructor(e={}){this._options=e,this.absolute=this._getValue(this._options.absolute,!1),this.baseNameMatch=this._getValue(this._options.baseNameMatch,!1),this.braceExpansion=this._getValue(this._options.braceExpansion,!0),this.caseSensitiveMatch=this._getValue(this._options.caseSensitiveMatch,!0),this.concurrency=this._getValue(this._options.concurrency,Ptt),this.cwd=this._getValue(this._options.cwd,process.cwd()),this.deep=this._getValue(this._options.deep,1/0),this.dot=this._getValue(this._options.dot,!1),this.extglob=this._getValue(this._options.extglob,!0),this.followSymbolicLinks=this._getValue(this._options.followSymbolicLinks,!0),this.fs=this._getFileSystemMethods(this._options.fs),this.globstar=this._getValue(this._options.globstar,!0),this.ignore=this._getValue(this._options.ignore,[]),this.markDirectories=this._getValue(this._options.markDirectories,!1),this.objectMode=this._getValue(this._options.objectMode,!1),this.onlyDirectories=this._getValue(this._options.onlyDirectories,!1),this.onlyFiles=this._getValue(this._options.onlyFiles,!0),this.stats=this._getValue(this._options.stats,!1),this.suppressErrors=this._getValue(this._options.suppressErrors,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!1),this.unique=this._getValue(this._options.unique,!0),this.onlyDirectories&&(this.onlyFiles=!1),this.stats&&(this.objectMode=!0)}_getValue(e,r){return e===void 0?r:e}_getFileSystemMethods(e={}){return Object.assign(Object.assign({},iE.DEFAULT_FILE_SYSTEM_ADAPTER),e)}};iE.default=JM});var RS=_((DNt,ese)=>{"use strict";var Zie=eie(),$ie=rie(),Stt=Vie(),xtt=Kie(),btt=zie(),zM=Xie(),wd=Df();async function XM(t,e){sE(t);let r=ZM(t,Stt.default,e),o=await Promise.all(r);return wd.array.flatten(o)}(function(t){function e(u,A){sE(u);let p=ZM(u,btt.default,A);return wd.array.flatten(p)}t.sync=e;function r(u,A){sE(u);let p=ZM(u,xtt.default,A);return wd.stream.merge(p)}t.stream=r;function o(u,A){sE(u);let p=$ie.transform([].concat(u)),h=new zM.default(A);return Zie.generate(p,h)}t.generateTasks=o;function a(u,A){sE(u);let p=new zM.default(A);return wd.pattern.isDynamicPattern(u,p)}t.isDynamicPattern=a;function n(u){return sE(u),wd.path.escape(u)}t.escapePath=n})(XM||(XM={}));function ZM(t,e,r){let o=$ie.transform([].concat(t)),a=new zM.default(r),n=Zie.generate(o,a),u=new e(a);return n.map(u.read,u)}function sE(t){if(![].concat(t).every(o=>wd.string.isString(o)&&!wd.string.isEmpty(o)))throw new TypeError("Patterns must be a string (non empty) or an array of strings")}ese.exports=XM});var wn={};Kt(wn,{checksumFile:()=>LS,checksumPattern:()=>MS,makeHash:()=>zs});function zs(...t){let e=(0,NS.createHash)("sha512"),r="";for(let o of t)typeof o=="string"?r+=o:o&&(r&&(e.update(r),r=""),e.update(o));return r&&e.update(r),e.digest("hex")}async function LS(t,{baseFs:e,algorithm:r}={baseFs:oe,algorithm:"sha512"}){let o=await e.openPromise(t,"r");try{let n=Buffer.allocUnsafeSlow(65536),u=(0,NS.createHash)(r),A=0;for(;(A=await e.readPromise(o,n,0,65536))!==0;)u.update(A===65536?n:n.slice(0,A));return u.digest("hex")}finally{await e.closePromise(o)}}async function MS(t,{cwd:e}){let o=(await(0,$M.default)(t,{cwd:ue.fromPortablePath(e),onlyDirectories:!0})).map(A=>`${A}/**/*`),a=await(0,$M.default)([t,...o],{cwd:ue.fromPortablePath(e),onlyFiles:!1});a.sort();let n=await Promise.all(a.map(async A=>{let p=[Buffer.from(A)],h=ue.toPortablePath(A),E=await oe.lstatPromise(h);return E.isSymbolicLink()?p.push(Buffer.from(await oe.readlinkPromise(h))):E.isFile()&&p.push(await oe.readFilePromise(h)),p.join("\0")})),u=(0,NS.createHash)("sha512");for(let A of n)u.update(A);return u.digest("hex")}var NS,$M,rh=Et(()=>{Pt();NS=Be("crypto"),$M=$e(RS())});var W={};Kt(W,{areDescriptorsEqual:()=>sse,areIdentsEqual:()=>r1,areLocatorsEqual:()=>n1,areVirtualPackagesEquivalent:()=>Ott,bindDescriptor:()=>Ltt,bindLocator:()=>Mtt,convertDescriptorToLocator:()=>OS,convertLocatorToDescriptor:()=>tO,convertPackageToLocator:()=>Ttt,convertToIdent:()=>Ftt,convertToManifestRange:()=>Ktt,copyPackage:()=>$I,devirtualizeDescriptor:()=>e1,devirtualizeLocator:()=>t1,ensureDevirtualizedDescriptor:()=>Rtt,ensureDevirtualizedLocator:()=>Ntt,getIdentVendorPath:()=>sO,isPackageCompatible:()=>qS,isVirtualDescriptor:()=>Sf,isVirtualLocator:()=>Hc,makeDescriptor:()=>In,makeIdent:()=>eA,makeLocator:()=>Qs,makeRange:()=>HS,parseDescriptor:()=>nh,parseFileStyleRange:()=>Wtt,parseIdent:()=>Js,parseLocator:()=>xf,parseRange:()=>Id,prettyDependent:()=>FL,prettyDescriptor:()=>qn,prettyIdent:()=>cs,prettyLocator:()=>jr,prettyLocatorNoColors:()=>QL,prettyRange:()=>lE,prettyReference:()=>s1,prettyResolution:()=>XI,prettyWorkspace:()=>o1,renamePackage:()=>rO,slugifyIdent:()=>eO,slugifyLocator:()=>aE,sortDescriptors:()=>cE,stringifyDescriptor:()=>Sa,stringifyIdent:()=>fn,stringifyLocator:()=>xa,tryParseDescriptor:()=>i1,tryParseIdent:()=>ose,tryParseLocator:()=>_S,tryParseRange:()=>Ytt,virtualizeDescriptor:()=>nO,virtualizePackage:()=>iO});function eA(t,e){if(t?.startsWith("@"))throw new Error("Invalid scope: don't prefix it with '@'");return{identHash:zs(t,e),scope:t,name:e}}function In(t,e){return{identHash:t.identHash,scope:t.scope,name:t.name,descriptorHash:zs(t.identHash,e),range:e}}function Qs(t,e){return{identHash:t.identHash,scope:t.scope,name:t.name,locatorHash:zs(t.identHash,e),reference:e}}function Ftt(t){return{identHash:t.identHash,scope:t.scope,name:t.name}}function OS(t){return{identHash:t.identHash,scope:t.scope,name:t.name,locatorHash:t.descriptorHash,reference:t.range}}function tO(t){return{identHash:t.identHash,scope:t.scope,name:t.name,descriptorHash:t.locatorHash,range:t.reference}}function Ttt(t){return{identHash:t.identHash,scope:t.scope,name:t.name,locatorHash:t.locatorHash,reference:t.reference}}function rO(t,e){return{identHash:e.identHash,scope:e.scope,name:e.name,locatorHash:e.locatorHash,reference:e.reference,version:t.version,languageName:t.languageName,linkType:t.linkType,conditions:t.conditions,dependencies:new Map(t.dependencies),peerDependencies:new Map(t.peerDependencies),dependenciesMeta:new Map(t.dependenciesMeta),peerDependenciesMeta:new Map(t.peerDependenciesMeta),bin:new Map(t.bin)}}function $I(t){return rO(t,t)}function nO(t,e){if(e.includes("#"))throw new Error("Invalid entropy");return In(t,`virtual:${e}#${t.range}`)}function iO(t,e){if(e.includes("#"))throw new Error("Invalid entropy");return rO(t,Qs(t,`virtual:${e}#${t.reference}`))}function Sf(t){return t.range.startsWith(ZI)}function Hc(t){return t.reference.startsWith(ZI)}function e1(t){if(!Sf(t))throw new Error("Not a virtual descriptor");return In(t,t.range.replace(US,""))}function t1(t){if(!Hc(t))throw new Error("Not a virtual descriptor");return Qs(t,t.reference.replace(US,""))}function Rtt(t){return Sf(t)?In(t,t.range.replace(US,"")):t}function Ntt(t){return Hc(t)?Qs(t,t.reference.replace(US,"")):t}function Ltt(t,e){return t.range.includes("::")?t:In(t,`${t.range}::${oE.default.stringify(e)}`)}function Mtt(t,e){return t.reference.includes("::")?t:Qs(t,`${t.reference}::${oE.default.stringify(e)}`)}function r1(t,e){return t.identHash===e.identHash}function sse(t,e){return t.descriptorHash===e.descriptorHash}function n1(t,e){return t.locatorHash===e.locatorHash}function Ott(t,e){if(!Hc(t))throw new Error("Invalid package type");if(!Hc(e))throw new Error("Invalid package type");if(!r1(t,e)||t.dependencies.size!==e.dependencies.size)return!1;for(let r of t.dependencies.values()){let o=e.dependencies.get(r.identHash);if(!o||!sse(r,o))return!1}return!0}function Js(t){let e=ose(t);if(!e)throw new Error(`Invalid ident (${t})`);return e}function ose(t){let e=t.match(Utt);if(!e)return null;let[,r,o]=e;return eA(typeof r<"u"?r:null,o)}function nh(t,e=!1){let r=i1(t,e);if(!r)throw new Error(`Invalid descriptor (${t})`);return r}function i1(t,e=!1){let r=e?t.match(_tt):t.match(Htt);if(!r)return null;let[,o,a,n]=r;if(n==="unknown")throw new Error(`Invalid range (${t})`);let u=typeof o<"u"?o:null,A=typeof n<"u"?n:"unknown";return In(eA(u,a),A)}function xf(t,e=!1){let r=_S(t,e);if(!r)throw new Error(`Invalid locator (${t})`);return r}function _S(t,e=!1){let r=e?t.match(jtt):t.match(qtt);if(!r)return null;let[,o,a,n]=r;if(n==="unknown")throw new Error(`Invalid reference (${t})`);let u=typeof o<"u"?o:null,A=typeof n<"u"?n:"unknown";return Qs(eA(u,a),A)}function Id(t,e){let r=t.match(Gtt);if(r===null)throw new Error(`Invalid range (${t})`);let o=typeof r[1]<"u"?r[1]:null;if(typeof e?.requireProtocol=="string"&&o!==e.requireProtocol)throw new Error(`Invalid protocol (${o})`);if(e?.requireProtocol&&o===null)throw new Error(`Missing protocol (${o})`);let a=typeof r[3]<"u"?decodeURIComponent(r[2]):null;if(e?.requireSource&&a===null)throw new Error(`Missing source (${t})`);let n=typeof r[3]<"u"?decodeURIComponent(r[3]):decodeURIComponent(r[2]),u=e?.parseSelector?oE.default.parse(n):n,A=typeof r[4]<"u"?oE.default.parse(r[4]):null;return{protocol:o,source:a,selector:u,params:A}}function Ytt(t,e){try{return Id(t,e)}catch{return null}}function Wtt(t,{protocol:e}){let{selector:r,params:o}=Id(t,{requireProtocol:e,requireBindings:!0});if(typeof o.locator!="string")throw new Error(`Assertion failed: Invalid bindings for ${t}`);return{parentLocator:xf(o.locator,!0),path:r}}function tse(t){return t=t.replaceAll("%","%25"),t=t.replaceAll(":","%3A"),t=t.replaceAll("#","%23"),t}function Vtt(t){return t===null?!1:Object.entries(t).length>0}function HS({protocol:t,source:e,selector:r,params:o}){let a="";return t!==null&&(a+=`${t}`),e!==null&&(a+=`${tse(e)}#`),a+=tse(r),Vtt(o)&&(a+=`::${oE.default.stringify(o)}`),a}function Ktt(t){let{params:e,protocol:r,source:o,selector:a}=Id(t);for(let n in e)n.startsWith("__")&&delete e[n];return HS({protocol:r,source:o,params:e,selector:a})}function fn(t){return t.scope?`@${t.scope}/${t.name}`:`${t.name}`}function Sa(t){return t.scope?`@${t.scope}/${t.name}@${t.range}`:`${t.name}@${t.range}`}function xa(t){return t.scope?`@${t.scope}/${t.name}@${t.reference}`:`${t.name}@${t.reference}`}function eO(t){return t.scope!==null?`@${t.scope}-${t.name}`:t.name}function aE(t){let{protocol:e,selector:r}=Id(t.reference),o=e!==null?e.replace(Jtt,""):"exotic",a=rse.default.valid(r),n=a!==null?`${o}-${a}`:`${o}`,u=10;return t.scope?`${eO(t)}-${n}-${t.locatorHash.slice(0,u)}`:`${eO(t)}-${n}-${t.locatorHash.slice(0,u)}`}function cs(t,e){return e.scope?`${Ot(t,`@${e.scope}/`,yt.SCOPE)}${Ot(t,e.name,yt.NAME)}`:`${Ot(t,e.name,yt.NAME)}`}function jS(t){if(t.startsWith(ZI)){let e=jS(t.substring(t.indexOf("#")+1)),r=t.substring(ZI.length,ZI.length+ktt);return`${e} [${r}]`}else return t.replace(ztt,"?[...]")}function lE(t,e){return`${Ot(t,jS(e),yt.RANGE)}`}function qn(t,e){return`${cs(t,e)}${Ot(t,"@",yt.RANGE)}${lE(t,e.range)}`}function s1(t,e){return`${Ot(t,jS(e),yt.REFERENCE)}`}function jr(t,e){return`${cs(t,e)}${Ot(t,"@",yt.REFERENCE)}${s1(t,e.reference)}`}function QL(t){return`${fn(t)}@${jS(t.reference)}`}function cE(t){return ks(t,[e=>fn(e),e=>e.range])}function o1(t,e){return cs(t,e.anchoredLocator)}function XI(t,e,r){let o=Sf(e)?e1(e):e;return r===null?`${qn(t,o)} \u2192 ${kL(t).Cross}`:o.identHash===r.identHash?`${qn(t,o)} \u2192 ${s1(t,r.reference)}`:`${qn(t,o)} \u2192 ${jr(t,r)}`}function FL(t,e,r){return r===null?`${jr(t,e)}`:`${jr(t,e)} (via ${lE(t,r.range)})`}function sO(t){return`node_modules/${fn(t)}`}function qS(t,e){return t.conditions?Qtt(t.conditions,r=>{let[,o,a]=r.match(ise),n=e[o];return n?n.includes(a):!0}):!0}var oE,rse,nse,ZI,ktt,ise,Qtt,US,Utt,_tt,Htt,jtt,qtt,Gtt,Jtt,ztt,xo=Et(()=>{oE=$e(Be("querystring")),rse=$e(zn()),nse=$e(rX());ql();rh();jl();xo();ZI="virtual:",ktt=5,ise=/(os|cpu|libc)=([a-z0-9_-]+)/,Qtt=(0,nse.makeParser)(ise);US=/^[^#]*#/;Utt=/^(?:@([^/]+?)\/)?([^@/]+)$/;_tt=/^(?:@([^/]+?)\/)?([^@/]+?)(?:@(.+))$/,Htt=/^(?:@([^/]+?)\/)?([^@/]+?)(?:@(.+))?$/;jtt=/^(?:@([^/]+?)\/)?([^@/]+?)(?:@(.+))$/,qtt=/^(?:@([^/]+?)\/)?([^@/]+?)(?:@(.+))?$/;Gtt=/^([^#:]*:)?((?:(?!::)[^#])*)(?:#((?:(?!::).)*))?(?:::(.*))?$/;Jtt=/:$/;ztt=/\?.*/});var ase,lse=Et(()=>{xo();ase={hooks:{reduceDependency:(t,e,r,o,{resolver:a,resolveOptions:n})=>{for(let{pattern:u,reference:A}of e.topLevelWorkspace.manifest.resolutions){if(u.from&&(u.from.fullName!==fn(r)||e.configuration.normalizeLocator(Qs(Js(u.from.fullName),u.from.description??r.reference)).locatorHash!==r.locatorHash)||u.descriptor.fullName!==fn(t)||e.configuration.normalizeDependency(In(xf(u.descriptor.fullName),u.descriptor.description??t.range)).descriptorHash!==t.descriptorHash)continue;return a.bindDescriptor(e.configuration.normalizeDependency(In(t,A)),e.topLevelWorkspace.anchoredLocator,n)}return t},validateProject:async(t,e)=>{for(let r of t.workspaces){let o=o1(t.configuration,r);await t.configuration.triggerHook(a=>a.validateWorkspace,r,{reportWarning:(a,n)=>e.reportWarning(a,`${o}: ${n}`),reportError:(a,n)=>e.reportError(a,`${o}: ${n}`)})}},validateWorkspace:async(t,e)=>{let{manifest:r}=t;r.resolutions.length&&t.cwd!==t.project.cwd&&r.errors.push(new Error("Resolutions field will be ignored"));for(let o of r.errors)e.reportWarning(57,o.message)}}}});var a1,Xn,Bd=Et(()=>{a1=class{supportsDescriptor(e,r){return!!(e.range.startsWith(a1.protocol)||r.project.tryWorkspaceByDescriptor(e)!==null)}supportsLocator(e,r){return!!e.reference.startsWith(a1.protocol)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){return[o.project.getWorkspaceByDescriptor(e).anchoredLocator]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){let o=r.project.getWorkspaceByCwd(e.reference.slice(a1.protocol.length));return{...e,version:o.manifest.version||"0.0.0",languageName:"unknown",linkType:"SOFT",conditions:null,dependencies:r.project.configuration.normalizeDependencyMap(new Map([...o.manifest.dependencies,...o.manifest.devDependencies])),peerDependencies:new Map([...o.manifest.peerDependencies]),dependenciesMeta:o.manifest.dependenciesMeta,peerDependenciesMeta:o.manifest.peerDependenciesMeta,bin:o.manifest.bin}}},Xn=a1;Xn.protocol="workspace:"});var kr={};Kt(kr,{SemVer:()=>pse.SemVer,clean:()=>Ztt,getComparator:()=>Ase,mergeComparators:()=>oO,satisfiesWithPrereleases:()=>bf,simplifyRanges:()=>aO,stringifyComparator:()=>fse,validRange:()=>ba});function bf(t,e,r=!1){if(!t)return!1;let o=`${e}${r}`,a=cse.get(o);if(typeof a>"u")try{a=new ih.default.Range(e,{includePrerelease:!0,loose:r})}catch{return!1}finally{cse.set(o,a||null)}else if(a===null)return!1;let n;try{n=new ih.default.SemVer(t,a)}catch{return!1}return a.test(n)?!0:(n.prerelease&&(n.prerelease=[]),a.set.some(u=>{for(let A of u)A.semver.prerelease&&(A.semver.prerelease=[]);return u.every(A=>A.test(n))}))}function ba(t){if(t.indexOf(":")!==-1)return null;let e=use.get(t);if(typeof e<"u")return e;try{e=new ih.default.Range(t)}catch{e=null}return use.set(t,e),e}function Ztt(t){let e=Xtt.exec(t);return e?e[1]:null}function Ase(t){if(t.semver===ih.default.Comparator.ANY)return{gt:null,lt:null};switch(t.operator){case"":return{gt:[">=",t.semver],lt:["<=",t.semver]};case">":case">=":return{gt:[t.operator,t.semver],lt:null};case"<":case"<=":return{gt:null,lt:[t.operator,t.semver]};default:throw new Error(`Assertion failed: Unexpected comparator operator (${t.operator})`)}}function oO(t){if(t.length===0)return null;let e=null,r=null;for(let o of t){if(o.gt){let a=e!==null?ih.default.compare(o.gt[1],e[1]):null;(a===null||a>0||a===0&&o.gt[0]===">")&&(e=o.gt)}if(o.lt){let a=r!==null?ih.default.compare(o.lt[1],r[1]):null;(a===null||a<0||a===0&&o.lt[0]==="<")&&(r=o.lt)}}if(e&&r){let o=ih.default.compare(e[1],r[1]);if(o===0&&(e[0]===">"||r[0]==="<")||o>0)return null}return{gt:e,lt:r}}function fse(t){if(t.gt&&t.lt){if(t.gt[0]===">="&&t.lt[0]==="<="&&t.gt[1].version===t.lt[1].version)return t.gt[1].version;if(t.gt[0]===">="&&t.lt[0]==="<"){if(t.lt[1].version===`${t.gt[1].major+1}.0.0-0`)return`^${t.gt[1].version}`;if(t.lt[1].version===`${t.gt[1].major}.${t.gt[1].minor+1}.0-0`)return`~${t.gt[1].version}`}}let e=[];return t.gt&&e.push(t.gt[0]+t.gt[1].version),t.lt&&e.push(t.lt[0]+t.lt[1].version),e.length?e.join(" "):"*"}function aO(t){let e=t.map(o=>ba(o).set.map(a=>a.map(n=>Ase(n)))),r=e.shift().map(o=>oO(o)).filter(o=>o!==null);for(let o of e){let a=[];for(let n of r)for(let u of o){let A=oO([n,...u]);A!==null&&a.push(A)}r=a}return r.length===0?null:r.map(o=>fse(o)).join(" || ")}var ih,pse,cse,use,Xtt,kf=Et(()=>{ih=$e(zn()),pse=$e(zn()),cse=new Map;use=new Map;Xtt=/^(?:[\sv=]*?)((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\s*)$/});function hse(t){let e=t.match(/^[ \t]+/m);return e?e[0]:" "}function gse(t){return t.charCodeAt(0)===65279?t.slice(1):t}function $o(t){return t.replace(/\\/g,"/")}function GS(t,{yamlCompatibilityMode:e}){return e?IL(t):typeof t>"u"||typeof t=="boolean"?t:null}function dse(t,e){let r=e.search(/[^!]/);if(r===-1)return"invalid";let o=r%2===0?"":"!",a=e.slice(r);return`${o}${t}=${a}`}function lO(t,e){return e.length===1?dse(t,e[0]):`(${e.map(r=>dse(t,r)).join(" | ")})`}var mse,uE,Mt,AE=Et(()=>{Pt();Nl();mse=$e(zn());Bd();jl();kf();xo();uE=class{constructor(){this.indent=" ";this.name=null;this.version=null;this.os=null;this.cpu=null;this.libc=null;this.type=null;this.packageManager=null;this.private=!1;this.license=null;this.main=null;this.module=null;this.browser=null;this.languageName=null;this.bin=new Map;this.scripts=new Map;this.dependencies=new Map;this.devDependencies=new Map;this.peerDependencies=new Map;this.workspaceDefinitions=[];this.dependenciesMeta=new Map;this.peerDependenciesMeta=new Map;this.resolutions=[];this.files=null;this.publishConfig=null;this.installConfig=null;this.preferUnplugged=null;this.raw={};this.errors=[]}static async tryFind(e,{baseFs:r=new Rn}={}){let o=K.join(e,"package.json");try{return await uE.fromFile(o,{baseFs:r})}catch(a){if(a.code==="ENOENT")return null;throw a}}static async find(e,{baseFs:r}={}){let o=await uE.tryFind(e,{baseFs:r});if(o===null)throw new Error("Manifest not found");return o}static async fromFile(e,{baseFs:r=new Rn}={}){let o=new uE;return await o.loadFile(e,{baseFs:r}),o}static fromText(e){let r=new uE;return r.loadFromText(e),r}loadFromText(e){let r;try{r=JSON.parse(gse(e)||"{}")}catch(o){throw o.message+=` (when parsing ${e})`,o}this.load(r),this.indent=hse(e)}async loadFile(e,{baseFs:r=new Rn}){let o=await r.readFilePromise(e,"utf8"),a;try{a=JSON.parse(gse(o)||"{}")}catch(n){throw n.message+=` (when parsing ${e})`,n}this.load(a),this.indent=hse(o)}load(e,{yamlCompatibilityMode:r=!1}={}){if(typeof e!="object"||e===null)throw new Error(`Utterly invalid manifest data (${e})`);this.raw=e;let o=[];if(this.name=null,typeof e.name=="string")try{this.name=Js(e.name)}catch{o.push(new Error("Parsing failed for the 'name' field"))}if(typeof e.version=="string"?this.version=e.version:this.version=null,Array.isArray(e.os)){let n=[];this.os=n;for(let u of e.os)typeof u!="string"?o.push(new Error("Parsing failed for the 'os' field")):n.push(u)}else this.os=null;if(Array.isArray(e.cpu)){let n=[];this.cpu=n;for(let u of e.cpu)typeof u!="string"?o.push(new Error("Parsing failed for the 'cpu' field")):n.push(u)}else this.cpu=null;if(Array.isArray(e.libc)){let n=[];this.libc=n;for(let u of e.libc)typeof u!="string"?o.push(new Error("Parsing failed for the 'libc' field")):n.push(u)}else this.libc=null;if(typeof e.type=="string"?this.type=e.type:this.type=null,typeof e.packageManager=="string"?this.packageManager=e.packageManager:this.packageManager=null,typeof e.private=="boolean"?this.private=e.private:this.private=!1,typeof e.license=="string"?this.license=e.license:this.license=null,typeof e.languageName=="string"?this.languageName=e.languageName:this.languageName=null,typeof e.main=="string"?this.main=$o(e.main):this.main=null,typeof e.module=="string"?this.module=$o(e.module):this.module=null,e.browser!=null)if(typeof e.browser=="string")this.browser=$o(e.browser);else{this.browser=new Map;for(let[n,u]of Object.entries(e.browser))this.browser.set($o(n),typeof u=="string"?$o(u):u)}else this.browser=null;if(this.bin=new Map,typeof e.bin=="string")e.bin.trim()===""?o.push(new Error("Invalid bin field")):this.name!==null?this.bin.set(this.name.name,$o(e.bin)):o.push(new Error("String bin field, but no attached package name"));else if(typeof e.bin=="object"&&e.bin!==null)for(let[n,u]of Object.entries(e.bin)){if(typeof u!="string"||u.trim()===""){o.push(new Error(`Invalid bin definition for '${n}'`));continue}let A=Js(n);this.bin.set(A.name,$o(u))}if(this.scripts=new Map,typeof e.scripts=="object"&&e.scripts!==null)for(let[n,u]of Object.entries(e.scripts)){if(typeof u!="string"){o.push(new Error(`Invalid script definition for '${n}'`));continue}this.scripts.set(n,u)}if(this.dependencies=new Map,typeof e.dependencies=="object"&&e.dependencies!==null)for(let[n,u]of Object.entries(e.dependencies)){if(typeof u!="string"){o.push(new Error(`Invalid dependency range for '${n}'`));continue}let A;try{A=Js(n)}catch{o.push(new Error(`Parsing failed for the dependency name '${n}'`));continue}let p=In(A,u);this.dependencies.set(p.identHash,p)}if(this.devDependencies=new Map,typeof e.devDependencies=="object"&&e.devDependencies!==null)for(let[n,u]of Object.entries(e.devDependencies)){if(typeof u!="string"){o.push(new Error(`Invalid dependency range for '${n}'`));continue}let A;try{A=Js(n)}catch{o.push(new Error(`Parsing failed for the dependency name '${n}'`));continue}let p=In(A,u);this.devDependencies.set(p.identHash,p)}if(this.peerDependencies=new Map,typeof e.peerDependencies=="object"&&e.peerDependencies!==null)for(let[n,u]of Object.entries(e.peerDependencies)){let A;try{A=Js(n)}catch{o.push(new Error(`Parsing failed for the dependency name '${n}'`));continue}(typeof u!="string"||!u.startsWith(Xn.protocol)&&!ba(u))&&(o.push(new Error(`Invalid dependency range for '${n}'`)),u="*");let p=In(A,u);this.peerDependencies.set(p.identHash,p)}typeof e.workspaces=="object"&&e.workspaces!==null&&e.workspaces.nohoist&&o.push(new Error("'nohoist' is deprecated, please use 'installConfig.hoistingLimits' instead"));let a=Array.isArray(e.workspaces)?e.workspaces:typeof e.workspaces=="object"&&e.workspaces!==null&&Array.isArray(e.workspaces.packages)?e.workspaces.packages:[];this.workspaceDefinitions=[];for(let n of a){if(typeof n!="string"){o.push(new Error(`Invalid workspace definition for '${n}'`));continue}this.workspaceDefinitions.push({pattern:n})}if(this.dependenciesMeta=new Map,typeof e.dependenciesMeta=="object"&&e.dependenciesMeta!==null)for(let[n,u]of Object.entries(e.dependenciesMeta)){if(typeof u!="object"||u===null){o.push(new Error(`Invalid meta field for '${n}`));continue}let A=nh(n),p=this.ensureDependencyMeta(A),h=GS(u.built,{yamlCompatibilityMode:r});if(h===null){o.push(new Error(`Invalid built meta field for '${n}'`));continue}let E=GS(u.optional,{yamlCompatibilityMode:r});if(E===null){o.push(new Error(`Invalid optional meta field for '${n}'`));continue}let I=GS(u.unplugged,{yamlCompatibilityMode:r});if(I===null){o.push(new Error(`Invalid unplugged meta field for '${n}'`));continue}Object.assign(p,{built:h,optional:E,unplugged:I})}if(this.peerDependenciesMeta=new Map,typeof e.peerDependenciesMeta=="object"&&e.peerDependenciesMeta!==null)for(let[n,u]of Object.entries(e.peerDependenciesMeta)){if(typeof u!="object"||u===null){o.push(new Error(`Invalid meta field for '${n}'`));continue}let A=nh(n),p=this.ensurePeerDependencyMeta(A),h=GS(u.optional,{yamlCompatibilityMode:r});if(h===null){o.push(new Error(`Invalid optional meta field for '${n}'`));continue}Object.assign(p,{optional:h})}if(this.resolutions=[],typeof e.resolutions=="object"&&e.resolutions!==null)for(let[n,u]of Object.entries(e.resolutions)){if(typeof u!="string"){o.push(new Error(`Invalid resolution entry for '${n}'`));continue}try{this.resolutions.push({pattern:UD(n),reference:u})}catch(A){o.push(A);continue}}if(Array.isArray(e.files)){this.files=new Set;for(let n of e.files){if(typeof n!="string"){o.push(new Error(`Invalid files entry for '${n}'`));continue}this.files.add(n)}}else this.files=null;if(typeof e.publishConfig=="object"&&e.publishConfig!==null){if(this.publishConfig={},typeof e.publishConfig.access=="string"&&(this.publishConfig.access=e.publishConfig.access),typeof e.publishConfig.main=="string"&&(this.publishConfig.main=$o(e.publishConfig.main)),typeof e.publishConfig.module=="string"&&(this.publishConfig.module=$o(e.publishConfig.module)),e.publishConfig.browser!=null)if(typeof e.publishConfig.browser=="string")this.publishConfig.browser=$o(e.publishConfig.browser);else{this.publishConfig.browser=new Map;for(let[n,u]of Object.entries(e.publishConfig.browser))this.publishConfig.browser.set($o(n),typeof u=="string"?$o(u):u)}if(typeof e.publishConfig.registry=="string"&&(this.publishConfig.registry=e.publishConfig.registry),typeof e.publishConfig.bin=="string")this.name!==null?this.publishConfig.bin=new Map([[this.name.name,$o(e.publishConfig.bin)]]):o.push(new Error("String bin field, but no attached package name"));else if(typeof e.publishConfig.bin=="object"&&e.publishConfig.bin!==null){this.publishConfig.bin=new Map;for(let[n,u]of Object.entries(e.publishConfig.bin)){if(typeof u!="string"){o.push(new Error(`Invalid bin definition for '${n}'`));continue}this.publishConfig.bin.set(n,$o(u))}}if(Array.isArray(e.publishConfig.executableFiles)){this.publishConfig.executableFiles=new Set;for(let n of e.publishConfig.executableFiles){if(typeof n!="string"){o.push(new Error("Invalid executable file definition"));continue}this.publishConfig.executableFiles.add($o(n))}}}else this.publishConfig=null;if(typeof e.installConfig=="object"&&e.installConfig!==null){this.installConfig={};for(let n of Object.keys(e.installConfig))n==="hoistingLimits"?typeof e.installConfig.hoistingLimits=="string"?this.installConfig.hoistingLimits=e.installConfig.hoistingLimits:o.push(new Error("Invalid hoisting limits definition")):n=="selfReferences"?typeof e.installConfig.selfReferences=="boolean"?this.installConfig.selfReferences=e.installConfig.selfReferences:o.push(new Error("Invalid selfReferences definition, must be a boolean value")):o.push(new Error(`Unrecognized installConfig key: ${n}`))}else this.installConfig=null;if(typeof e.optionalDependencies=="object"&&e.optionalDependencies!==null)for(let[n,u]of Object.entries(e.optionalDependencies)){if(typeof u!="string"){o.push(new Error(`Invalid dependency range for '${n}'`));continue}let A;try{A=Js(n)}catch{o.push(new Error(`Parsing failed for the dependency name '${n}'`));continue}let p=In(A,u);this.dependencies.set(p.identHash,p);let h=In(A,"unknown"),E=this.ensureDependencyMeta(h);Object.assign(E,{optional:!0})}typeof e.preferUnplugged=="boolean"?this.preferUnplugged=e.preferUnplugged:this.preferUnplugged=null,this.errors=o}getForScope(e){switch(e){case"dependencies":return this.dependencies;case"devDependencies":return this.devDependencies;case"peerDependencies":return this.peerDependencies;default:throw new Error(`Unsupported value ("${e}")`)}}hasConsumerDependency(e){return!!(this.dependencies.has(e.identHash)||this.peerDependencies.has(e.identHash))}hasHardDependency(e){return!!(this.dependencies.has(e.identHash)||this.devDependencies.has(e.identHash))}hasSoftDependency(e){return!!this.peerDependencies.has(e.identHash)}hasDependency(e){return!!(this.hasHardDependency(e)||this.hasSoftDependency(e))}getConditions(){let e=[];return this.os&&this.os.length>0&&e.push(lO("os",this.os)),this.cpu&&this.cpu.length>0&&e.push(lO("cpu",this.cpu)),this.libc&&this.libc.length>0&&e.push(lO("libc",this.libc)),e.length>0?e.join(" & "):null}ensureDependencyMeta(e){if(e.range!=="unknown"&&!mse.default.valid(e.range))throw new Error(`Invalid meta field range for '${Sa(e)}'`);let r=fn(e),o=e.range!=="unknown"?e.range:null,a=this.dependenciesMeta.get(r);a||this.dependenciesMeta.set(r,a=new Map);let n=a.get(o);return n||a.set(o,n={}),n}ensurePeerDependencyMeta(e){if(e.range!=="unknown")throw new Error(`Invalid meta field range for '${Sa(e)}'`);let r=fn(e),o=this.peerDependenciesMeta.get(r);return o||this.peerDependenciesMeta.set(r,o={}),o}setRawField(e,r,{after:o=[]}={}){let a=new Set(o.filter(n=>Object.hasOwn(this.raw,n)));if(a.size===0||Object.hasOwn(this.raw,e))this.raw[e]=r;else{let n=this.raw,u=this.raw={},A=!1;for(let p of Object.keys(n))u[p]=n[p],A||(a.delete(p),a.size===0&&(u[e]=r,A=!0))}}exportTo(e,{compatibilityMode:r=!0}={}){if(Object.assign(e,this.raw),this.name!==null?e.name=fn(this.name):delete e.name,this.version!==null?e.version=this.version:delete e.version,this.os!==null?e.os=this.os:delete e.os,this.cpu!==null?e.cpu=this.cpu:delete e.cpu,this.type!==null?e.type=this.type:delete e.type,this.packageManager!==null?e.packageManager=this.packageManager:delete e.packageManager,this.private?e.private=!0:delete e.private,this.license!==null?e.license=this.license:delete e.license,this.languageName!==null?e.languageName=this.languageName:delete e.languageName,this.main!==null?e.main=this.main:delete e.main,this.module!==null?e.module=this.module:delete e.module,this.browser!==null){let n=this.browser;typeof n=="string"?e.browser=n:n instanceof Map&&(e.browser=Object.assign({},...Array.from(n.keys()).sort().map(u=>({[u]:n.get(u)}))))}else delete e.browser;this.bin.size===1&&this.name!==null&&this.bin.has(this.name.name)?e.bin=this.bin.get(this.name.name):this.bin.size>0?e.bin=Object.assign({},...Array.from(this.bin.keys()).sort().map(n=>({[n]:this.bin.get(n)}))):delete e.bin,this.workspaceDefinitions.length>0?this.raw.workspaces&&!Array.isArray(this.raw.workspaces)?e.workspaces={...this.raw.workspaces,packages:this.workspaceDefinitions.map(({pattern:n})=>n)}:e.workspaces=this.workspaceDefinitions.map(({pattern:n})=>n):this.raw.workspaces&&!Array.isArray(this.raw.workspaces)&&Object.keys(this.raw.workspaces).length>0?e.workspaces=this.raw.workspaces:delete e.workspaces;let o=[],a=[];for(let n of this.dependencies.values()){let u=this.dependenciesMeta.get(fn(n)),A=!1;if(r&&u){let p=u.get(null);p&&p.optional&&(A=!0)}A?a.push(n):o.push(n)}o.length>0?e.dependencies=Object.assign({},...cE(o).map(n=>({[fn(n)]:n.range}))):delete e.dependencies,a.length>0?e.optionalDependencies=Object.assign({},...cE(a).map(n=>({[fn(n)]:n.range}))):delete e.optionalDependencies,this.devDependencies.size>0?e.devDependencies=Object.assign({},...cE(this.devDependencies.values()).map(n=>({[fn(n)]:n.range}))):delete e.devDependencies,this.peerDependencies.size>0?e.peerDependencies=Object.assign({},...cE(this.peerDependencies.values()).map(n=>({[fn(n)]:n.range}))):delete e.peerDependencies,e.dependenciesMeta={};for(let[n,u]of ks(this.dependenciesMeta.entries(),([A,p])=>A))for(let[A,p]of ks(u.entries(),([h,E])=>h!==null?`0${h}`:"1")){let h=A!==null?Sa(In(Js(n),A)):n,E={...p};r&&A===null&&delete E.optional,Object.keys(E).length!==0&&(e.dependenciesMeta[h]=E)}if(Object.keys(e.dependenciesMeta).length===0&&delete e.dependenciesMeta,this.peerDependenciesMeta.size>0?e.peerDependenciesMeta=Object.assign({},...ks(this.peerDependenciesMeta.entries(),([n,u])=>n).map(([n,u])=>({[n]:u}))):delete e.peerDependenciesMeta,this.resolutions.length>0?e.resolutions=Object.assign({},...this.resolutions.map(({pattern:n,reference:u})=>({[_D(n)]:u}))):delete e.resolutions,this.files!==null?e.files=Array.from(this.files):delete e.files,this.preferUnplugged!==null?e.preferUnplugged=this.preferUnplugged:delete e.preferUnplugged,this.scripts!==null&&this.scripts.size>0){e.scripts??={};for(let n of Object.keys(e.scripts))this.scripts.has(n)||delete e.scripts[n];for(let[n,u]of this.scripts.entries())e.scripts[n]=u}else delete e.scripts;return e}},Mt=uE;Mt.fileName="package.json",Mt.allDependencies=["dependencies","devDependencies","peerDependencies"],Mt.hardDependencies=["dependencies","devDependencies"]});var Ese=_((_Nt,yse)=>{var $tt=_l(),ert=function(){return $tt.Date.now()};yse.exports=ert});var wse=_((HNt,Cse)=>{var trt=/\s/;function rrt(t){for(var e=t.length;e--&&trt.test(t.charAt(e)););return e}Cse.exports=rrt});var Bse=_((jNt,Ise)=>{var nrt=wse(),irt=/^\s+/;function srt(t){return t&&t.slice(0,nrt(t)+1).replace(irt,"")}Ise.exports=srt});var fE=_((qNt,vse)=>{var ort=pd(),art=Ju(),lrt="[object Symbol]";function crt(t){return typeof t=="symbol"||art(t)&&ort(t)==lrt}vse.exports=crt});var xse=_((GNt,Sse)=>{var urt=Bse(),Dse=il(),Art=fE(),Pse=0/0,frt=/^[-+]0x[0-9a-f]+$/i,prt=/^0b[01]+$/i,hrt=/^0o[0-7]+$/i,grt=parseInt;function drt(t){if(typeof t=="number")return t;if(Art(t))return Pse;if(Dse(t)){var e=typeof t.valueOf=="function"?t.valueOf():t;t=Dse(e)?e+"":e}if(typeof t!="string")return t===0?t:+t;t=urt(t);var r=prt.test(t);return r||hrt.test(t)?grt(t.slice(2),r?2:8):frt.test(t)?Pse:+t}Sse.exports=drt});var Qse=_((YNt,kse)=>{var mrt=il(),cO=Ese(),bse=xse(),yrt="Expected a function",Ert=Math.max,Crt=Math.min;function wrt(t,e,r){var o,a,n,u,A,p,h=0,E=!1,I=!1,v=!0;if(typeof t!="function")throw new TypeError(yrt);e=bse(e)||0,mrt(r)&&(E=!!r.leading,I="maxWait"in r,n=I?Ert(bse(r.maxWait)||0,e):n,v="trailing"in r?!!r.trailing:v);function b(Ae){var ye=o,ae=a;return o=a=void 0,h=Ae,u=t.apply(ae,ye),u}function C(Ae){return h=Ae,A=setTimeout(U,e),E?b(Ae):u}function T(Ae){var ye=Ae-p,ae=Ae-h,we=e-ye;return I?Crt(we,n-ae):we}function L(Ae){var ye=Ae-p,ae=Ae-h;return p===void 0||ye>=e||ye<0||I&&ae>=n}function U(){var Ae=cO();if(L(Ae))return J(Ae);A=setTimeout(U,T(Ae))}function J(Ae){return A=void 0,v&&o?b(Ae):(o=a=void 0,u)}function te(){A!==void 0&&clearTimeout(A),h=0,o=p=a=A=void 0}function le(){return A===void 0?u:J(cO())}function pe(){var Ae=cO(),ye=L(Ae);if(o=arguments,a=this,p=Ae,ye){if(A===void 0)return C(p);if(I)return clearTimeout(A),A=setTimeout(U,e),b(p)}return A===void 0&&(A=setTimeout(U,e)),u}return pe.cancel=te,pe.flush=le,pe}kse.exports=wrt});var uO=_((WNt,Fse)=>{var Irt=Qse(),Brt=il(),vrt="Expected a function";function Drt(t,e,r){var o=!0,a=!0;if(typeof t!="function")throw new TypeError(vrt);return Brt(r)&&(o="leading"in r?!!r.leading:o,a="trailing"in r?!!r.trailing:a),Irt(t,e,{leading:o,maxWait:e,trailing:a})}Fse.exports=Drt});function Srt(t){return typeof t.reportCode<"u"}var Tse,Rse,Nse,Prt,zt,Xs,Yl=Et(()=>{Tse=$e(uO()),Rse=Be("stream"),Nse=Be("string_decoder"),Prt=15,zt=class extends Error{constructor(r,o,a){super(o);this.reportExtra=a;this.reportCode=r}};Xs=class{constructor(){this.cacheHits=new Set;this.cacheMisses=new Set;this.reportedInfos=new Set;this.reportedWarnings=new Set;this.reportedErrors=new Set}getRecommendedLength(){return 180}reportCacheHit(e){this.cacheHits.add(e.locatorHash)}reportCacheMiss(e,r){this.cacheMisses.add(e.locatorHash)}static progressViaCounter(e){let r=0,o,a=new Promise(p=>{o=p}),n=p=>{let h=o;a=new Promise(E=>{o=E}),r=p,h()},u=(p=0)=>{n(r+1)},A=async function*(){for(;r<e;)await a,yield{progress:r/e}}();return{[Symbol.asyncIterator](){return A},hasProgress:!0,hasTitle:!1,set:n,tick:u}}static progressViaTitle(){let e,r,o=new Promise(u=>{r=u}),a=(0,Tse.default)(u=>{let A=r;o=new Promise(p=>{r=p}),e=u,A()},1e3/Prt),n=async function*(){for(;;)await o,yield{title:e}}();return{[Symbol.asyncIterator](){return n},hasProgress:!1,hasTitle:!0,setTitle:a}}async startProgressPromise(e,r){let o=this.reportProgress(e);try{return await r(e)}finally{o.stop()}}startProgressSync(e,r){let o=this.reportProgress(e);try{return r(e)}finally{o.stop()}}reportInfoOnce(e,r,o){let a=o&&o.key?o.key:r;this.reportedInfos.has(a)||(this.reportedInfos.add(a),this.reportInfo(e,r),o?.reportExtra?.(this))}reportWarningOnce(e,r,o){let a=o&&o.key?o.key:r;this.reportedWarnings.has(a)||(this.reportedWarnings.add(a),this.reportWarning(e,r),o?.reportExtra?.(this))}reportErrorOnce(e,r,o){let a=o&&o.key?o.key:r;this.reportedErrors.has(a)||(this.reportedErrors.add(a),this.reportError(e,r),o?.reportExtra?.(this))}reportExceptionOnce(e){Srt(e)?this.reportErrorOnce(e.reportCode,e.message,{key:e,reportExtra:e.reportExtra}):this.reportErrorOnce(1,e.stack||e.message,{key:e})}createStreamReporter(e=null){let r=new Rse.PassThrough,o=new Nse.StringDecoder,a="";return r.on("data",n=>{let u=o.write(n),A;do if(A=u.indexOf(` +`),A!==-1){let p=a+u.substring(0,A);u=u.substring(A+1),a="",e!==null?this.reportInfo(null,`${e} ${p}`):this.reportInfo(null,p)}while(A!==-1);a+=u}),r.on("end",()=>{let n=o.end();n!==""&&(e!==null?this.reportInfo(null,`${e} ${n}`):this.reportInfo(null,n))}),r}}});var pE,AO=Et(()=>{Yl();xo();pE=class{constructor(e){this.fetchers=e}supports(e,r){return!!this.tryFetcher(e,r)}getLocalPath(e,r){return this.getFetcher(e,r).getLocalPath(e,r)}async fetch(e,r){return await this.getFetcher(e,r).fetch(e,r)}tryFetcher(e,r){let o=this.fetchers.find(a=>a.supports(e,r));return o||null}getFetcher(e,r){let o=this.fetchers.find(a=>a.supports(e,r));if(!o)throw new zt(11,`${jr(r.project.configuration,e)} isn't supported by any available fetcher`);return o}}});var vd,fO=Et(()=>{xo();vd=class{constructor(e){this.resolvers=e.filter(r=>r)}supportsDescriptor(e,r){return!!this.tryResolverByDescriptor(e,r)}supportsLocator(e,r){return!!this.tryResolverByLocator(e,r)}shouldPersistResolution(e,r){return this.getResolverByLocator(e,r).shouldPersistResolution(e,r)}bindDescriptor(e,r,o){return this.getResolverByDescriptor(e,o).bindDescriptor(e,r,o)}getResolutionDependencies(e,r){return this.getResolverByDescriptor(e,r).getResolutionDependencies(e,r)}async getCandidates(e,r,o){return await this.getResolverByDescriptor(e,o).getCandidates(e,r,o)}async getSatisfying(e,r,o,a){return this.getResolverByDescriptor(e,a).getSatisfying(e,r,o,a)}async resolve(e,r){return await this.getResolverByLocator(e,r).resolve(e,r)}tryResolverByDescriptor(e,r){let o=this.resolvers.find(a=>a.supportsDescriptor(e,r));return o||null}getResolverByDescriptor(e,r){let o=this.resolvers.find(a=>a.supportsDescriptor(e,r));if(!o)throw new Error(`${qn(r.project.configuration,e)} isn't supported by any available resolver`);return o}tryResolverByLocator(e,r){let o=this.resolvers.find(a=>a.supportsLocator(e,r));return o||null}getResolverByLocator(e,r){let o=this.resolvers.find(a=>a.supportsLocator(e,r));if(!o)throw new Error(`${jr(r.project.configuration,e)} isn't supported by any available resolver`);return o}}});var hE,pO=Et(()=>{Pt();xo();hE=class{supports(e){return!!e.reference.startsWith("virtual:")}getLocalPath(e,r){let o=e.reference.indexOf("#");if(o===-1)throw new Error("Invalid virtual package reference");let a=e.reference.slice(o+1),n=Qs(e,a);return r.fetcher.getLocalPath(n,r)}async fetch(e,r){let o=e.reference.indexOf("#");if(o===-1)throw new Error("Invalid virtual package reference");let a=e.reference.slice(o+1),n=Qs(e,a),u=await r.fetcher.fetch(n,r);return await this.ensureVirtualLink(e,u,r)}getLocatorFilename(e){return aE(e)}async ensureVirtualLink(e,r,o){let a=r.packageFs.getRealPath(),n=o.project.configuration.get("virtualFolder"),u=this.getLocatorFilename(e),A=mi.makeVirtualPath(n,u,a),p=new Uu(A,{baseFs:r.packageFs,pathUtils:K});return{...r,packageFs:p}}}});var gE,l1,Lse=Et(()=>{gE=class{static isVirtualDescriptor(e){return!!e.range.startsWith(gE.protocol)}static isVirtualLocator(e){return!!e.reference.startsWith(gE.protocol)}supportsDescriptor(e,r){return gE.isVirtualDescriptor(e)}supportsLocator(e,r){return gE.isVirtualLocator(e)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){throw new Error('Assertion failed: calling "bindDescriptor" on a virtual descriptor is unsupported')}getResolutionDependencies(e,r){throw new Error('Assertion failed: calling "getResolutionDependencies" on a virtual descriptor is unsupported')}async getCandidates(e,r,o){throw new Error('Assertion failed: calling "getCandidates" on a virtual descriptor is unsupported')}async getSatisfying(e,r,o,a){throw new Error('Assertion failed: calling "getSatisfying" on a virtual descriptor is unsupported')}async resolve(e,r){throw new Error('Assertion failed: calling "resolve" on a virtual locator is unsupported')}},l1=gE;l1.protocol="virtual:"});var dE,hO=Et(()=>{Pt();Bd();dE=class{supports(e){return!!e.reference.startsWith(Xn.protocol)}getLocalPath(e,r){return this.getWorkspace(e,r).cwd}async fetch(e,r){let o=this.getWorkspace(e,r).cwd;return{packageFs:new gn(o),prefixPath:Bt.dot,localPath:o}}getWorkspace(e,r){return r.project.getWorkspaceByCwd(e.reference.slice(Xn.protocol.length))}}});function c1(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Mse(t){return typeof t>"u"?3:c1(t)?0:Array.isArray(t)?1:2}function mO(t,e){return Object.hasOwn(t,e)}function brt(t){return c1(t)&&mO(t,"onConflict")&&typeof t.onConflict=="string"}function krt(t){if(typeof t>"u")return{onConflict:"default",value:t};if(!brt(t))return{onConflict:"default",value:t};if(mO(t,"value"))return t;let{onConflict:e,...r}=t;return{onConflict:e,value:r}}function Ose(t,e){let r=c1(t)&&mO(t,e)?t[e]:void 0;return krt(r)}function mE(t,e){return[t,e,Use]}function yO(t){return Array.isArray(t)?t[2]===Use:!1}function gO(t,e){if(c1(t)){let r={};for(let o of Object.keys(t))r[o]=gO(t[o],e);return mE(e,r)}return Array.isArray(t)?mE(e,t.map(r=>gO(r,e))):mE(e,t)}function dO(t,e,r,o,a){let n,u=[],A=a,p=0;for(let E=a-1;E>=o;--E){let[I,v]=t[E],{onConflict:b,value:C}=Ose(v,r),T=Mse(C);if(T!==3){if(n??=T,T!==n||b==="hardReset"){p=A;break}if(T===2)return mE(I,C);if(u.unshift([I,C]),b==="reset"){p=E;break}b==="extend"&&E===o&&(o=0),A=E}}if(typeof n>"u")return null;let h=u.map(([E])=>E).join(", ");switch(n){case 1:return mE(h,new Array().concat(...u.map(([E,I])=>I.map(v=>gO(v,E)))));case 0:{let E=Object.assign({},...u.map(([,T])=>T)),I=Object.keys(E),v={},b=t.map(([T,L])=>[T,Ose(L,r).value]),C=xrt(b,([T,L])=>{let U=Mse(L);return U!==0&&U!==3});if(C!==-1){let T=b.slice(C+1);for(let L of I)v[L]=dO(T,e,L,0,T.length)}else for(let T of I)v[T]=dO(b,e,T,p,b.length);return mE(h,v)}default:throw new Error("Assertion failed: Non-extendable value type")}}function _se(t){return dO(t.map(([e,r])=>[e,{["."]:r}]),[],".",0,t.length)}function u1(t){return yO(t)?t[1]:t}function YS(t){let e=yO(t)?t[1]:t;if(Array.isArray(e))return e.map(r=>YS(r));if(c1(e)){let r={};for(let[o,a]of Object.entries(e))r[o]=YS(a);return r}return e}function EO(t){return yO(t)?t[0]:null}var xrt,Use,Hse=Et(()=>{xrt=(t,e,r)=>{let o=[...t];return o.reverse(),o.findIndex(e,r)};Use=Symbol()});var WS={};Kt(WS,{getDefaultGlobalFolder:()=>wO,getHomeFolder:()=>yE,isFolderInside:()=>IO});function wO(){if(process.platform==="win32"){let t=ue.toPortablePath(process.env.LOCALAPPDATA||ue.join((0,CO.homedir)(),"AppData","Local"));return K.resolve(t,"Yarn/Berry")}if(process.env.XDG_DATA_HOME){let t=ue.toPortablePath(process.env.XDG_DATA_HOME);return K.resolve(t,"yarn/berry")}return K.resolve(yE(),".yarn/berry")}function yE(){return ue.toPortablePath((0,CO.homedir)()||"/usr/local/share")}function IO(t,e){let r=K.relative(e,t);return r&&!r.startsWith("..")&&!K.isAbsolute(r)}var CO,VS=Et(()=>{Pt();CO=Be("os")});var Yse=_(EE=>{"use strict";var sLt=Be("net"),Frt=Be("tls"),BO=Be("http"),jse=Be("https"),Trt=Be("events"),oLt=Be("assert"),Rrt=Be("util");EE.httpOverHttp=Nrt;EE.httpsOverHttp=Lrt;EE.httpOverHttps=Mrt;EE.httpsOverHttps=Ort;function Nrt(t){var e=new Qf(t);return e.request=BO.request,e}function Lrt(t){var e=new Qf(t);return e.request=BO.request,e.createSocket=qse,e.defaultPort=443,e}function Mrt(t){var e=new Qf(t);return e.request=jse.request,e}function Ort(t){var e=new Qf(t);return e.request=jse.request,e.createSocket=qse,e.defaultPort=443,e}function Qf(t){var e=this;e.options=t||{},e.proxyOptions=e.options.proxy||{},e.maxSockets=e.options.maxSockets||BO.Agent.defaultMaxSockets,e.requests=[],e.sockets=[],e.on("free",function(o,a,n,u){for(var A=Gse(a,n,u),p=0,h=e.requests.length;p<h;++p){var E=e.requests[p];if(E.host===A.host&&E.port===A.port){e.requests.splice(p,1),E.request.onSocket(o);return}}o.destroy(),e.removeSocket(o)})}Rrt.inherits(Qf,Trt.EventEmitter);Qf.prototype.addRequest=function(e,r,o,a){var n=this,u=vO({request:e},n.options,Gse(r,o,a));if(n.sockets.length>=this.maxSockets){n.requests.push(u);return}n.createSocket(u,function(A){A.on("free",p),A.on("close",h),A.on("agentRemove",h),e.onSocket(A);function p(){n.emit("free",A,u)}function h(E){n.removeSocket(A),A.removeListener("free",p),A.removeListener("close",h),A.removeListener("agentRemove",h)}})};Qf.prototype.createSocket=function(e,r){var o=this,a={};o.sockets.push(a);var n=vO({},o.proxyOptions,{method:"CONNECT",path:e.host+":"+e.port,agent:!1,headers:{host:e.host+":"+e.port}});e.localAddress&&(n.localAddress=e.localAddress),n.proxyAuth&&(n.headers=n.headers||{},n.headers["Proxy-Authorization"]="Basic "+new Buffer(n.proxyAuth).toString("base64")),sh("making CONNECT request");var u=o.request(n);u.useChunkedEncodingByDefault=!1,u.once("response",A),u.once("upgrade",p),u.once("connect",h),u.once("error",E),u.end();function A(I){I.upgrade=!0}function p(I,v,b){process.nextTick(function(){h(I,v,b)})}function h(I,v,b){if(u.removeAllListeners(),v.removeAllListeners(),I.statusCode!==200){sh("tunneling socket could not be established, statusCode=%d",I.statusCode),v.destroy();var C=new Error("tunneling socket could not be established, statusCode="+I.statusCode);C.code="ECONNRESET",e.request.emit("error",C),o.removeSocket(a);return}if(b.length>0){sh("got illegal response body from proxy"),v.destroy();var C=new Error("got illegal response body from proxy");C.code="ECONNRESET",e.request.emit("error",C),o.removeSocket(a);return}return sh("tunneling connection has established"),o.sockets[o.sockets.indexOf(a)]=v,r(v)}function E(I){u.removeAllListeners(),sh(`tunneling socket could not be established, cause=%s +`,I.message,I.stack);var v=new Error("tunneling socket could not be established, cause="+I.message);v.code="ECONNRESET",e.request.emit("error",v),o.removeSocket(a)}};Qf.prototype.removeSocket=function(e){var r=this.sockets.indexOf(e);if(r!==-1){this.sockets.splice(r,1);var o=this.requests.shift();o&&this.createSocket(o,function(a){o.request.onSocket(a)})}};function qse(t,e){var r=this;Qf.prototype.createSocket.call(r,t,function(o){var a=t.request.getHeader("host"),n=vO({},r.options,{socket:o,servername:a?a.replace(/:.*$/,""):t.host}),u=Frt.connect(0,n);r.sockets[r.sockets.indexOf(o)]=u,e(u)})}function Gse(t,e,r){return typeof t=="string"?{host:t,port:e,localAddress:r}:t}function vO(t){for(var e=1,r=arguments.length;e<r;++e){var o=arguments[e];if(typeof o=="object")for(var a=Object.keys(o),n=0,u=a.length;n<u;++n){var A=a[n];o[A]!==void 0&&(t[A]=o[A])}}return t}var sh;process.env.NODE_DEBUG&&/\btunnel\b/.test(process.env.NODE_DEBUG)?sh=function(){var t=Array.prototype.slice.call(arguments);typeof t[0]=="string"?t[0]="TUNNEL: "+t[0]:t.unshift("TUNNEL:"),console.error.apply(console,t)}:sh=function(){};EE.debug=sh});var Vse=_((lLt,Wse)=>{Wse.exports=Yse()});var Tf=_((Ff,KS)=>{"use strict";Object.defineProperty(Ff,"__esModule",{value:!0});var Kse=["Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array"];function Urt(t){return Kse.includes(t)}var _rt=["Function","Generator","AsyncGenerator","GeneratorFunction","AsyncGeneratorFunction","AsyncFunction","Observable","Array","Buffer","Object","RegExp","Date","Error","Map","Set","WeakMap","WeakSet","ArrayBuffer","SharedArrayBuffer","DataView","Promise","URL","FormData","URLSearchParams","HTMLElement",...Kse];function Hrt(t){return _rt.includes(t)}var jrt=["null","undefined","string","number","bigint","boolean","symbol"];function qrt(t){return jrt.includes(t)}function CE(t){return e=>typeof e===t}var{toString:Jse}=Object.prototype,A1=t=>{let e=Jse.call(t).slice(8,-1);if(/HTML\w+Element/.test(e)&&xe.domElement(t))return"HTMLElement";if(Hrt(e))return e},ei=t=>e=>A1(e)===t;function xe(t){if(t===null)return"null";switch(typeof t){case"undefined":return"undefined";case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"function":return"Function";case"bigint":return"bigint";case"symbol":return"symbol";default:}if(xe.observable(t))return"Observable";if(xe.array(t))return"Array";if(xe.buffer(t))return"Buffer";let e=A1(t);if(e)return e;if(t instanceof String||t instanceof Boolean||t instanceof Number)throw new TypeError("Please don't use object wrappers for primitive types");return"Object"}xe.undefined=CE("undefined");xe.string=CE("string");var Grt=CE("number");xe.number=t=>Grt(t)&&!xe.nan(t);xe.bigint=CE("bigint");xe.function_=CE("function");xe.null_=t=>t===null;xe.class_=t=>xe.function_(t)&&t.toString().startsWith("class ");xe.boolean=t=>t===!0||t===!1;xe.symbol=CE("symbol");xe.numericString=t=>xe.string(t)&&!xe.emptyStringOrWhitespace(t)&&!Number.isNaN(Number(t));xe.array=(t,e)=>Array.isArray(t)?xe.function_(e)?t.every(e):!0:!1;xe.buffer=t=>{var e,r,o,a;return(a=(o=(r=(e=t)===null||e===void 0?void 0:e.constructor)===null||r===void 0?void 0:r.isBuffer)===null||o===void 0?void 0:o.call(r,t))!==null&&a!==void 0?a:!1};xe.nullOrUndefined=t=>xe.null_(t)||xe.undefined(t);xe.object=t=>!xe.null_(t)&&(typeof t=="object"||xe.function_(t));xe.iterable=t=>{var e;return xe.function_((e=t)===null||e===void 0?void 0:e[Symbol.iterator])};xe.asyncIterable=t=>{var e;return xe.function_((e=t)===null||e===void 0?void 0:e[Symbol.asyncIterator])};xe.generator=t=>xe.iterable(t)&&xe.function_(t.next)&&xe.function_(t.throw);xe.asyncGenerator=t=>xe.asyncIterable(t)&&xe.function_(t.next)&&xe.function_(t.throw);xe.nativePromise=t=>ei("Promise")(t);var Yrt=t=>{var e,r;return xe.function_((e=t)===null||e===void 0?void 0:e.then)&&xe.function_((r=t)===null||r===void 0?void 0:r.catch)};xe.promise=t=>xe.nativePromise(t)||Yrt(t);xe.generatorFunction=ei("GeneratorFunction");xe.asyncGeneratorFunction=t=>A1(t)==="AsyncGeneratorFunction";xe.asyncFunction=t=>A1(t)==="AsyncFunction";xe.boundFunction=t=>xe.function_(t)&&!t.hasOwnProperty("prototype");xe.regExp=ei("RegExp");xe.date=ei("Date");xe.error=ei("Error");xe.map=t=>ei("Map")(t);xe.set=t=>ei("Set")(t);xe.weakMap=t=>ei("WeakMap")(t);xe.weakSet=t=>ei("WeakSet")(t);xe.int8Array=ei("Int8Array");xe.uint8Array=ei("Uint8Array");xe.uint8ClampedArray=ei("Uint8ClampedArray");xe.int16Array=ei("Int16Array");xe.uint16Array=ei("Uint16Array");xe.int32Array=ei("Int32Array");xe.uint32Array=ei("Uint32Array");xe.float32Array=ei("Float32Array");xe.float64Array=ei("Float64Array");xe.bigInt64Array=ei("BigInt64Array");xe.bigUint64Array=ei("BigUint64Array");xe.arrayBuffer=ei("ArrayBuffer");xe.sharedArrayBuffer=ei("SharedArrayBuffer");xe.dataView=ei("DataView");xe.directInstanceOf=(t,e)=>Object.getPrototypeOf(t)===e.prototype;xe.urlInstance=t=>ei("URL")(t);xe.urlString=t=>{if(!xe.string(t))return!1;try{return new URL(t),!0}catch{return!1}};xe.truthy=t=>Boolean(t);xe.falsy=t=>!t;xe.nan=t=>Number.isNaN(t);xe.primitive=t=>xe.null_(t)||qrt(typeof t);xe.integer=t=>Number.isInteger(t);xe.safeInteger=t=>Number.isSafeInteger(t);xe.plainObject=t=>{if(Jse.call(t)!=="[object Object]")return!1;let e=Object.getPrototypeOf(t);return e===null||e===Object.getPrototypeOf({})};xe.typedArray=t=>Urt(A1(t));var Wrt=t=>xe.safeInteger(t)&&t>=0;xe.arrayLike=t=>!xe.nullOrUndefined(t)&&!xe.function_(t)&&Wrt(t.length);xe.inRange=(t,e)=>{if(xe.number(e))return t>=Math.min(0,e)&&t<=Math.max(e,0);if(xe.array(e)&&e.length===2)return t>=Math.min(...e)&&t<=Math.max(...e);throw new TypeError(`Invalid range: ${JSON.stringify(e)}`)};var Vrt=1,Krt=["innerHTML","ownerDocument","style","attributes","nodeValue"];xe.domElement=t=>xe.object(t)&&t.nodeType===Vrt&&xe.string(t.nodeName)&&!xe.plainObject(t)&&Krt.every(e=>e in t);xe.observable=t=>{var e,r,o,a;return t?t===((r=(e=t)[Symbol.observable])===null||r===void 0?void 0:r.call(e))||t===((a=(o=t)["@@observable"])===null||a===void 0?void 0:a.call(o)):!1};xe.nodeStream=t=>xe.object(t)&&xe.function_(t.pipe)&&!xe.observable(t);xe.infinite=t=>t===1/0||t===-1/0;var zse=t=>e=>xe.integer(e)&&Math.abs(e%2)===t;xe.evenInteger=zse(0);xe.oddInteger=zse(1);xe.emptyArray=t=>xe.array(t)&&t.length===0;xe.nonEmptyArray=t=>xe.array(t)&&t.length>0;xe.emptyString=t=>xe.string(t)&&t.length===0;xe.nonEmptyString=t=>xe.string(t)&&t.length>0;var Jrt=t=>xe.string(t)&&!/\S/.test(t);xe.emptyStringOrWhitespace=t=>xe.emptyString(t)||Jrt(t);xe.emptyObject=t=>xe.object(t)&&!xe.map(t)&&!xe.set(t)&&Object.keys(t).length===0;xe.nonEmptyObject=t=>xe.object(t)&&!xe.map(t)&&!xe.set(t)&&Object.keys(t).length>0;xe.emptySet=t=>xe.set(t)&&t.size===0;xe.nonEmptySet=t=>xe.set(t)&&t.size>0;xe.emptyMap=t=>xe.map(t)&&t.size===0;xe.nonEmptyMap=t=>xe.map(t)&&t.size>0;xe.propertyKey=t=>xe.any([xe.string,xe.number,xe.symbol],t);xe.formData=t=>ei("FormData")(t);xe.urlSearchParams=t=>ei("URLSearchParams")(t);var Xse=(t,e,r)=>{if(!xe.function_(e))throw new TypeError(`Invalid predicate: ${JSON.stringify(e)}`);if(r.length===0)throw new TypeError("Invalid number of values");return t.call(r,e)};xe.any=(t,...e)=>(xe.array(t)?t:[t]).some(o=>Xse(Array.prototype.some,o,e));xe.all=(t,...e)=>Xse(Array.prototype.every,t,e);var Ht=(t,e,r,o={})=>{if(!t){let{multipleValues:a}=o,n=a?`received values of types ${[...new Set(r.map(u=>`\`${xe(u)}\``))].join(", ")}`:`received value of type \`${xe(r)}\``;throw new TypeError(`Expected value which is \`${e}\`, ${n}.`)}};Ff.assert={undefined:t=>Ht(xe.undefined(t),"undefined",t),string:t=>Ht(xe.string(t),"string",t),number:t=>Ht(xe.number(t),"number",t),bigint:t=>Ht(xe.bigint(t),"bigint",t),function_:t=>Ht(xe.function_(t),"Function",t),null_:t=>Ht(xe.null_(t),"null",t),class_:t=>Ht(xe.class_(t),"Class",t),boolean:t=>Ht(xe.boolean(t),"boolean",t),symbol:t=>Ht(xe.symbol(t),"symbol",t),numericString:t=>Ht(xe.numericString(t),"string with a number",t),array:(t,e)=>{Ht(xe.array(t),"Array",t),e&&t.forEach(e)},buffer:t=>Ht(xe.buffer(t),"Buffer",t),nullOrUndefined:t=>Ht(xe.nullOrUndefined(t),"null or undefined",t),object:t=>Ht(xe.object(t),"Object",t),iterable:t=>Ht(xe.iterable(t),"Iterable",t),asyncIterable:t=>Ht(xe.asyncIterable(t),"AsyncIterable",t),generator:t=>Ht(xe.generator(t),"Generator",t),asyncGenerator:t=>Ht(xe.asyncGenerator(t),"AsyncGenerator",t),nativePromise:t=>Ht(xe.nativePromise(t),"native Promise",t),promise:t=>Ht(xe.promise(t),"Promise",t),generatorFunction:t=>Ht(xe.generatorFunction(t),"GeneratorFunction",t),asyncGeneratorFunction:t=>Ht(xe.asyncGeneratorFunction(t),"AsyncGeneratorFunction",t),asyncFunction:t=>Ht(xe.asyncFunction(t),"AsyncFunction",t),boundFunction:t=>Ht(xe.boundFunction(t),"Function",t),regExp:t=>Ht(xe.regExp(t),"RegExp",t),date:t=>Ht(xe.date(t),"Date",t),error:t=>Ht(xe.error(t),"Error",t),map:t=>Ht(xe.map(t),"Map",t),set:t=>Ht(xe.set(t),"Set",t),weakMap:t=>Ht(xe.weakMap(t),"WeakMap",t),weakSet:t=>Ht(xe.weakSet(t),"WeakSet",t),int8Array:t=>Ht(xe.int8Array(t),"Int8Array",t),uint8Array:t=>Ht(xe.uint8Array(t),"Uint8Array",t),uint8ClampedArray:t=>Ht(xe.uint8ClampedArray(t),"Uint8ClampedArray",t),int16Array:t=>Ht(xe.int16Array(t),"Int16Array",t),uint16Array:t=>Ht(xe.uint16Array(t),"Uint16Array",t),int32Array:t=>Ht(xe.int32Array(t),"Int32Array",t),uint32Array:t=>Ht(xe.uint32Array(t),"Uint32Array",t),float32Array:t=>Ht(xe.float32Array(t),"Float32Array",t),float64Array:t=>Ht(xe.float64Array(t),"Float64Array",t),bigInt64Array:t=>Ht(xe.bigInt64Array(t),"BigInt64Array",t),bigUint64Array:t=>Ht(xe.bigUint64Array(t),"BigUint64Array",t),arrayBuffer:t=>Ht(xe.arrayBuffer(t),"ArrayBuffer",t),sharedArrayBuffer:t=>Ht(xe.sharedArrayBuffer(t),"SharedArrayBuffer",t),dataView:t=>Ht(xe.dataView(t),"DataView",t),urlInstance:t=>Ht(xe.urlInstance(t),"URL",t),urlString:t=>Ht(xe.urlString(t),"string with a URL",t),truthy:t=>Ht(xe.truthy(t),"truthy",t),falsy:t=>Ht(xe.falsy(t),"falsy",t),nan:t=>Ht(xe.nan(t),"NaN",t),primitive:t=>Ht(xe.primitive(t),"primitive",t),integer:t=>Ht(xe.integer(t),"integer",t),safeInteger:t=>Ht(xe.safeInteger(t),"integer",t),plainObject:t=>Ht(xe.plainObject(t),"plain object",t),typedArray:t=>Ht(xe.typedArray(t),"TypedArray",t),arrayLike:t=>Ht(xe.arrayLike(t),"array-like",t),domElement:t=>Ht(xe.domElement(t),"HTMLElement",t),observable:t=>Ht(xe.observable(t),"Observable",t),nodeStream:t=>Ht(xe.nodeStream(t),"Node.js Stream",t),infinite:t=>Ht(xe.infinite(t),"infinite number",t),emptyArray:t=>Ht(xe.emptyArray(t),"empty array",t),nonEmptyArray:t=>Ht(xe.nonEmptyArray(t),"non-empty array",t),emptyString:t=>Ht(xe.emptyString(t),"empty string",t),nonEmptyString:t=>Ht(xe.nonEmptyString(t),"non-empty string",t),emptyStringOrWhitespace:t=>Ht(xe.emptyStringOrWhitespace(t),"empty string or whitespace",t),emptyObject:t=>Ht(xe.emptyObject(t),"empty object",t),nonEmptyObject:t=>Ht(xe.nonEmptyObject(t),"non-empty object",t),emptySet:t=>Ht(xe.emptySet(t),"empty set",t),nonEmptySet:t=>Ht(xe.nonEmptySet(t),"non-empty set",t),emptyMap:t=>Ht(xe.emptyMap(t),"empty map",t),nonEmptyMap:t=>Ht(xe.nonEmptyMap(t),"non-empty map",t),propertyKey:t=>Ht(xe.propertyKey(t),"PropertyKey",t),formData:t=>Ht(xe.formData(t),"FormData",t),urlSearchParams:t=>Ht(xe.urlSearchParams(t),"URLSearchParams",t),evenInteger:t=>Ht(xe.evenInteger(t),"even integer",t),oddInteger:t=>Ht(xe.oddInteger(t),"odd integer",t),directInstanceOf:(t,e)=>Ht(xe.directInstanceOf(t,e),"T",t),inRange:(t,e)=>Ht(xe.inRange(t,e),"in range",t),any:(t,...e)=>Ht(xe.any(t,...e),"predicate returns truthy for any value",e,{multipleValues:!0}),all:(t,...e)=>Ht(xe.all(t,...e),"predicate returns truthy for all values",e,{multipleValues:!0})};Object.defineProperties(xe,{class:{value:xe.class_},function:{value:xe.function_},null:{value:xe.null_}});Object.defineProperties(Ff.assert,{class:{value:Ff.assert.class_},function:{value:Ff.assert.function_},null:{value:Ff.assert.null_}});Ff.default=xe;KS.exports=xe;KS.exports.default=xe;KS.exports.assert=Ff.assert});var Zse=_((cLt,DO)=>{"use strict";var JS=class extends Error{constructor(e){super(e||"Promise was canceled"),this.name="CancelError"}get isCanceled(){return!0}},wE=class{static fn(e){return(...r)=>new wE((o,a,n)=>{r.push(n),e(...r).then(o,a)})}constructor(e){this._cancelHandlers=[],this._isPending=!0,this._isCanceled=!1,this._rejectOnCancel=!0,this._promise=new Promise((r,o)=>{this._reject=o;let a=A=>{this._isPending=!1,r(A)},n=A=>{this._isPending=!1,o(A)},u=A=>{if(!this._isPending)throw new Error("The `onCancel` handler was attached after the promise settled.");this._cancelHandlers.push(A)};return Object.defineProperties(u,{shouldReject:{get:()=>this._rejectOnCancel,set:A=>{this._rejectOnCancel=A}}}),e(a,n,u)})}then(e,r){return this._promise.then(e,r)}catch(e){return this._promise.catch(e)}finally(e){return this._promise.finally(e)}cancel(e){if(!(!this._isPending||this._isCanceled)){if(this._cancelHandlers.length>0)try{for(let r of this._cancelHandlers)r()}catch(r){this._reject(r)}this._isCanceled=!0,this._rejectOnCancel&&this._reject(new JS(e))}}get isCanceled(){return this._isCanceled}};Object.setPrototypeOf(wE.prototype,Promise.prototype);DO.exports=wE;DO.exports.CancelError=JS});var $se=_((SO,xO)=>{"use strict";Object.defineProperty(SO,"__esModule",{value:!0});var zrt=Be("tls"),PO=(t,e)=>{let r;typeof e=="function"?r={connect:e}:r=e;let o=typeof r.connect=="function",a=typeof r.secureConnect=="function",n=typeof r.close=="function",u=()=>{o&&r.connect(),t instanceof zrt.TLSSocket&&a&&(t.authorized?r.secureConnect():t.authorizationError||t.once("secureConnect",r.secureConnect)),n&&t.once("close",r.close)};t.writable&&!t.connecting?u():t.connecting?t.once("connect",u):t.destroyed&&n&&r.close(t._hadError)};SO.default=PO;xO.exports=PO;xO.exports.default=PO});var eoe=_((kO,QO)=>{"use strict";Object.defineProperty(kO,"__esModule",{value:!0});var Xrt=$se(),Zrt=Number(process.versions.node.split(".")[0]),bO=t=>{let e={start:Date.now(),socket:void 0,lookup:void 0,connect:void 0,secureConnect:void 0,upload:void 0,response:void 0,end:void 0,error:void 0,abort:void 0,phases:{wait:void 0,dns:void 0,tcp:void 0,tls:void 0,request:void 0,firstByte:void 0,download:void 0,total:void 0}};t.timings=e;let r=u=>{let A=u.emit.bind(u);u.emit=(p,...h)=>(p==="error"&&(e.error=Date.now(),e.phases.total=e.error-e.start,u.emit=A),A(p,...h))};r(t),t.prependOnceListener("abort",()=>{e.abort=Date.now(),(!e.response||Zrt>=13)&&(e.phases.total=Date.now()-e.start)});let o=u=>{e.socket=Date.now(),e.phases.wait=e.socket-e.start;let A=()=>{e.lookup=Date.now(),e.phases.dns=e.lookup-e.socket};u.prependOnceListener("lookup",A),Xrt.default(u,{connect:()=>{e.connect=Date.now(),e.lookup===void 0&&(u.removeListener("lookup",A),e.lookup=e.connect,e.phases.dns=e.lookup-e.socket),e.phases.tcp=e.connect-e.lookup},secureConnect:()=>{e.secureConnect=Date.now(),e.phases.tls=e.secureConnect-e.connect}})};t.socket?o(t.socket):t.prependOnceListener("socket",o);let a=()=>{var u;e.upload=Date.now(),e.phases.request=e.upload-(u=e.secureConnect,u??e.connect)};return(()=>typeof t.writableFinished=="boolean"?t.writableFinished:t.finished&&t.outputSize===0&&(!t.socket||t.socket.writableLength===0))()?a():t.prependOnceListener("finish",a),t.prependOnceListener("response",u=>{e.response=Date.now(),e.phases.firstByte=e.response-e.upload,u.timings=e,r(u),u.prependOnceListener("end",()=>{e.end=Date.now(),e.phases.download=e.end-e.response,e.phases.total=e.end-e.start})}),e};kO.default=bO;QO.exports=bO;QO.exports.default=bO});var aoe=_((uLt,RO)=>{"use strict";var{V4MAPPED:$rt,ADDRCONFIG:ent,ALL:ooe,promises:{Resolver:toe},lookup:tnt}=Be("dns"),{promisify:FO}=Be("util"),rnt=Be("os"),IE=Symbol("cacheableLookupCreateConnection"),TO=Symbol("cacheableLookupInstance"),roe=Symbol("expires"),nnt=typeof ooe=="number",noe=t=>{if(!(t&&typeof t.createConnection=="function"))throw new Error("Expected an Agent instance as the first argument")},int=t=>{for(let e of t)e.family!==6&&(e.address=`::ffff:${e.address}`,e.family=6)},ioe=()=>{let t=!1,e=!1;for(let r of Object.values(rnt.networkInterfaces()))for(let o of r)if(!o.internal&&(o.family==="IPv6"?e=!0:t=!0,t&&e))return{has4:t,has6:e};return{has4:t,has6:e}},snt=t=>Symbol.iterator in t,soe={ttl:!0},ont={all:!0},zS=class{constructor({cache:e=new Map,maxTtl:r=1/0,fallbackDuration:o=3600,errorTtl:a=.15,resolver:n=new toe,lookup:u=tnt}={}){if(this.maxTtl=r,this.errorTtl=a,this._cache=e,this._resolver=n,this._dnsLookup=FO(u),this._resolver instanceof toe?(this._resolve4=this._resolver.resolve4.bind(this._resolver),this._resolve6=this._resolver.resolve6.bind(this._resolver)):(this._resolve4=FO(this._resolver.resolve4.bind(this._resolver)),this._resolve6=FO(this._resolver.resolve6.bind(this._resolver))),this._iface=ioe(),this._pending={},this._nextRemovalTime=!1,this._hostnamesToFallback=new Set,o<1)this._fallback=!1;else{this._fallback=!0;let A=setInterval(()=>{this._hostnamesToFallback.clear()},o*1e3);A.unref&&A.unref()}this.lookup=this.lookup.bind(this),this.lookupAsync=this.lookupAsync.bind(this)}set servers(e){this.clear(),this._resolver.setServers(e)}get servers(){return this._resolver.getServers()}lookup(e,r,o){if(typeof r=="function"?(o=r,r={}):typeof r=="number"&&(r={family:r}),!o)throw new Error("Callback must be a function.");this.lookupAsync(e,r).then(a=>{r.all?o(null,a):o(null,a.address,a.family,a.expires,a.ttl)},o)}async lookupAsync(e,r={}){typeof r=="number"&&(r={family:r});let o=await this.query(e);if(r.family===6){let a=o.filter(n=>n.family===6);r.hints&$rt&&(nnt&&r.hints&ooe||a.length===0)?int(o):o=a}else r.family===4&&(o=o.filter(a=>a.family===4));if(r.hints&ent){let{_iface:a}=this;o=o.filter(n=>n.family===6?a.has6:a.has4)}if(o.length===0){let a=new Error(`cacheableLookup ENOTFOUND ${e}`);throw a.code="ENOTFOUND",a.hostname=e,a}return r.all?o:o[0]}async query(e){let r=await this._cache.get(e);if(!r){let o=this._pending[e];if(o)r=await o;else{let a=this.queryAndCache(e);this._pending[e]=a,r=await a}}return r=r.map(o=>({...o})),r}async _resolve(e){let r=async h=>{try{return await h}catch(E){if(E.code==="ENODATA"||E.code==="ENOTFOUND")return[];throw E}},[o,a]=await Promise.all([this._resolve4(e,soe),this._resolve6(e,soe)].map(h=>r(h))),n=0,u=0,A=0,p=Date.now();for(let h of o)h.family=4,h.expires=p+h.ttl*1e3,n=Math.max(n,h.ttl);for(let h of a)h.family=6,h.expires=p+h.ttl*1e3,u=Math.max(u,h.ttl);return o.length>0?a.length>0?A=Math.min(n,u):A=n:A=u,{entries:[...o,...a],cacheTtl:A}}async _lookup(e){try{return{entries:await this._dnsLookup(e,{all:!0}),cacheTtl:0}}catch{return{entries:[],cacheTtl:0}}}async _set(e,r,o){if(this.maxTtl>0&&o>0){o=Math.min(o,this.maxTtl)*1e3,r[roe]=Date.now()+o;try{await this._cache.set(e,r,o)}catch(a){this.lookupAsync=async()=>{let n=new Error("Cache Error. Please recreate the CacheableLookup instance.");throw n.cause=a,n}}snt(this._cache)&&this._tick(o)}}async queryAndCache(e){if(this._hostnamesToFallback.has(e))return this._dnsLookup(e,ont);try{let r=await this._resolve(e);r.entries.length===0&&this._fallback&&(r=await this._lookup(e),r.entries.length!==0&&this._hostnamesToFallback.add(e));let o=r.entries.length===0?this.errorTtl:r.cacheTtl;return await this._set(e,r.entries,o),delete this._pending[e],r.entries}catch(r){throw delete this._pending[e],r}}_tick(e){let r=this._nextRemovalTime;(!r||e<r)&&(clearTimeout(this._removalTimeout),this._nextRemovalTime=e,this._removalTimeout=setTimeout(()=>{this._nextRemovalTime=!1;let o=1/0,a=Date.now();for(let[n,u]of this._cache){let A=u[roe];a>=A?this._cache.delete(n):A<o&&(o=A)}o!==1/0&&this._tick(o-a)},e),this._removalTimeout.unref&&this._removalTimeout.unref())}install(e){if(noe(e),IE in e)throw new Error("CacheableLookup has been already installed");e[IE]=e.createConnection,e[TO]=this,e.createConnection=(r,o)=>("lookup"in r||(r.lookup=this.lookup),e[IE](r,o))}uninstall(e){if(noe(e),e[IE]){if(e[TO]!==this)throw new Error("The agent is not owned by this CacheableLookup instance");e.createConnection=e[IE],delete e[IE],delete e[TO]}}updateInterfaceInfo(){let{_iface:e}=this;this._iface=ioe(),(e.has4&&!this._iface.has4||e.has6&&!this._iface.has6)&&this._cache.clear()}clear(e){if(e){this._cache.delete(e);return}this._cache.clear()}};RO.exports=zS;RO.exports.default=zS});var uoe=_((ALt,NO)=>{"use strict";var ant=typeof URL>"u"?Be("url").URL:URL,lnt="text/plain",cnt="us-ascii",loe=(t,e)=>e.some(r=>r instanceof RegExp?r.test(t):r===t),unt=(t,{stripHash:e})=>{let r=t.match(/^data:([^,]*?),([^#]*?)(?:#(.*))?$/);if(!r)throw new Error(`Invalid URL: ${t}`);let o=r[1].split(";"),a=r[2],n=e?"":r[3],u=!1;o[o.length-1]==="base64"&&(o.pop(),u=!0);let A=(o.shift()||"").toLowerCase(),h=[...o.map(E=>{let[I,v=""]=E.split("=").map(b=>b.trim());return I==="charset"&&(v=v.toLowerCase(),v===cnt)?"":`${I}${v?`=${v}`:""}`}).filter(Boolean)];return u&&h.push("base64"),(h.length!==0||A&&A!==lnt)&&h.unshift(A),`data:${h.join(";")},${u?a.trim():a}${n?`#${n}`:""}`},coe=(t,e)=>{if(e={defaultProtocol:"http:",normalizeProtocol:!0,forceHttp:!1,forceHttps:!1,stripAuthentication:!0,stripHash:!1,stripWWW:!0,removeQueryParameters:[/^utm_\w+/i],removeTrailingSlash:!0,removeDirectoryIndex:!1,sortQueryParameters:!0,...e},Reflect.has(e,"normalizeHttps"))throw new Error("options.normalizeHttps is renamed to options.forceHttp");if(Reflect.has(e,"normalizeHttp"))throw new Error("options.normalizeHttp is renamed to options.forceHttps");if(Reflect.has(e,"stripFragment"))throw new Error("options.stripFragment is renamed to options.stripHash");if(t=t.trim(),/^data:/i.test(t))return unt(t,e);let r=t.startsWith("//");!r&&/^\.*\//.test(t)||(t=t.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,e.defaultProtocol));let a=new ant(t);if(e.forceHttp&&e.forceHttps)throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");if(e.forceHttp&&a.protocol==="https:"&&(a.protocol="http:"),e.forceHttps&&a.protocol==="http:"&&(a.protocol="https:"),e.stripAuthentication&&(a.username="",a.password=""),e.stripHash&&(a.hash=""),a.pathname&&(a.pathname=a.pathname.replace(/((?!:).|^)\/{2,}/g,(n,u)=>/^(?!\/)/g.test(u)?`${u}/`:"/")),a.pathname&&(a.pathname=decodeURI(a.pathname)),e.removeDirectoryIndex===!0&&(e.removeDirectoryIndex=[/^index\.[a-z]+$/]),Array.isArray(e.removeDirectoryIndex)&&e.removeDirectoryIndex.length>0){let n=a.pathname.split("/"),u=n[n.length-1];loe(u,e.removeDirectoryIndex)&&(n=n.slice(0,n.length-1),a.pathname=n.slice(1).join("/")+"/")}if(a.hostname&&(a.hostname=a.hostname.replace(/\.$/,""),e.stripWWW&&/^www\.([a-z\-\d]{2,63})\.([a-z.]{2,5})$/.test(a.hostname)&&(a.hostname=a.hostname.replace(/^www\./,""))),Array.isArray(e.removeQueryParameters))for(let n of[...a.searchParams.keys()])loe(n,e.removeQueryParameters)&&a.searchParams.delete(n);return e.sortQueryParameters&&a.searchParams.sort(),e.removeTrailingSlash&&(a.pathname=a.pathname.replace(/\/$/,"")),t=a.toString(),(e.removeTrailingSlash||a.pathname==="/")&&a.hash===""&&(t=t.replace(/\/$/,"")),r&&!e.normalizeProtocol&&(t=t.replace(/^http:\/\//,"//")),e.stripProtocol&&(t=t.replace(/^(?:https?:)?\/\//,"")),t};NO.exports=coe;NO.exports.default=coe});var poe=_((fLt,foe)=>{foe.exports=Aoe;function Aoe(t,e){if(t&&e)return Aoe(t)(e);if(typeof t!="function")throw new TypeError("need wrapper function");return Object.keys(t).forEach(function(o){r[o]=t[o]}),r;function r(){for(var o=new Array(arguments.length),a=0;a<o.length;a++)o[a]=arguments[a];var n=t.apply(this,o),u=o[o.length-1];return typeof n=="function"&&n!==u&&Object.keys(u).forEach(function(A){n[A]=u[A]}),n}}});var MO=_((pLt,LO)=>{var hoe=poe();LO.exports=hoe(XS);LO.exports.strict=hoe(goe);XS.proto=XS(function(){Object.defineProperty(Function.prototype,"once",{value:function(){return XS(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return goe(this)},configurable:!0})});function XS(t){var e=function(){return e.called?e.value:(e.called=!0,e.value=t.apply(this,arguments))};return e.called=!1,e}function goe(t){var e=function(){if(e.called)throw new Error(e.onceError);return e.called=!0,e.value=t.apply(this,arguments)},r=t.name||"Function wrapped with `once`";return e.onceError=r+" shouldn't be called more than once",e.called=!1,e}});var OO=_((hLt,moe)=>{var Ant=MO(),fnt=function(){},pnt=function(t){return t.setHeader&&typeof t.abort=="function"},hnt=function(t){return t.stdio&&Array.isArray(t.stdio)&&t.stdio.length===3},doe=function(t,e,r){if(typeof e=="function")return doe(t,null,e);e||(e={}),r=Ant(r||fnt);var o=t._writableState,a=t._readableState,n=e.readable||e.readable!==!1&&t.readable,u=e.writable||e.writable!==!1&&t.writable,A=function(){t.writable||p()},p=function(){u=!1,n||r.call(t)},h=function(){n=!1,u||r.call(t)},E=function(C){r.call(t,C?new Error("exited with error code: "+C):null)},I=function(C){r.call(t,C)},v=function(){if(n&&!(a&&a.ended))return r.call(t,new Error("premature close"));if(u&&!(o&&o.ended))return r.call(t,new Error("premature close"))},b=function(){t.req.on("finish",p)};return pnt(t)?(t.on("complete",p),t.on("abort",v),t.req?b():t.on("request",b)):u&&!o&&(t.on("end",A),t.on("close",A)),hnt(t)&&t.on("exit",E),t.on("end",h),t.on("finish",p),e.error!==!1&&t.on("error",I),t.on("close",v),function(){t.removeListener("complete",p),t.removeListener("abort",v),t.removeListener("request",b),t.req&&t.req.removeListener("finish",p),t.removeListener("end",A),t.removeListener("close",A),t.removeListener("finish",p),t.removeListener("exit",E),t.removeListener("end",h),t.removeListener("error",I),t.removeListener("close",v)}};moe.exports=doe});var Coe=_((gLt,Eoe)=>{var gnt=MO(),dnt=OO(),UO=Be("fs"),f1=function(){},mnt=/^v?\.0/.test(process.version),ZS=function(t){return typeof t=="function"},ynt=function(t){return!mnt||!UO?!1:(t instanceof(UO.ReadStream||f1)||t instanceof(UO.WriteStream||f1))&&ZS(t.close)},Ent=function(t){return t.setHeader&&ZS(t.abort)},Cnt=function(t,e,r,o){o=gnt(o);var a=!1;t.on("close",function(){a=!0}),dnt(t,{readable:e,writable:r},function(u){if(u)return o(u);a=!0,o()});var n=!1;return function(u){if(!a&&!n){if(n=!0,ynt(t))return t.close(f1);if(Ent(t))return t.abort();if(ZS(t.destroy))return t.destroy();o(u||new Error("stream was destroyed"))}}},yoe=function(t){t()},wnt=function(t,e){return t.pipe(e)},Int=function(){var t=Array.prototype.slice.call(arguments),e=ZS(t[t.length-1]||f1)&&t.pop()||f1;if(Array.isArray(t[0])&&(t=t[0]),t.length<2)throw new Error("pump requires two streams per minimum");var r,o=t.map(function(a,n){var u=n<t.length-1,A=n>0;return Cnt(a,u,A,function(p){r||(r=p),p&&o.forEach(yoe),!u&&(o.forEach(yoe),e(r))})});return t.reduce(wnt)};Eoe.exports=Int});var Ioe=_((dLt,woe)=>{"use strict";var{PassThrough:Bnt}=Be("stream");woe.exports=t=>{t={...t};let{array:e}=t,{encoding:r}=t,o=r==="buffer",a=!1;e?a=!(r||o):r=r||"utf8",o&&(r=null);let n=new Bnt({objectMode:a});r&&n.setEncoding(r);let u=0,A=[];return n.on("data",p=>{A.push(p),a?u=A.length:u+=p.length}),n.getBufferedValue=()=>e?A:o?Buffer.concat(A,u):A.join(""),n.getBufferedLength=()=>u,n}});var Boe=_((mLt,BE)=>{"use strict";var vnt=Coe(),Dnt=Ioe(),$S=class extends Error{constructor(){super("maxBuffer exceeded"),this.name="MaxBufferError"}};async function ex(t,e){if(!t)return Promise.reject(new Error("Expected a stream"));e={maxBuffer:1/0,...e};let{maxBuffer:r}=e,o;return await new Promise((a,n)=>{let u=A=>{A&&(A.bufferedData=o.getBufferedValue()),n(A)};o=vnt(t,Dnt(e),A=>{if(A){u(A);return}a()}),o.on("data",()=>{o.getBufferedLength()>r&&u(new $S)})}),o.getBufferedValue()}BE.exports=ex;BE.exports.default=ex;BE.exports.buffer=(t,e)=>ex(t,{...e,encoding:"buffer"});BE.exports.array=(t,e)=>ex(t,{...e,array:!0});BE.exports.MaxBufferError=$S});var Doe=_((ELt,voe)=>{"use strict";var Pnt=new Set([200,203,204,206,300,301,404,405,410,414,501]),Snt=new Set([200,203,204,300,301,302,303,307,308,404,405,410,414,501]),xnt=new Set([500,502,503,504]),bnt={date:!0,connection:!0,"keep-alive":!0,"proxy-authenticate":!0,"proxy-authorization":!0,te:!0,trailer:!0,"transfer-encoding":!0,upgrade:!0},knt={"content-length":!0,"content-encoding":!0,"transfer-encoding":!0,"content-range":!0};function Dd(t){let e=parseInt(t,10);return isFinite(e)?e:0}function Qnt(t){return t?xnt.has(t.status):!0}function _O(t){let e={};if(!t)return e;let r=t.trim().split(/\s*,\s*/);for(let o of r){let[a,n]=o.split(/\s*=\s*/,2);e[a]=n===void 0?!0:n.replace(/^"|"$/g,"")}return e}function Fnt(t){let e=[];for(let r in t){let o=t[r];e.push(o===!0?r:r+"="+o)}if(!!e.length)return e.join(", ")}voe.exports=class{constructor(e,r,{shared:o,cacheHeuristic:a,immutableMinTimeToLive:n,ignoreCargoCult:u,_fromObject:A}={}){if(A){this._fromObject(A);return}if(!r||!r.headers)throw Error("Response headers missing");this._assertRequestHasHeaders(e),this._responseTime=this.now(),this._isShared=o!==!1,this._cacheHeuristic=a!==void 0?a:.1,this._immutableMinTtl=n!==void 0?n:24*3600*1e3,this._status="status"in r?r.status:200,this._resHeaders=r.headers,this._rescc=_O(r.headers["cache-control"]),this._method="method"in e?e.method:"GET",this._url=e.url,this._host=e.headers.host,this._noAuthorization=!e.headers.authorization,this._reqHeaders=r.headers.vary?e.headers:null,this._reqcc=_O(e.headers["cache-control"]),u&&"pre-check"in this._rescc&&"post-check"in this._rescc&&(delete this._rescc["pre-check"],delete this._rescc["post-check"],delete this._rescc["no-cache"],delete this._rescc["no-store"],delete this._rescc["must-revalidate"],this._resHeaders=Object.assign({},this._resHeaders,{"cache-control":Fnt(this._rescc)}),delete this._resHeaders.expires,delete this._resHeaders.pragma),r.headers["cache-control"]==null&&/no-cache/.test(r.headers.pragma)&&(this._rescc["no-cache"]=!0)}now(){return Date.now()}storable(){return!!(!this._reqcc["no-store"]&&(this._method==="GET"||this._method==="HEAD"||this._method==="POST"&&this._hasExplicitExpiration())&&Snt.has(this._status)&&!this._rescc["no-store"]&&(!this._isShared||!this._rescc.private)&&(!this._isShared||this._noAuthorization||this._allowsStoringAuthenticated())&&(this._resHeaders.expires||this._rescc["max-age"]||this._isShared&&this._rescc["s-maxage"]||this._rescc.public||Pnt.has(this._status)))}_hasExplicitExpiration(){return this._isShared&&this._rescc["s-maxage"]||this._rescc["max-age"]||this._resHeaders.expires}_assertRequestHasHeaders(e){if(!e||!e.headers)throw Error("Request headers missing")}satisfiesWithoutRevalidation(e){this._assertRequestHasHeaders(e);let r=_O(e.headers["cache-control"]);return r["no-cache"]||/no-cache/.test(e.headers.pragma)||r["max-age"]&&this.age()>r["max-age"]||r["min-fresh"]&&this.timeToLive()<1e3*r["min-fresh"]||this.stale()&&!(r["max-stale"]&&!this._rescc["must-revalidate"]&&(r["max-stale"]===!0||r["max-stale"]>this.age()-this.maxAge()))?!1:this._requestMatches(e,!1)}_requestMatches(e,r){return(!this._url||this._url===e.url)&&this._host===e.headers.host&&(!e.method||this._method===e.method||r&&e.method==="HEAD")&&this._varyMatches(e)}_allowsStoringAuthenticated(){return this._rescc["must-revalidate"]||this._rescc.public||this._rescc["s-maxage"]}_varyMatches(e){if(!this._resHeaders.vary)return!0;if(this._resHeaders.vary==="*")return!1;let r=this._resHeaders.vary.trim().toLowerCase().split(/\s*,\s*/);for(let o of r)if(e.headers[o]!==this._reqHeaders[o])return!1;return!0}_copyWithoutHopByHopHeaders(e){let r={};for(let o in e)bnt[o]||(r[o]=e[o]);if(e.connection){let o=e.connection.trim().split(/\s*,\s*/);for(let a of o)delete r[a]}if(r.warning){let o=r.warning.split(/,/).filter(a=>!/^\s*1[0-9][0-9]/.test(a));o.length?r.warning=o.join(",").trim():delete r.warning}return r}responseHeaders(){let e=this._copyWithoutHopByHopHeaders(this._resHeaders),r=this.age();return r>3600*24&&!this._hasExplicitExpiration()&&this.maxAge()>3600*24&&(e.warning=(e.warning?`${e.warning}, `:"")+'113 - "rfc7234 5.5.4"'),e.age=`${Math.round(r)}`,e.date=new Date(this.now()).toUTCString(),e}date(){let e=Date.parse(this._resHeaders.date);return isFinite(e)?e:this._responseTime}age(){let e=this._ageValue(),r=(this.now()-this._responseTime)/1e3;return e+r}_ageValue(){return Dd(this._resHeaders.age)}maxAge(){if(!this.storable()||this._rescc["no-cache"]||this._isShared&&this._resHeaders["set-cookie"]&&!this._rescc.public&&!this._rescc.immutable||this._resHeaders.vary==="*")return 0;if(this._isShared){if(this._rescc["proxy-revalidate"])return 0;if(this._rescc["s-maxage"])return Dd(this._rescc["s-maxage"])}if(this._rescc["max-age"])return Dd(this._rescc["max-age"]);let e=this._rescc.immutable?this._immutableMinTtl:0,r=this.date();if(this._resHeaders.expires){let o=Date.parse(this._resHeaders.expires);return Number.isNaN(o)||o<r?0:Math.max(e,(o-r)/1e3)}if(this._resHeaders["last-modified"]){let o=Date.parse(this._resHeaders["last-modified"]);if(isFinite(o)&&r>o)return Math.max(e,(r-o)/1e3*this._cacheHeuristic)}return e}timeToLive(){let e=this.maxAge()-this.age(),r=e+Dd(this._rescc["stale-if-error"]),o=e+Dd(this._rescc["stale-while-revalidate"]);return Math.max(0,e,r,o)*1e3}stale(){return this.maxAge()<=this.age()}_useStaleIfError(){return this.maxAge()+Dd(this._rescc["stale-if-error"])>this.age()}useStaleWhileRevalidate(){return this.maxAge()+Dd(this._rescc["stale-while-revalidate"])>this.age()}static fromObject(e){return new this(void 0,void 0,{_fromObject:e})}_fromObject(e){if(this._responseTime)throw Error("Reinitialized");if(!e||e.v!==1)throw Error("Invalid serialization");this._responseTime=e.t,this._isShared=e.sh,this._cacheHeuristic=e.ch,this._immutableMinTtl=e.imm!==void 0?e.imm:24*3600*1e3,this._status=e.st,this._resHeaders=e.resh,this._rescc=e.rescc,this._method=e.m,this._url=e.u,this._host=e.h,this._noAuthorization=e.a,this._reqHeaders=e.reqh,this._reqcc=e.reqcc}toObject(){return{v:1,t:this._responseTime,sh:this._isShared,ch:this._cacheHeuristic,imm:this._immutableMinTtl,st:this._status,resh:this._resHeaders,rescc:this._rescc,m:this._method,u:this._url,h:this._host,a:this._noAuthorization,reqh:this._reqHeaders,reqcc:this._reqcc}}revalidationHeaders(e){this._assertRequestHasHeaders(e);let r=this._copyWithoutHopByHopHeaders(e.headers);if(delete r["if-range"],!this._requestMatches(e,!0)||!this.storable())return delete r["if-none-match"],delete r["if-modified-since"],r;if(this._resHeaders.etag&&(r["if-none-match"]=r["if-none-match"]?`${r["if-none-match"]}, ${this._resHeaders.etag}`:this._resHeaders.etag),r["accept-ranges"]||r["if-match"]||r["if-unmodified-since"]||this._method&&this._method!="GET"){if(delete r["if-modified-since"],r["if-none-match"]){let a=r["if-none-match"].split(/,/).filter(n=>!/^\s*W\//.test(n));a.length?r["if-none-match"]=a.join(",").trim():delete r["if-none-match"]}}else this._resHeaders["last-modified"]&&!r["if-modified-since"]&&(r["if-modified-since"]=this._resHeaders["last-modified"]);return r}revalidatedPolicy(e,r){if(this._assertRequestHasHeaders(e),this._useStaleIfError()&&Qnt(r))return{modified:!1,matches:!1,policy:this};if(!r||!r.headers)throw Error("Response headers missing");let o=!1;if(r.status!==void 0&&r.status!=304?o=!1:r.headers.etag&&!/^\s*W\//.test(r.headers.etag)?o=this._resHeaders.etag&&this._resHeaders.etag.replace(/^\s*W\//,"")===r.headers.etag:this._resHeaders.etag&&r.headers.etag?o=this._resHeaders.etag.replace(/^\s*W\//,"")===r.headers.etag.replace(/^\s*W\//,""):this._resHeaders["last-modified"]?o=this._resHeaders["last-modified"]===r.headers["last-modified"]:!this._resHeaders.etag&&!this._resHeaders["last-modified"]&&!r.headers.etag&&!r.headers["last-modified"]&&(o=!0),!o)return{policy:new this.constructor(e,r),modified:r.status!=304,matches:!1};let a={};for(let u in this._resHeaders)a[u]=u in r.headers&&!knt[u]?r.headers[u]:this._resHeaders[u];let n=Object.assign({},r,{status:this._status,method:this._method,headers:a});return{policy:new this.constructor(e,n,{shared:this._isShared,cacheHeuristic:this._cacheHeuristic,immutableMinTimeToLive:this._immutableMinTtl}),modified:!1,matches:!0}}}});var tx=_((CLt,Poe)=>{"use strict";Poe.exports=t=>{let e={};for(let[r,o]of Object.entries(t))e[r.toLowerCase()]=o;return e}});var xoe=_((wLt,Soe)=>{"use strict";var Tnt=Be("stream").Readable,Rnt=tx(),HO=class extends Tnt{constructor(e,r,o,a){if(typeof e!="number")throw new TypeError("Argument `statusCode` should be a number");if(typeof r!="object")throw new TypeError("Argument `headers` should be an object");if(!(o instanceof Buffer))throw new TypeError("Argument `body` should be a buffer");if(typeof a!="string")throw new TypeError("Argument `url` should be a string");super(),this.statusCode=e,this.headers=Rnt(r),this.body=o,this.url=a}_read(){this.push(this.body),this.push(null)}};Soe.exports=HO});var koe=_((ILt,boe)=>{"use strict";var Nnt=["destroy","setTimeout","socket","headers","trailers","rawHeaders","statusCode","httpVersion","httpVersionMinor","httpVersionMajor","rawTrailers","statusMessage"];boe.exports=(t,e)=>{let r=new Set(Object.keys(t).concat(Nnt));for(let o of r)o in e||(e[o]=typeof t[o]=="function"?t[o].bind(t):t[o])}});var Foe=_((BLt,Qoe)=>{"use strict";var Lnt=Be("stream").PassThrough,Mnt=koe(),Ont=t=>{if(!(t&&t.pipe))throw new TypeError("Parameter `response` must be a response stream.");let e=new Lnt;return Mnt(t,e),t.pipe(e)};Qoe.exports=Ont});var Toe=_(jO=>{jO.stringify=function t(e){if(typeof e>"u")return e;if(e&&Buffer.isBuffer(e))return JSON.stringify(":base64:"+e.toString("base64"));if(e&&e.toJSON&&(e=e.toJSON()),e&&typeof e=="object"){var r="",o=Array.isArray(e);r=o?"[":"{";var a=!0;for(var n in e){var u=typeof e[n]=="function"||!o&&typeof e[n]>"u";Object.hasOwnProperty.call(e,n)&&!u&&(a||(r+=","),a=!1,o?e[n]==null?r+="null":r+=t(e[n]):e[n]!==void 0&&(r+=t(n)+":"+t(e[n])))}return r+=o?"]":"}",r}else return typeof e=="string"?JSON.stringify(/^:/.test(e)?":"+e:e):typeof e>"u"?"null":JSON.stringify(e)};jO.parse=function(t){return JSON.parse(t,function(e,r){return typeof r=="string"?/^:base64:/.test(r)?Buffer.from(r.substring(8),"base64"):/^:/.test(r)?r.substring(1):r:r})}});var Loe=_((DLt,Noe)=>{"use strict";var Unt=Be("events"),Roe=Toe(),_nt=t=>{let e={redis:"@keyv/redis",mongodb:"@keyv/mongo",mongo:"@keyv/mongo",sqlite:"@keyv/sqlite",postgresql:"@keyv/postgres",postgres:"@keyv/postgres",mysql:"@keyv/mysql"};if(t.adapter||t.uri){let r=t.adapter||/^[^:]*/.exec(t.uri)[0];return new(Be(e[r]))(t)}return new Map},qO=class extends Unt{constructor(e,r){if(super(),this.opts=Object.assign({namespace:"keyv",serialize:Roe.stringify,deserialize:Roe.parse},typeof e=="string"?{uri:e}:e,r),!this.opts.store){let o=Object.assign({},this.opts);this.opts.store=_nt(o)}typeof this.opts.store.on=="function"&&this.opts.store.on("error",o=>this.emit("error",o)),this.opts.store.namespace=this.opts.namespace}_getKeyPrefix(e){return`${this.opts.namespace}:${e}`}get(e,r){e=this._getKeyPrefix(e);let{store:o}=this.opts;return Promise.resolve().then(()=>o.get(e)).then(a=>typeof a=="string"?this.opts.deserialize(a):a).then(a=>{if(a!==void 0){if(typeof a.expires=="number"&&Date.now()>a.expires){this.delete(e);return}return r&&r.raw?a:a.value}})}set(e,r,o){e=this._getKeyPrefix(e),typeof o>"u"&&(o=this.opts.ttl),o===0&&(o=void 0);let{store:a}=this.opts;return Promise.resolve().then(()=>{let n=typeof o=="number"?Date.now()+o:null;return r={value:r,expires:n},this.opts.serialize(r)}).then(n=>a.set(e,n,o)).then(()=>!0)}delete(e){e=this._getKeyPrefix(e);let{store:r}=this.opts;return Promise.resolve().then(()=>r.delete(e))}clear(){let{store:e}=this.opts;return Promise.resolve().then(()=>e.clear())}};Noe.exports=qO});var Uoe=_((SLt,Ooe)=>{"use strict";var Hnt=Be("events"),rx=Be("url"),jnt=uoe(),qnt=Boe(),GO=Doe(),Moe=xoe(),Gnt=tx(),Ynt=Foe(),Wnt=Loe(),jc=class{constructor(e,r){if(typeof e!="function")throw new TypeError("Parameter `request` must be a function");return this.cache=new Wnt({uri:typeof r=="string"&&r,store:typeof r!="string"&&r,namespace:"cacheable-request"}),this.createCacheableRequest(e)}createCacheableRequest(e){return(r,o)=>{let a;if(typeof r=="string")a=YO(rx.parse(r)),r={};else if(r instanceof rx.URL)a=YO(rx.parse(r.toString())),r={};else{let[I,...v]=(r.path||"").split("?"),b=v.length>0?`?${v.join("?")}`:"";a=YO({...r,pathname:I,search:b})}r={headers:{},method:"GET",cache:!0,strictTtl:!1,automaticFailover:!1,...r,...Vnt(a)},r.headers=Gnt(r.headers);let n=new Hnt,u=jnt(rx.format(a),{stripWWW:!1,removeTrailingSlash:!1,stripAuthentication:!1}),A=`${r.method}:${u}`,p=!1,h=!1,E=I=>{h=!0;let v=!1,b,C=new Promise(L=>{b=()=>{v||(v=!0,L())}}),T=L=>{if(p&&!I.forceRefresh){L.status=L.statusCode;let J=GO.fromObject(p.cachePolicy).revalidatedPolicy(I,L);if(!J.modified){let te=J.policy.responseHeaders();L=new Moe(p.statusCode,te,p.body,p.url),L.cachePolicy=J.policy,L.fromCache=!0}}L.fromCache||(L.cachePolicy=new GO(I,L,I),L.fromCache=!1);let U;I.cache&&L.cachePolicy.storable()?(U=Ynt(L),(async()=>{try{let J=qnt.buffer(L);if(await Promise.race([C,new Promise(Ae=>L.once("end",Ae))]),v)return;let te=await J,le={cachePolicy:L.cachePolicy.toObject(),url:L.url,statusCode:L.fromCache?p.statusCode:L.statusCode,body:te},pe=I.strictTtl?L.cachePolicy.timeToLive():void 0;I.maxTtl&&(pe=pe?Math.min(pe,I.maxTtl):I.maxTtl),await this.cache.set(A,le,pe)}catch(J){n.emit("error",new jc.CacheError(J))}})()):I.cache&&p&&(async()=>{try{await this.cache.delete(A)}catch(J){n.emit("error",new jc.CacheError(J))}})(),n.emit("response",U||L),typeof o=="function"&&o(U||L)};try{let L=e(I,T);L.once("error",b),L.once("abort",b),n.emit("request",L)}catch(L){n.emit("error",new jc.RequestError(L))}};return(async()=>{let I=async b=>{await Promise.resolve();let C=b.cache?await this.cache.get(A):void 0;if(typeof C>"u")return E(b);let T=GO.fromObject(C.cachePolicy);if(T.satisfiesWithoutRevalidation(b)&&!b.forceRefresh){let L=T.responseHeaders(),U=new Moe(C.statusCode,L,C.body,C.url);U.cachePolicy=T,U.fromCache=!0,n.emit("response",U),typeof o=="function"&&o(U)}else p=C,b.headers=T.revalidationHeaders(b),E(b)},v=b=>n.emit("error",new jc.CacheError(b));this.cache.once("error",v),n.on("response",()=>this.cache.removeListener("error",v));try{await I(r)}catch(b){r.automaticFailover&&!h&&E(r),n.emit("error",new jc.CacheError(b))}})(),n}}};function Vnt(t){let e={...t};return e.path=`${t.pathname||"/"}${t.search||""}`,delete e.pathname,delete e.search,e}function YO(t){return{protocol:t.protocol,auth:t.auth,hostname:t.hostname||t.host||"localhost",port:t.port,pathname:t.pathname,search:t.search}}jc.RequestError=class extends Error{constructor(t){super(t.message),this.name="RequestError",Object.assign(this,t)}};jc.CacheError=class extends Error{constructor(t){super(t.message),this.name="CacheError",Object.assign(this,t)}};Ooe.exports=jc});var Hoe=_((kLt,_oe)=>{"use strict";var Knt=["aborted","complete","headers","httpVersion","httpVersionMinor","httpVersionMajor","method","rawHeaders","rawTrailers","setTimeout","socket","statusCode","statusMessage","trailers","url"];_oe.exports=(t,e)=>{if(e._readableState.autoDestroy)throw new Error("The second stream must have the `autoDestroy` option set to `false`");let r=new Set(Object.keys(t).concat(Knt)),o={};for(let a of r)a in e||(o[a]={get(){let n=t[a];return typeof n=="function"?n.bind(t):n},set(n){t[a]=n},enumerable:!0,configurable:!1});return Object.defineProperties(e,o),t.once("aborted",()=>{e.destroy(),e.emit("aborted")}),t.once("close",()=>{t.complete&&e.readable?e.once("end",()=>{e.emit("close")}):e.emit("close")}),e}});var qoe=_((QLt,joe)=>{"use strict";var{Transform:Jnt,PassThrough:znt}=Be("stream"),WO=Be("zlib"),Xnt=Hoe();joe.exports=t=>{let e=(t.headers["content-encoding"]||"").toLowerCase();if(!["gzip","deflate","br"].includes(e))return t;let r=e==="br";if(r&&typeof WO.createBrotliDecompress!="function")return t.destroy(new Error("Brotli is not supported on Node.js < 12")),t;let o=!0,a=new Jnt({transform(A,p,h){o=!1,h(null,A)},flush(A){A()}}),n=new znt({autoDestroy:!1,destroy(A,p){t.destroy(),p(A)}}),u=r?WO.createBrotliDecompress():WO.createUnzip();return u.once("error",A=>{if(o&&!t.readable){n.end();return}n.destroy(A)}),Xnt(t,n),t.pipe(a).pipe(u).pipe(n),n}});var KO=_((FLt,Goe)=>{"use strict";var VO=class{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError("`maxSize` must be a number greater than 0");this.maxSize=e.maxSize,this.onEviction=e.onEviction,this.cache=new Map,this.oldCache=new Map,this._size=0}_set(e,r){if(this.cache.set(e,r),this._size++,this._size>=this.maxSize){if(this._size=0,typeof this.onEviction=="function")for(let[o,a]of this.oldCache.entries())this.onEviction(o,a);this.oldCache=this.cache,this.cache=new Map}}get(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e)){let r=this.oldCache.get(e);return this.oldCache.delete(e),this._set(e,r),r}}set(e,r){return this.cache.has(e)?this.cache.set(e,r):this._set(e,r),this}has(e){return this.cache.has(e)||this.oldCache.has(e)}peek(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e))return this.oldCache.get(e)}delete(e){let r=this.cache.delete(e);return r&&this._size--,this.oldCache.delete(e)||r}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0}*keys(){for(let[e]of this)yield e}*values(){for(let[,e]of this)yield e}*[Symbol.iterator](){for(let e of this.cache)yield e;for(let e of this.oldCache){let[r]=e;this.cache.has(r)||(yield e)}}get size(){let e=0;for(let r of this.oldCache.keys())this.cache.has(r)||e++;return Math.min(this._size+e,this.maxSize)}};Goe.exports=VO});var zO=_((TLt,Koe)=>{"use strict";var Znt=Be("events"),$nt=Be("tls"),eit=Be("http2"),tit=KO(),ea=Symbol("currentStreamsCount"),Yoe=Symbol("request"),Wl=Symbol("cachedOriginSet"),vE=Symbol("gracefullyClosing"),rit=["maxDeflateDynamicTableSize","maxSessionMemory","maxHeaderListPairs","maxOutstandingPings","maxReservedRemoteStreams","maxSendHeaderBlockLength","paddingStrategy","localAddress","path","rejectUnauthorized","minDHSize","ca","cert","clientCertEngine","ciphers","key","pfx","servername","minVersion","maxVersion","secureProtocol","crl","honorCipherOrder","ecdhCurve","dhparam","secureOptions","sessionIdContext"],nit=(t,e,r)=>{let o=0,a=t.length;for(;o<a;){let n=o+a>>>1;r(t[n],e)?o=n+1:a=n}return o},iit=(t,e)=>t.remoteSettings.maxConcurrentStreams>e.remoteSettings.maxConcurrentStreams,JO=(t,e)=>{for(let r of t)r[Wl].length<e[Wl].length&&r[Wl].every(o=>e[Wl].includes(o))&&r[ea]+e[ea]<=e.remoteSettings.maxConcurrentStreams&&Voe(r)},sit=(t,e)=>{for(let r of t)e[Wl].length<r[Wl].length&&e[Wl].every(o=>r[Wl].includes(o))&&e[ea]+r[ea]<=r.remoteSettings.maxConcurrentStreams&&Voe(e)},Woe=({agent:t,isFree:e})=>{let r={};for(let o in t.sessions){let n=t.sessions[o].filter(u=>{let A=u[tA.kCurrentStreamsCount]<u.remoteSettings.maxConcurrentStreams;return e?A:!A});n.length!==0&&(r[o]=n)}return r},Voe=t=>{t[vE]=!0,t[ea]===0&&t.close()},tA=class extends Znt{constructor({timeout:e=6e4,maxSessions:r=1/0,maxFreeSessions:o=10,maxCachedTlsSessions:a=100}={}){super(),this.sessions={},this.queue={},this.timeout=e,this.maxSessions=r,this.maxFreeSessions=o,this._freeSessionsCount=0,this._sessionsCount=0,this.settings={enablePush:!1},this.tlsSessionCache=new tit({maxSize:a})}static normalizeOrigin(e,r){return typeof e=="string"&&(e=new URL(e)),r&&e.hostname!==r&&(e.hostname=r),e.origin}normalizeOptions(e){let r="";if(e)for(let o of rit)e[o]&&(r+=`:${e[o]}`);return r}_tryToCreateNewSession(e,r){if(!(e in this.queue)||!(r in this.queue[e]))return;let o=this.queue[e][r];this._sessionsCount<this.maxSessions&&!o.completed&&(o.completed=!0,o())}getSession(e,r,o){return new Promise((a,n)=>{Array.isArray(o)?(o=[...o],a()):o=[{resolve:a,reject:n}];let u=this.normalizeOptions(r),A=tA.normalizeOrigin(e,r&&r.servername);if(A===void 0){for(let{reject:E}of o)E(new TypeError("The `origin` argument needs to be a string or an URL object"));return}if(u in this.sessions){let E=this.sessions[u],I=-1,v=-1,b;for(let C of E){let T=C.remoteSettings.maxConcurrentStreams;if(T<I)break;if(C[Wl].includes(A)){let L=C[ea];if(L>=T||C[vE]||C.destroyed)continue;b||(I=T),L>v&&(b=C,v=L)}}if(b){if(o.length!==1){for(let{reject:C}of o){let T=new Error(`Expected the length of listeners to be 1, got ${o.length}. +Please report this to https://github.com/szmarczak/http2-wrapper/`);C(T)}return}o[0].resolve(b);return}}if(u in this.queue){if(A in this.queue[u]){this.queue[u][A].listeners.push(...o),this._tryToCreateNewSession(u,A);return}}else this.queue[u]={};let p=()=>{u in this.queue&&this.queue[u][A]===h&&(delete this.queue[u][A],Object.keys(this.queue[u]).length===0&&delete this.queue[u])},h=()=>{let E=`${A}:${u}`,I=!1;try{let v=eit.connect(e,{createConnection:this.createConnection,settings:this.settings,session:this.tlsSessionCache.get(E),...r});v[ea]=0,v[vE]=!1;let b=()=>v[ea]<v.remoteSettings.maxConcurrentStreams,C=!0;v.socket.once("session",L=>{this.tlsSessionCache.set(E,L)}),v.once("error",L=>{for(let{reject:U}of o)U(L);this.tlsSessionCache.delete(E)}),v.setTimeout(this.timeout,()=>{v.destroy()}),v.once("close",()=>{if(I){C&&this._freeSessionsCount--,this._sessionsCount--;let L=this.sessions[u];L.splice(L.indexOf(v),1),L.length===0&&delete this.sessions[u]}else{let L=new Error("Session closed without receiving a SETTINGS frame");L.code="HTTP2WRAPPER_NOSETTINGS";for(let{reject:U}of o)U(L);p()}this._tryToCreateNewSession(u,A)});let T=()=>{if(!(!(u in this.queue)||!b())){for(let L of v[Wl])if(L in this.queue[u]){let{listeners:U}=this.queue[u][L];for(;U.length!==0&&b();)U.shift().resolve(v);let J=this.queue[u];if(J[L].listeners.length===0&&(delete J[L],Object.keys(J).length===0)){delete this.queue[u];break}if(!b())break}}};v.on("origin",()=>{v[Wl]=v.originSet,b()&&(T(),JO(this.sessions[u],v))}),v.once("remoteSettings",()=>{if(v.ref(),v.unref(),this._sessionsCount++,h.destroyed){let L=new Error("Agent has been destroyed");for(let U of o)U.reject(L);v.destroy();return}v[Wl]=v.originSet;{let L=this.sessions;if(u in L){let U=L[u];U.splice(nit(U,v,iit),0,v)}else L[u]=[v]}this._freeSessionsCount+=1,I=!0,this.emit("session",v),T(),p(),v[ea]===0&&this._freeSessionsCount>this.maxFreeSessions&&v.close(),o.length!==0&&(this.getSession(A,r,o),o.length=0),v.on("remoteSettings",()=>{T(),JO(this.sessions[u],v)})}),v[Yoe]=v.request,v.request=(L,U)=>{if(v[vE])throw new Error("The session is gracefully closing. No new streams are allowed.");let J=v[Yoe](L,U);return v.ref(),++v[ea],v[ea]===v.remoteSettings.maxConcurrentStreams&&this._freeSessionsCount--,J.once("close",()=>{if(C=b(),--v[ea],!v.destroyed&&!v.closed&&(sit(this.sessions[u],v),b()&&!v.closed)){C||(this._freeSessionsCount++,C=!0);let te=v[ea]===0;te&&v.unref(),te&&(this._freeSessionsCount>this.maxFreeSessions||v[vE])?v.close():(JO(this.sessions[u],v),T())}}),J}}catch(v){for(let b of o)b.reject(v);p()}};h.listeners=o,h.completed=!1,h.destroyed=!1,this.queue[u][A]=h,this._tryToCreateNewSession(u,A)})}request(e,r,o,a){return new Promise((n,u)=>{this.getSession(e,r,[{reject:u,resolve:A=>{try{n(A.request(o,a))}catch(p){u(p)}}}])})}createConnection(e,r){return tA.connect(e,r)}static connect(e,r){r.ALPNProtocols=["h2"];let o=e.port||443,a=e.hostname||e.host;return typeof r.servername>"u"&&(r.servername=a),$nt.connect(o,a,r)}closeFreeSessions(){for(let e of Object.values(this.sessions))for(let r of e)r[ea]===0&&r.close()}destroy(e){for(let r of Object.values(this.sessions))for(let o of r)o.destroy(e);for(let r of Object.values(this.queue))for(let o of Object.values(r))o.destroyed=!0;this.queue={}}get freeSessions(){return Woe({agent:this,isFree:!0})}get busySessions(){return Woe({agent:this,isFree:!1})}};tA.kCurrentStreamsCount=ea;tA.kGracefullyClosing=vE;Koe.exports={Agent:tA,globalAgent:new tA}});var ZO=_((RLt,Joe)=>{"use strict";var{Readable:oit}=Be("stream"),XO=class extends oit{constructor(e,r){super({highWaterMark:r,autoDestroy:!1}),this.statusCode=null,this.statusMessage="",this.httpVersion="2.0",this.httpVersionMajor=2,this.httpVersionMinor=0,this.headers={},this.trailers={},this.req=null,this.aborted=!1,this.complete=!1,this.upgrade=null,this.rawHeaders=[],this.rawTrailers=[],this.socket=e,this.connection=e,this._dumped=!1}_destroy(e){this.req._request.destroy(e)}setTimeout(e,r){return this.req.setTimeout(e,r),this}_dump(){this._dumped||(this._dumped=!0,this.removeAllListeners("data"),this.resume())}_read(){this.req&&this.req._request.resume()}};Joe.exports=XO});var $O=_((NLt,zoe)=>{"use strict";zoe.exports=t=>{let e={protocol:t.protocol,hostname:typeof t.hostname=="string"&&t.hostname.startsWith("[")?t.hostname.slice(1,-1):t.hostname,host:t.host,hash:t.hash,search:t.search,pathname:t.pathname,href:t.href,path:`${t.pathname||""}${t.search||""}`};return typeof t.port=="string"&&t.port.length!==0&&(e.port=Number(t.port)),(t.username||t.password)&&(e.auth=`${t.username||""}:${t.password||""}`),e}});var Zoe=_((LLt,Xoe)=>{"use strict";Xoe.exports=(t,e,r)=>{for(let o of r)t.on(o,(...a)=>e.emit(o,...a))}});var eae=_((MLt,$oe)=>{"use strict";$oe.exports=t=>{switch(t){case":method":case":scheme":case":authority":case":path":return!0;default:return!1}}});var rae=_((ULt,tae)=>{"use strict";var DE=(t,e,r)=>{tae.exports[e]=class extends t{constructor(...a){super(typeof r=="string"?r:r(a)),this.name=`${super.name} [${e}]`,this.code=e}}};DE(TypeError,"ERR_INVALID_ARG_TYPE",t=>{let e=t[0].includes(".")?"property":"argument",r=t[1],o=Array.isArray(r);return o&&(r=`${r.slice(0,-1).join(", ")} or ${r.slice(-1)}`),`The "${t[0]}" ${e} must be ${o?"one of":"of"} type ${r}. Received ${typeof t[2]}`});DE(TypeError,"ERR_INVALID_PROTOCOL",t=>`Protocol "${t[0]}" not supported. Expected "${t[1]}"`);DE(Error,"ERR_HTTP_HEADERS_SENT",t=>`Cannot ${t[0]} headers after they are sent to the client`);DE(TypeError,"ERR_INVALID_HTTP_TOKEN",t=>`${t[0]} must be a valid HTTP token [${t[1]}]`);DE(TypeError,"ERR_HTTP_INVALID_HEADER_VALUE",t=>`Invalid value "${t[0]} for header "${t[1]}"`);DE(TypeError,"ERR_INVALID_CHAR",t=>`Invalid character in ${t[0]} [${t[1]}]`)});var i4=_((_Lt,cae)=>{"use strict";var ait=Be("http2"),{Writable:lit}=Be("stream"),{Agent:nae,globalAgent:cit}=zO(),uit=ZO(),Ait=$O(),fit=Zoe(),pit=eae(),{ERR_INVALID_ARG_TYPE:e4,ERR_INVALID_PROTOCOL:hit,ERR_HTTP_HEADERS_SENT:iae,ERR_INVALID_HTTP_TOKEN:git,ERR_HTTP_INVALID_HEADER_VALUE:dit,ERR_INVALID_CHAR:mit}=rae(),{HTTP2_HEADER_STATUS:sae,HTTP2_HEADER_METHOD:oae,HTTP2_HEADER_PATH:aae,HTTP2_METHOD_CONNECT:yit}=ait.constants,Qo=Symbol("headers"),t4=Symbol("origin"),r4=Symbol("session"),lae=Symbol("options"),nx=Symbol("flushedHeaders"),p1=Symbol("jobs"),Eit=/^[\^`\-\w!#$%&*+.|~]+$/,Cit=/[^\t\u0020-\u007E\u0080-\u00FF]/,n4=class extends lit{constructor(e,r,o){super({autoDestroy:!1});let a=typeof e=="string"||e instanceof URL;if(a&&(e=Ait(e instanceof URL?e:new URL(e))),typeof r=="function"||r===void 0?(o=r,r=a?e:{...e}):r={...e,...r},r.h2session)this[r4]=r.h2session;else if(r.agent===!1)this.agent=new nae({maxFreeSessions:0});else if(typeof r.agent>"u"||r.agent===null)typeof r.createConnection=="function"?(this.agent=new nae({maxFreeSessions:0}),this.agent.createConnection=r.createConnection):this.agent=cit;else if(typeof r.agent.request=="function")this.agent=r.agent;else throw new e4("options.agent",["Agent-like Object","undefined","false"],r.agent);if(r.protocol&&r.protocol!=="https:")throw new hit(r.protocol,"https:");let n=r.port||r.defaultPort||this.agent&&this.agent.defaultPort||443,u=r.hostname||r.host||"localhost";delete r.hostname,delete r.host,delete r.port;let{timeout:A}=r;if(r.timeout=void 0,this[Qo]=Object.create(null),this[p1]=[],this.socket=null,this.connection=null,this.method=r.method||"GET",this.path=r.path,this.res=null,this.aborted=!1,this.reusedSocket=!1,r.headers)for(let[p,h]of Object.entries(r.headers))this.setHeader(p,h);r.auth&&!("authorization"in this[Qo])&&(this[Qo].authorization="Basic "+Buffer.from(r.auth).toString("base64")),r.session=r.tlsSession,r.path=r.socketPath,this[lae]=r,n===443?(this[t4]=`https://${u}`,":authority"in this[Qo]||(this[Qo][":authority"]=u)):(this[t4]=`https://${u}:${n}`,":authority"in this[Qo]||(this[Qo][":authority"]=`${u}:${n}`)),A&&this.setTimeout(A),o&&this.once("response",o),this[nx]=!1}get method(){return this[Qo][oae]}set method(e){e&&(this[Qo][oae]=e.toUpperCase())}get path(){return this[Qo][aae]}set path(e){e&&(this[Qo][aae]=e)}get _mustNotHaveABody(){return this.method==="GET"||this.method==="HEAD"||this.method==="DELETE"}_write(e,r,o){if(this._mustNotHaveABody){o(new Error("The GET, HEAD and DELETE methods must NOT have a body"));return}this.flushHeaders();let a=()=>this._request.write(e,r,o);this._request?a():this[p1].push(a)}_final(e){if(this.destroyed)return;this.flushHeaders();let r=()=>{if(this._mustNotHaveABody){e();return}this._request.end(e)};this._request?r():this[p1].push(r)}abort(){this.res&&this.res.complete||(this.aborted||process.nextTick(()=>this.emit("abort")),this.aborted=!0,this.destroy())}_destroy(e,r){this.res&&this.res._dump(),this._request&&this._request.destroy(),r(e)}async flushHeaders(){if(this[nx]||this.destroyed)return;this[nx]=!0;let e=this.method===yit,r=o=>{if(this._request=o,this.destroyed){o.destroy();return}e||fit(o,this,["timeout","continue","close","error"]);let a=u=>(...A)=>{!this.writable&&!this.destroyed?u(...A):this.once("finish",()=>{u(...A)})};o.once("response",a((u,A,p)=>{let h=new uit(this.socket,o.readableHighWaterMark);this.res=h,h.req=this,h.statusCode=u[sae],h.headers=u,h.rawHeaders=p,h.once("end",()=>{this.aborted?(h.aborted=!0,h.emit("aborted")):(h.complete=!0,h.socket=null,h.connection=null)}),e?(h.upgrade=!0,this.emit("connect",h,o,Buffer.alloc(0))?this.emit("close"):o.destroy()):(o.on("data",E=>{!h._dumped&&!h.push(E)&&o.pause()}),o.once("end",()=>{h.push(null)}),this.emit("response",h)||h._dump())})),o.once("headers",a(u=>this.emit("information",{statusCode:u[sae]}))),o.once("trailers",a((u,A,p)=>{let{res:h}=this;h.trailers=u,h.rawTrailers=p}));let{socket:n}=o.session;this.socket=n,this.connection=n;for(let u of this[p1])u();this.emit("socket",this.socket)};if(this[r4])try{r(this[r4].request(this[Qo]))}catch(o){this.emit("error",o)}else{this.reusedSocket=!0;try{r(await this.agent.request(this[t4],this[lae],this[Qo]))}catch(o){this.emit("error",o)}}}getHeader(e){if(typeof e!="string")throw new e4("name","string",e);return this[Qo][e.toLowerCase()]}get headersSent(){return this[nx]}removeHeader(e){if(typeof e!="string")throw new e4("name","string",e);if(this.headersSent)throw new iae("remove");delete this[Qo][e.toLowerCase()]}setHeader(e,r){if(this.headersSent)throw new iae("set");if(typeof e!="string"||!Eit.test(e)&&!pit(e))throw new git("Header name",e);if(typeof r>"u")throw new dit(r,e);if(Cit.test(r))throw new mit("header content",e);this[Qo][e.toLowerCase()]=r}setNoDelay(){}setSocketKeepAlive(){}setTimeout(e,r){let o=()=>this._request.setTimeout(e,r);return this._request?o():this[p1].push(o),this}get maxHeadersCount(){if(!this.destroyed&&this._request)return this._request.session.localSettings.maxHeaderListSize}set maxHeadersCount(e){}};cae.exports=n4});var Aae=_((HLt,uae)=>{"use strict";var wit=Be("tls");uae.exports=(t={})=>new Promise((e,r)=>{let o=wit.connect(t,()=>{t.resolveSocket?(o.off("error",r),e({alpnProtocol:o.alpnProtocol,socket:o})):(o.destroy(),e({alpnProtocol:o.alpnProtocol}))});o.on("error",r)})});var pae=_((jLt,fae)=>{"use strict";var Iit=Be("net");fae.exports=t=>{let e=t.host,r=t.headers&&t.headers.host;return r&&(r.startsWith("[")?r.indexOf("]")===-1?e=r:e=r.slice(1,-1):e=r.split(":",1)[0]),Iit.isIP(e)?"":e}});var dae=_((qLt,o4)=>{"use strict";var hae=Be("http"),s4=Be("https"),Bit=Aae(),vit=KO(),Dit=i4(),Pit=pae(),Sit=$O(),ix=new vit({maxSize:100}),h1=new Map,gae=(t,e,r)=>{e._httpMessage={shouldKeepAlive:!0};let o=()=>{t.emit("free",e,r)};e.on("free",o);let a=()=>{t.removeSocket(e,r)};e.on("close",a);let n=()=>{t.removeSocket(e,r),e.off("close",a),e.off("free",o),e.off("agentRemove",n)};e.on("agentRemove",n),t.emit("free",e,r)},xit=async t=>{let e=`${t.host}:${t.port}:${t.ALPNProtocols.sort()}`;if(!ix.has(e)){if(h1.has(e))return(await h1.get(e)).alpnProtocol;let{path:r,agent:o}=t;t.path=t.socketPath;let a=Bit(t);h1.set(e,a);try{let{socket:n,alpnProtocol:u}=await a;if(ix.set(e,u),t.path=r,u==="h2")n.destroy();else{let{globalAgent:A}=s4,p=s4.Agent.prototype.createConnection;o?o.createConnection===p?gae(o,n,t):n.destroy():A.createConnection===p?gae(A,n,t):n.destroy()}return h1.delete(e),u}catch(n){throw h1.delete(e),n}}return ix.get(e)};o4.exports=async(t,e,r)=>{if((typeof t=="string"||t instanceof URL)&&(t=Sit(new URL(t))),typeof e=="function"&&(r=e,e=void 0),e={ALPNProtocols:["h2","http/1.1"],...t,...e,resolveSocket:!0},!Array.isArray(e.ALPNProtocols)||e.ALPNProtocols.length===0)throw new Error("The `ALPNProtocols` option must be an Array with at least one entry");e.protocol=e.protocol||"https:";let o=e.protocol==="https:";e.host=e.hostname||e.host||"localhost",e.session=e.tlsSession,e.servername=e.servername||Pit(e),e.port=e.port||(o?443:80),e._defaultAgent=o?s4.globalAgent:hae.globalAgent;let a=e.agent;if(a){if(a.addRequest)throw new Error("The `options.agent` object can contain only `http`, `https` or `http2` properties");e.agent=a[o?"https":"http"]}return o&&await xit(e)==="h2"?(a&&(e.agent=a.http2),new Dit(e,r)):hae.request(e,r)};o4.exports.protocolCache=ix});var yae=_((GLt,mae)=>{"use strict";var bit=Be("http2"),kit=zO(),a4=i4(),Qit=ZO(),Fit=dae(),Tit=(t,e,r)=>new a4(t,e,r),Rit=(t,e,r)=>{let o=new a4(t,e,r);return o.end(),o};mae.exports={...bit,ClientRequest:a4,IncomingMessage:Qit,...kit,request:Tit,get:Rit,auto:Fit}});var c4=_(l4=>{"use strict";Object.defineProperty(l4,"__esModule",{value:!0});var Eae=Tf();l4.default=t=>Eae.default.nodeStream(t)&&Eae.default.function_(t.getBoundary)});var Bae=_(u4=>{"use strict";Object.defineProperty(u4,"__esModule",{value:!0});var wae=Be("fs"),Iae=Be("util"),Cae=Tf(),Nit=c4(),Lit=Iae.promisify(wae.stat);u4.default=async(t,e)=>{if(e&&"content-length"in e)return Number(e["content-length"]);if(!t)return 0;if(Cae.default.string(t))return Buffer.byteLength(t);if(Cae.default.buffer(t))return t.length;if(Nit.default(t))return Iae.promisify(t.getLength.bind(t))();if(t instanceof wae.ReadStream){let{size:r}=await Lit(t.path);return r===0?void 0:r}}});var f4=_(A4=>{"use strict";Object.defineProperty(A4,"__esModule",{value:!0});function Mit(t,e,r){let o={};for(let a of r)o[a]=(...n)=>{e.emit(a,...n)},t.on(a,o[a]);return()=>{for(let a of r)t.off(a,o[a])}}A4.default=Mit});var vae=_(p4=>{"use strict";Object.defineProperty(p4,"__esModule",{value:!0});p4.default=()=>{let t=[];return{once(e,r,o){e.once(r,o),t.push({origin:e,event:r,fn:o})},unhandleAll(){for(let e of t){let{origin:r,event:o,fn:a}=e;r.removeListener(o,a)}t.length=0}}}});var Pae=_(g1=>{"use strict";Object.defineProperty(g1,"__esModule",{value:!0});g1.TimeoutError=void 0;var Oit=Be("net"),Uit=vae(),Dae=Symbol("reentry"),_it=()=>{},sx=class extends Error{constructor(e,r){super(`Timeout awaiting '${r}' for ${e}ms`),this.event=r,this.name="TimeoutError",this.code="ETIMEDOUT"}};g1.TimeoutError=sx;g1.default=(t,e,r)=>{if(Dae in t)return _it;t[Dae]=!0;let o=[],{once:a,unhandleAll:n}=Uit.default(),u=(I,v,b)=>{var C;let T=setTimeout(v,I,I,b);(C=T.unref)===null||C===void 0||C.call(T);let L=()=>{clearTimeout(T)};return o.push(L),L},{host:A,hostname:p}=r,h=(I,v)=>{t.destroy(new sx(I,v))},E=()=>{for(let I of o)I();n()};if(t.once("error",I=>{if(E(),t.listenerCount("error")===0)throw I}),t.once("close",E),a(t,"response",I=>{a(I,"end",E)}),typeof e.request<"u"&&u(e.request,h,"request"),typeof e.socket<"u"){let I=()=>{h(e.socket,"socket")};t.setTimeout(e.socket,I),o.push(()=>{t.removeListener("timeout",I)})}return a(t,"socket",I=>{var v;let{socketPath:b}=t;if(I.connecting){let C=Boolean(b??Oit.isIP((v=p??A)!==null&&v!==void 0?v:"")!==0);if(typeof e.lookup<"u"&&!C&&typeof I.address().address>"u"){let T=u(e.lookup,h,"lookup");a(I,"lookup",T)}if(typeof e.connect<"u"){let T=()=>u(e.connect,h,"connect");C?a(I,"connect",T()):a(I,"lookup",L=>{L===null&&a(I,"connect",T())})}typeof e.secureConnect<"u"&&r.protocol==="https:"&&a(I,"connect",()=>{let T=u(e.secureConnect,h,"secureConnect");a(I,"secureConnect",T)})}if(typeof e.send<"u"){let C=()=>u(e.send,h,"send");I.connecting?a(I,"connect",()=>{a(t,"upload-complete",C())}):a(t,"upload-complete",C())}}),typeof e.response<"u"&&a(t,"upload-complete",()=>{let I=u(e.response,h,"response");a(t,"response",I)}),E}});var xae=_(h4=>{"use strict";Object.defineProperty(h4,"__esModule",{value:!0});var Sae=Tf();h4.default=t=>{t=t;let e={protocol:t.protocol,hostname:Sae.default.string(t.hostname)&&t.hostname.startsWith("[")?t.hostname.slice(1,-1):t.hostname,host:t.host,hash:t.hash,search:t.search,pathname:t.pathname,href:t.href,path:`${t.pathname||""}${t.search||""}`};return Sae.default.string(t.port)&&t.port.length>0&&(e.port=Number(t.port)),(t.username||t.password)&&(e.auth=`${t.username||""}:${t.password||""}`),e}});var bae=_(g4=>{"use strict";Object.defineProperty(g4,"__esModule",{value:!0});var Hit=Be("url"),jit=["protocol","host","hostname","port","pathname","search"];g4.default=(t,e)=>{var r,o;if(e.path){if(e.pathname)throw new TypeError("Parameters `path` and `pathname` are mutually exclusive.");if(e.search)throw new TypeError("Parameters `path` and `search` are mutually exclusive.");if(e.searchParams)throw new TypeError("Parameters `path` and `searchParams` are mutually exclusive.")}if(e.search&&e.searchParams)throw new TypeError("Parameters `search` and `searchParams` are mutually exclusive.");if(!t){if(!e.protocol)throw new TypeError("No URL protocol specified");t=`${e.protocol}//${(o=(r=e.hostname)!==null&&r!==void 0?r:e.host)!==null&&o!==void 0?o:""}`}let a=new Hit.URL(t);if(e.path){let n=e.path.indexOf("?");n===-1?e.pathname=e.path:(e.pathname=e.path.slice(0,n),e.search=e.path.slice(n+1)),delete e.path}for(let n of jit)e[n]&&(a[n]=e[n].toString());return a}});var kae=_(m4=>{"use strict";Object.defineProperty(m4,"__esModule",{value:!0});var d4=class{constructor(){this.weakMap=new WeakMap,this.map=new Map}set(e,r){typeof e=="object"?this.weakMap.set(e,r):this.map.set(e,r)}get(e){return typeof e=="object"?this.weakMap.get(e):this.map.get(e)}has(e){return typeof e=="object"?this.weakMap.has(e):this.map.has(e)}};m4.default=d4});var E4=_(y4=>{"use strict";Object.defineProperty(y4,"__esModule",{value:!0});var qit=async t=>{let e=[],r=0;for await(let o of t)e.push(o),r+=Buffer.byteLength(o);return Buffer.isBuffer(e[0])?Buffer.concat(e,r):Buffer.from(e.join(""))};y4.default=qit});var Fae=_(Pd=>{"use strict";Object.defineProperty(Pd,"__esModule",{value:!0});Pd.dnsLookupIpVersionToFamily=Pd.isDnsLookupIpVersion=void 0;var Qae={auto:0,ipv4:4,ipv6:6};Pd.isDnsLookupIpVersion=t=>t in Qae;Pd.dnsLookupIpVersionToFamily=t=>{if(Pd.isDnsLookupIpVersion(t))return Qae[t];throw new Error("Invalid DNS lookup IP version")}});var C4=_(ox=>{"use strict";Object.defineProperty(ox,"__esModule",{value:!0});ox.isResponseOk=void 0;ox.isResponseOk=t=>{let{statusCode:e}=t,r=t.request.options.followRedirect?299:399;return e>=200&&e<=r||e===304}});var Rae=_(w4=>{"use strict";Object.defineProperty(w4,"__esModule",{value:!0});var Tae=new Set;w4.default=t=>{Tae.has(t)||(Tae.add(t),process.emitWarning(`Got: ${t}`,{type:"DeprecationWarning"}))}});var Nae=_(I4=>{"use strict";Object.defineProperty(I4,"__esModule",{value:!0});var Ai=Tf(),Git=(t,e)=>{if(Ai.default.null_(t.encoding))throw new TypeError("To get a Buffer, set `options.responseType` to `buffer` instead");Ai.assert.any([Ai.default.string,Ai.default.undefined],t.encoding),Ai.assert.any([Ai.default.boolean,Ai.default.undefined],t.resolveBodyOnly),Ai.assert.any([Ai.default.boolean,Ai.default.undefined],t.methodRewriting),Ai.assert.any([Ai.default.boolean,Ai.default.undefined],t.isStream),Ai.assert.any([Ai.default.string,Ai.default.undefined],t.responseType),t.responseType===void 0&&(t.responseType="text");let{retry:r}=t;if(e?t.retry={...e.retry}:t.retry={calculateDelay:o=>o.computedValue,limit:0,methods:[],statusCodes:[],errorCodes:[],maxRetryAfter:void 0},Ai.default.object(r)?(t.retry={...t.retry,...r},t.retry.methods=[...new Set(t.retry.methods.map(o=>o.toUpperCase()))],t.retry.statusCodes=[...new Set(t.retry.statusCodes)],t.retry.errorCodes=[...new Set(t.retry.errorCodes)]):Ai.default.number(r)&&(t.retry.limit=r),Ai.default.undefined(t.retry.maxRetryAfter)&&(t.retry.maxRetryAfter=Math.min(...[t.timeout.request,t.timeout.connect].filter(Ai.default.number))),Ai.default.object(t.pagination)){e&&(t.pagination={...e.pagination,...t.pagination});let{pagination:o}=t;if(!Ai.default.function_(o.transform))throw new Error("`options.pagination.transform` must be implemented");if(!Ai.default.function_(o.shouldContinue))throw new Error("`options.pagination.shouldContinue` must be implemented");if(!Ai.default.function_(o.filter))throw new TypeError("`options.pagination.filter` must be implemented");if(!Ai.default.function_(o.paginate))throw new Error("`options.pagination.paginate` must be implemented")}return t.responseType==="json"&&t.headers.accept===void 0&&(t.headers.accept="application/json"),t};I4.default=Git});var Lae=_(d1=>{"use strict";Object.defineProperty(d1,"__esModule",{value:!0});d1.retryAfterStatusCodes=void 0;d1.retryAfterStatusCodes=new Set([413,429,503]);var Yit=({attemptCount:t,retryOptions:e,error:r,retryAfter:o})=>{if(t>e.limit)return 0;let a=e.methods.includes(r.options.method),n=e.errorCodes.includes(r.code),u=r.response&&e.statusCodes.includes(r.response.statusCode);if(!a||!n&&!u)return 0;if(r.response){if(o)return e.maxRetryAfter===void 0||o>e.maxRetryAfter?0:o;if(r.response.statusCode===413)return 0}let A=Math.random()*100;return 2**(t-1)*1e3+A};d1.default=Yit});var E1=_(Bn=>{"use strict";Object.defineProperty(Bn,"__esModule",{value:!0});Bn.UnsupportedProtocolError=Bn.ReadError=Bn.TimeoutError=Bn.UploadError=Bn.CacheError=Bn.HTTPError=Bn.MaxRedirectsError=Bn.RequestError=Bn.setNonEnumerableProperties=Bn.knownHookEvents=Bn.withoutBody=Bn.kIsNormalizedAlready=void 0;var Mae=Be("util"),Oae=Be("stream"),Wit=Be("fs"),oh=Be("url"),Uae=Be("http"),B4=Be("http"),Vit=Be("https"),Kit=eoe(),Jit=aoe(),_ae=Uoe(),zit=qoe(),Xit=yae(),Zit=tx(),st=Tf(),$it=Bae(),Hae=c4(),est=f4(),jae=Pae(),tst=xae(),qae=bae(),rst=kae(),nst=E4(),Gae=Fae(),ist=C4(),ah=Rae(),sst=Nae(),ost=Lae(),v4,Zs=Symbol("request"),cx=Symbol("response"),PE=Symbol("responseSize"),SE=Symbol("downloadedSize"),xE=Symbol("bodySize"),bE=Symbol("uploadedSize"),ax=Symbol("serverResponsesPiped"),Yae=Symbol("unproxyEvents"),Wae=Symbol("isFromCache"),D4=Symbol("cancelTimeouts"),Vae=Symbol("startedReading"),kE=Symbol("stopReading"),lx=Symbol("triggerRead"),lh=Symbol("body"),m1=Symbol("jobs"),Kae=Symbol("originalResponse"),Jae=Symbol("retryTimeout");Bn.kIsNormalizedAlready=Symbol("isNormalizedAlready");var ast=st.default.string(process.versions.brotli);Bn.withoutBody=new Set(["GET","HEAD"]);Bn.knownHookEvents=["init","beforeRequest","beforeRedirect","beforeError","beforeRetry","afterResponse"];function lst(t){for(let e in t){let r=t[e];if(!st.default.string(r)&&!st.default.number(r)&&!st.default.boolean(r)&&!st.default.null_(r)&&!st.default.undefined(r))throw new TypeError(`The \`searchParams\` value '${String(r)}' must be a string, number, boolean or null`)}}function cst(t){return st.default.object(t)&&!("statusCode"in t)}var P4=new rst.default,ust=async t=>new Promise((e,r)=>{let o=a=>{r(a)};t.pending||e(),t.once("error",o),t.once("ready",()=>{t.off("error",o),e()})}),Ast=new Set([300,301,302,303,304,307,308]),fst=["context","body","json","form"];Bn.setNonEnumerableProperties=(t,e)=>{let r={};for(let o of t)if(!!o)for(let a of fst)a in o&&(r[a]={writable:!0,configurable:!0,enumerable:!1,value:o[a]});Object.defineProperties(e,r)};var Ki=class extends Error{constructor(e,r,o){var a;if(super(e),Error.captureStackTrace(this,this.constructor),this.name="RequestError",this.code=r.code,o instanceof dx?(Object.defineProperty(this,"request",{enumerable:!1,value:o}),Object.defineProperty(this,"response",{enumerable:!1,value:o[cx]}),Object.defineProperty(this,"options",{enumerable:!1,value:o.options})):Object.defineProperty(this,"options",{enumerable:!1,value:o}),this.timings=(a=this.request)===null||a===void 0?void 0:a.timings,st.default.string(r.stack)&&st.default.string(this.stack)){let n=this.stack.indexOf(this.message)+this.message.length,u=this.stack.slice(n).split(` +`).reverse(),A=r.stack.slice(r.stack.indexOf(r.message)+r.message.length).split(` +`).reverse();for(;A.length!==0&&A[0]===u[0];)u.shift();this.stack=`${this.stack.slice(0,n)}${u.reverse().join(` +`)}${A.reverse().join(` +`)}`}}};Bn.RequestError=Ki;var ux=class extends Ki{constructor(e){super(`Redirected ${e.options.maxRedirects} times. Aborting.`,{},e),this.name="MaxRedirectsError"}};Bn.MaxRedirectsError=ux;var Ax=class extends Ki{constructor(e){super(`Response code ${e.statusCode} (${e.statusMessage})`,{},e.request),this.name="HTTPError"}};Bn.HTTPError=Ax;var fx=class extends Ki{constructor(e,r){super(e.message,e,r),this.name="CacheError"}};Bn.CacheError=fx;var px=class extends Ki{constructor(e,r){super(e.message,e,r),this.name="UploadError"}};Bn.UploadError=px;var hx=class extends Ki{constructor(e,r,o){super(e.message,e,o),this.name="TimeoutError",this.event=e.event,this.timings=r}};Bn.TimeoutError=hx;var y1=class extends Ki{constructor(e,r){super(e.message,e,r),this.name="ReadError"}};Bn.ReadError=y1;var gx=class extends Ki{constructor(e){super(`Unsupported protocol "${e.url.protocol}"`,{},e),this.name="UnsupportedProtocolError"}};Bn.UnsupportedProtocolError=gx;var pst=["socket","connect","continue","information","upgrade","timeout"],dx=class extends Oae.Duplex{constructor(e,r={},o){super({autoDestroy:!1,highWaterMark:0}),this[SE]=0,this[bE]=0,this.requestInitialized=!1,this[ax]=new Set,this.redirects=[],this[kE]=!1,this[lx]=!1,this[m1]=[],this.retryCount=0,this._progressCallbacks=[];let a=()=>this._unlockWrite(),n=()=>this._lockWrite();this.on("pipe",h=>{h.prependListener("data",a),h.on("data",n),h.prependListener("end",a),h.on("end",n)}),this.on("unpipe",h=>{h.off("data",a),h.off("data",n),h.off("end",a),h.off("end",n)}),this.on("pipe",h=>{h instanceof B4.IncomingMessage&&(this.options.headers={...h.headers,...this.options.headers})});let{json:u,body:A,form:p}=r;if((u||A||p)&&this._lockWrite(),Bn.kIsNormalizedAlready in r)this.options=r;else try{this.options=this.constructor.normalizeArguments(e,r,o)}catch(h){st.default.nodeStream(r.body)&&r.body.destroy(),this.destroy(h);return}(async()=>{var h;try{this.options.body instanceof Wit.ReadStream&&await ust(this.options.body);let{url:E}=this.options;if(!E)throw new TypeError("Missing `url` property");if(this.requestUrl=E.toString(),decodeURI(this.requestUrl),await this._finalizeBody(),await this._makeRequest(),this.destroyed){(h=this[Zs])===null||h===void 0||h.destroy();return}for(let I of this[m1])I();this[m1].length=0,this.requestInitialized=!0}catch(E){if(E instanceof Ki){this._beforeError(E);return}this.destroyed||this.destroy(E)}})()}static normalizeArguments(e,r,o){var a,n,u,A,p;let h=r;if(st.default.object(e)&&!st.default.urlInstance(e))r={...o,...e,...r};else{if(e&&r&&r.url!==void 0)throw new TypeError("The `url` option is mutually exclusive with the `input` argument");r={...o,...r},e!==void 0&&(r.url=e),st.default.urlInstance(r.url)&&(r.url=new oh.URL(r.url.toString()))}if(r.cache===!1&&(r.cache=void 0),r.dnsCache===!1&&(r.dnsCache=void 0),st.assert.any([st.default.string,st.default.undefined],r.method),st.assert.any([st.default.object,st.default.undefined],r.headers),st.assert.any([st.default.string,st.default.urlInstance,st.default.undefined],r.prefixUrl),st.assert.any([st.default.object,st.default.undefined],r.cookieJar),st.assert.any([st.default.object,st.default.string,st.default.undefined],r.searchParams),st.assert.any([st.default.object,st.default.string,st.default.undefined],r.cache),st.assert.any([st.default.object,st.default.number,st.default.undefined],r.timeout),st.assert.any([st.default.object,st.default.undefined],r.context),st.assert.any([st.default.object,st.default.undefined],r.hooks),st.assert.any([st.default.boolean,st.default.undefined],r.decompress),st.assert.any([st.default.boolean,st.default.undefined],r.ignoreInvalidCookies),st.assert.any([st.default.boolean,st.default.undefined],r.followRedirect),st.assert.any([st.default.number,st.default.undefined],r.maxRedirects),st.assert.any([st.default.boolean,st.default.undefined],r.throwHttpErrors),st.assert.any([st.default.boolean,st.default.undefined],r.http2),st.assert.any([st.default.boolean,st.default.undefined],r.allowGetBody),st.assert.any([st.default.string,st.default.undefined],r.localAddress),st.assert.any([Gae.isDnsLookupIpVersion,st.default.undefined],r.dnsLookupIpVersion),st.assert.any([st.default.object,st.default.undefined],r.https),st.assert.any([st.default.boolean,st.default.undefined],r.rejectUnauthorized),r.https&&(st.assert.any([st.default.boolean,st.default.undefined],r.https.rejectUnauthorized),st.assert.any([st.default.function_,st.default.undefined],r.https.checkServerIdentity),st.assert.any([st.default.string,st.default.object,st.default.array,st.default.undefined],r.https.certificateAuthority),st.assert.any([st.default.string,st.default.object,st.default.array,st.default.undefined],r.https.key),st.assert.any([st.default.string,st.default.object,st.default.array,st.default.undefined],r.https.certificate),st.assert.any([st.default.string,st.default.undefined],r.https.passphrase),st.assert.any([st.default.string,st.default.buffer,st.default.array,st.default.undefined],r.https.pfx)),st.assert.any([st.default.object,st.default.undefined],r.cacheOptions),st.default.string(r.method)?r.method=r.method.toUpperCase():r.method="GET",r.headers===o?.headers?r.headers={...r.headers}:r.headers=Zit({...o?.headers,...r.headers}),"slashes"in r)throw new TypeError("The legacy `url.Url` has been deprecated. Use `URL` instead.");if("auth"in r)throw new TypeError("Parameter `auth` is deprecated. Use `username` / `password` instead.");if("searchParams"in r&&r.searchParams&&r.searchParams!==o?.searchParams){let b;if(st.default.string(r.searchParams)||r.searchParams instanceof oh.URLSearchParams)b=new oh.URLSearchParams(r.searchParams);else{lst(r.searchParams),b=new oh.URLSearchParams;for(let C in r.searchParams){let T=r.searchParams[C];T===null?b.append(C,""):T!==void 0&&b.append(C,T)}}(a=o?.searchParams)===null||a===void 0||a.forEach((C,T)=>{b.has(T)||b.append(T,C)}),r.searchParams=b}if(r.username=(n=r.username)!==null&&n!==void 0?n:"",r.password=(u=r.password)!==null&&u!==void 0?u:"",st.default.undefined(r.prefixUrl)?r.prefixUrl=(A=o?.prefixUrl)!==null&&A!==void 0?A:"":(r.prefixUrl=r.prefixUrl.toString(),r.prefixUrl!==""&&!r.prefixUrl.endsWith("/")&&(r.prefixUrl+="/")),st.default.string(r.url)){if(r.url.startsWith("/"))throw new Error("`input` must not start with a slash when using `prefixUrl`");r.url=qae.default(r.prefixUrl+r.url,r)}else(st.default.undefined(r.url)&&r.prefixUrl!==""||r.protocol)&&(r.url=qae.default(r.prefixUrl,r));if(r.url){"port"in r&&delete r.port;let{prefixUrl:b}=r;Object.defineProperty(r,"prefixUrl",{set:T=>{let L=r.url;if(!L.href.startsWith(T))throw new Error(`Cannot change \`prefixUrl\` from ${b} to ${T}: ${L.href}`);r.url=new oh.URL(T+L.href.slice(b.length)),b=T},get:()=>b});let{protocol:C}=r.url;if(C==="unix:"&&(C="http:",r.url=new oh.URL(`http://unix${r.url.pathname}${r.url.search}`)),r.searchParams&&(r.url.search=r.searchParams.toString()),C!=="http:"&&C!=="https:")throw new gx(r);r.username===""?r.username=r.url.username:r.url.username=r.username,r.password===""?r.password=r.url.password:r.url.password=r.password}let{cookieJar:E}=r;if(E){let{setCookie:b,getCookieString:C}=E;st.assert.function_(b),st.assert.function_(C),b.length===4&&C.length===0&&(b=Mae.promisify(b.bind(r.cookieJar)),C=Mae.promisify(C.bind(r.cookieJar)),r.cookieJar={setCookie:b,getCookieString:C})}let{cache:I}=r;if(I&&(P4.has(I)||P4.set(I,new _ae((b,C)=>{let T=b[Zs](b,C);return st.default.promise(T)&&(T.once=(L,U)=>{if(L==="error")T.catch(U);else if(L==="abort")(async()=>{try{(await T).once("abort",U)}catch{}})();else throw new Error(`Unknown HTTP2 promise event: ${L}`);return T}),T},I))),r.cacheOptions={...r.cacheOptions},r.dnsCache===!0)v4||(v4=new Jit.default),r.dnsCache=v4;else if(!st.default.undefined(r.dnsCache)&&!r.dnsCache.lookup)throw new TypeError(`Parameter \`dnsCache\` must be a CacheableLookup instance or a boolean, got ${st.default(r.dnsCache)}`);st.default.number(r.timeout)?r.timeout={request:r.timeout}:o&&r.timeout!==o.timeout?r.timeout={...o.timeout,...r.timeout}:r.timeout={...r.timeout},r.context||(r.context={});let v=r.hooks===o?.hooks;r.hooks={...r.hooks};for(let b of Bn.knownHookEvents)if(b in r.hooks)if(st.default.array(r.hooks[b]))r.hooks[b]=[...r.hooks[b]];else throw new TypeError(`Parameter \`${b}\` must be an Array, got ${st.default(r.hooks[b])}`);else r.hooks[b]=[];if(o&&!v)for(let b of Bn.knownHookEvents)o.hooks[b].length>0&&(r.hooks[b]=[...o.hooks[b],...r.hooks[b]]);if("family"in r&&ah.default('"options.family" was never documented, please use "options.dnsLookupIpVersion"'),o?.https&&(r.https={...o.https,...r.https}),"rejectUnauthorized"in r&&ah.default('"options.rejectUnauthorized" is now deprecated, please use "options.https.rejectUnauthorized"'),"checkServerIdentity"in r&&ah.default('"options.checkServerIdentity" was never documented, please use "options.https.checkServerIdentity"'),"ca"in r&&ah.default('"options.ca" was never documented, please use "options.https.certificateAuthority"'),"key"in r&&ah.default('"options.key" was never documented, please use "options.https.key"'),"cert"in r&&ah.default('"options.cert" was never documented, please use "options.https.certificate"'),"passphrase"in r&&ah.default('"options.passphrase" was never documented, please use "options.https.passphrase"'),"pfx"in r&&ah.default('"options.pfx" was never documented, please use "options.https.pfx"'),"followRedirects"in r)throw new TypeError("The `followRedirects` option does not exist. Use `followRedirect` instead.");if(r.agent){for(let b in r.agent)if(b!=="http"&&b!=="https"&&b!=="http2")throw new TypeError(`Expected the \`options.agent\` properties to be \`http\`, \`https\` or \`http2\`, got \`${b}\``)}return r.maxRedirects=(p=r.maxRedirects)!==null&&p!==void 0?p:0,Bn.setNonEnumerableProperties([o,h],r),sst.default(r,o)}_lockWrite(){let e=()=>{throw new TypeError("The payload has been already provided")};this.write=e,this.end=e}_unlockWrite(){this.write=super.write,this.end=super.end}async _finalizeBody(){let{options:e}=this,{headers:r}=e,o=!st.default.undefined(e.form),a=!st.default.undefined(e.json),n=!st.default.undefined(e.body),u=o||a||n,A=Bn.withoutBody.has(e.method)&&!(e.method==="GET"&&e.allowGetBody);if(this._cannotHaveBody=A,u){if(A)throw new TypeError(`The \`${e.method}\` method cannot be used with a body`);if([n,o,a].filter(p=>p).length>1)throw new TypeError("The `body`, `json` and `form` options are mutually exclusive");if(n&&!(e.body instanceof Oae.Readable)&&!st.default.string(e.body)&&!st.default.buffer(e.body)&&!Hae.default(e.body))throw new TypeError("The `body` option must be a stream.Readable, string or Buffer");if(o&&!st.default.object(e.form))throw new TypeError("The `form` option must be an Object");{let p=!st.default.string(r["content-type"]);n?(Hae.default(e.body)&&p&&(r["content-type"]=`multipart/form-data; boundary=${e.body.getBoundary()}`),this[lh]=e.body):o?(p&&(r["content-type"]="application/x-www-form-urlencoded"),this[lh]=new oh.URLSearchParams(e.form).toString()):(p&&(r["content-type"]="application/json"),this[lh]=e.stringifyJson(e.json));let h=await $it.default(this[lh],e.headers);st.default.undefined(r["content-length"])&&st.default.undefined(r["transfer-encoding"])&&!A&&!st.default.undefined(h)&&(r["content-length"]=String(h))}}else A?this._lockWrite():this._unlockWrite();this[xE]=Number(r["content-length"])||void 0}async _onResponseBase(e){let{options:r}=this,{url:o}=r;this[Kae]=e,r.decompress&&(e=zit(e));let a=e.statusCode,n=e;n.statusMessage=n.statusMessage?n.statusMessage:Uae.STATUS_CODES[a],n.url=r.url.toString(),n.requestUrl=this.requestUrl,n.redirectUrls=this.redirects,n.request=this,n.isFromCache=e.fromCache||!1,n.ip=this.ip,n.retryCount=this.retryCount,this[Wae]=n.isFromCache,this[PE]=Number(e.headers["content-length"])||void 0,this[cx]=e,e.once("end",()=>{this[PE]=this[SE],this.emit("downloadProgress",this.downloadProgress)}),e.once("error",A=>{e.destroy(),this._beforeError(new y1(A,this))}),e.once("aborted",()=>{this._beforeError(new y1({name:"Error",message:"The server aborted pending request",code:"ECONNRESET"},this))}),this.emit("downloadProgress",this.downloadProgress);let u=e.headers["set-cookie"];if(st.default.object(r.cookieJar)&&u){let A=u.map(async p=>r.cookieJar.setCookie(p,o.toString()));r.ignoreInvalidCookies&&(A=A.map(async p=>p.catch(()=>{})));try{await Promise.all(A)}catch(p){this._beforeError(p);return}}if(r.followRedirect&&e.headers.location&&Ast.has(a)){if(e.resume(),this[Zs]&&(this[D4](),delete this[Zs],this[Yae]()),(a===303&&r.method!=="GET"&&r.method!=="HEAD"||!r.methodRewriting)&&(r.method="GET","body"in r&&delete r.body,"json"in r&&delete r.json,"form"in r&&delete r.form,this[lh]=void 0,delete r.headers["content-length"]),this.redirects.length>=r.maxRedirects){this._beforeError(new ux(this));return}try{let p=Buffer.from(e.headers.location,"binary").toString(),h=new oh.URL(p,o),E=h.toString();decodeURI(E),h.hostname!==o.hostname||h.port!==o.port?("host"in r.headers&&delete r.headers.host,"cookie"in r.headers&&delete r.headers.cookie,"authorization"in r.headers&&delete r.headers.authorization,(r.username||r.password)&&(r.username="",r.password="")):(h.username=r.username,h.password=r.password),this.redirects.push(E),r.url=h;for(let I of r.hooks.beforeRedirect)await I(r,n);this.emit("redirect",n,r),await this._makeRequest()}catch(p){this._beforeError(p);return}return}if(r.isStream&&r.throwHttpErrors&&!ist.isResponseOk(n)){this._beforeError(new Ax(n));return}e.on("readable",()=>{this[lx]&&this._read()}),this.on("resume",()=>{e.resume()}),this.on("pause",()=>{e.pause()}),e.once("end",()=>{this.push(null)}),this.emit("response",e);for(let A of this[ax])if(!A.headersSent){for(let p in e.headers){let h=r.decompress?p!=="content-encoding":!0,E=e.headers[p];h&&A.setHeader(p,E)}A.statusCode=a}}async _onResponse(e){try{await this._onResponseBase(e)}catch(r){this._beforeError(r)}}_onRequest(e){let{options:r}=this,{timeout:o,url:a}=r;Kit.default(e),this[D4]=jae.default(e,o,a);let n=r.cache?"cacheableResponse":"response";e.once(n,p=>{this._onResponse(p)}),e.once("error",p=>{var h;e.destroy(),(h=e.res)===null||h===void 0||h.removeAllListeners("end"),p=p instanceof jae.TimeoutError?new hx(p,this.timings,this):new Ki(p.message,p,this),this._beforeError(p)}),this[Yae]=est.default(e,this,pst),this[Zs]=e,this.emit("uploadProgress",this.uploadProgress);let u=this[lh],A=this.redirects.length===0?this:e;st.default.nodeStream(u)?(u.pipe(A),u.once("error",p=>{this._beforeError(new px(p,this))})):(this._unlockWrite(),st.default.undefined(u)?(this._cannotHaveBody||this._noPipe)&&(A.end(),this._lockWrite()):(this._writeRequest(u,void 0,()=>{}),A.end(),this._lockWrite())),this.emit("request",e)}async _createCacheableRequest(e,r){return new Promise((o,a)=>{Object.assign(r,tst.default(e)),delete r.url;let n,u=P4.get(r.cache)(r,async A=>{A._readableState.autoDestroy=!1,n&&(await n).emit("cacheableResponse",A),o(A)});r.url=e,u.once("error",a),u.once("request",async A=>{n=A,o(n)})})}async _makeRequest(){var e,r,o,a,n;let{options:u}=this,{headers:A}=u;for(let U in A)if(st.default.undefined(A[U]))delete A[U];else if(st.default.null_(A[U]))throw new TypeError(`Use \`undefined\` instead of \`null\` to delete the \`${U}\` header`);if(u.decompress&&st.default.undefined(A["accept-encoding"])&&(A["accept-encoding"]=ast?"gzip, deflate, br":"gzip, deflate"),u.cookieJar){let U=await u.cookieJar.getCookieString(u.url.toString());st.default.nonEmptyString(U)&&(u.headers.cookie=U)}for(let U of u.hooks.beforeRequest){let J=await U(u);if(!st.default.undefined(J)){u.request=()=>J;break}}u.body&&this[lh]!==u.body&&(this[lh]=u.body);let{agent:p,request:h,timeout:E,url:I}=u;if(u.dnsCache&&!("lookup"in u)&&(u.lookup=u.dnsCache.lookup),I.hostname==="unix"){let U=/(?<socketPath>.+?):(?<path>.+)/.exec(`${I.pathname}${I.search}`);if(U?.groups){let{socketPath:J,path:te}=U.groups;Object.assign(u,{socketPath:J,path:te,host:""})}}let v=I.protocol==="https:",b;u.http2?b=Xit.auto:b=v?Vit.request:Uae.request;let C=(e=u.request)!==null&&e!==void 0?e:b,T=u.cache?this._createCacheableRequest:C;p&&!u.http2&&(u.agent=p[v?"https":"http"]),u[Zs]=C,delete u.request,delete u.timeout;let L=u;if(L.shared=(r=u.cacheOptions)===null||r===void 0?void 0:r.shared,L.cacheHeuristic=(o=u.cacheOptions)===null||o===void 0?void 0:o.cacheHeuristic,L.immutableMinTimeToLive=(a=u.cacheOptions)===null||a===void 0?void 0:a.immutableMinTimeToLive,L.ignoreCargoCult=(n=u.cacheOptions)===null||n===void 0?void 0:n.ignoreCargoCult,u.dnsLookupIpVersion!==void 0)try{L.family=Gae.dnsLookupIpVersionToFamily(u.dnsLookupIpVersion)}catch{throw new Error("Invalid `dnsLookupIpVersion` option value")}u.https&&("rejectUnauthorized"in u.https&&(L.rejectUnauthorized=u.https.rejectUnauthorized),u.https.checkServerIdentity&&(L.checkServerIdentity=u.https.checkServerIdentity),u.https.certificateAuthority&&(L.ca=u.https.certificateAuthority),u.https.certificate&&(L.cert=u.https.certificate),u.https.key&&(L.key=u.https.key),u.https.passphrase&&(L.passphrase=u.https.passphrase),u.https.pfx&&(L.pfx=u.https.pfx));try{let U=await T(I,L);st.default.undefined(U)&&(U=b(I,L)),u.request=h,u.timeout=E,u.agent=p,u.https&&("rejectUnauthorized"in u.https&&delete L.rejectUnauthorized,u.https.checkServerIdentity&&delete L.checkServerIdentity,u.https.certificateAuthority&&delete L.ca,u.https.certificate&&delete L.cert,u.https.key&&delete L.key,u.https.passphrase&&delete L.passphrase,u.https.pfx&&delete L.pfx),cst(U)?this._onRequest(U):this.writable?(this.once("finish",()=>{this._onResponse(U)}),this._unlockWrite(),this.end(),this._lockWrite()):this._onResponse(U)}catch(U){throw U instanceof _ae.CacheError?new fx(U,this):new Ki(U.message,U,this)}}async _error(e){try{for(let r of this.options.hooks.beforeError)e=await r(e)}catch(r){e=new Ki(r.message,r,this)}this.destroy(e)}_beforeError(e){if(this[kE])return;let{options:r}=this,o=this.retryCount+1;this[kE]=!0,e instanceof Ki||(e=new Ki(e.message,e,this));let a=e,{response:n}=a;(async()=>{if(n&&!n.body){n.setEncoding(this._readableState.encoding);try{n.rawBody=await nst.default(n),n.body=n.rawBody.toString()}catch{}}if(this.listenerCount("retry")!==0){let u;try{let A;n&&"retry-after"in n.headers&&(A=Number(n.headers["retry-after"]),Number.isNaN(A)?(A=Date.parse(n.headers["retry-after"])-Date.now(),A<=0&&(A=1)):A*=1e3),u=await r.retry.calculateDelay({attemptCount:o,retryOptions:r.retry,error:a,retryAfter:A,computedValue:ost.default({attemptCount:o,retryOptions:r.retry,error:a,retryAfter:A,computedValue:0})})}catch(A){this._error(new Ki(A.message,A,this));return}if(u){let A=async()=>{try{for(let p of this.options.hooks.beforeRetry)await p(this.options,a,o)}catch(p){this._error(new Ki(p.message,e,this));return}this.destroyed||(this.destroy(),this.emit("retry",o,e))};this[Jae]=setTimeout(A,u);return}}this._error(a)})()}_read(){this[lx]=!0;let e=this[cx];if(e&&!this[kE]){e.readableLength&&(this[lx]=!1);let r;for(;(r=e.read())!==null;){this[SE]+=r.length,this[Vae]=!0;let o=this.downloadProgress;o.percent<1&&this.emit("downloadProgress",o),this.push(r)}}}_write(e,r,o){let a=()=>{this._writeRequest(e,r,o)};this.requestInitialized?a():this[m1].push(a)}_writeRequest(e,r,o){this[Zs].destroyed||(this._progressCallbacks.push(()=>{this[bE]+=Buffer.byteLength(e,r);let a=this.uploadProgress;a.percent<1&&this.emit("uploadProgress",a)}),this[Zs].write(e,r,a=>{!a&&this._progressCallbacks.length>0&&this._progressCallbacks.shift()(),o(a)}))}_final(e){let r=()=>{for(;this._progressCallbacks.length!==0;)this._progressCallbacks.shift()();if(!(Zs in this)){e();return}if(this[Zs].destroyed){e();return}this[Zs].end(o=>{o||(this[xE]=this[bE],this.emit("uploadProgress",this.uploadProgress),this[Zs].emit("upload-complete")),e(o)})};this.requestInitialized?r():this[m1].push(r)}_destroy(e,r){var o;this[kE]=!0,clearTimeout(this[Jae]),Zs in this&&(this[D4](),!((o=this[cx])===null||o===void 0)&&o.complete||this[Zs].destroy()),e!==null&&!st.default.undefined(e)&&!(e instanceof Ki)&&(e=new Ki(e.message,e,this)),r(e)}get _isAboutToError(){return this[kE]}get ip(){var e;return(e=this.socket)===null||e===void 0?void 0:e.remoteAddress}get aborted(){var e,r,o;return((r=(e=this[Zs])===null||e===void 0?void 0:e.destroyed)!==null&&r!==void 0?r:this.destroyed)&&!(!((o=this[Kae])===null||o===void 0)&&o.complete)}get socket(){var e,r;return(r=(e=this[Zs])===null||e===void 0?void 0:e.socket)!==null&&r!==void 0?r:void 0}get downloadProgress(){let e;return this[PE]?e=this[SE]/this[PE]:this[PE]===this[SE]?e=1:e=0,{percent:e,transferred:this[SE],total:this[PE]}}get uploadProgress(){let e;return this[xE]?e=this[bE]/this[xE]:this[xE]===this[bE]?e=1:e=0,{percent:e,transferred:this[bE],total:this[xE]}}get timings(){var e;return(e=this[Zs])===null||e===void 0?void 0:e.timings}get isFromCache(){return this[Wae]}pipe(e,r){if(this[Vae])throw new Error("Failed to pipe. The response has been emitted already.");return e instanceof B4.ServerResponse&&this[ax].add(e),super.pipe(e,r)}unpipe(e){return e instanceof B4.ServerResponse&&this[ax].delete(e),super.unpipe(e),this}};Bn.default=dx});var C1=_(qc=>{"use strict";var hst=qc&&qc.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),gst=qc&&qc.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&hst(e,t,r)};Object.defineProperty(qc,"__esModule",{value:!0});qc.CancelError=qc.ParseError=void 0;var zae=E1(),S4=class extends zae.RequestError{constructor(e,r){let{options:o}=r.request;super(`${e.message} in "${o.url.toString()}"`,e,r.request),this.name="ParseError"}};qc.ParseError=S4;var x4=class extends zae.RequestError{constructor(e){super("Promise was canceled",{},e),this.name="CancelError"}get isCanceled(){return!0}};qc.CancelError=x4;gst(E1(),qc)});var Zae=_(b4=>{"use strict";Object.defineProperty(b4,"__esModule",{value:!0});var Xae=C1(),dst=(t,e,r,o)=>{let{rawBody:a}=t;try{if(e==="text")return a.toString(o);if(e==="json")return a.length===0?"":r(a.toString());if(e==="buffer")return a;throw new Xae.ParseError({message:`Unknown body type '${e}'`,name:"Error"},t)}catch(n){throw new Xae.ParseError(n,t)}};b4.default=dst});var k4=_(ch=>{"use strict";var mst=ch&&ch.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),yst=ch&&ch.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&mst(e,t,r)};Object.defineProperty(ch,"__esModule",{value:!0});var Est=Be("events"),Cst=Tf(),wst=Zse(),mx=C1(),$ae=Zae(),ele=E1(),Ist=f4(),Bst=E4(),tle=C4(),vst=["request","response","redirect","uploadProgress","downloadProgress"];function rle(t){let e,r,o=new Est.EventEmitter,a=new wst((u,A,p)=>{let h=E=>{let I=new ele.default(void 0,t);I.retryCount=E,I._noPipe=!0,p(()=>I.destroy()),p.shouldReject=!1,p(()=>A(new mx.CancelError(I))),e=I,I.once("response",async C=>{var T;if(C.retryCount=E,C.request.aborted)return;let L;try{L=await Bst.default(I),C.rawBody=L}catch{return}if(I._isAboutToError)return;let U=((T=C.headers["content-encoding"])!==null&&T!==void 0?T:"").toLowerCase(),J=["gzip","deflate","br"].includes(U),{options:te}=I;if(J&&!te.decompress)C.body=L;else try{C.body=$ae.default(C,te.responseType,te.parseJson,te.encoding)}catch(le){if(C.body=L.toString(),tle.isResponseOk(C)){I._beforeError(le);return}}try{for(let[le,pe]of te.hooks.afterResponse.entries())C=await pe(C,async Ae=>{let ye=ele.default.normalizeArguments(void 0,{...Ae,retry:{calculateDelay:()=>0},throwHttpErrors:!1,resolveBodyOnly:!1},te);ye.hooks.afterResponse=ye.hooks.afterResponse.slice(0,le);for(let we of ye.hooks.beforeRetry)await we(ye);let ae=rle(ye);return p(()=>{ae.catch(()=>{}),ae.cancel()}),ae})}catch(le){I._beforeError(new mx.RequestError(le.message,le,I));return}if(!tle.isResponseOk(C)){I._beforeError(new mx.HTTPError(C));return}r=C,u(I.options.resolveBodyOnly?C.body:C)});let v=C=>{if(a.isCanceled)return;let{options:T}=I;if(C instanceof mx.HTTPError&&!T.throwHttpErrors){let{response:L}=C;u(I.options.resolveBodyOnly?L.body:L);return}A(C)};I.once("error",v);let b=I.options.body;I.once("retry",(C,T)=>{var L,U;if(b===((L=T.request)===null||L===void 0?void 0:L.options.body)&&Cst.default.nodeStream((U=T.request)===null||U===void 0?void 0:U.options.body)){v(T);return}h(C)}),Ist.default(I,o,vst)};h(0)});a.on=(u,A)=>(o.on(u,A),a);let n=u=>{let A=(async()=>{await a;let{options:p}=r.request;return $ae.default(r,u,p.parseJson,p.encoding)})();return Object.defineProperties(A,Object.getOwnPropertyDescriptors(a)),A};return a.json=()=>{let{headers:u}=e.options;return!e.writableFinished&&u.accept===void 0&&(u.accept="application/json"),n("json")},a.buffer=()=>n("buffer"),a.text=()=>n("text"),a}ch.default=rle;yst(C1(),ch)});var nle=_(Q4=>{"use strict";Object.defineProperty(Q4,"__esModule",{value:!0});var Dst=C1();function Pst(t,...e){let r=(async()=>{if(t instanceof Dst.RequestError)try{for(let a of e)if(a)for(let n of a)t=await n(t)}catch(a){t=a}throw t})(),o=()=>r;return r.json=o,r.text=o,r.buffer=o,r.on=o,r}Q4.default=Pst});var ole=_(F4=>{"use strict";Object.defineProperty(F4,"__esModule",{value:!0});var ile=Tf();function sle(t){for(let e of Object.values(t))(ile.default.plainObject(e)||ile.default.array(e))&&sle(e);return Object.freeze(t)}F4.default=sle});var lle=_(ale=>{"use strict";Object.defineProperty(ale,"__esModule",{value:!0})});var T4=_(Kl=>{"use strict";var Sst=Kl&&Kl.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),xst=Kl&&Kl.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Sst(e,t,r)};Object.defineProperty(Kl,"__esModule",{value:!0});Kl.defaultHandler=void 0;var cle=Tf(),Vl=k4(),bst=nle(),Ex=E1(),kst=ole(),Qst={RequestError:Vl.RequestError,CacheError:Vl.CacheError,ReadError:Vl.ReadError,HTTPError:Vl.HTTPError,MaxRedirectsError:Vl.MaxRedirectsError,TimeoutError:Vl.TimeoutError,ParseError:Vl.ParseError,CancelError:Vl.CancelError,UnsupportedProtocolError:Vl.UnsupportedProtocolError,UploadError:Vl.UploadError},Fst=async t=>new Promise(e=>{setTimeout(e,t)}),{normalizeArguments:yx}=Ex.default,ule=(...t)=>{let e;for(let r of t)e=yx(void 0,r,e);return e},Tst=t=>t.isStream?new Ex.default(void 0,t):Vl.default(t),Rst=t=>"defaults"in t&&"options"in t.defaults,Nst=["get","post","put","patch","head","delete"];Kl.defaultHandler=(t,e)=>e(t);var Ale=(t,e)=>{if(t)for(let r of t)r(e)},fle=t=>{t._rawHandlers=t.handlers,t.handlers=t.handlers.map(o=>(a,n)=>{let u,A=o(a,p=>(u=n(p),u));if(A!==u&&!a.isStream&&u){let p=A,{then:h,catch:E,finally:I}=p;Object.setPrototypeOf(p,Object.getPrototypeOf(u)),Object.defineProperties(p,Object.getOwnPropertyDescriptors(u)),p.then=h,p.catch=E,p.finally=I}return A});let e=(o,a={},n)=>{var u,A;let p=0,h=E=>t.handlers[p++](E,p===t.handlers.length?Tst:h);if(cle.default.plainObject(o)){let E={...o,...a};Ex.setNonEnumerableProperties([o,a],E),a=E,o=void 0}try{let E;try{Ale(t.options.hooks.init,a),Ale((u=a.hooks)===null||u===void 0?void 0:u.init,a)}catch(v){E=v}let I=yx(o,a,n??t.options);if(I[Ex.kIsNormalizedAlready]=!0,E)throw new Vl.RequestError(E.message,E,I);return h(I)}catch(E){if(a.isStream)throw E;return bst.default(E,t.options.hooks.beforeError,(A=a.hooks)===null||A===void 0?void 0:A.beforeError)}};e.extend=(...o)=>{let a=[t.options],n=[...t._rawHandlers],u;for(let A of o)Rst(A)?(a.push(A.defaults.options),n.push(...A.defaults._rawHandlers),u=A.defaults.mutableDefaults):(a.push(A),"handlers"in A&&n.push(...A.handlers),u=A.mutableDefaults);return n=n.filter(A=>A!==Kl.defaultHandler),n.length===0&&n.push(Kl.defaultHandler),fle({options:ule(...a),handlers:n,mutableDefaults:Boolean(u)})};let r=async function*(o,a){let n=yx(o,a,t.options);n.resolveBodyOnly=!1;let u=n.pagination;if(!cle.default.object(u))throw new TypeError("`options.pagination` must be implemented");let A=[],{countLimit:p}=u,h=0;for(;h<u.requestLimit;){h!==0&&await Fst(u.backoff);let E=await e(void 0,void 0,n),I=await u.transform(E),v=[];for(let C of I)if(u.filter(C,A,v)&&(!u.shouldContinue(C,A,v)||(yield C,u.stackAllItems&&A.push(C),v.push(C),--p<=0)))return;let b=u.paginate(E,A,v);if(b===!1)return;b===E.request.options?n=E.request.options:b!==void 0&&(n=yx(void 0,b,n)),h++}};e.paginate=r,e.paginate.all=async(o,a)=>{let n=[];for await(let u of r(o,a))n.push(u);return n},e.paginate.each=r,e.stream=(o,a)=>e(o,{...a,isStream:!0});for(let o of Nst)e[o]=(a,n)=>e(a,{...n,method:o}),e.stream[o]=(a,n)=>e(a,{...n,method:o,isStream:!0});return Object.assign(e,Qst),Object.defineProperty(e,"defaults",{value:t.mutableDefaults?t:kst.default(t),writable:t.mutableDefaults,configurable:t.mutableDefaults,enumerable:!0}),e.mergeOptions=ule,e};Kl.default=fle;xst(lle(),Kl)});var gle=_((Rf,Cx)=>{"use strict";var Lst=Rf&&Rf.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),ple=Rf&&Rf.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&Lst(e,t,r)};Object.defineProperty(Rf,"__esModule",{value:!0});var Mst=Be("url"),hle=T4(),Ost={options:{method:"GET",retry:{limit:2,methods:["GET","PUT","HEAD","DELETE","OPTIONS","TRACE"],statusCodes:[408,413,429,500,502,503,504,521,522,524],errorCodes:["ETIMEDOUT","ECONNRESET","EADDRINUSE","ECONNREFUSED","EPIPE","ENOTFOUND","ENETUNREACH","EAI_AGAIN"],maxRetryAfter:void 0,calculateDelay:({computedValue:t})=>t},timeout:{},headers:{"user-agent":"got (https://github.com/sindresorhus/got)"},hooks:{init:[],beforeRequest:[],beforeRedirect:[],beforeRetry:[],beforeError:[],afterResponse:[]},cache:void 0,dnsCache:void 0,decompress:!0,throwHttpErrors:!0,followRedirect:!0,isStream:!1,responseType:"text",resolveBodyOnly:!1,maxRedirects:10,prefixUrl:"",methodRewriting:!0,ignoreInvalidCookies:!1,context:{},http2:!1,allowGetBody:!1,https:void 0,pagination:{transform:t=>t.request.options.responseType==="json"?t.body:JSON.parse(t.body),paginate:t=>{if(!Reflect.has(t.headers,"link"))return!1;let e=t.headers.link.split(","),r;for(let o of e){let a=o.split(";");if(a[1].includes("next")){r=a[0].trimStart().trim(),r=r.slice(1,-1);break}}return r?{url:new Mst.URL(r)}:!1},filter:()=>!0,shouldContinue:()=>!0,countLimit:1/0,backoff:0,requestLimit:1e4,stackAllItems:!0},parseJson:t=>JSON.parse(t),stringifyJson:t=>JSON.stringify(t),cacheOptions:{}},handlers:[hle.defaultHandler],mutableDefaults:!1},R4=hle.default(Ost);Rf.default=R4;Cx.exports=R4;Cx.exports.default=R4;Cx.exports.__esModule=!0;ple(T4(),Rf);ple(k4(),Rf)});var rn={};Kt(rn,{Method:()=>Ile,del:()=>qst,get:()=>O4,getNetworkSettings:()=>wle,post:()=>U4,put:()=>jst,request:()=>w1});function yle(t){let e=new wx.URL(t),r={host:e.hostname,headers:{}};return e.port&&(r.port=Number(e.port)),e.username&&e.password&&(r.proxyAuth=`${e.username}:${e.password}`),{proxy:r}}async function N4(t){return ol(mle,t,()=>oe.readFilePromise(t).then(e=>(mle.set(t,e),e)))}function Hst({statusCode:t,statusMessage:e},r){let o=Ot(r,t,yt.NUMBER),a=`https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/${t}`;return Xy(r,`${o}${e?` (${e})`:""}`,a)}async function Ix(t,{configuration:e,customErrorMessage:r}){try{return await t}catch(o){if(o.name!=="HTTPError")throw o;let a=r?.(o,e)??o.response.body?.error;a==null&&(o.message.startsWith("Response code")?a="The remote server failed to provide the requested resource":a=o.message),o.code==="ETIMEDOUT"&&o.event==="socket"&&(a+=`(can be increased via ${Ot(e,"httpTimeout",yt.SETTING)})`);let n=new zt(35,a,u=>{o.response&&u.reportError(35,` ${zu(e,{label:"Response Code",value:_c(yt.NO_HINT,Hst(o.response,e))})}`),o.request&&(u.reportError(35,` ${zu(e,{label:"Request Method",value:_c(yt.NO_HINT,o.request.options.method)})}`),u.reportError(35,` ${zu(e,{label:"Request URL",value:_c(yt.URL,o.request.requestUrl)})}`)),o.request.redirects.length>0&&u.reportError(35,` ${zu(e,{label:"Request Redirects",value:_c(yt.NO_HINT,bL(e,o.request.redirects,yt.URL))})}`),o.request.retryCount===o.request.options.retry.limit&&u.reportError(35,` ${zu(e,{label:"Request Retry Count",value:_c(yt.NO_HINT,`${Ot(e,o.request.retryCount,yt.NUMBER)} (can be increased via ${Ot(e,"httpRetry",yt.SETTING)})`)})}`)});throw n.originalError=o,n}}function wle(t,e){let r=[...e.configuration.get("networkSettings")].sort(([u],[A])=>A.length-u.length),o={enableNetwork:void 0,httpsCaFilePath:void 0,httpProxy:void 0,httpsProxy:void 0,httpsKeyFilePath:void 0,httpsCertFilePath:void 0},a=Object.keys(o),n=typeof t=="string"?new wx.URL(t):t;for(let[u,A]of r)if(M4.default.isMatch(n.hostname,u))for(let p of a){let h=A.get(p);h!==null&&typeof o[p]>"u"&&(o[p]=h)}for(let u of a)typeof o[u]>"u"&&(o[u]=e.configuration.get(u));return o}async function w1(t,e,{configuration:r,headers:o,jsonRequest:a,jsonResponse:n,method:u="GET",wrapNetworkRequest:A}){let p={target:t,body:e,configuration:r,headers:o,jsonRequest:a,jsonResponse:n,method:u},h=async()=>await Gst(t,e,p),E=typeof A<"u"?await A(h,p):h;return await(await r.reduceHook(v=>v.wrapNetworkRequest,E,p))()}async function O4(t,{configuration:e,jsonResponse:r,customErrorMessage:o,wrapNetworkRequest:a,...n}){let u=()=>Ix(w1(t,null,{configuration:e,wrapNetworkRequest:a,...n}),{configuration:e,customErrorMessage:o}).then(p=>p.body),A=await(typeof a<"u"?u():ol(dle,t,()=>u().then(p=>(dle.set(t,p),p))));return r?JSON.parse(A.toString()):A}async function jst(t,e,{customErrorMessage:r,...o}){return(await Ix(w1(t,e,{...o,method:"PUT"}),{customErrorMessage:r,configuration:o.configuration})).body}async function U4(t,e,{customErrorMessage:r,...o}){return(await Ix(w1(t,e,{...o,method:"POST"}),{customErrorMessage:r,configuration:o.configuration})).body}async function qst(t,{customErrorMessage:e,...r}){return(await Ix(w1(t,null,{...r,method:"DELETE"}),{customErrorMessage:e,configuration:r.configuration})).body}async function Gst(t,e,{configuration:r,headers:o,jsonRequest:a,jsonResponse:n,method:u="GET"}){let A=typeof t=="string"?new wx.URL(t):t,p=wle(A,{configuration:r});if(p.enableNetwork===!1)throw new zt(80,`Request to '${A.href}' has been blocked because of your configuration settings`);if(A.protocol==="http:"&&!M4.default.isMatch(A.hostname,r.get("unsafeHttpWhitelist")))throw new zt(81,`Unsafe http requests must be explicitly whitelisted in your configuration (${A.hostname})`);let E={agent:{http:p.httpProxy?L4.default.httpOverHttp(yle(p.httpProxy)):Ust,https:p.httpsProxy?L4.default.httpsOverHttp(yle(p.httpsProxy)):_st},headers:o,method:u};E.responseType=n?"json":"buffer",e!==null&&(Buffer.isBuffer(e)||!a&&typeof e=="string"?E.body=e:E.json=e);let I=r.get("httpTimeout"),v=r.get("httpRetry"),b=r.get("enableStrictSsl"),C=p.httpsCaFilePath,T=p.httpsCertFilePath,L=p.httpsKeyFilePath,{default:U}=await Promise.resolve().then(()=>$e(gle())),J=C?await N4(C):void 0,te=T?await N4(T):void 0,le=L?await N4(L):void 0,pe=U.extend({timeout:{socket:I},retry:v,https:{rejectUnauthorized:b,certificateAuthority:J,certificate:te,key:le},...E});return r.getLimit("networkConcurrency")(()=>pe(A))}var Ele,Cle,M4,L4,wx,dle,mle,Ust,_st,Ile,Bx=Et(()=>{Pt();Ele=Be("https"),Cle=Be("http"),M4=$e(Zo()),L4=$e(Vse()),wx=Be("url");Yl();ql();jl();dle=new Map,mle=new Map,Ust=new Cle.Agent({keepAlive:!0}),_st=new Ele.Agent({keepAlive:!0});Ile=(a=>(a.GET="GET",a.PUT="PUT",a.POST="POST",a.DELETE="DELETE",a))(Ile||{})});var Ji={};Kt(Ji,{availableParallelism:()=>H4,getArchitecture:()=>I1,getArchitectureName:()=>Jst,getArchitectureSet:()=>_4,getCaller:()=>$st,major:()=>Yst,openUrl:()=>Wst});function Kst(){if(process.platform==="darwin"||process.platform==="win32")return null;let t;try{t=oe.readFileSync(Vst)}catch{}if(typeof t<"u"){if(t&&t.includes("GLIBC"))return"glibc";if(t&&t.includes("musl"))return"musl"}let r=(process.report?.getReport()??{}).sharedObjects??[],o=/\/(?:(ld-linux-|[^/]+-linux-gnu\/)|(libc.musl-|ld-musl-))/;return WI(r,a=>{let n=a.match(o);if(!n)return WI.skip;if(n[1])return"glibc";if(n[2])return"musl";throw new Error("Assertion failed: Expected the libc variant to have been detected")})??null}function I1(){return vle=vle??{os:process.platform,cpu:process.arch,libc:Kst()}}function Jst(t=I1()){return t.libc?`${t.os}-${t.cpu}-${t.libc}`:`${t.os}-${t.cpu}`}function _4(){let t=I1();return Dle=Dle??{os:[t.os],cpu:[t.cpu],libc:t.libc?[t.libc]:[]}}function Zst(t){let e=zst.exec(t);if(!e)return null;let r=e[2]&&e[2].indexOf("native")===0,o=e[2]&&e[2].indexOf("eval")===0,a=Xst.exec(e[2]);return o&&a!=null&&(e[2]=a[1],e[3]=a[2],e[4]=a[3]),{file:r?null:e[2],methodName:e[1]||"<unknown>",arguments:r?[e[2]]:[],line:e[3]?+e[3]:null,column:e[4]?+e[4]:null}}function $st(){let e=new Error().stack.split(` +`)[3];return Zst(e)}function H4(){return typeof vx.default.availableParallelism<"u"?vx.default.availableParallelism():Math.max(1,vx.default.cpus().length)}var vx,Yst,Ble,Wst,Vst,vle,Dle,zst,Xst,Dx=Et(()=>{Pt();vx=$e(Be("os"));Px();jl();Yst=Number(process.versions.node.split(".")[0]),Ble=new Map([["darwin","open"],["linux","xdg-open"],["win32","explorer.exe"]]).get(process.platform),Wst=typeof Ble<"u"?async t=>{try{return await j4(Ble,[t],{cwd:K.cwd()}),!0}catch{return!1}}:void 0,Vst="/usr/bin/ldd";zst=/^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,Xst=/\((\S*)(?::(\d+))(?::(\d+))\)/});function V4(t,e,r,o,a){let n=u1(r);if(o.isArray||o.type==="ANY"&&Array.isArray(n))return Array.isArray(n)?n.map((u,A)=>q4(t,`${e}[${A}]`,u,o,a)):String(n).split(/,/).map(u=>q4(t,e,u,o,a));if(Array.isArray(n))throw new Error(`Non-array configuration settings "${e}" cannot be an array`);return q4(t,e,r,o,a)}function q4(t,e,r,o,a){let n=u1(r);switch(o.type){case"ANY":return YS(n);case"SHAPE":return not(t,e,r,o,a);case"MAP":return iot(t,e,r,o,a)}if(n===null&&!o.isNullable&&o.default!==null)throw new Error(`Non-nullable configuration settings "${e}" cannot be set to null`);if(o.values?.includes(n))return n;let A=(()=>{if(o.type==="BOOLEAN"&&typeof n!="string")return VI(n);if(typeof n!="string")throw new Error(`Expected configuration setting "${e}" to be a string, got ${typeof n}`);let p=sS(n,{env:t.env});switch(o.type){case"ABSOLUTE_PATH":{let h=a,E=EO(r);return E&&E[0]!=="<"&&(h=K.dirname(E)),K.resolve(h,ue.toPortablePath(p))}case"LOCATOR_LOOSE":return xf(p,!1);case"NUMBER":return parseInt(p);case"LOCATOR":return xf(p);case"BOOLEAN":return VI(p);default:return p}})();if(o.values&&!o.values.includes(A))throw new Error(`Invalid value, expected one of ${o.values.join(", ")}`);return A}function not(t,e,r,o,a){let n=u1(r);if(typeof n!="object"||Array.isArray(n))throw new it(`Object configuration settings "${e}" must be an object`);let u=K4(t,o,{ignoreArrays:!0});if(n===null)return u;for(let[A,p]of Object.entries(n)){let h=`${e}.${A}`;if(!o.properties[A])throw new it(`Unrecognized configuration settings found: ${e}.${A} - run "yarn config -v" to see the list of settings supported in Yarn`);u.set(A,V4(t,h,p,o.properties[A],a))}return u}function iot(t,e,r,o,a){let n=u1(r),u=new Map;if(typeof n!="object"||Array.isArray(n))throw new it(`Map configuration settings "${e}" must be an object`);if(n===null)return u;for(let[A,p]of Object.entries(n)){let h=o.normalizeKeys?o.normalizeKeys(A):A,E=`${e}['${h}']`,I=o.valueDefinition;u.set(h,V4(t,E,p,I,a))}return u}function K4(t,e,{ignoreArrays:r=!1}={}){switch(e.type){case"SHAPE":{if(e.isArray&&!r)return[];let o=new Map;for(let[a,n]of Object.entries(e.properties))o.set(a,K4(t,n));return o}case"MAP":return e.isArray&&!r?[]:new Map;case"ABSOLUTE_PATH":return e.default===null?null:t.projectCwd===null?Array.isArray(e.default)?e.default.map(o=>K.normalize(o)):K.isAbsolute(e.default)?K.normalize(e.default):e.isNullable?null:void 0:Array.isArray(e.default)?e.default.map(o=>K.resolve(t.projectCwd,o)):K.resolve(t.projectCwd,e.default);default:return e.default}}function xx(t,e,r){if(e.type==="SECRET"&&typeof t=="string"&&r.hideSecrets)return rot;if(e.type==="ABSOLUTE_PATH"&&typeof t=="string"&&r.getNativePaths)return ue.fromPortablePath(t);if(e.isArray&&Array.isArray(t)){let o=[];for(let a of t)o.push(xx(a,e,r));return o}if(e.type==="MAP"&&t instanceof Map){if(t.size===0)return;let o=new Map;for(let[a,n]of t.entries()){let u=xx(n,e.valueDefinition,r);typeof u<"u"&&o.set(a,u)}return o}if(e.type==="SHAPE"&&t instanceof Map){if(t.size===0)return;let o=new Map;for(let[a,n]of t.entries()){let u=e.properties[a],A=xx(n,u,r);typeof A<"u"&&o.set(a,A)}return o}return t}function sot(){let t={};for(let[e,r]of Object.entries(process.env))e=e.toLowerCase(),e.startsWith(bx)&&(e=(0,Sle.default)(e.slice(bx.length)),t[e]=r);return t}function Y4(){let t=`${bx}rc_filename`;for(let[e,r]of Object.entries(process.env))if(e.toLowerCase()===t&&typeof r=="string")return r;return W4}async function Ple(t){try{return await oe.readFilePromise(t)}catch{return Buffer.of()}}async function oot(t,e){return Buffer.compare(...await Promise.all([Ple(t),Ple(e)]))===0}async function aot(t,e){let[r,o]=await Promise.all([oe.statPromise(t),oe.statPromise(e)]);return r.dev===o.dev&&r.ino===o.ino}async function cot({configuration:t,selfPath:e}){let r=t.get("yarnPath");return t.get("ignorePath")||r===null||r===e||await lot(r,e)?null:r}var Sle,Nf,xle,ble,kle,G4,eot,B1,tot,QE,bx,W4,rot,v1,Qle,kx,Sx,lot,rA,Ve,D1=Et(()=>{Pt();Nl();Sle=$e(aK()),Nf=$e(ed());qt();xle=$e(eJ()),ble=Be("module"),kle=$e(nd()),G4=Be("stream");lse();AE();AO();fO();pO();Lse();hO();Bd();Hse();VS();ql();rh();Bx();jl();Dx();kf();xo();eot=function(){if(!Nf.GITHUB_ACTIONS||!process.env.GITHUB_EVENT_PATH)return!1;let t=ue.toPortablePath(process.env.GITHUB_EVENT_PATH),e;try{e=oe.readJsonSync(t)}catch{return!1}return!(!("repository"in e)||!e.repository||(e.repository.private??!0))}(),B1=new Set(["@yarnpkg/plugin-constraints","@yarnpkg/plugin-exec","@yarnpkg/plugin-interactive-tools","@yarnpkg/plugin-stage","@yarnpkg/plugin-typescript","@yarnpkg/plugin-version","@yarnpkg/plugin-workspace-tools"]),tot=new Set(["isTestEnv","injectNpmUser","injectNpmPassword","injectNpm2FaToken","cacheCheckpointOverride","cacheVersionOverride","lockfileVersionOverride","binFolder","version","flags","profile","gpg","ignoreNode","wrapOutput","home","confDir","registry","ignoreCwd"]),QE=/^(?!v)[a-z0-9._-]+$/i,bx="yarn_",W4=".yarnrc.yml",rot="********",v1=(E=>(E.ANY="ANY",E.BOOLEAN="BOOLEAN",E.ABSOLUTE_PATH="ABSOLUTE_PATH",E.LOCATOR="LOCATOR",E.LOCATOR_LOOSE="LOCATOR_LOOSE",E.NUMBER="NUMBER",E.STRING="STRING",E.SECRET="SECRET",E.SHAPE="SHAPE",E.MAP="MAP",E))(v1||{}),Qle=yt,kx=(r=>(r.JUNCTIONS="junctions",r.SYMLINKS="symlinks",r))(kx||{}),Sx={lastUpdateCheck:{description:"Last timestamp we checked whether new Yarn versions were available",type:"STRING",default:null},yarnPath:{description:"Path to the local executable that must be used over the global one",type:"ABSOLUTE_PATH",default:null},ignorePath:{description:"If true, the local executable will be ignored when using the global one",type:"BOOLEAN",default:!1},globalFolder:{description:"Folder where all system-global files are stored",type:"ABSOLUTE_PATH",default:wO()},cacheFolder:{description:"Folder where the cache files must be written",type:"ABSOLUTE_PATH",default:"./.yarn/cache"},compressionLevel:{description:"Zip files compression level, from 0 to 9 or mixed (a variant of 9, which stores some files uncompressed, when compression doesn't yield good results)",type:"NUMBER",values:["mixed",0,1,2,3,4,5,6,7,8,9],default:0},virtualFolder:{description:"Folder where the virtual packages (cf doc) will be mapped on the disk (must be named __virtual__)",type:"ABSOLUTE_PATH",default:"./.yarn/__virtual__"},installStatePath:{description:"Path of the file where the install state will be persisted",type:"ABSOLUTE_PATH",default:"./.yarn/install-state.gz"},immutablePatterns:{description:"Array of glob patterns; files matching them won't be allowed to change during immutable installs",type:"STRING",default:[],isArray:!0},rcFilename:{description:"Name of the files where the configuration can be found",type:"STRING",default:Y4()},enableGlobalCache:{description:"If true, the system-wide cache folder will be used regardless of `cache-folder`",type:"BOOLEAN",default:!0},cacheMigrationMode:{description:"Defines the conditions under which Yarn upgrades should cause the cache archives to be regenerated.",type:"STRING",values:["always","match-spec","required-only"],default:"always"},enableColors:{description:"If true, the CLI is allowed to use colors in its output",type:"BOOLEAN",default:lS,defaultText:"<dynamic>"},enableHyperlinks:{description:"If true, the CLI is allowed to use hyperlinks in its output",type:"BOOLEAN",default:xL,defaultText:"<dynamic>"},enableInlineBuilds:{description:"If true, the CLI will print the build output on the command line",type:"BOOLEAN",default:Nf.isCI,defaultText:"<dynamic>"},enableMessageNames:{description:"If true, the CLI will prefix most messages with codes suitable for search engines",type:"BOOLEAN",default:!0},enableProgressBars:{description:"If true, the CLI is allowed to show a progress bar for long-running events",type:"BOOLEAN",default:!Nf.isCI,defaultText:"<dynamic>"},enableTimers:{description:"If true, the CLI is allowed to print the time spent executing commands",type:"BOOLEAN",default:!0},enableTips:{description:"If true, installs will print a helpful message every day of the week",type:"BOOLEAN",default:!Nf.isCI,defaultText:"<dynamic>"},preferInteractive:{description:"If true, the CLI will automatically use the interactive mode when called from a TTY",type:"BOOLEAN",default:!1},preferTruncatedLines:{description:"If true, the CLI will truncate lines that would go beyond the size of the terminal",type:"BOOLEAN",default:!1},progressBarStyle:{description:"Which style of progress bar should be used (only when progress bars are enabled)",type:"STRING",default:void 0,defaultText:"<dynamic>"},defaultLanguageName:{description:"Default language mode that should be used when a package doesn't offer any insight",type:"STRING",default:"node"},defaultProtocol:{description:"Default resolution protocol used when resolving pure semver and tag ranges",type:"STRING",default:"npm:"},enableTransparentWorkspaces:{description:"If false, Yarn won't automatically resolve workspace dependencies unless they use the `workspace:` protocol",type:"BOOLEAN",default:!0},supportedArchitectures:{description:"Architectures that Yarn will fetch and inject into the resolver",type:"SHAPE",properties:{os:{description:"Array of supported process.platform strings, or null to target them all",type:"STRING",isArray:!0,isNullable:!0,default:["current"]},cpu:{description:"Array of supported process.arch strings, or null to target them all",type:"STRING",isArray:!0,isNullable:!0,default:["current"]},libc:{description:"Array of supported libc libraries, or null to target them all",type:"STRING",isArray:!0,isNullable:!0,default:["current"]}}},enableMirror:{description:"If true, the downloaded packages will be retrieved and stored in both the local and global folders",type:"BOOLEAN",default:!0},enableNetwork:{description:"If false, Yarn will refuse to use the network if required to",type:"BOOLEAN",default:!0},enableOfflineMode:{description:"If true, Yarn will attempt to retrieve files and metadata from the global cache rather than the network",type:"BOOLEAN",default:!1},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:"STRING",default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:"STRING",default:null},unsafeHttpWhitelist:{description:"List of the hostnames for which http queries are allowed (glob patterns are supported)",type:"STRING",default:[],isArray:!0},httpTimeout:{description:"Timeout of each http request in milliseconds",type:"NUMBER",default:6e4},httpRetry:{description:"Retry times on http failure",type:"NUMBER",default:3},networkConcurrency:{description:"Maximal number of concurrent requests",type:"NUMBER",default:50},taskPoolConcurrency:{description:"Maximal amount of concurrent heavy task processing",type:"NUMBER",default:H4()},taskPoolMode:{description:"Execution strategy for heavy tasks",type:"STRING",values:["async","workers"],default:"workers"},networkSettings:{description:"Network settings per hostname (glob patterns are supported)",type:"MAP",valueDefinition:{description:"",type:"SHAPE",properties:{httpsCaFilePath:{description:"Path to file containing one or multiple Certificate Authority signing certificates",type:"ABSOLUTE_PATH",default:null},enableNetwork:{description:"If false, the package manager will refuse to use the network if required to",type:"BOOLEAN",default:null},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:"STRING",default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:"STRING",default:null},httpsKeyFilePath:{description:"Path to file containing private key in PEM format",type:"ABSOLUTE_PATH",default:null},httpsCertFilePath:{description:"Path to file containing certificate chain in PEM format",type:"ABSOLUTE_PATH",default:null}}}},httpsCaFilePath:{description:"A path to a file containing one or multiple Certificate Authority signing certificates",type:"ABSOLUTE_PATH",default:null},httpsKeyFilePath:{description:"Path to file containing private key in PEM format",type:"ABSOLUTE_PATH",default:null},httpsCertFilePath:{description:"Path to file containing certificate chain in PEM format",type:"ABSOLUTE_PATH",default:null},enableStrictSsl:{description:"If false, SSL certificate errors will be ignored",type:"BOOLEAN",default:!0},logFilters:{description:"Overrides for log levels",type:"SHAPE",isArray:!0,concatenateValues:!0,properties:{code:{description:"Code of the messages covered by this override",type:"STRING",default:void 0},text:{description:"Code of the texts covered by this override",type:"STRING",default:void 0},pattern:{description:"Code of the patterns covered by this override",type:"STRING",default:void 0},level:{description:"Log level override, set to null to remove override",type:"STRING",values:Object.values(uS),isNullable:!0,default:void 0}}},enableTelemetry:{description:"If true, telemetry will be periodically sent, following the rules in https://yarnpkg.com/advanced/telemetry",type:"BOOLEAN",default:!0},telemetryInterval:{description:"Minimal amount of time between two telemetry uploads, in days",type:"NUMBER",default:7},telemetryUserId:{description:"If you desire to tell us which project you are, you can set this field. Completely optional and opt-in.",type:"STRING",default:null},enableHardenedMode:{description:"If true, automatically enable --check-resolutions --refresh-lockfile on installs",type:"BOOLEAN",default:Nf.isPR&&eot,defaultText:"<true on public PRs>"},enableScripts:{description:"If true, packages are allowed to have install scripts by default",type:"BOOLEAN",default:!0},enableStrictSettings:{description:"If true, unknown settings will cause Yarn to abort",type:"BOOLEAN",default:!0},enableImmutableCache:{description:"If true, the cache is reputed immutable and actions that would modify it will throw",type:"BOOLEAN",default:!1},checksumBehavior:{description:"Enumeration defining what to do when a checksum doesn't match expectations",type:"STRING",default:"throw"},injectEnvironmentFiles:{description:"List of all the environment files that Yarn should inject inside the process when it starts",type:"ABSOLUTE_PATH",default:[".env.yarn?"],isArray:!0},packageExtensions:{description:"Map of package corrections to apply on the dependency tree",type:"MAP",valueDefinition:{description:"The extension that will be applied to any package whose version matches the specified range",type:"SHAPE",properties:{dependencies:{description:"The set of dependencies that must be made available to the current package in order for it to work properly",type:"MAP",valueDefinition:{description:"A range",type:"STRING"}},peerDependencies:{description:"Inherited dependencies - the consumer of the package will be tasked to provide them",type:"MAP",valueDefinition:{description:"A semver range",type:"STRING"}},peerDependenciesMeta:{description:"Extra information related to the dependencies listed in the peerDependencies field",type:"MAP",valueDefinition:{description:"The peerDependency meta",type:"SHAPE",properties:{optional:{description:"If true, the selected peer dependency will be marked as optional by the package manager and the consumer omitting it won't be reported as an error",type:"BOOLEAN",default:!1}}}}}}}};lot=process.platform==="win32"?oot:aot;rA=class{constructor(e){this.isCI=Nf.isCI;this.projectCwd=null;this.plugins=new Map;this.settings=new Map;this.values=new Map;this.sources=new Map;this.invalid=new Map;this.env={};this.limits=new Map;this.packageExtensions=null;this.startingCwd=e}static create(e,r,o){let a=new rA(e);typeof r<"u"&&!(r instanceof Map)&&(a.projectCwd=r),a.importSettings(Sx);let n=typeof o<"u"?o:r instanceof Map?r:new Map;for(let[u,A]of n)a.activatePlugin(u,A);return a}static async find(e,r,{strict:o=!0,usePathCheck:a=null,useRc:n=!0}={}){let u=sot();delete u.rcFilename;let A=new rA(e),p=await rA.findRcFiles(e),h=await rA.findFolderRcFile(yE());h&&(p.find(ye=>ye.path===h.path)||p.unshift(h));let E=_se(p.map(Ae=>[Ae.path,Ae.data])),I=Bt.dot,v=new Set(Object.keys(Sx)),b=({yarnPath:Ae,ignorePath:ye,injectEnvironmentFiles:ae})=>({yarnPath:Ae,ignorePath:ye,injectEnvironmentFiles:ae}),C=({yarnPath:Ae,ignorePath:ye,injectEnvironmentFiles:ae,...we})=>{let Pe={};for(let[g,Ee]of Object.entries(we))v.has(g)&&(Pe[g]=Ee);return Pe},T=({yarnPath:Ae,ignorePath:ye,...ae})=>{let we={};for(let[Pe,g]of Object.entries(ae))v.has(Pe)||(we[Pe]=g);return we};if(A.importSettings(b(Sx)),A.useWithSource("<environment>",b(u),e,{strict:!1}),E){let[Ae,ye]=E;A.useWithSource(Ae,b(ye),I,{strict:!1})}if(a){if(await cot({configuration:A,selfPath:a})!==null)return A;A.useWithSource("<override>",{ignorePath:!0},e,{strict:!1,overwrite:!0})}let L=await rA.findProjectCwd(e);A.startingCwd=e,A.projectCwd=L;let U=Object.assign(Object.create(null),process.env);A.env=U;let J=await Promise.all(A.get("injectEnvironmentFiles").map(async Ae=>{let ye=Ae.endsWith("?")?await oe.readFilePromise(Ae.slice(0,-1),"utf8").catch(()=>""):await oe.readFilePromise(Ae,"utf8");return(0,xle.parse)(ye)}));for(let Ae of J)for(let[ye,ae]of Object.entries(Ae))A.env[ye]=sS(ae,{env:U});if(A.importSettings(C(Sx)),A.useWithSource("<environment>",C(u),e,{strict:o}),E){let[Ae,ye]=E;A.useWithSource(Ae,C(ye),I,{strict:o})}let te=Ae=>"default"in Ae?Ae.default:Ae,le=new Map([["@@core",ase]]);if(r!==null)for(let Ae of r.plugins.keys())le.set(Ae,te(r.modules.get(Ae)));for(let[Ae,ye]of le)A.activatePlugin(Ae,ye);let pe=new Map([]);if(r!==null){let Ae=new Map;for(let we of ble.builtinModules)Ae.set(we,()=>vf(we));for(let[we,Pe]of r.modules)Ae.set(we,()=>Pe);let ye=new Set,ae=async(we,Pe)=>{let{factory:g,name:Ee}=vf(we);if(!g||ye.has(Ee))return;let De=new Map(Ae),ce=ee=>{if(De.has(ee))return De.get(ee)();throw new it(`This plugin cannot access the package referenced via ${ee} which is neither a builtin, nor an exposed entry`)},ne=await Wy(async()=>te(await g(ce)),ee=>`${ee} (when initializing ${Ee}, defined in ${Pe})`);Ae.set(Ee,()=>ne),ye.add(Ee),pe.set(Ee,ne)};if(u.plugins)for(let we of u.plugins.split(";")){let Pe=K.resolve(e,ue.toPortablePath(we));await ae(Pe,"<environment>")}for(let{path:we,cwd:Pe,data:g}of p)if(!!n&&!!Array.isArray(g.plugins))for(let Ee of g.plugins){let De=typeof Ee!="string"?Ee.path:Ee,ce=Ee?.spec??"",ne=Ee?.checksum??"";if(B1.has(ce))continue;let ee=K.resolve(Pe,ue.toPortablePath(De));if(!await oe.existsPromise(ee)){if(!ce){let ht=Ot(A,K.basename(ee,".cjs"),yt.NAME),H=Ot(A,".gitignore",yt.NAME),lt=Ot(A,A.values.get("rcFilename"),yt.NAME),Re=Ot(A,"https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored",yt.URL);throw new it(`Missing source for the ${ht} plugin - please try to remove the plugin from ${lt} then reinstall it manually. This error usually occurs because ${H} is incorrect, check ${Re} to make sure your plugin folder isn't gitignored.`)}if(!ce.match(/^https?:/)){let ht=Ot(A,K.basename(ee,".cjs"),yt.NAME),H=Ot(A,A.values.get("rcFilename"),yt.NAME);throw new it(`Failed to recognize the source for the ${ht} plugin - please try to delete the plugin from ${H} then reinstall it manually.`)}let Ie=await O4(ce,{configuration:A}),ke=zs(Ie);if(ne&&ne!==ke){let ht=Ot(A,K.basename(ee,".cjs"),yt.NAME),H=Ot(A,A.values.get("rcFilename"),yt.NAME),lt=Ot(A,`yarn plugin import ${ce}`,yt.CODE);throw new it(`Failed to fetch the ${ht} plugin from its remote location: its checksum seems to have changed. If this is expected, please remove the plugin from ${H} then run ${lt} to reimport it.`)}await oe.mkdirPromise(K.dirname(ee),{recursive:!0}),await oe.writeFilePromise(ee,Ie)}await ae(ee,we)}}for(let[Ae,ye]of pe)A.activatePlugin(Ae,ye);if(A.useWithSource("<environment>",T(u),e,{strict:o}),E){let[Ae,ye]=E;A.useWithSource(Ae,T(ye),I,{strict:o})}return A.get("enableGlobalCache")&&(A.values.set("cacheFolder",`${A.get("globalFolder")}/cache`),A.sources.set("cacheFolder","<internal>")),A}static async findRcFiles(e){let r=Y4(),o=[],a=e,n=null;for(;a!==n;){n=a;let u=K.join(n,r);if(oe.existsSync(u)){let A=await oe.readFilePromise(u,"utf8"),p;try{p=Vi(A)}catch{let E="";throw A.match(/^\s+(?!-)[^:]+\s+\S+/m)&&(E=" (in particular, make sure you list the colons after each key name)"),new it(`Parse error when loading ${u}; please check it's proper Yaml${E}`)}o.unshift({path:u,cwd:n,data:p})}a=K.dirname(n)}return o}static async findFolderRcFile(e){let r=K.join(e,dr.rc),o;try{o=await oe.readFilePromise(r,"utf8")}catch(n){if(n.code==="ENOENT")return null;throw n}let a=Vi(o);return{path:r,cwd:e,data:a}}static async findProjectCwd(e){let r=null,o=e,a=null;for(;o!==a;){if(a=o,oe.existsSync(K.join(a,dr.lockfile)))return a;oe.existsSync(K.join(a,dr.manifest))&&(r=a),o=K.dirname(a)}return r}static async updateConfiguration(e,r,o={}){let a=Y4(),n=K.join(e,a),u=oe.existsSync(n)?Vi(await oe.readFilePromise(n,"utf8")):{},A=!1,p;if(typeof r=="function"){try{p=r(u)}catch{p=r({})}if(p===u)return!1}else{p=u;for(let h of Object.keys(r)){let E=u[h],I=r[h],v;if(typeof I=="function")try{v=I(E)}catch{v=I(void 0)}else v=I;E!==v&&(v===rA.deleteProperty?delete p[h]:p[h]=v,A=!0)}if(!A)return!1}return await oe.changeFilePromise(n,Ba(p),{automaticNewlines:!0}),!0}static async addPlugin(e,r){r.length!==0&&await rA.updateConfiguration(e,o=>{let a=o.plugins??[];if(a.length===0)return{...o,plugins:r};let n=[],u=[...r];for(let A of a){let p=typeof A!="string"?A.path:A,h=u.find(E=>E.path===p);h?(n.push(h),u=u.filter(E=>E!==h)):n.push(A)}return n.push(...u),{...o,plugins:n}})}static async updateHomeConfiguration(e){let r=yE();return await rA.updateConfiguration(r,e)}activatePlugin(e,r){this.plugins.set(e,r),typeof r.configuration<"u"&&this.importSettings(r.configuration)}importSettings(e){for(let[r,o]of Object.entries(e))if(o!=null){if(this.settings.has(r))throw new Error(`Cannot redefine settings "${r}"`);this.settings.set(r,o),this.values.set(r,K4(this,o))}}useWithSource(e,r,o,a){try{this.use(e,r,o,a)}catch(n){throw n.message+=` (in ${Ot(this,e,yt.PATH)})`,n}}use(e,r,o,{strict:a=!0,overwrite:n=!1}={}){a=a&&this.get("enableStrictSettings");for(let u of["enableStrictSettings",...Object.keys(r)]){let A=r[u],p=EO(A);if(p&&(e=p),typeof A>"u"||u==="plugins"||e==="<environment>"&&tot.has(u))continue;if(u==="rcFilename")throw new it(`The rcFilename settings can only be set via ${`${bx}RC_FILENAME`.toUpperCase()}, not via a rc file`);let h=this.settings.get(u);if(!h){let I=yE(),v=e[0]!=="<"?K.dirname(e):null;if(a&&!(v!==null?I===v:!1))throw new it(`Unrecognized or legacy configuration settings found: ${u} - run "yarn config -v" to see the list of settings supported in Yarn`);this.invalid.set(u,e);continue}if(this.sources.has(u)&&!(n||h.type==="MAP"||h.isArray&&h.concatenateValues))continue;let E;try{E=V4(this,u,A,h,o)}catch(I){throw I.message+=` in ${Ot(this,e,yt.PATH)}`,I}if(u==="enableStrictSettings"&&e!=="<environment>"){a=E;continue}if(h.type==="MAP"){let I=this.values.get(u);this.values.set(u,new Map(n?[...I,...E]:[...E,...I])),this.sources.set(u,`${this.sources.get(u)}, ${e}`)}else if(h.isArray&&h.concatenateValues){let I=this.values.get(u);this.values.set(u,n?[...I,...E]:[...E,...I]),this.sources.set(u,`${this.sources.get(u)}, ${e}`)}else this.values.set(u,E),this.sources.set(u,e)}}get(e){if(!this.values.has(e))throw new Error(`Invalid configuration key "${e}"`);return this.values.get(e)}getSpecial(e,{hideSecrets:r=!1,getNativePaths:o=!1}){let a=this.get(e),n=this.settings.get(e);if(typeof n>"u")throw new it(`Couldn't find a configuration settings named "${e}"`);return xx(a,n,{hideSecrets:r,getNativePaths:o})}getSubprocessStreams(e,{header:r,prefix:o,report:a}){let n,u,A=oe.createWriteStream(e);if(this.get("enableInlineBuilds")){let p=a.createStreamReporter(`${o} ${Ot(this,"STDOUT","green")}`),h=a.createStreamReporter(`${o} ${Ot(this,"STDERR","red")}`);n=new G4.PassThrough,n.pipe(p),n.pipe(A),u=new G4.PassThrough,u.pipe(h),u.pipe(A)}else n=A,u=A,typeof r<"u"&&n.write(`${r} +`);return{stdout:n,stderr:u}}makeResolver(){let e=[];for(let r of this.plugins.values())for(let o of r.resolvers||[])e.push(new o);return new vd([new l1,new Xn,...e])}makeFetcher(){let e=[];for(let r of this.plugins.values())for(let o of r.fetchers||[])e.push(new o);return new pE([new hE,new dE,...e])}getLinkers(){let e=[];for(let r of this.plugins.values())for(let o of r.linkers||[])e.push(new o);return e}getSupportedArchitectures(){let e=I1(),r=this.get("supportedArchitectures"),o=r.get("os");o!==null&&(o=o.map(u=>u==="current"?e.os:u));let a=r.get("cpu");a!==null&&(a=a.map(u=>u==="current"?e.cpu:u));let n=r.get("libc");return n!==null&&(n=sl(n,u=>u==="current"?e.libc??sl.skip:u)),{os:o,cpu:a,libc:n}}async getPackageExtensions(){if(this.packageExtensions!==null)return this.packageExtensions;this.packageExtensions=new Map;let e=this.packageExtensions,r=(o,a,{userProvided:n=!1}={})=>{if(!ba(o.range))throw new Error("Only semver ranges are allowed as keys for the packageExtensions setting");let u=new Mt;u.load(a,{yamlCompatibilityMode:!0});let A=Gy(e,o.identHash),p=[];A.push([o.range,p]);let h={status:"inactive",userProvided:n,parentDescriptor:o};for(let E of u.dependencies.values())p.push({...h,type:"Dependency",descriptor:E});for(let E of u.peerDependencies.values())p.push({...h,type:"PeerDependency",descriptor:E});for(let[E,I]of u.peerDependenciesMeta)for(let[v,b]of Object.entries(I))p.push({...h,type:"PeerDependencyMeta",selector:E,key:v,value:b})};await this.triggerHook(o=>o.registerPackageExtensions,this,r);for(let[o,a]of this.get("packageExtensions"))r(nh(o,!0),iS(a),{userProvided:!0});return e}normalizeLocator(e){return ba(e.reference)?Qs(e,`${this.get("defaultProtocol")}${e.reference}`):QE.test(e.reference)?Qs(e,`${this.get("defaultProtocol")}${e.reference}`):e}normalizeDependency(e){return ba(e.range)?In(e,`${this.get("defaultProtocol")}${e.range}`):QE.test(e.range)?In(e,`${this.get("defaultProtocol")}${e.range}`):e}normalizeDependencyMap(e){return new Map([...e].map(([r,o])=>[r,this.normalizeDependency(o)]))}normalizePackage(e,{packageExtensions:r}){let o=$I(e),a=r.get(e.identHash);if(typeof a<"u"){let u=e.version;if(u!==null){for(let[A,p]of a)if(!!bf(u,A))for(let h of p)switch(h.status==="inactive"&&(h.status="redundant"),h.type){case"Dependency":typeof o.dependencies.get(h.descriptor.identHash)>"u"&&(h.status="active",o.dependencies.set(h.descriptor.identHash,this.normalizeDependency(h.descriptor)));break;case"PeerDependency":typeof o.peerDependencies.get(h.descriptor.identHash)>"u"&&(h.status="active",o.peerDependencies.set(h.descriptor.identHash,h.descriptor));break;case"PeerDependencyMeta":{let E=o.peerDependenciesMeta.get(h.selector);(typeof E>"u"||!Object.hasOwn(E,h.key)||E[h.key]!==h.value)&&(h.status="active",ol(o.peerDependenciesMeta,h.selector,()=>({}))[h.key]=h.value)}break;default:CL(h)}}}let n=u=>u.scope?`${u.scope}__${u.name}`:`${u.name}`;for(let u of o.peerDependenciesMeta.keys()){let A=Js(u);o.peerDependencies.has(A.identHash)||o.peerDependencies.set(A.identHash,In(A,"*"))}for(let u of o.peerDependencies.values()){if(u.scope==="types")continue;let A=n(u),p=eA("types",A),h=fn(p);o.peerDependencies.has(p.identHash)||o.peerDependenciesMeta.has(h)||(o.peerDependencies.set(p.identHash,In(p,"*")),o.peerDependenciesMeta.set(h,{optional:!0}))}return o.dependencies=new Map(ks(o.dependencies,([,u])=>Sa(u))),o.peerDependencies=new Map(ks(o.peerDependencies,([,u])=>Sa(u))),o}getLimit(e){return ol(this.limits,e,()=>(0,kle.default)(this.get(e)))}async triggerHook(e,...r){for(let o of this.plugins.values()){let a=o.hooks;if(!a)continue;let n=e(a);!n||await n(...r)}}async triggerMultipleHooks(e,r){for(let o of r)await this.triggerHook(e,...o)}async reduceHook(e,r,...o){let a=r;for(let n of this.plugins.values()){let u=n.hooks;if(!u)continue;let A=e(u);!A||(a=await A(a,...o))}return a}async firstHook(e,...r){for(let o of this.plugins.values()){let a=o.hooks;if(!a)continue;let n=e(a);if(!n)continue;let u=await n(...r);if(typeof u<"u")return u}return null}},Ve=rA;Ve.deleteProperty=Symbol(),Ve.telemetry=null});var Ur={};Kt(Ur,{EndStrategy:()=>Z4,ExecError:()=>Qx,PipeError:()=>P1,execvp:()=>j4,pipevp:()=>Gc});function Sd(t){return t!==null&&typeof t.fd=="number"}function J4(){}function z4(){for(let t of xd)t.kill()}async function Gc(t,e,{cwd:r,env:o=process.env,strict:a=!1,stdin:n=null,stdout:u,stderr:A,end:p=2}){let h=["pipe","pipe","pipe"];n===null?h[0]="ignore":Sd(n)&&(h[0]=n),Sd(u)&&(h[1]=u),Sd(A)&&(h[2]=A);let E=(0,X4.default)(t,e,{cwd:ue.fromPortablePath(r),env:{...o,PWD:ue.fromPortablePath(r)},stdio:h});xd.add(E),xd.size===1&&(process.on("SIGINT",J4),process.on("SIGTERM",z4)),!Sd(n)&&n!==null&&n.pipe(E.stdin),Sd(u)||E.stdout.pipe(u,{end:!1}),Sd(A)||E.stderr.pipe(A,{end:!1});let I=()=>{for(let v of new Set([u,A]))Sd(v)||v.end()};return new Promise((v,b)=>{E.on("error",C=>{xd.delete(E),xd.size===0&&(process.off("SIGINT",J4),process.off("SIGTERM",z4)),(p===2||p===1)&&I(),b(C)}),E.on("close",(C,T)=>{xd.delete(E),xd.size===0&&(process.off("SIGINT",J4),process.off("SIGTERM",z4)),(p===2||p===1&&C!==0)&&I(),C===0||!a?v({code:$4(C,T)}):b(new P1({fileName:t,code:C,signal:T}))})})}async function j4(t,e,{cwd:r,env:o=process.env,encoding:a="utf8",strict:n=!1}){let u=["ignore","pipe","pipe"],A=[],p=[],h=ue.fromPortablePath(r);typeof o.PWD<"u"&&(o={...o,PWD:h});let E=(0,X4.default)(t,e,{cwd:h,env:o,stdio:u});return E.stdout.on("data",I=>{A.push(I)}),E.stderr.on("data",I=>{p.push(I)}),await new Promise((I,v)=>{E.on("error",b=>{let C=Ve.create(r),T=Ot(C,t,yt.PATH);v(new zt(1,`Process ${T} failed to spawn`,L=>{L.reportError(1,` ${zu(C,{label:"Thrown Error",value:_c(yt.NO_HINT,b.message)})}`)}))}),E.on("close",(b,C)=>{let T=a==="buffer"?Buffer.concat(A):Buffer.concat(A).toString(a),L=a==="buffer"?Buffer.concat(p):Buffer.concat(p).toString(a);b===0||!n?I({code:$4(b,C),stdout:T,stderr:L}):v(new Qx({fileName:t,code:b,signal:C,stdout:T,stderr:L}))})})}function $4(t,e){let r=uot.get(e);return typeof r<"u"?128+r:t??1}function Aot(t,e,{configuration:r,report:o}){o.reportError(1,` ${zu(r,t!==null?{label:"Exit Code",value:_c(yt.NUMBER,t)}:{label:"Exit Signal",value:_c(yt.CODE,e)})}`)}var X4,Z4,P1,Qx,xd,uot,Px=Et(()=>{Pt();X4=$e(aR());D1();Yl();ql();Z4=(o=>(o[o.Never=0]="Never",o[o.ErrorCode=1]="ErrorCode",o[o.Always=2]="Always",o))(Z4||{}),P1=class extends zt{constructor({fileName:r,code:o,signal:a}){let n=Ve.create(K.cwd()),u=Ot(n,r,yt.PATH);super(1,`Child ${u} reported an error`,A=>{Aot(o,a,{configuration:n,report:A})});this.code=$4(o,a)}},Qx=class extends P1{constructor({fileName:r,code:o,signal:a,stdout:n,stderr:u}){super({fileName:r,code:o,signal:a});this.stdout=n,this.stderr=u}};xd=new Set;uot=new Map([["SIGINT",2],["SIGQUIT",3],["SIGKILL",9],["SIGTERM",15]])});function Tle(t){Fle=t}function S1(){return typeof eU>"u"&&(eU=Fle()),eU}var eU,Fle,tU=Et(()=>{Fle=()=>{throw new Error("Assertion failed: No libzip instance is available, and no factory was configured")}});var Rle=_((Fx,nU)=>{var fot=Object.assign({},Be("fs")),rU=function(){var t=typeof document<"u"&&document.currentScript?document.currentScript.src:void 0;return typeof __filename<"u"&&(t=t||__filename),function(e){e=e||{};var r=typeof e<"u"?e:{},o,a;r.ready=new Promise(function(We,tt){o=We,a=tt});var n={},u;for(u in r)r.hasOwnProperty(u)&&(n[u]=r[u]);var A=[],p="./this.program",h=function(We,tt){throw tt},E=!1,I=!0,v="";function b(We){return r.locateFile?r.locateFile(We,v):v+We}var C,T,L,U;I&&(E?v=Be("path").dirname(v)+"/":v=__dirname+"/",C=function(tt,It){var nr=ii(tt);return nr?It?nr:nr.toString():(L||(L=fot),U||(U=Be("path")),tt=U.normalize(tt),L.readFileSync(tt,It?null:"utf8"))},T=function(tt){var It=C(tt,!0);return It.buffer||(It=new Uint8Array(It)),Ee(It.buffer),It},process.argv.length>1&&(p=process.argv[1].replace(/\\/g,"/")),A=process.argv.slice(2),h=function(We){process.exit(We)},r.inspect=function(){return"[Emscripten Module object]"});var J=r.print||console.log.bind(console),te=r.printErr||console.warn.bind(console);for(u in n)n.hasOwnProperty(u)&&(r[u]=n[u]);n=null,r.arguments&&(A=r.arguments),r.thisProgram&&(p=r.thisProgram),r.quit&&(h=r.quit);var le=0,pe=function(We){le=We},Ae;r.wasmBinary&&(Ae=r.wasmBinary);var ye=r.noExitRuntime||!0;typeof WebAssembly!="object"&&Ri("no native wasm support detected");function ae(We,tt,It){switch(tt=tt||"i8",tt.charAt(tt.length-1)==="*"&&(tt="i32"),tt){case"i1":return _e[We>>0];case"i8":return _e[We>>0];case"i16":return lp((We>>1)*2);case"i32":return Ms((We>>2)*4);case"i64":return Ms((We>>2)*4);case"float":return cu((We>>2)*4);case"double":return ap((We>>3)*8);default:Ri("invalid type for getValue: "+tt)}return null}var we,Pe=!1,g;function Ee(We,tt){We||Ri("Assertion failed: "+tt)}function De(We){var tt=r["_"+We];return Ee(tt,"Cannot call unknown function "+We+", make sure it is exported"),tt}function ce(We,tt,It,nr,$){var me={string:function(es){var xi=0;if(es!=null&&es!==0){var jo=(es.length<<2)+1;xi=Un(jo),ht(es,xi,jo)}return xi},array:function(es){var xi=Un(es.length);return Re(es,xi),xi}};function Le(es){return tt==="string"?Ie(es):tt==="boolean"?Boolean(es):es}var ft=De(We),pt=[],Rt=0;if(nr)for(var er=0;er<nr.length;er++){var Zr=me[It[er]];Zr?(Rt===0&&(Rt=ms()),pt[er]=Zr(nr[er])):pt[er]=nr[er]}var qi=ft.apply(null,pt);return qi=Le(qi),Rt!==0&&_s(Rt),qi}function ne(We,tt,It,nr){It=It||[];var $=It.every(function(Le){return Le==="number"}),me=tt!=="string";return me&&$&&!nr?De(We):function(){return ce(We,tt,It,arguments,nr)}}var ee=new TextDecoder("utf8");function Ie(We,tt){if(!We)return"";for(var It=We+tt,nr=We;!(nr>=It)&&Te[nr];)++nr;return ee.decode(Te.subarray(We,nr))}function ke(We,tt,It,nr){if(!(nr>0))return 0;for(var $=It,me=It+nr-1,Le=0;Le<We.length;++Le){var ft=We.charCodeAt(Le);if(ft>=55296&&ft<=57343){var pt=We.charCodeAt(++Le);ft=65536+((ft&1023)<<10)|pt&1023}if(ft<=127){if(It>=me)break;tt[It++]=ft}else if(ft<=2047){if(It+1>=me)break;tt[It++]=192|ft>>6,tt[It++]=128|ft&63}else if(ft<=65535){if(It+2>=me)break;tt[It++]=224|ft>>12,tt[It++]=128|ft>>6&63,tt[It++]=128|ft&63}else{if(It+3>=me)break;tt[It++]=240|ft>>18,tt[It++]=128|ft>>12&63,tt[It++]=128|ft>>6&63,tt[It++]=128|ft&63}}return tt[It]=0,It-$}function ht(We,tt,It){return ke(We,Te,tt,It)}function H(We){for(var tt=0,It=0;It<We.length;++It){var nr=We.charCodeAt(It);nr>=55296&&nr<=57343&&(nr=65536+((nr&1023)<<10)|We.charCodeAt(++It)&1023),nr<=127?++tt:nr<=2047?tt+=2:nr<=65535?tt+=3:tt+=4}return tt}function lt(We){var tt=H(We)+1,It=Li(tt);return It&&ke(We,_e,It,tt),It}function Re(We,tt){_e.set(We,tt)}function Qe(We,tt){return We%tt>0&&(We+=tt-We%tt),We}var be,_e,Te,Je,He,x,w,S,y,F;function z(We){be=We,r.HEAP_DATA_VIEW=F=new DataView(We),r.HEAP8=_e=new Int8Array(We),r.HEAP16=Je=new Int16Array(We),r.HEAP32=x=new Int32Array(We),r.HEAPU8=Te=new Uint8Array(We),r.HEAPU16=He=new Uint16Array(We),r.HEAPU32=w=new Uint32Array(We),r.HEAPF32=S=new Float32Array(We),r.HEAPF64=y=new Float64Array(We)}var X=r.INITIAL_MEMORY||16777216,Z,ie=[],Se=[],Ne=[],ot=!1;function dt(){if(r.preRun)for(typeof r.preRun=="function"&&(r.preRun=[r.preRun]);r.preRun.length;)xt(r.preRun.shift());oo(ie)}function jt(){ot=!0,oo(Se)}function $t(){if(r.postRun)for(typeof r.postRun=="function"&&(r.postRun=[r.postRun]);r.postRun.length;)Qr(r.postRun.shift());oo(Ne)}function xt(We){ie.unshift(We)}function an(We){Se.unshift(We)}function Qr(We){Ne.unshift(We)}var mr=0,xr=null,Wr=null;function Vn(We){mr++,r.monitorRunDependencies&&r.monitorRunDependencies(mr)}function Ns(We){if(mr--,r.monitorRunDependencies&&r.monitorRunDependencies(mr),mr==0&&(xr!==null&&(clearInterval(xr),xr=null),Wr)){var tt=Wr;Wr=null,tt()}}r.preloadedImages={},r.preloadedAudios={};function Ri(We){r.onAbort&&r.onAbort(We),We+="",te(We),Pe=!0,g=1,We="abort("+We+"). Build with -s ASSERTIONS=1 for more info.";var tt=new WebAssembly.RuntimeError(We);throw a(tt),tt}var ps="data:application/octet-stream;base64,";function io(We){return We.startsWith(ps)}var Si="data:application/octet-stream;base64,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QCAAKAJIIgEgASADaiADEAcaAkAgAyAAKAJsIgFNBEAgACABIANrNgJsDAELIABCADcCbAsgACAAKAJoIANrIgE2AmggACAAKAJYIANrNgJYIAEgACgChC5JBEAgACABNgKELgsgAEH8gAEoAgARAwAgAiADaiECCwJAIAAoAgAiASgCBCIERQ0AIAAoAjwhBSAAIAIgBCACIARJGyICBH8gACgCSCAAKAJoaiAFaiEFIAEgBCACazYCBAJAAkACQAJAIAEoAhwiBCgCFEEBaw4CAQACCyAEQaABaiAFIAEoAgAgAkHcgAEoAgARCAAMAgsgASABKAIwIAUgASgCACACQcSAASgCABEEADYCMAwBCyAFIAEoAgAgAhAHGgsgASABKAIAIAJqNgIAIAEgASgCCCACajYCCCAAKAI8BSAFCyACaiICNgI8AkAgACgChC4iASACakEDSQ0AIAAoAmggAWshAQJAIAAoAnRBgQhPBEAgACAAIAAoAkggAWoiAi0AACACLQABIAAoAnwRAAA2AlQMAQsgAUUNACAAIAFBAWsgACgChAERAgAaCyAAKAKELiAAKAI8IgJBAUZrIgRFDQAgACABIAQgACgCgAERBQAgACAAKAKELiAEazYChC4gACgCPCECCyACQYUCSw0AIAAoAgAoAgRFDQAgACgCMCEBDAELCwJAIAAoAkQiAiAAKAJAIgNNDQAgAAJ/IAAoAjwgACgCaGoiASADSwRAIAAoAkggAWpBACACIAFrIgNBggIgA0GCAkkbIgMQGSABIANqDAELIAFBggJqIgEgA00NASAAKAJIIANqQQAgAiADayICIAEgA2siAyACIANJGyIDEBkgACgCQCADags2AkALC50CAQF/AkAgAAJ/IAAoAqAuIgFBwABGBEAgACgCBCAAKAIQaiAAKQOYLjcAACAAQgA3A5guIAAgACgCEEEIajYCEEEADAELIAFBIE4EQCAAKAIEIAAoAhBqIAApA5guPgAAIAAgAEGcLmo1AgA3A5guIAAgACgCEEEEajYCECAAIAAoAqAuQSBrIgE2AqAuCyABQRBOBEAgACgCBCAAKAIQaiAAKQOYLj0AACAAIAAoAhBBAmo2AhAgACAAKQOYLkIQiDcDmC4gACAAKAKgLkEQayIBNgKgLgsgAUEISA0BIAAgACgCECIBQQFqNgIQIAEgACgCBGogACkDmC48AAAgACAAKQOYLkIIiDcDmC4gACgCoC5BCGsLNgKgLgsLEAAgACgCCBAGIABBADYCCAvwAQECf0F/IQECQCAALQAoDQAgACgCJEEDRgRAIABBDGoEQCAAQQA2AhAgAEEXNgIMC0F/DwsCQCAAKAIgBEAgACkDGELAAINCAFINASAAQQxqBEAgAEEANgIQIABBHTYCDAtBfw8LAkAgACgCACICRQ0AIAIQMkF/Sg0AIAAoAgAhASAAQQxqIgAEQCAAIAEoAgw2AgAgACABKAIQNgIEC0F/DwsgAEEAQgBBABAOQn9VDQAgACgCACIARQ0BIAAQGhpBfw8LQQAhASAAQQA7ATQgAEEMagRAIABCADcCDAsgACAAKAIgQQFqNgIgCyABCzsAIAAtACgEfkJ/BSAAKAIgRQRAIABBDGoiAARAIABBADYCBCAAQRI2AgALQn8PCyAAQQBCAEEHEA4LC5oIAQt/IABFBEAgARAJDwsgAUFATwRAQYSEAUEwNgIAQQAPCwJ/QRAgAUELakF4cSABQQtJGyEGIABBCGsiBSgCBCIJQXhxIQQCQCAJQQNxRQRAQQAgBkGAAkkNAhogBkEEaiAETQRAIAUhAiAEIAZrQZSIASgCAEEBdE0NAgtBAAwCCyAEIAVqIQcCQCAEIAZPBEAgBCAGayIDQRBJDQEgBSAJQQFxIAZyQQJyNgIEIAUgBmoiAiADQQNyNgIEIAcgBygCBEEBcjYCBCACIAMQOwwBCyAHQcyEASgCAEYEQEHAhAEoAgAgBGoiBCAGTQ0CIAUgCUEBcSAGckECcjYCBCAFIAZqIgMgBCAGayICQQFyNgIEQcCEASACNgIAQcyEASADNgIADAELIAdByIQBKAIARgRAQbyEASgCACAEaiIDIAZJDQICQCADIAZrIgJBEE8EQCAFIAlBAXEgBnJBAnI2AgQgBSAGaiIEIAJBAXI2AgQgAyAFaiIDIAI2AgAgAyADKAIEQX5xNgIEDAELIAUgCUEBcSADckECcjYCBCADIAVqIgIgAigCBEEBcjYCBEEAIQJBACEEC0HIhAEgBDYCAEG8hAEgAjYCAAwBCyAHKAIEIgNBAnENASADQXhxIARqIgogBkkNASAKIAZrIQwCQCADQf8BTQRAIAcoAggiBCADQQN2IgJBA3RB3IQBakYaIAQgBygCDCIDRgRAQbSEAUG0hAEoAgBBfiACd3E2AgAMAgsgBCADNgIMIAMgBDYCCAwBCyAHKAIYIQsCQCAHIAcoAgwiCEcEQCAHKAIIIgJBxIQBKAIASRogAiAINgIMIAggAjYCCAwBCwJAIAdBFGoiBCgCACICDQAgB0EQaiIEKAIAIgINAEEAIQgMAQsDQCAEIQMgAiIIQRRqIgQoAgAiAg0AIAhBEGohBCAIKAIQIgINAAsgA0EANgIACyALRQ0AAkAgByAHKAIcIgNBAnRB5IYBaiICKAIARgRAIAIgCDYCACAIDQFBuIQBQbiEASgCAEF+IAN3cTYCAAwCCyALQRBBFCALKAIQIAdGG2ogCDYCACAIRQ0BCyAIIAs2AhggBygCECICBEAgCCACNgIQIAIgCDYCGAsgBygCFCICRQ0AIAggAjYCFCACIAg2AhgLIAxBD00EQCAFIAlBAXEgCnJBAnI2AgQgBSAKaiICIAIoAgRBAXI2AgQMAQsgBSAJQQFxIAZyQQJyNgIEIAUgBmoiAyAMQQNyNgIEIAUgCmoiAiACKAIEQQFyNgIEIAMgDBA7CyAFIQILIAILIgIEQCACQQhqDwsgARAJIgVFBEBBAA8LIAUgAEF8QXggAEEEaygCACICQQNxGyACQXhxaiICIAEgASACSxsQBxogABAGIAUL6QEBA38CQCABRQ0AIAJBgDBxIgIEfwJ/IAJBgCBHBEBBAiACQYAQRg0BGiADBEAgA0EANgIEIANBEjYCAAtBAA8LQQQLIQJBAAVBAQshBkEUEAkiBEUEQCADBEAgA0EANgIEIANBDjYCAAtBAA8LIAQgAUEBahAJIgU2AgAgBUUEQCAEEAZBAA8LIAUgACABEAcgAWpBADoAACAEQQA2AhAgBEIANwMIIAQgATsBBCAGDQAgBCACECNBBUcNACAEKAIAEAYgBCgCDBAGIAQQBkEAIQQgAwRAIANBADYCBCADQRI2AgALCyAEC7UBAQJ/AkACQAJAAkACQAJAAkAgAC0ABQRAIAAtAABBAnFFDQELIAAoAjAQECAAQQA2AjAgAC0ABUUNAQsgAC0AAEEIcUUNAQsgACgCNBAcIABBADYCNCAALQAFRQ0BCyAALQAAQQRxRQ0BCyAAKAI4EBAgAEEANgI4IAAtAAVFDQELIAAtAABBgAFxRQ0BCyAAKAJUIgEEfyABQQAgARAiEBkgACgCVAVBAAsQBiAAQQA2AlQLC9wMAgl/AX4jAEFAaiIGJAACQAJAAkACQAJAIAEoAjBBABAjIgVBAkZBACABKAI4QQAQIyIEQQFGGw0AIAVBAUZBACAEQQJGGw0AIAVBAkciAw0BIARBAkcNAQsgASABLwEMQYAQcjsBDEEAIQMMAQsgASABLwEMQf/vA3E7AQxBACEFIANFBEBB9eABIAEoAjAgAEEIahBpIgVFDQILIAJBgAJxBEAgBSEDDAELIARBAkcEQCAFIQMMAQtB9cYBIAEoAjggAEEIahBpIgNFBEAgBRAcDAILIAMgBTYCAAsgASABLwEMQf7/A3EgAS8BUiIFQQBHcjsBDAJAAkACQAJAAn8CQAJAIAEpAyhC/v///w9WDQAgASkDIEL+////D1YNACACQYAEcUUNASABKQNIQv////8PVA0BCyAFQYECa0H//wNxQQNJIQdBAQwBCyAFQYECa0H//wNxIQQgAkGACnFBgApHDQEgBEEDSSEHQQALIQkgBkIcEBciBEUEQCAAQQhqIgAEQCAAQQA2AgQgAEEONgIACyADEBwMBQsgAkGACHEhBQJAAkAgAkGAAnEEQAJAIAUNACABKQMgQv////8PVg0AIAEpAyhCgICAgBBUDQMLIAQgASkDKBAYIAEpAyAhDAwBCwJAAkACQCAFDQAgASkDIEL/////D1YNACABKQMoIgxC/////w9WDQEgASkDSEKAgICAEFQNBAsgASkDKCIMQv////8PVA0BCyAEIAwQGAsgASkDICIMQv////8PWgRAIAQgDBAYCyABKQNIIgxC/////w9UDQELIAQgDBAYCyAELQAARQRAIABBCGoiAARAIABBADYCBCAAQRQ2AgALIAQQCCADEBwMBQtBASEKQQEgBC0AAAR+IAQpAxAFQgALp0H//wNxIAYQRyEFIAQQCCAFIAM2AgAgBw0BDAILIAMhBSAEQQJLDQELIAZCBxAXIgRFBEAgAEEIaiIABEAgAEEANgIEIABBDjYCAAsgBRAcDAMLIARBAhANIARBhxJBAhAsIAQgAS0AUhBwIAQgAS8BEBANIAQtAABFBEAgAEEIaiIABEAgAEEANgIEIABBFDYCAAsgBBAIDAILQYGyAkEHIAYQRyEDIAQQCCADIAU2AgBBASEL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NgIEIABB7A42AhggGiEdDAMLIARB/wFxIgJBwABxRQRAIAggDSADLwECQQJ0aiAdp0F/IAJ0QX9zcUECdGoiAy0AASICayEIIB0gAq2IIR0gAy0AACIERQ0HDAELCyAEQSBxBEAgB0G//gA2AgQgASECDAgLIAdB0f4ANgIEIABB0A42AhggASECDAcLIB1BfyAGdEF/c62DIBt8IhunIQUgCCAEQQ9xIgNrIQggGiAErUIPg4ghHSABIBdrIgYgAjMBAiAaQX8gA3RBf3Otg3ynIgRPDQIgBCAGayIGIBlNDQEgBygCjEdFDQEgB0HR/gA2AgQgAEG5DDYCGAsgASECIAshBQwFCwJAIA5FBEAgDCARIAZraiEDDAELIAYgDk0EQCAMIA4gBmtqIQMMAQsgDCARIAYgDmsiBmtqIQMgBSAGTQ0AIAUgBmshBQJAAkAgASADTSABIA8gAWusIhogBq0iGyAaIBtUGyIapyIGaiICIANLcQ0AIAMgBmogAUsgASADT3ENACABIAMgBhAHGiACIQEMAQsgASADIAMgAWsiASABQR91IgFqIAFzIgIQByACaiEBIBogAq0iHn0iHFANACACIANqIQIDQAJAIBwgHiAcIB5UGyIbQiBUBEAgGyEaDAELIBsiGkIgfSIgQgWIQgF8QgODIh9QRQRAA0AgASACKQAANwAAIAEgAikAGDcAGCABIAIpABA3ABAgASACKQAINwAIIBpCIH0hGiACQSBqIQIgAUEgaiEBIB9CAX0iH0IAUg0ACwsgIELgAFQNAANAIAEgAikAADcAACABIAIpABg3ABggASACKQAQNwAQIAEgAikACDcACCABIAIpADg3ADggASACKQAwNwAwIAEgAikAKDcAKCABIAIpACA3ACAgASACKQBYNwBYIAEgAikAUDcAUCABIAIpAEg3AEggASACKQBANwBAIAEgAikAYDcAYCABIAIpAGg3AGggASACKQBwNwBwIAEgAikAeDcAeCACQYABaiECIAFBgAFqIQEgGkKAAX0iGkIfVg0ACwsgGkIQWgRAIAEgAikAADcAACABIAIpAAg3AAggGkIQfSEaIAJBEGohAiABQRBqIQELIBpCCFoEQCABIAIpAAA3AAAgGkIIfSEaIAJBCGohAiABQQhqIQELIBpCBFoEQCABIAIoAAA2AAAgGkIEfSEaIAJBBGohAiABQQRqIQELIBpCAloEQCABIAIvAAA7AAAgGkICfSEaIAJBAmohAiABQQJqIQELIBwgG30hHCAaUEUEQCABIAItAAA6AAAgAkEBaiECIAFBAWohAQsgHEIAUg0ACwsgDiEGIAwhAwsgBSAGSwRAAkACQCABIANNIAEgDyABa6wiGiAGrSIbIBogG1QbIhqnIglqIgIgA0txDQAgAyAJaiABSyABIANPcQ0AIAEgAyAJEAcaDAELIAEgAyADIAFrIgEgAUEfdSIBaiABcyIBEAcgAWohAiAaIAGtIh59IhxQDQAgASADaiEBA0ACQCAcIB4gHCAeVBsiG0IgVARAIBshGgwBCyAbIhpCIH0iIEIFiEIBfEIDgyIfUEUEQANAIAIgASkAADcAACACIAEpABg3ABggAiABKQAQNwAQIAIgASkACDcACCAaQiB9IRogAUEgaiEBIAJBIGohAiAfQgF9Ih9CAFINAAsLICBC4ABUDQADQCACIAEpAAA3AAAgAiABKQAYNwAYIAIgASkAEDcAECACIAEpAAg3AAggAiABKQA4NwA4IAIgASkAMDcAMCACIAEpACg3ACggAiABKQAgNwAgIAIgASkAWDcAWCACIAEpAFA3AFAgAiABKQBINwBIIAIgASkAQDcAQCACIAEpAGA3AGAgAiABKQBoNwBoIAIgASkAcDcAcCACIAEpAHg3AHggAUGAAWohASACQYABaiECIBpCgAF9IhpCH1YNAAsLIBpCEFoEQCACIAEpAAA3AAAgAiABKQAINwAIIBpCEH0hGiACQRBqIQIgAUEQaiEBCyAaQghaBEAgAiABKQAANwAAIBpCCH0hGiACQQhqIQIgAUEIaiEBCyAaQgRaBEAgAiABKAAANgAAIBpCBH0hGiACQQRqIQIgAUEEaiEBCyAaQgJaBEAgAiABLwAAOwAAIBpCAn0hGiACQQJqIQIgAUECaiEBCyAcIBt9IRwgGlBFBEAgAiABLQAAOgAAIAJBAWohAiABQQFqIQELIBxCAFINAAsLIAUgBmshAUEAIARrIQUCQCAEQQdLBEAgBCEDDAELIAEgBE0EQCAEIQMMAQsgAiAEayEFA0ACQCACIAUpAAA3AAAgBEEBdCEDIAEgBGshASACIARqIQIgBEEDSw0AIAMhBCABIANLDQELC0EAIANrIQULIAIgBWohBAJAIAUgDyACa6wiGiABrSIbIBogG1QbIhqnIgFIIAVBf0pxDQAgBUEBSCABIARqIAJLcQ0AIAIgBCABEAcgAWohAgwDCyACIAQgAyADQR91IgFqIAFzIgEQByABaiECIBogAa0iHn0iHFANAiABIARqIQEDQAJAIBwgHiAcIB5UGyIbQiBUBEAgGyEaDAELIBsiGkIgfSIgQgWIQgF8QgODIh9QRQRAA0AgAiABKQAANwAAIAIgASkAGDcAGCACIAEpABA3ABAgAiABKQAINwAIIBpCIH0hGiABQSBqIQEgAkEgaiECIB9CAX0iH0IAUg0ACwsgIELgAFQNAANAIAIgASkAADcAACACIAEpABg3ABggAiABKQAQNwAQIAIgASkACDcACCACIAEpADg3ADggAiABKQAwNwAwIAIgASkAKDcAKCACIAEpACA3ACAgAiABKQBYNwBYIAIgASkAUDcAUCACIAEpAEg3AEggAiABKQBANwBAIAIgASkAYDcAYCACIAEpAGg3AGggAiABKQBwNwBwIAIgASkAeDcAeCABQYABaiEBIAJBgAFqIQIgGkKAAX0iGkIfVg0ACwsgGkIQWgRAIAIgASkAADcAACACIAEpAAg3AAggGkIQfSEaIAJBEGohAiABQRBqIQELIBpCCFoEQCACIAEpAAA3AAAgGkIIfSEaIAJBCGohAiABQQhqIQELIBpCBFoEQCACIAEoAAA2AAAgGkIEfSEaIAJBBGohAiABQQRqIQELIBpCAloEQCACIAEvAAA7AAAgGkICfSEaIAJBAmohAiABQQJqIQELIBwgG30hHCAaUEUEQCACIAEtAAA6AAAgAkEBaiECIAFBAWohAQsgHFBFDQALDAILAkAgASADTSABIA8gAWusIhogBa0iGyAaIBtUGyIapyIEaiICIANLcQ0AIAMgBGogAUsgASADT3ENACABIAMgBBAHGgwCCyABIAMgAyABayIBIAFBH3UiAWogAXMiARAHIAFqIQIgGiABrSIefSIcUA0BIAEgA2ohAQNAAkAgHCAeIBwgHlQbIhtCIFQEQCAbIRoMAQsgGyIaQiB9IiBCBYhCAXxCA4MiH1BFBEADQCACIAEpAAA3AAAgAiABKQAYNwAYIAIgASkAEDcAECACIAEpAAg3AAggGkIgfSEaIAFBIGohASACQSBqIQIgH0IBfSIfQgBSDQALCyAgQuAAVA0AA0AgAiABKQAANwAAIAIgASkAGDcAGCACIAEpABA3ABAgAiABKQAINwAIIAIgASkAODcAOCACIAEpADA3ADAgAiABKQAoNwAoIAIgASkAIDcAICACIAEpAFg3AFggAiABKQBQNwBQIAIgASkASDcASCACIAEpAEA3AEAgAiABKQBgNwBgIAIgASkAaDcAaCACIAEpAHA3AHAgAiABKQB4NwB4IAFBgAFqIQEgAkGAAWohAiAaQoABfSIaQh9WDQALCyAaQhBaBEAgAiABKQAANwAAIAIgASkACDcACCAaQhB9IRogAkEQaiECIAFBEGohAQsgGkIIWgRAIAIgASkAADcAACAaQgh9IRogAkEIaiECIAFBCGohAQsgGkIEWgRAIAIgASgAADYAACAaQgR9IRogAkEEaiECIAFBBGohAQsgGkICWgRAIAIgAS8AADsAACAaQgJ9IRogAkECaiECIAFBAmohAQsgHCAbfSEcIBpQRQRAIAIgAS0AADoAACACQQFqIQIgAUEBaiEBCyAcUEUNAAsMAQsCQAJAIBYEQAJAIAQgBUkEQCAHKAKYRyAESw0BCyABIARrIQMCQEEAIARrIgVBf0ogDyABa6wiGiAbIBogG1QbIhqnIgIgBUpxDQAgBUEBSCACIANqIAFLcQ0AIAEgAyACEAcgAmohAgwFCyABIAMgBCAEQR91IgFqIAFzIgEQByABaiECIBogAa0iHn0iHFANBCABIANqIQEDQAJAIBwgHiAcIB5UGyIbQiBUBEAgGyEaDAELIBsiGkIgfSIgQgWIQgF8QgODIh9QRQRAA0AgAiABKQAANwAAIAIgASkAGDcAGCACIAEpABA3ABAgAiABKQAINwAIIBpCIH0hGiABQSBqIQEgAkEgaiECIB9CAX0iH0IAUg0ACwsgIELgAFQNAANAIAIgASkAADcAACACIAEpABg3ABggAiABKQAQNwAQIAIgASkACDcACCACIAEpADg3ADggAiABKQAwNwAwIAIgASkAKDcAKCACIAEpACA3ACAgAiABKQBYNwBYIAIgASkAUDcAUCACIAEpAEg3AEggAiABKQBANwBAIAIgASkAYDcAYCACIAEpAGg3AGggAiABKQBwNwBwIAIgASkAeDcAeCABQYABaiEBIAJBgAFqIQIgGkKAAX0iGkIfVg0ACwsgGkIQWgRAIAIgASkAADcAACACIAEpAAg3AAggGkIQfSEaIAJBEGohAiABQRBqIQELIBpCCFoEQCACIAEpAAA3AAAgGkIIfSEaIAJBCGohAiABQQhqIQELIBpCBFoEQCACIAEoAAA2AAAgGkIEfSEaIAJBBGohAiABQQRqIQELIBpCAloEQCACIAEvAAA7AAAgGkICfSEaIAJBAmohAiABQQJqIQELIBwgG30hHCAaUEUEQCACIAEtAAA6AAAgAkEBaiECIAFBAWohAQsgHFBFDQALDAQLIBAgAWsiCUEBaiIGIAUgBSAGSxshAyABIARrIQIgAUEHcUUNAiADRQ0CIAEgAi0AADoAACACQQFqIQIgAUEBaiIGQQdxQQAgA0EBayIFGw0BIAYhASAFIQMgCSEGDAILAkAgBCAFSQRAIAcoAphHIARLDQELIAEgASAEayIGKQAANwAAIAEgBUEBa0EHcUEBaiIDaiECIAUgA2siBEUNAyADIAZqIQEDQCACIAEpAAA3AAAgAUEIaiEBIAJBCGohAiAEQQhrIgQNAAsMAwsgASAEIAUQPyECDAILIAEgAi0AADoAASAJQQFrIQYgA0ECayEFIAJBAWohAgJAIAFBAmoiCkEHcUUNACAFRQ0AIAEgAi0AADoAAiAJQQJrIQYgA0EDayEFIAJBAWohAgJAIAFBA2oiCkEHcUUNACAFRQ0AIAEgAi0AADoAAyAJQQNrIQYgA0EEayEFIAJBAWohAgJAIAFBBGoiCkEHcUUNACAFRQ0AIAEgAi0AADoABCAJQQRrIQYgA0EFayEFIAJBAWohAgJAIAFBBWoiCkEHcUUNACAFRQ0AIAEgAi0AADoABSAJQQVrIQYgA0EGayEFIAJBAWohAgJAIAFBBmoiCkEHcUUNACAFRQ0AIAEgAi0AADoABiAJQQZrIQYgA0EHayEFIAJBAWohAgJAIAFBB2oiCkEHcUUNACAFRQ0AIAEgAi0AADoAByAJQQdrIQYgA0EIayEDIAFBCGohASACQQFqIQIMBgsgCiEBIAUhAwwFCyAKIQEgBSEDDAQLIAohASAFIQMMAwsgCiEBIAUhAwwCCyAKIQEgBSEDDAELIAohASAFIQMLAkACQCAGQRdNBEAgA0UNASADQQFrIQUgA0EHcSIEBEADQCABIAItAAA6AAAgA0EBayEDIAFBAWohASACQQFqIQIgBEEBayIEDQALCyAFQQdJDQEDQCABIAItAAA6AAAgASACLQABOgABIAEgAi0AAjoAAiABIAItAAM6AAMgASACLQAEOgAEIAEgAi0ABToABSABIAItAAY6AAYgASACLQAHOgAHIAFBCGohASACQQhqIQIgA0EIayIDDQALDAELIAMNAQsgASECDAELIAEgBCADED8hAgsgCyEFDAELIAEgAy0AAjoAACABQQFqIQILIAUgFE8NACACIBNJDQELCyAAIAI2AgwgACAFIAhBA3ZrIgE2AgAgACATIAJrQYMCajYCECAAIBQgAWtBDmo2AgQgByAIQQdxIgA2AogBIAcgHUJ/IACthkJ/hYM+AoQBC+cFAQR/IAMgAiACIANLGyEEIAAgAWshAgJAIABBB3FFDQAgBEUNACAAIAItAAA6AAAgA0EBayEGIAJBAWohAiAAQQFqIgdBB3FBACAEQQFrIgUbRQRAIAchACAFIQQgBiEDDAELIAAgAi0AADoAASADQQJrIQYgBEECayEFIAJBAWohAgJAIABBAmoiB0EHcUUNACAFRQ0AIAAgAi0AADoAAiADQQNrIQYgBEEDayEFIAJBAWohAgJAIABBA2oiB0EHcUUNACAFRQ0AIAAgAi0AADoAAyADQQRrIQYgBEEEayEFIAJBAWohAgJAIABBBGoiB0EHcUUNACAFRQ0AIAAgAi0AADoABCADQQVrIQYgBEEFayEFIAJBAWohAgJAIABBBWoiB0EHcUUNACAFRQ0AIAAgAi0AADoABSADQQZrIQYgBEEGayEFIAJBAWohAgJAIABBBmoiB0EHcUUNACAFRQ0AIAAgAi0AADoABiADQQdrIQYgBEEHayEFIAJBAWohAgJAIABBB2oiB0EHcUUNACAFRQ0AIAAgAi0AADoAByADQQhrIQMgBEEIayEEIABBCGohACACQQFqIQIMBgsgByEAIAUhBCAGIQMMBQsgByEAIAUhBCAGIQMMBAsgByEAIAUhBCAGIQMMAwsgByEAIAUhBCAGIQMMAgsgByEAIAUhBCAGIQMMAQsgByEAIAUhBCAGIQMLAkAgA0EXTQRAIARFDQEgBEEBayEBIARBB3EiAwRAA0AgACACLQAAOgAAIARBAWshBCAAQQFqIQAgAkEBaiECIANBAWsi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CyAAIAMtAAAEfiADKQMQBUIAC6dB//8DcSADKAIEEEcLIQUgAxAICyAEQRBqJAAgBQvgAQICfwF+QTAQCSICRQRAIAEEQCABQQA2AgQgAUEONgIAC0EADwsgAkIANwMIIAJBADYCACACQgA3AxAgAkIANwMYIAJCADcDICACQgA3ACUgAFAEQCACDwsCQCAAQv////8AVg0AIACnQQR0EAkiA0UNACACIAM2AgBBACEBQgEhBANAIAMgAUEEdGoiAUIANwIAIAFCADcABSAAIARSBEAgBKchASAEQgF8IQQMAQsLIAIgADcDCCACIAA3AxAgAg8LIAEEQCABQQA2AgQgAUEONgIAC0EAEBAgAhAGQQAL7gECA38BfiMAQRBrIgQkAAJAIARBDGpCBBAXIgNFBEBBfyECDAELAkAgAQRAIAJBgAZxIQUDQAJAIAUgASgCBHFFDQACQCADKQMIQgBUBEAgA0EAOgAADAELIANCADcDECADQQE6AAALIAMgAS8BCBANIAMgAS8BChANIAMtAABFBEAgAEEIaiIABEAgAEEANgIEIABBFDYCAAtBfyECDAQLQX8hAiAAIARBDGpCBBAbQQBIDQMgATMBCiIGUA0AIAAgASgCDCAGEBtBAEgNAwsgASgCACIBDQALC0EAIQILIAMQCAsgBEEQaiQAIAILPAEBfyAABEAgAUGABnEhAQNAIAEgACgCBHEEQCACIAAvAQpqQQRqIQILIAAoAgAiAA0ACwsgAkH//wNxC5wBAQN/IABFBEBBAA8LIAAhAwNAAn8CQAJAIAAvAQgiAUH04AFNBEAgAUEBRg0BIAFB9cYBRg0BDAILIAFBgbICRg0AIAFB9eABRw0BCyAAKAIAIQEgAEEANgIAIAAoAgwQBiAAEAYgASADIAAgA0YbIQMCQCACRQRAQQAhAgwBCyACIAE2AgALIAEMAQsgACICKAIACyIADQALIAMLsgQCBX8BfgJAAkACQCAAIAGtEBciAQRAIAEtAAANAUEAIQAMAgsgBARAIARBADYCBCAEQQ42AgALQQAPC0EAIQADQCABLQAABH4gASkDCCABKQMQfQVCAAtCBFQNASABEAwhByABIAEQDCIGrRATIghFBEBBACECIAQEQCAEQQA2AgQgBEEVNgIACyABEAggAEUNAwNAIAAoAgAhASAAKAIMEAYg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DCAAQRg2AggLDAMLIAAgBiAFLwFqQQAgBCABEQYAIQEgBhALIAFFDQILAkAgDUUEQCABIQMMAQsgACABIAUvAWgQgQEhAyABEAsgA0UNAQsCQCAJRSAMckUEQCADIQEMAQsgACADQQEQgAEhASADEAsgAUUNAQsgASEDDAELQQAhAwsgBUHwAGokACADC4UBAQF/IAFFBEAgAEEIaiIABEAgAEEANgIEIABBEjYCAAtBAA8LQTgQCSIDRQRAIABBCGoiAARAIABBADYCBCAAQQ42AgALQQAPCyADQQA2AhAgA0IANwIIIANCADcDKCADQQA2AgQgAyACNgIAIANCADcDGCADQQA2AjAgACABQTsgAxBCCw8AIAAgASACQQBBABCCAQusAgECfyABRQRAIABBCGoiAARAIABBADYCBCAAQRI2AgALQQAPCwJAIAJBfUsNACACQf//A3FBCEYNACAAQQhqIgAEQCAAQQA2AgQgAEEQNgIAC0EADwsCQEGwwAAQCSIFBEAgBUEANgIIIAVCADcCACAFQYiBAUGogQEgAxs2AqhAIAUgAjYCFCAFIAM6ABAgBUEAOgAPIAVBADsBDCAFIAMgAkF9SyIGcToADiAFQQggAiAGG0H//wNxIAQgBUGIgQFBqIEBIAMbKAIAEQAAIgI2AqxAIAINASAFEDEgBRAGCyAAQQhqIgAEQCAAQQA2AgQgAEEONgIAC0EADwsgACABQTogBRBCIgAEfyAABSAFKAKsQCAFKAKoQCgCBBEDACAFEDEgBRAGQQALC6ABAQF/IAIgACgCBCIDIAIgA0kbIgIEQCAAIAMgAms2AgQCQAJAAkACQCAAKAIcIgMoAhRBAWsOAgEAAgsgA0GgAWogASAAKAIAIAJB3IABKAIAEQgADAILIAAgACgCMCABIAAoAgAgAkHEgAEoAgARBAA2AjAMAQsgASAAKAIAIAIQBxoLIAAgACgCACACajYCACAAIAAoAgggAmo2AggLC7cCAQR/QX4hAgJAIABFDQAgACgCIEUNACAAKAIkIgRFDQAgACgCHCIBRQ0AIAEoAgAgAEcNAAJAAkAgASgCICIDQTlrDjkBAgICAgICAgICAgIBAgICAQICAgICAgICAgICAgICAgICAQICAgICAgICAgICAQICAgICAgICAgEACyADQZoFRg0AIANBKkcN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DCABajYCDCAGIAYoAgggAWo2AgggBSAFKAIUIAFqNgIUIAUgBSgCECABazYCECAGIAYoAhAgAWsiATYCECABDQAgBiAGKAIENgIIC0EAIQRBACEJIAMoAhBFDQAMCgsgAygCHCgCJCEGIAMgAygCGCIBQQFqNgIYIAEgBmotAAAhASADIARBAWo2AhAgAygCBCAEaiABOgAAIAEEQCADKAIQIQQMAQsLIAMoAhwoAixFDQAgAygCECIGIAlNDQAgBQJ/IAUoAjAhBEEAIAMoAgQgCWoiAUUNABogBCABIAYgCWtB1IABKAIAEQAACzYCMAsgA0HnADYCIAsCQCADKAIcKAIsBEAgAygCDCADKAIQIgFBAmpJBH8gBRAKIAMoAhANAkEABSABCyADKAIEaiAFKAIwOwAAIAMgAygCEEECajYCECADQaABakHkgAEoAgARAQAaCyADQfEANgIgIAUQCiADKAIQRQ0BDAcLDAYLIAUoAgQNAQsgAygCPA0AIApFDQEgAygCIEGaBUYNAQsCfyADKAKIASIBRQRAIAMgChCFAQwBCwJAAkACQCADKAKMAUECaw4CAAECCwJ/AkADQAJAAkAgAygCPA0AIAMQLyADKAI8DQAgCg0BQQAMBAsgAygCSCADKAJoai0AACEEIAMgAygC8C0iAUEBajYC8C0gASADKALsLWpBADoAACADIAMoAvAtIgFBAWo2AvAtIAEgAygC7C1qQQA6AAAgAyADKALwLSIBQQFqNgLwLSABIAMoAuwtaiAEOgAAIAMgBEECdGoiASABLwHkAUEBajsB5AEgAyADKAI8QQFrNgI8IAMgAygCaEEBaiIBNgJoIAMoAvAtIAMoAvQtRw0BQQAhBCADIAMoAlgiBkEATgR/IAMoAkggBmoFQQALIAEgBmtBABAPIAMgAygCaDYCWCADKAIAEAogAygCACgCEA0BDAILCyADQQA2AoQuIApBBEYEQCADIAMoAlgiAUEATgR/IAMoAkggAWoFQQALIAMoAmggAWtBARAPIAMgAygCaDYCWCADKAIAEApBA0ECIAMoAgAoAhAbDAILIAMoAvAtBEBBACEEIAMgAygCWCIBQQBOBH8gAygCSCABagVBAAsgAygCaCABa0EAEA8gAyADKAJoNgJYIAMoAgAQCiADKAIAKAIQRQ0BC0EBIQQLIAQL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bGl0ZXJhbC9sZW5ndGhzIHNldABpbnZhbGlkIGNvZGUgbGVuZ3RocyBzZXQAdW5rbm93biBoZWFkZXIgZmxhZ3Mgc2V0AGludmFsaWQgZGlzdGFuY2VzIHNldABpbnZhbGlkIGJpdCBsZW5ndGggcmVwZWF0AEZpbGUgYWxyZWFkeSBleGlzdHMAdG9vIG1hbnkgbGVuZ3RoIG9yIGRpc3RhbmNlIHN5bWJvbHMAaW52YWxpZCBzdG9yZWQgYmxvY2sgbGVuZ3RocwAlcyVzJXMAYnVmZmVyIGVycm9yAE5vIGVycm9yAHN0cmVhbSBlcnJvcgBUZWxsIGVycm9yAEludGVybmFsIGVycm9yAFNlZWsgZXJyb3IAV3JpdGUgZXJyb3IAZmlsZSBlcnJvcgBSZWFkIGVycm9yAFpsaWIgZXJyb3IAZGF0YSBlcnJvcgBDUkMgZXJyb3IAaW5jb21wYXRpYmxlIHZlcnNpb24AaW52YWxpZCBjb2RlIC0tIG1pc3NpbmcgZW5kLW9mLWJsb2NrAGluY29ycmVjdCBoZWFkZXIgY2hlY2sAaW5jb3JyZWN0IGxlbmd0aCBjaGVjawBpbmNvcnJlY3QgZGF0YSBjaGVjawBpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjawBoZWFkZXIgY3JjIG1pc21hdGNoADEuMi4xMy56bGliLW5nAGludmFsaWQgd2luZG93IHNpemUAUmVhZC1vbmx5IGFyY2hpdmUATm90IGEgemlwIGFyY2hpdmUAUmVzb3VyY2Ugc3RpbGwgaW4gdXNlAE1hbGxvYyBmYWlsdXJlAGludmFsaWQgYmxvY2sgdHlwZQBGYWlsdXJlIHRvIGNyZWF0ZSB0ZW1wb3JhcnkgZmlsZQBDYW4ndCBvcGVuIGZpbGUATm8gc3VjaCBmaWxlAFByZW1hdHVyZSBlbmQgb2YgZmlsZQBDYW4ndCByZW1vdmUgZmlsZQBpbnZhbGlkIGxpdGVyYWwvbGVuZ3RoIGNvZGUAaW52YWxpZCBkaXN0YW5jZSBjb2RlAHVua25vd24gY29tcHJlc3Npb24gbWV0aG9kAHN0cmVhbSBlbmQAQ29tcHJlc3NlZCBkYXRhIGludmFsaWQATXVsdGktZGlzayB6aXAgYXJjaGl2ZXMgbm90IHN1cHBvcnRl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UgAIANIACAAyAAgAsgAIAHIACADyAAgACgAIAIoACABKAAgAygAIACoACACqAAgAagAIAOoACAAaAAgAmgAIAFoACADaAAgAOgAIALoACAB6AAgA+gAIAAYACACGAAgARgAIAMYACAAmAAgApgAIAGYACADmAAgAFgAIAJYACABWAAgA1gAIADYACAC2AAgAdgAIAPYACAAOAAgAjgAIAE4ACADOAAgALgAIAK4ACABuAAgA7gAIAB4ACACeAAgAXgAIAN4ACAA+AAgAvgAIAH4ACAD+AAgAAQAIAIEACABBAAgAwQAIACEACAChAAgAYQAIAOEACAARAAgAkQAIAFEACADRAAgAMQAIALEACABxAAgA8QAIAAkACACJAAgASQAIAMkACAApAAgAqQAIAGkACADpAAgAGQAIAJkACABZAAgA2QAIADkACAC5AAgAeQAIAPkACAAFAAgAhQAIAEUACADFAAgAJQAIAKUACABlAAgA5QAIABUACACVAAgAVQAIANUACAA1AAgAtQAIAHUACAD1AAgADQAIAI0ACABNAAgAzQAIAC0ACACtAAgAbQAIAO0ACAAdAAgAnQAIAF0ACADdAAgAPQAIAL0ACAB9AAgA/QAIABMACQATAQkAkwAJAJMBCQBTAAkAUwEJANMACQDTAQkAMwAJADMBCQCzAAkAswEJAHMACQBzAQkA8wAJAPMBCQALAAkACwEJAIsACQCLAQkASwAJAEsBCQDLAAkAywEJACsACQArAQkAqwAJAKsBCQBrAAkAawEJAOsACQDrAQkAGwAJABsBCQCbAAkAmwEJAFsACQBbAQkA2wAJANsBCQA7AAkAOwEJALsACQC7AQkAewAJAHsBCQD7AAkA+wEJAAcACQAHAQkAhwAJAIcBCQBHAAkARwEJAMcACQDHAQkAJwAJACcBCQCnAAkApwEJAGcACQBnAQkA5wAJAOcBCQAXAAkAFwEJAJcACQCXAQkAVwAJAFcBCQDXAAkA1wEJADcACQA3AQkAtwAJALcBCQB3AAkAdwEJAPcACQD3AQkADwAJAA8BCQCPAAkAjwEJAE8ACQBPAQkAzwAJAM8BCQAvAAkALwEJAK8ACQCvAQkAbwAJAG8BCQDvAAkA7wEJAB8ACQAfAQkAnwAJAJ8BCQBfAAkAXwEJAN8ACQDfAQkAPwAJAD8BCQC/AAkA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SXMgYSBkaXJlY3RvcnkAVGV4dCBmaWxlIGJ1c3kARXhlYyBmb3JtYXQgZXJyb3IASW52YWxpZCBhcmd1bWVudABBcmd1bWVudCBsaXN0IHRvbyBsb25nAFN5bWJvbGljIGxpbmsgbG9vcABGaWxlbmFtZSB0b28gbG9uZwBUb28gbWFueSBvcGVuIGZpbGVzIGluIHN5c3RlbQBObyBmaWxlIGRlc2NyaXB0b3JzIGF2YWlsYWJsZQBCYWQgZmlsZSBkZXNjcmlwdG9yAE5vIGNoaWxkIHByb2Nlc3MAQmFkIGFkZHJlc3MARmlsZSB0b28gbGFyZ2UAVG9vIG1hbnkgbGlua3MATm8gbG9ja3MgYXZhaWxhYmxlAFJlc291cmNlIGRlYWRsb2NrIHdvdWxkIG9jY3VyAFN0YXRlIG5vdCByZWNvdmVyYWJsZQBQcmV2aW91cyBvd25lciBkaWVkAE9wZXJhdGlvbiBjYW5jZWxlZABGdW5jdGlvbiBub3QgaW1wbGVtZW50ZWQATm8gbWVzc2FnZSBvZiBkZXNpcmVkIHR5cGUASWRlbnRpZmllciByZW1vdmVkAERldmljZSBub3QgYSBzdHJlYW0ATm8gZGF0YSBhdmFpbGFibGUARGV2aWNlIHRpbWVvdXQAT3V0IG9mIHN0cmVhbXMgcmVzb3VyY2VzAExpbmsgaGFzIGJlZW4gc2V2ZXJlZABQcm90b2NvbCBlcnJvcgBCYWQgbWVzc2FnZQBGaWxlIGRlc2NyaXB0b3IgaW4gYmFkIHN0YXRlAE5vdCBhIHNvY2tldABEZXN0aW5hdGlvbiBhZGRyZXNzIHJlcXVpcmVkAE1lc3NhZ2UgdG9vIGxhcmdlAFByb3RvY29sIHdyb25nIHR5cGUgZm9yIHNvY2tldABQcm90b2NvbCBub3QgYXZhaWxhYmxlAFByb3RvY29sIG5vdCBzdXBwb3J0ZWQAU29ja2V0IHR5cGUgbm90IHN1cHBvcnRlZABOb3Qgc3VwcG9ydGVkAFByb3RvY29sIGZhbWlseSBub3Qgc3VwcG9ydGVkAEFkZHJlc3MgZmFtaWx5IG5vdCBzdXBwb3J0ZWQgYnkgcHJvdG9jb2wAQWRkcmVzcyBub3QgYXZhaWxhYmxlAE5ldHdvcmsgaXMgZG93bgBOZXR3b3JrIHVucmVhY2hhYmxlAENvbm5lY3Rpb24gcmVzZXQgYnkgbmV0d29yawBDb25uZWN0aW9uIGFib3J0ZWQATm8gYnVmZmVyIHNwYWNlIGF2YWlsYWJsZQBTb2NrZXQgaXMgY29ubmVjdGVkAFNvY2tldCBub3QgY29ubmVjdGVkAENhbm5vdCBzZW5kIGFmdGVyIHNvY2tldCBzaHV0ZG93bgBPcGVyYXRpb24gYWxyZWFkeSBpbiBwcm9ncmVzcwBPcGVyYXRpb24gaW4gcHJvZ3Jlc3MAU3RhbGUgZmlsZSBoYW5kbGUAUmVtb3RlIEkvTyBlcnJvcgBRdW90YSBleGNlZWRlZABObyBtZWRpdW0gZm91bmQAV3JvbmcgbWVkaXVtIHR5cGUATm8gZXJyb3IgaW5mb3JtYXRpb24AQcCAAQuFARMAAAAUAAAAFQAAABYAAAAXAAAAGAAAABkAAAAaAAAAGwAAABwAAAAdAAAAHgAAAB8AAAAgAAAAIQAAACIAAAAjAAAAgERQADEAAAAyAAAAMwAAADQAAAA1AAAANgAAADcAAAA4AAAAOQAAADIAAAAzAAAANAAAADUAAAA2AAAANwAAADgAQfSCAQsCXEQAQbCDAQsQ/////////////////////w==";io(Si)||(Si=b(Si));function Ls(We){try{if(We==Si&&Ae)return new Uint8Array(Ae);var tt=ii(We);if(tt)return tt;if(T)return T(We);throw"sync fetching of the wasm failed: you can preload it to Module['wasmBinary'] manually, or emcc.py will do that for you when generating HTML (but not JS)"}catch(It){Ri(It)}}function so(We,tt){var It,nr,$;try{$=Ls(We),nr=new WebAssembly.Module($),It=new WebAssembly.Instance(nr,tt)}catch(Le){var me=Le.toString();throw te("failed to compile wasm module: "+me),(me.includes("imported Memory")||me.includes("memory import"))&&te("Memory size incompatibility issues may be due to changing INITIAL_MEMORY at runtime to something too large. Use ALLOW_MEMORY_GROWTH to allow any size memory (and also make sure not to set INITIAL_MEMORY at runtime to something smaller than it was at compile time)."),Le}return[It,nr]}function cc(){var We={a:Oa};function tt($,me){var Le=$.exports;r.asm=Le,we=r.asm.g,z(we.buffer),Z=r.asm.W,an(r.asm.h),Ns("wasm-instantiate")}if(Vn("wasm-instantiate"),r.instantiateWasm)try{var It=r.instantiateWasm(We,tt);return It}catch($){return te("Module.instantiateWasm callback failed with error: "+$),!1}var nr=so(Si,We);return tt(nr[0]),r.asm}function cu(We){return F.getFloat32(We,!0)}function ap(We){return F.getFloat64(We,!0)}function lp(We){return F.getInt16(We,!0)}function Ms(We){return F.getInt32(We,!0)}function Dn(We,tt){F.setInt32(We,tt,!0)}function oo(We){for(;We.length>0;){var tt=We.shift();if(typeof tt=="function"){tt(r);continue}var It=tt.func;typeof It=="number"?tt.arg===void 0?Z.get(It)():Z.get(It)(tt.arg):It(tt.arg===void 0?null:tt.arg)}}function Os(We,tt){var It=new Date(Ms((We>>2)*4)*1e3);Dn((tt>>2)*4,It.getUTCSeconds()),Dn((tt+4>>2)*4,It.getUTCMinutes()),Dn((tt+8>>2)*4,It.getUTCHours()),Dn((tt+12>>2)*4,It.getUTCDate()),Dn((tt+16>>2)*4,It.getUTCMonth()),Dn((tt+20>>2)*4,It.getUTCFullYear()-1900),Dn((tt+24>>2)*4,It.getUTCDay()),Dn((tt+36>>2)*4,0),Dn((tt+32>>2)*4,0);var nr=Date.UTC(It.getUTCFullYear(),0,1,0,0,0,0),$=(It.getTime()-nr)/(1e3*60*60*24)|0;return Dn((tt+28>>2)*4,$),Os.GMTString||(Os.GMTString=lt("GMT")),Dn((tt+40>>2)*4,Os.GMTString),tt}function ml(We,tt){return Os(We,tt)}function yl(We,tt,It){Te.copyWithin(We,tt,tt+It)}function ao(We){try{return we.grow(We-be.byteLength+65535>>>16),z(we.buffer),1}catch{}}function Kn(We){var tt=Te.length;We=We>>>0;var It=2147483648;if(We>It)return!1;for(var nr=1;nr<=4;nr*=2){var $=tt*(1+.2/nr);$=Math.min($,We+100663296);var me=Math.min(It,Qe(Math.max(We,$),65536)),Le=ao(me);if(Le)return!0}return!1}function Mn(We){pe(We)}function Ni(We){var tt=Date.now()/1e3|0;return We&&Dn((We>>2)*4,tt),tt}function On(){if(On.called)return;On.called=!0;var We=new Date().getFullYear(),tt=new Date(We,0,1),It=new Date(We,6,1),nr=tt.getTimezoneOffset(),$=It.getTimezoneOffset(),me=Math.max(nr,$);Dn((ds()>>2)*4,me*60),Dn((gs()>>2)*4,Number(nr!=$));function Le(Zr){var qi=Zr.toTimeString().match(/\(([A-Za-z ]+)\)$/);return qi?qi[1]:"GMT"}var ft=Le(tt),pt=Le(It),Rt=lt(ft),er=lt(pt);$<nr?(Dn((wi()>>2)*4,Rt),Dn((wi()+4>>2)*4,er)):(Dn((wi()>>2)*4,er),Dn((wi()+4>>2)*4,Rt))}function _i(We){On();var tt=Date.UTC(Ms((We+20>>2)*4)+1900,Ms((We+16>>2)*4),Ms((We+12>>2)*4),Ms((We+8>>2)*4),Ms((We+4>>2)*4),Ms((We>>2)*4),0),It=new Date(tt);Dn((We+24>>2)*4,It.getUTCDay());var nr=Date.UTC(It.getUTCFullYear(),0,1,0,0,0,0),$=(It.getTime()-nr)/(1e3*60*60*24)|0;return Dn((We+28>>2)*4,$),It.getTime()/1e3|0}var tr=typeof atob=="function"?atob:function(We){var tt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",It="",nr,$,me,Le,ft,pt,Rt,er=0;We=We.replace(/[^A-Za-z0-9\+\/\=]/g,"");do Le=tt.indexOf(We.charAt(er++)),ft=tt.indexOf(We.charAt(er++)),pt=tt.indexOf(We.charAt(er++)),Rt=tt.indexOf(We.charAt(er++)),nr=Le<<2|ft>>4,$=(ft&15)<<4|pt>>2,me=(pt&3)<<6|Rt,It=It+String.fromCharCode(nr),pt!==64&&(It=It+String.fromCharCode($)),Rt!==64&&(It=It+String.fromCharCode(me));while(er<We.length);return It};function Me(We){if(typeof I=="boolean"&&I){var tt;try{tt=Buffer.from(We,"base64")}catch{tt=new Buffer(We,"base64")}return new Uint8Array(tt.buffer,tt.byteOffset,tt.byteLength)}try{for(var It=tr(We),nr=new Uint8Array(It.length),$=0;$<It.length;++$)nr[$]=It.charCodeAt($);return nr}catch{throw new Error("Converting base64 string to bytes failed.")}}function ii(We){if(!!io(We))return Me(We.slice(ps.length))}var Oa={e:ml,c:yl,d:Kn,a:Mn,b:Ni,f:_i},hr=cc(),uc=r.___wasm_call_ctors=hr.h,uu=r._zip_ext_count_symlinks=hr.i,Ac=r._zip_file_get_external_attributes=hr.j,El=r._zipstruct_statS=hr.k,vA=r._zipstruct_stat_size=hr.l,Au=r._zipstruct_stat_mtime=hr.m,Ce=r._zipstruct_stat_crc=hr.n,Tt=r._zipstruct_errorS=hr.o,fc=r._zipstruct_error_code_zip=hr.p,Hi=r._zipstruct_stat_comp_size=hr.q,fu=r._zipstruct_stat_comp_method=hr.r,Yt=r._zip_close=hr.s,Cl=r._zip_delete=hr.t,DA=r._zip_dir_add=hr.u,cp=r._zip_discard=hr.v,pc=r._zip_error_init_with_code=hr.w,PA=r._zip_get_error=hr.x,Qn=r._zip_file_get_error=hr.y,hi=r._zip_error_strerror=hr.z,hc=r._zip_fclose=hr.A,SA=r._zip_file_add=hr.B,sa=r._free=hr.C,Li=r._malloc=hr.D,_o=r._zip_source_error=hr.E,Ze=r._zip_source_seek=hr.F,lo=r._zip_file_set_external_attributes=hr.G,gc=r._zip_file_set_mtime=hr.H,pu=r._zip_fopen_index=hr.I,ji=r._zip_fread=hr.J,hu=r._zip_get_name=hr.K,xA=r._zip_get_num_entries=hr.L,Ua=r._zip_source_read=hr.M,dc=r._zip_name_locate=hr.N,hs=r._zip_open_from_source=hr.O,_t=r._zip_set_file_compression=hr.P,Fn=r._zip_source_buffer=hr.Q,Ci=r._zip_source_buffer_create=hr.R,oa=r._zip_source_close=hr.S,co=r._zip_source_free=hr.T,Us=r._zip_source_keep=hr.U,aa=r._zip_source_open=hr.V,la=r._zip_source_tell=hr.X,Ho=r._zip_stat_index=hr.Y,wi=r.__get_tzname=hr.Z,gs=r.__get_daylight=hr._,ds=r.__get_timezone=hr.$,ms=r.stackSave=hr.aa,_s=r.stackRestore=hr.ba,Un=r.stackAlloc=hr.ca;r.cwrap=ne,r.getValue=ae;var Pn;Wr=function We(){Pn||ys(),Pn||(Wr=We)};function ys(We){if(We=We||A,mr>0||(dt(),mr>0))return;function tt(){Pn||(Pn=!0,r.calledRun=!0,!Pe&&(jt(),o(r),r.onRuntimeInitialized&&r.onRuntimeInitialized(),$t()))}r.setStatus?(r.setStatus("Running..."),setTimeout(function(){setTimeout(function(){r.setStatus("")},1),tt()},1)):tt()}if(r.run=ys,r.preInit)for(typeof r.preInit=="function"&&(r.preInit=[r.preInit]);r.preInit.length>0;)r.preInit.pop()();return ys(),e}}();typeof Fx=="object"&&typeof nU=="object"?nU.exports=rU:typeof define=="function"&&define.amd?define([],function(){return rU}):typeof Fx=="object"&&(Fx.createModule=rU)});var Lf,Nle,Lle,Mle=Et(()=>{Lf=["number","number"],Nle=(ee=>(ee[ee.ZIP_ER_OK=0]="ZIP_ER_OK",ee[ee.ZIP_ER_MULTIDISK=1]="ZIP_ER_MULTIDISK",ee[ee.ZIP_ER_RENAME=2]="ZIP_ER_RENAME",ee[ee.ZIP_ER_CLOSE=3]="ZIP_ER_CLOSE",ee[ee.ZIP_ER_SEEK=4]="ZIP_ER_SEEK",ee[ee.ZIP_ER_READ=5]="ZIP_ER_READ",ee[ee.ZIP_ER_WRITE=6]="ZIP_ER_WRITE",ee[ee.ZIP_ER_CRC=7]="ZIP_ER_CRC",ee[ee.ZIP_ER_ZIPCLOSED=8]="ZIP_ER_ZIPCLOSED",ee[ee.ZIP_ER_NOENT=9]="ZIP_ER_NOENT",ee[ee.ZIP_ER_EXISTS=10]="ZIP_ER_EXISTS",ee[ee.ZIP_ER_OPEN=11]="ZIP_ER_OPEN",ee[ee.ZIP_ER_TMPOPEN=12]="ZIP_ER_TMPOPEN",ee[ee.ZIP_ER_ZLIB=13]="ZIP_ER_ZLIB",ee[ee.ZIP_ER_MEMORY=14]="ZIP_ER_MEMORY",ee[ee.ZIP_ER_CHANGED=15]="ZIP_ER_CHANGED",ee[ee.ZIP_ER_COMPNOTSUPP=16]="ZIP_ER_COMPNOTSUPP",ee[ee.ZIP_ER_EOF=17]="ZIP_ER_EOF",ee[ee.ZIP_ER_INVAL=18]="ZIP_ER_INVAL",ee[ee.ZIP_ER_NOZIP=19]="ZIP_ER_NOZIP",ee[ee.ZIP_ER_INTERNAL=20]="ZIP_ER_INTERNAL",ee[ee.ZIP_ER_INCONS=21]="ZIP_ER_INCONS",ee[ee.ZIP_ER_REMOVE=22]="ZIP_ER_REMOVE",ee[ee.ZIP_ER_DELETED=23]="ZIP_ER_DELETED",ee[ee.ZIP_ER_ENCRNOTSUPP=24]="ZIP_ER_ENCRNOTSUPP",ee[ee.ZIP_ER_RDONLY=25]="ZIP_ER_RDONLY",ee[ee.ZIP_ER_NOPASSWD=26]="ZIP_ER_NOPASSWD",ee[ee.ZIP_ER_WRONGPASSWD=27]="ZIP_ER_WRONGPASSWD",ee[ee.ZIP_ER_OPNOTSUPP=28]="ZIP_ER_OPNOTSUPP",ee[ee.ZIP_ER_INUSE=29]="ZIP_ER_INUSE",ee[ee.ZIP_ER_TELL=30]="ZIP_ER_TELL",ee[ee.ZIP_ER_COMPRESSED_DATA=31]="ZIP_ER_COMPRESSED_DATA",ee))(Nle||{}),Lle=t=>({get HEAPU8(){return t.HEAPU8},errors:Nle,SEEK_SET:0,SEEK_CUR:1,SEEK_END:2,ZIP_CHECKCONS:4,ZIP_EXCL:2,ZIP_RDONLY:16,ZIP_FL_OVERWRITE:8192,ZIP_FL_COMPRESSED:4,ZIP_OPSYS_DOS:0,ZIP_OPSYS_AMIGA:1,ZIP_OPSYS_OPENVMS:2,ZIP_OPSYS_UNIX:3,ZIP_OPSYS_VM_CMS:4,ZIP_OPSYS_ATARI_ST:5,ZIP_OPSYS_OS_2:6,ZIP_OPSYS_MACINTOSH:7,ZIP_OPSYS_Z_SYSTEM:8,ZIP_OPSYS_CPM:9,ZIP_OPSYS_WINDOWS_NTFS:10,ZIP_OPSYS_MVS:11,ZIP_OPSYS_VSE:12,ZIP_OPSYS_ACORN_RISC:13,ZIP_OPSYS_VFAT:14,ZIP_OPSYS_ALTERNATE_MVS:15,ZIP_OPSYS_BEOS:16,ZIP_OPSYS_TANDEM:17,ZIP_OPSYS_OS_400:18,ZIP_OPSYS_OS_X:19,ZIP_CM_DEFAULT:-1,ZIP_CM_STORE:0,ZIP_CM_DEFLATE:8,uint08S:t._malloc(1),uint32S:t._malloc(4),malloc:t._malloc,free:t._free,getValue:t.getValue,openFromSource:t.cwrap("zip_open_from_source","number",["number","number","number"]),close:t.cwrap("zip_close","number",["number"]),discard:t.cwrap("zip_discard",null,["number"]),getError:t.cwrap("zip_get_error","number",["number"]),getName:t.cwrap("zip_get_name","string",["number","number","number"]),getNumEntries:t.cwrap("zip_get_num_entries","number",["number","number"]),delete:t.cwrap("zip_delete","number",["number","number"]),statIndex:t.cwrap("zip_stat_index","number",["number",...Lf,"number","number"]),fopenIndex:t.cwrap("zip_fopen_index","number",["number",...Lf,"number"]),fread:t.cwrap("zip_fread","number",["number","number","number","number"]),fclose:t.cwrap("zip_fclose","number",["number"]),dir:{add:t.cwrap("zip_dir_add","number",["number","string"])},file:{add:t.cwrap("zip_file_add","number",["number","string","number","number"]),getError:t.cwrap("zip_file_get_error","number",["number"]),getExternalAttributes:t.cwrap("zip_file_get_external_attributes","number",["number",...Lf,"number","number","number"]),setExternalAttributes:t.cwrap("zip_file_set_external_attributes","number",["number",...Lf,"number","number","number"]),setMtime:t.cwrap("zip_file_set_mtime","number",["number",...Lf,"number","number"]),setCompression:t.cwrap("zip_set_file_compression","number",["number",...Lf,"number","number"])},ext:{countSymlinks:t.cwrap("zip_ext_count_symlinks","number",["number"])},error:{initWithCode:t.cwrap("zip_error_init_with_code",null,["number","number"]),strerror:t.cwrap("zip_error_strerror","string",["number"])},name:{locate:t.cwrap("zip_name_locate","number",["number","string","number"])},source:{fromUnattachedBuffer:t.cwrap("zip_source_buffer_create","number",["number",...Lf,"number","number"]),fromBuffer:t.cwrap("zip_source_buffer","number",["number","number",...Lf,"number"]),free:t.cwrap("zip_source_free",null,["number"]),keep:t.cwrap("zip_source_keep",null,["number"]),open:t.cwrap("zip_source_open","number",["number"]),close:t.cwrap("zip_source_close","number",["number"]),seek:t.cwrap("zip_source_seek","number",["number",...Lf,"number"]),tell:t.cwrap("zip_source_tell","number",["number"]),read:t.cwrap("zip_source_read","number",["number","number","number"]),error:t.cwrap("zip_source_error","number",["number"])},struct:{statS:t.cwrap("zipstruct_statS","number",[]),statSize:t.cwrap("zipstruct_stat_size","number",["number"]),statCompSize:t.cwrap("zipstruct_stat_comp_size","number",["number"]),statCompMethod:t.cwrap("zipstruct_stat_comp_method","number",["number"]),statMtime:t.cwrap("zipstruct_stat_mtime","number",["number"]),statCrc:t.cwrap("zipstruct_stat_crc","number",["number"]),errorS:t.cwrap("zipstruct_errorS","number",[]),errorCodeZip:t.cwrap("zipstruct_error_code_zip","number",["number"])}})});function iU(t,e){let r=t.indexOf(e);if(r<=0)return null;let o=r;for(;r>=0&&(o=r+e.length,t[o]!==K.sep);){if(t[r-1]===K.sep)return null;r=t.indexOf(e,o)}return t.length>o&&t[o]!==K.sep?null:t.slice(0,o)}var Jl,Ole=Et(()=>{Pt();Pt();nA();Jl=class extends _p{static async openPromise(e,r){let o=new Jl(r);try{return await e(o)}finally{o.saveAndClose()}}constructor(e={}){let r=e.fileExtensions,o=e.readOnlyArchives,a=typeof r>"u"?A=>iU(A,".zip"):A=>{for(let p of r){let h=iU(A,p);if(h)return h}return null},n=(A,p)=>new zi(p,{baseFs:A,readOnly:o,stats:A.statSync(p)}),u=async(A,p)=>{let h={baseFs:A,readOnly:o,stats:await A.statPromise(p)};return()=>new zi(p,h)};super({...e,factorySync:n,factoryPromise:u,getMountPoint:a})}}});function pot(t){if(typeof t=="string"&&String(+t)===t)return+t;if(typeof t=="number"&&Number.isFinite(t))return t<0?Date.now()/1e3:t;if(Ule.types.isDate(t))return t.getTime()/1e3;throw new Error("Invalid time")}function Tx(){return Buffer.from([80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])}var ta,sU,Ule,oU,_le,Rx,zi,aU=Et(()=>{Pt();Pt();Pt();Pt();Pt();Pt();ta=Be("fs"),sU=Be("stream"),Ule=Be("util"),oU=$e(Be("zlib"));tU();_le="mixed";Rx=class extends Error{constructor(r,o){super(r);this.name="Libzip Error",this.code=o}},zi=class extends Ou{constructor(r,o={}){super();this.listings=new Map;this.entries=new Map;this.fileSources=new Map;this.fds=new Map;this.nextFd=0;this.ready=!1;this.readOnly=!1;let a=o;if(this.level=typeof a.level<"u"?a.level:_le,r??=Tx(),typeof r=="string"){let{baseFs:A=new Rn}=a;this.baseFs=A,this.path=r}else this.path=null,this.baseFs=null;if(o.stats)this.stats=o.stats;else if(typeof r=="string")try{this.stats=this.baseFs.statSync(r)}catch(A){if(A.code==="ENOENT"&&a.create)this.stats=Ea.makeDefaultStats();else throw A}else this.stats=Ea.makeDefaultStats();this.libzip=S1();let n=this.libzip.malloc(4);try{let A=0;o.readOnly&&(A|=this.libzip.ZIP_RDONLY,this.readOnly=!0),typeof r=="string"&&(r=a.create?Tx():this.baseFs.readFileSync(r));let p=this.allocateUnattachedSource(r);try{this.zip=this.libzip.openFromSource(p,A,n),this.lzSource=p}catch(h){throw this.libzip.source.free(p),h}if(this.zip===0){let h=this.libzip.struct.errorS();throw this.libzip.error.initWithCode(h,this.libzip.getValue(n,"i32")),this.makeLibzipError(h)}}finally{this.libzip.free(n)}this.listings.set(Bt.root,new Set);let u=this.libzip.getNumEntries(this.zip,0);for(let A=0;A<u;++A){let p=this.libzip.getName(this.zip,A,0);if(K.isAbsolute(p))continue;let h=K.resolve(Bt.root,p);this.registerEntry(h,A),p.endsWith("/")&&this.registerListing(h)}if(this.symlinkCount=this.libzip.ext.countSymlinks(this.zip),this.symlinkCount===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));this.ready=!0}makeLibzipError(r){let o=this.libzip.struct.errorCodeZip(r),a=this.libzip.error.strerror(r),n=new Rx(a,this.libzip.errors[o]);if(o===this.libzip.errors.ZIP_ER_CHANGED)throw new Error(`Assertion failed: Unexpected libzip error: ${n.message}`);return n}getExtractHint(r){for(let o of this.entries.keys()){let a=this.pathUtils.extname(o);if(r.relevantExtensions.has(a))return!0}return!1}getAllFiles(){return Array.from(this.entries.keys())}getRealPath(){if(!this.path)throw new Error("ZipFS don't have real paths when loaded from a buffer");return this.path}prepareClose(){if(!this.ready)throw ar.EBUSY("archive closed, close");Og(this)}getBufferAndClose(){if(this.prepareClose(),this.entries.size===0)return this.discardAndClose(),Tx();try{if(this.libzip.source.keep(this.lzSource),this.libzip.close(this.zip)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));if(this.libzip.source.open(this.lzSource)===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));if(this.libzip.source.seek(this.lzSource,0,0,this.libzip.SEEK_END)===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));let r=this.libzip.source.tell(this.lzSource);if(r===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));if(this.libzip.source.seek(this.lzSource,0,0,this.libzip.SEEK_SET)===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));let o=this.libzip.malloc(r);if(!o)throw new Error("Couldn't allocate enough memory");try{let a=this.libzip.source.read(this.lzSource,o,r);if(a===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));if(a<r)throw new Error("Incomplete read");if(a>r)throw new Error("Overread");let n=this.libzip.HEAPU8.subarray(o,o+r);return Buffer.from(n)}finally{this.libzip.free(o)}}finally{this.libzip.source.close(this.lzSource),this.libzip.source.free(this.lzSource),this.ready=!1}}discardAndClose(){this.prepareClose(),this.libzip.discard(this.zip),this.ready=!1}saveAndClose(){if(!this.path||!this.baseFs)throw new Error("ZipFS cannot be saved and must be discarded when loaded from a buffer");if(this.readOnly){this.discardAndClose();return}let r=this.baseFs.existsSync(this.path)||this.stats.mode===Ea.DEFAULT_MODE?void 0:this.stats.mode;this.baseFs.writeFileSync(this.path,this.getBufferAndClose(),{mode:r}),this.ready=!1}resolve(r){return K.resolve(Bt.root,r)}async openPromise(r,o,a){return this.openSync(r,o,a)}openSync(r,o,a){let n=this.nextFd++;return this.fds.set(n,{cursor:0,p:r}),n}hasOpenFileHandles(){return!!this.fds.size}async opendirPromise(r,o){return this.opendirSync(r,o)}opendirSync(r,o={}){let a=this.resolveFilename(`opendir '${r}'`,r);if(!this.entries.has(a)&&!this.listings.has(a))throw ar.ENOENT(`opendir '${r}'`);let n=this.listings.get(a);if(!n)throw ar.ENOTDIR(`opendir '${r}'`);let u=[...n],A=this.openSync(a,"r");return SD(this,a,u,{onClose:()=>{this.closeSync(A)}})}async readPromise(r,o,a,n,u){return this.readSync(r,o,a,n,u)}readSync(r,o,a=0,n=o.byteLength,u=-1){let A=this.fds.get(r);if(typeof A>"u")throw ar.EBADF("read");let p=u===-1||u===null?A.cursor:u,h=this.readFileSync(A.p);h.copy(o,a,p,p+n);let E=Math.max(0,Math.min(h.length-p,n));return(u===-1||u===null)&&(A.cursor+=E),E}async writePromise(r,o,a,n,u){return typeof o=="string"?this.writeSync(r,o,u):this.writeSync(r,o,a,n,u)}writeSync(r,o,a,n,u){throw typeof this.fds.get(r)>"u"?ar.EBADF("read"):new Error("Unimplemented")}async closePromise(r){return this.closeSync(r)}closeSync(r){if(typeof this.fds.get(r)>"u")throw ar.EBADF("read");this.fds.delete(r)}createReadStream(r,{encoding:o}={}){if(r===null)throw new Error("Unimplemented");let a=this.openSync(r,"r"),n=Object.assign(new sU.PassThrough({emitClose:!0,autoDestroy:!0,destroy:(A,p)=>{clearImmediate(u),this.closeSync(a),p(A)}}),{close(){n.destroy()},bytesRead:0,path:r,pending:!1}),u=setImmediate(async()=>{try{let A=await this.readFilePromise(r,o);n.bytesRead=A.length,n.end(A)}catch(A){n.destroy(A)}});return n}createWriteStream(r,{encoding:o}={}){if(this.readOnly)throw ar.EROFS(`open '${r}'`);if(r===null)throw new Error("Unimplemented");let a=[],n=this.openSync(r,"w"),u=Object.assign(new sU.PassThrough({autoDestroy:!0,emitClose:!0,destroy:(A,p)=>{try{A?p(A):(this.writeFileSync(r,Buffer.concat(a),o),p(null))}catch(h){p(h)}finally{this.closeSync(n)}}}),{close(){u.destroy()},bytesWritten:0,path:r,pending:!1});return u.on("data",A=>{let p=Buffer.from(A);u.bytesWritten+=p.length,a.push(p)}),u}async realpathPromise(r){return this.realpathSync(r)}realpathSync(r){let o=this.resolveFilename(`lstat '${r}'`,r);if(!this.entries.has(o)&&!this.listings.has(o))throw ar.ENOENT(`lstat '${r}'`);return o}async existsPromise(r){return this.existsSync(r)}existsSync(r){if(!this.ready)throw ar.EBUSY(`archive closed, existsSync '${r}'`);if(this.symlinkCount===0){let a=K.resolve(Bt.root,r);return this.entries.has(a)||this.listings.has(a)}let o;try{o=this.resolveFilename(`stat '${r}'`,r,void 0,!1)}catch{return!1}return o===void 0?!1:this.entries.has(o)||this.listings.has(o)}async accessPromise(r,o){return this.accessSync(r,o)}accessSync(r,o=ta.constants.F_OK){let a=this.resolveFilename(`access '${r}'`,r);if(!this.entries.has(a)&&!this.listings.has(a))throw ar.ENOENT(`access '${r}'`);if(this.readOnly&&o&ta.constants.W_OK)throw ar.EROFS(`access '${r}'`)}async statPromise(r,o={bigint:!1}){return o.bigint?this.statSync(r,{bigint:!0}):this.statSync(r)}statSync(r,o={bigint:!1,throwIfNoEntry:!0}){let a=this.resolveFilename(`stat '${r}'`,r,void 0,o.throwIfNoEntry);if(a!==void 0){if(!this.entries.has(a)&&!this.listings.has(a)){if(o.throwIfNoEntry===!1)return;throw ar.ENOENT(`stat '${r}'`)}if(r[r.length-1]==="/"&&!this.listings.has(a))throw ar.ENOTDIR(`stat '${r}'`);return this.statImpl(`stat '${r}'`,a,o)}}async fstatPromise(r,o){return this.fstatSync(r,o)}fstatSync(r,o){let a=this.fds.get(r);if(typeof a>"u")throw ar.EBADF("fstatSync");let{p:n}=a,u=this.resolveFilename(`stat '${n}'`,n);if(!this.entries.has(u)&&!this.listings.has(u))throw ar.ENOENT(`stat '${n}'`);if(n[n.length-1]==="/"&&!this.listings.has(u))throw ar.ENOTDIR(`stat '${n}'`);return this.statImpl(`fstat '${n}'`,u,o)}async lstatPromise(r,o={bigint:!1}){return o.bigint?this.lstatSync(r,{bigint:!0}):this.lstatSync(r)}lstatSync(r,o={bigint:!1,throwIfNoEntry:!0}){let a=this.resolveFilename(`lstat '${r}'`,r,!1,o.throwIfNoEntry);if(a!==void 0){if(!this.entries.has(a)&&!this.listings.has(a)){if(o.throwIfNoEntry===!1)return;throw ar.ENOENT(`lstat '${r}'`)}if(r[r.length-1]==="/"&&!this.listings.has(a))throw ar.ENOTDIR(`lstat '${r}'`);return this.statImpl(`lstat '${r}'`,a,o)}}statImpl(r,o,a={}){let n=this.entries.get(o);if(typeof n<"u"){let u=this.libzip.struct.statS();if(this.libzip.statIndex(this.zip,n,0,0,u)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));let p=this.stats.uid,h=this.stats.gid,E=this.libzip.struct.statSize(u)>>>0,I=512,v=Math.ceil(E/I),b=(this.libzip.struct.statMtime(u)>>>0)*1e3,C=b,T=b,L=b,U=new Date(C),J=new Date(T),te=new Date(L),le=new Date(b),pe=this.listings.has(o)?ta.constants.S_IFDIR:this.isSymbolicLink(n)?ta.constants.S_IFLNK:ta.constants.S_IFREG,Ae=pe===ta.constants.S_IFDIR?493:420,ye=pe|this.getUnixMode(n,Ae)&511,ae=this.libzip.struct.statCrc(u),we=Object.assign(new Ea.StatEntry,{uid:p,gid:h,size:E,blksize:I,blocks:v,atime:U,birthtime:J,ctime:te,mtime:le,atimeMs:C,birthtimeMs:T,ctimeMs:L,mtimeMs:b,mode:ye,crc:ae});return a.bigint===!0?Ea.convertToBigIntStats(we):we}if(this.listings.has(o)){let u=this.stats.uid,A=this.stats.gid,p=0,h=512,E=0,I=this.stats.mtimeMs,v=this.stats.mtimeMs,b=this.stats.mtimeMs,C=this.stats.mtimeMs,T=new Date(I),L=new Date(v),U=new Date(b),J=new Date(C),te=ta.constants.S_IFDIR|493,le=0,pe=Object.assign(new Ea.StatEntry,{uid:u,gid:A,size:p,blksize:h,blocks:E,atime:T,birthtime:L,ctime:U,mtime:J,atimeMs:I,birthtimeMs:v,ctimeMs:b,mtimeMs:C,mode:te,crc:le});return a.bigint===!0?Ea.convertToBigIntStats(pe):pe}throw new Error("Unreachable")}getUnixMode(r,o){if(this.libzip.file.getExternalAttributes(this.zip,r,0,0,this.libzip.uint08S,this.libzip.uint32S)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.libzip.getValue(this.libzip.uint08S,"i8")>>>0!==this.libzip.ZIP_OPSYS_UNIX?o:this.libzip.getValue(this.libzip.uint32S,"i32")>>>16}registerListing(r){let o=this.listings.get(r);if(o)return o;this.registerListing(K.dirname(r)).add(K.basename(r));let n=new Set;return this.listings.set(r,n),n}registerEntry(r,o){this.registerListing(K.dirname(r)).add(K.basename(r)),this.entries.set(r,o)}unregisterListing(r){this.listings.delete(r),this.listings.get(K.dirname(r))?.delete(K.basename(r))}unregisterEntry(r){this.unregisterListing(r);let o=this.entries.get(r);this.entries.delete(r),!(typeof o>"u")&&(this.fileSources.delete(o),this.isSymbolicLink(o)&&this.symlinkCount--)}deleteEntry(r,o){if(this.unregisterEntry(r),this.libzip.delete(this.zip,o)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}resolveFilename(r,o,a=!0,n=!0){if(!this.ready)throw ar.EBUSY(`archive closed, ${r}`);let u=K.resolve(Bt.root,o);if(u==="/")return Bt.root;let A=this.entries.get(u);if(a&&A!==void 0)if(this.symlinkCount!==0&&this.isSymbolicLink(A)){let p=this.getFileSource(A).toString();return this.resolveFilename(r,K.resolve(K.dirname(u),p),!0,n)}else return u;for(;;){let p=this.resolveFilename(r,K.dirname(u),!0,n);if(p===void 0)return p;let h=this.listings.has(p),E=this.entries.has(p);if(!h&&!E){if(n===!1)return;throw ar.ENOENT(r)}if(!h)throw ar.ENOTDIR(r);if(u=K.resolve(p,K.basename(u)),!a||this.symlinkCount===0)break;let I=this.libzip.name.locate(this.zip,u.slice(1),0);if(I===-1)break;if(this.isSymbolicLink(I)){let v=this.getFileSource(I).toString();u=K.resolve(K.dirname(u),v)}else break}return u}allocateBuffer(r){Buffer.isBuffer(r)||(r=Buffer.from(r));let o=this.libzip.malloc(r.byteLength);if(!o)throw new Error("Couldn't allocate enough memory");return new Uint8Array(this.libzip.HEAPU8.buffer,o,r.byteLength).set(r),{buffer:o,byteLength:r.byteLength}}allocateUnattachedSource(r){let o=this.libzip.struct.errorS(),{buffer:a,byteLength:n}=this.allocateBuffer(r),u=this.libzip.source.fromUnattachedBuffer(a,n,0,1,o);if(u===0)throw this.libzip.free(o),this.makeLibzipError(o);return u}allocateSource(r){let{buffer:o,byteLength:a}=this.allocateBuffer(r),n=this.libzip.source.fromBuffer(this.zip,o,a,0,1);if(n===0)throw this.libzip.free(o),this.makeLibzipError(this.libzip.getError(this.zip));return n}setFileSource(r,o){let a=Buffer.isBuffer(o)?o:Buffer.from(o),n=K.relative(Bt.root,r),u=this.allocateSource(o);try{let A=this.libzip.file.add(this.zip,n,u,this.libzip.ZIP_FL_OVERWRITE);if(A===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));if(this.level!=="mixed"){let p=this.level===0?this.libzip.ZIP_CM_STORE:this.libzip.ZIP_CM_DEFLATE;if(this.libzip.file.setCompression(this.zip,A,0,p,this.level)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}return this.fileSources.set(A,a),A}catch(A){throw this.libzip.source.free(u),A}}isSymbolicLink(r){if(this.symlinkCount===0)return!1;if(this.libzip.file.getExternalAttributes(this.zip,r,0,0,this.libzip.uint08S,this.libzip.uint32S)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.libzip.getValue(this.libzip.uint08S,"i8")>>>0!==this.libzip.ZIP_OPSYS_UNIX?!1:(this.libzip.getValue(this.libzip.uint32S,"i32")>>>16&ta.constants.S_IFMT)===ta.constants.S_IFLNK}getFileSource(r,o={asyncDecompress:!1}){let a=this.fileSources.get(r);if(typeof a<"u")return a;let n=this.libzip.struct.statS();if(this.libzip.statIndex(this.zip,r,0,0,n)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));let A=this.libzip.struct.statCompSize(n),p=this.libzip.struct.statCompMethod(n),h=this.libzip.malloc(A);try{let E=this.libzip.fopenIndex(this.zip,r,0,this.libzip.ZIP_FL_COMPRESSED);if(E===0)throw this.makeLibzipError(this.libzip.getError(this.zip));try{let I=this.libzip.fread(E,h,A,0);if(I===-1)throw this.makeLibzipError(this.libzip.file.getError(E));if(I<A)throw new Error("Incomplete read");if(I>A)throw new Error("Overread");let v=this.libzip.HEAPU8.subarray(h,h+A),b=Buffer.from(v);if(p===0)return this.fileSources.set(r,b),b;if(o.asyncDecompress)return new Promise((C,T)=>{oU.default.inflateRaw(b,(L,U)=>{L?T(L):(this.fileSources.set(r,U),C(U))})});{let C=oU.default.inflateRawSync(b);return this.fileSources.set(r,C),C}}finally{this.libzip.fclose(E)}}finally{this.libzip.free(h)}}async fchmodPromise(r,o){return this.chmodPromise(this.fdToPath(r,"fchmod"),o)}fchmodSync(r,o){return this.chmodSync(this.fdToPath(r,"fchmodSync"),o)}async chmodPromise(r,o){return this.chmodSync(r,o)}chmodSync(r,o){if(this.readOnly)throw ar.EROFS(`chmod '${r}'`);o&=493;let a=this.resolveFilename(`chmod '${r}'`,r,!1),n=this.entries.get(a);if(typeof n>"u")throw new Error(`Assertion failed: The entry should have been registered (${a})`);let A=this.getUnixMode(n,ta.constants.S_IFREG|0)&-512|o;if(this.libzip.file.setExternalAttributes(this.zip,n,0,0,this.libzip.ZIP_OPSYS_UNIX,A<<16)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}async fchownPromise(r,o,a){return this.chownPromise(this.fdToPath(r,"fchown"),o,a)}fchownSync(r,o,a){return this.chownSync(this.fdToPath(r,"fchownSync"),o,a)}async chownPromise(r,o,a){return this.chownSync(r,o,a)}chownSync(r,o,a){throw new Error("Unimplemented")}async renamePromise(r,o){return this.renameSync(r,o)}renameSync(r,o){throw new Error("Unimplemented")}async copyFilePromise(r,o,a){let{indexSource:n,indexDest:u,resolvedDestP:A}=this.prepareCopyFile(r,o,a),p=await this.getFileSource(n,{asyncDecompress:!0}),h=this.setFileSource(A,p);h!==u&&this.registerEntry(A,h)}copyFileSync(r,o,a=0){let{indexSource:n,indexDest:u,resolvedDestP:A}=this.prepareCopyFile(r,o,a),p=this.getFileSource(n),h=this.setFileSource(A,p);h!==u&&this.registerEntry(A,h)}prepareCopyFile(r,o,a=0){if(this.readOnly)throw ar.EROFS(`copyfile '${r} -> '${o}'`);if((a&ta.constants.COPYFILE_FICLONE_FORCE)!==0)throw ar.ENOSYS("unsupported clone operation",`copyfile '${r}' -> ${o}'`);let n=this.resolveFilename(`copyfile '${r} -> ${o}'`,r),u=this.entries.get(n);if(typeof u>"u")throw ar.EINVAL(`copyfile '${r}' -> '${o}'`);let A=this.resolveFilename(`copyfile '${r}' -> ${o}'`,o),p=this.entries.get(A);if((a&(ta.constants.COPYFILE_EXCL|ta.constants.COPYFILE_FICLONE_FORCE))!==0&&typeof p<"u")throw ar.EEXIST(`copyfile '${r}' -> '${o}'`);return{indexSource:u,resolvedDestP:A,indexDest:p}}async appendFilePromise(r,o,a){if(this.readOnly)throw ar.EROFS(`open '${r}'`);return typeof a>"u"?a={flag:"a"}:typeof a=="string"?a={flag:"a",encoding:a}:typeof a.flag>"u"&&(a={flag:"a",...a}),this.writeFilePromise(r,o,a)}appendFileSync(r,o,a={}){if(this.readOnly)throw ar.EROFS(`open '${r}'`);return typeof a>"u"?a={flag:"a"}:typeof a=="string"?a={flag:"a",encoding:a}:typeof a.flag>"u"&&(a={flag:"a",...a}),this.writeFileSync(r,o,a)}fdToPath(r,o){let a=this.fds.get(r)?.p;if(typeof a>"u")throw ar.EBADF(o);return a}async writeFilePromise(r,o,a){let{encoding:n,mode:u,index:A,resolvedP:p}=this.prepareWriteFile(r,a);A!==void 0&&typeof a=="object"&&a.flag&&a.flag.includes("a")&&(o=Buffer.concat([await this.getFileSource(A,{asyncDecompress:!0}),Buffer.from(o)])),n!==null&&(o=o.toString(n));let h=this.setFileSource(p,o);h!==A&&this.registerEntry(p,h),u!==null&&await this.chmodPromise(p,u)}writeFileSync(r,o,a){let{encoding:n,mode:u,index:A,resolvedP:p}=this.prepareWriteFile(r,a);A!==void 0&&typeof a=="object"&&a.flag&&a.flag.includes("a")&&(o=Buffer.concat([this.getFileSource(A),Buffer.from(o)])),n!==null&&(o=o.toString(n));let h=this.setFileSource(p,o);h!==A&&this.registerEntry(p,h),u!==null&&this.chmodSync(p,u)}prepareWriteFile(r,o){if(typeof r=="number"&&(r=this.fdToPath(r,"read")),this.readOnly)throw ar.EROFS(`open '${r}'`);let a=this.resolveFilename(`open '${r}'`,r);if(this.listings.has(a))throw ar.EISDIR(`open '${r}'`);let n=null,u=null;typeof o=="string"?n=o:typeof o=="object"&&({encoding:n=null,mode:u=null}=o);let A=this.entries.get(a);return{encoding:n,mode:u,resolvedP:a,index:A}}async unlinkPromise(r){return this.unlinkSync(r)}unlinkSync(r){if(this.readOnly)throw ar.EROFS(`unlink '${r}'`);let o=this.resolveFilename(`unlink '${r}'`,r);if(this.listings.has(o))throw ar.EISDIR(`unlink '${r}'`);let a=this.entries.get(o);if(typeof a>"u")throw ar.EINVAL(`unlink '${r}'`);this.deleteEntry(o,a)}async utimesPromise(r,o,a){return this.utimesSync(r,o,a)}utimesSync(r,o,a){if(this.readOnly)throw ar.EROFS(`utimes '${r}'`);let n=this.resolveFilename(`utimes '${r}'`,r);this.utimesImpl(n,a)}async lutimesPromise(r,o,a){return this.lutimesSync(r,o,a)}lutimesSync(r,o,a){if(this.readOnly)throw ar.EROFS(`lutimes '${r}'`);let n=this.resolveFilename(`utimes '${r}'`,r,!1);this.utimesImpl(n,a)}utimesImpl(r,o){this.listings.has(r)&&(this.entries.has(r)||this.hydrateDirectory(r));let a=this.entries.get(r);if(a===void 0)throw new Error("Unreachable");if(this.libzip.file.setMtime(this.zip,a,0,pot(o),0)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}async mkdirPromise(r,o){return this.mkdirSync(r,o)}mkdirSync(r,{mode:o=493,recursive:a=!1}={}){if(a)return this.mkdirpSync(r,{chmod:o});if(this.readOnly)throw ar.EROFS(`mkdir '${r}'`);let n=this.resolveFilename(`mkdir '${r}'`,r);if(this.entries.has(n)||this.listings.has(n))throw ar.EEXIST(`mkdir '${r}'`);this.hydrateDirectory(n),this.chmodSync(n,o)}async rmdirPromise(r,o){return this.rmdirSync(r,o)}rmdirSync(r,{recursive:o=!1}={}){if(this.readOnly)throw ar.EROFS(`rmdir '${r}'`);if(o){this.removeSync(r);return}let a=this.resolveFilename(`rmdir '${r}'`,r),n=this.listings.get(a);if(!n)throw ar.ENOTDIR(`rmdir '${r}'`);if(n.size>0)throw ar.ENOTEMPTY(`rmdir '${r}'`);let u=this.entries.get(a);if(typeof u>"u")throw ar.EINVAL(`rmdir '${r}'`);this.deleteEntry(r,u)}hydrateDirectory(r){let o=this.libzip.dir.add(this.zip,K.relative(Bt.root,r));if(o===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.registerListing(r),this.registerEntry(r,o),o}async linkPromise(r,o){return this.linkSync(r,o)}linkSync(r,o){throw ar.EOPNOTSUPP(`link '${r}' -> '${o}'`)}async symlinkPromise(r,o){return this.symlinkSync(r,o)}symlinkSync(r,o){if(this.readOnly)throw ar.EROFS(`symlink '${r}' -> '${o}'`);let a=this.resolveFilename(`symlink '${r}' -> '${o}'`,o);if(this.listings.has(a))throw ar.EISDIR(`symlink '${r}' -> '${o}'`);if(this.entries.has(a))throw ar.EEXIST(`symlink '${r}' -> '${o}'`);let n=this.setFileSource(a,r);if(this.registerEntry(a,n),this.libzip.file.setExternalAttributes(this.zip,n,0,0,this.libzip.ZIP_OPSYS_UNIX,(ta.constants.S_IFLNK|511)<<16)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));this.symlinkCount+=1}async readFilePromise(r,o){typeof o=="object"&&(o=o?o.encoding:void 0);let a=await this.readFileBuffer(r,{asyncDecompress:!0});return o?a.toString(o):a}readFileSync(r,o){typeof o=="object"&&(o=o?o.encoding:void 0);let a=this.readFileBuffer(r);return o?a.toString(o):a}readFileBuffer(r,o={asyncDecompress:!1}){typeof r=="number"&&(r=this.fdToPath(r,"read"));let a=this.resolveFilename(`open '${r}'`,r);if(!this.entries.has(a)&&!this.listings.has(a))throw ar.ENOENT(`open '${r}'`);if(r[r.length-1]==="/"&&!this.listings.has(a))throw ar.ENOTDIR(`open '${r}'`);if(this.listings.has(a))throw ar.EISDIR("read");let n=this.entries.get(a);if(n===void 0)throw new Error("Unreachable");return this.getFileSource(n,o)}async readdirPromise(r,o){return this.readdirSync(r,o)}readdirSync(r,o){let a=this.resolveFilename(`scandir '${r}'`,r);if(!this.entries.has(a)&&!this.listings.has(a))throw ar.ENOENT(`scandir '${r}'`);let n=this.listings.get(a);if(!n)throw ar.ENOTDIR(`scandir '${r}'`);if(o?.recursive)if(o?.withFileTypes){let u=Array.from(n,A=>Object.assign(this.statImpl("lstat",K.join(r,A)),{name:A,path:Bt.dot}));for(let A of u){if(!A.isDirectory())continue;let p=K.join(A.path,A.name),h=this.listings.get(K.join(a,p));for(let E of h)u.push(Object.assign(this.statImpl("lstat",K.join(r,p,E)),{name:E,path:p}))}return u}else{let u=[...n];for(let A of u){let p=this.listings.get(K.join(a,A));if(!(typeof p>"u"))for(let h of p)u.push(K.join(A,h))}return u}else return o?.withFileTypes?Array.from(n,u=>Object.assign(this.statImpl("lstat",K.join(r,u)),{name:u,path:void 0})):[...n]}async readlinkPromise(r){let o=this.prepareReadlink(r);return(await this.getFileSource(o,{asyncDecompress:!0})).toString()}readlinkSync(r){let o=this.prepareReadlink(r);return this.getFileSource(o).toString()}prepareReadlink(r){let o=this.resolveFilename(`readlink '${r}'`,r,!1);if(!this.entries.has(o)&&!this.listings.has(o))throw ar.ENOENT(`readlink '${r}'`);if(r[r.length-1]==="/"&&!this.listings.has(o))throw ar.ENOTDIR(`open '${r}'`);if(this.listings.has(o))throw ar.EINVAL(`readlink '${r}'`);let a=this.entries.get(o);if(a===void 0)throw new Error("Unreachable");if(!this.isSymbolicLink(a))throw ar.EINVAL(`readlink '${r}'`);return a}async truncatePromise(r,o=0){let a=this.resolveFilename(`open '${r}'`,r),n=this.entries.get(a);if(typeof n>"u")throw ar.EINVAL(`open '${r}'`);let u=await this.getFileSource(n,{asyncDecompress:!0}),A=Buffer.alloc(o,0);return u.copy(A),await this.writeFilePromise(r,A)}truncateSync(r,o=0){let a=this.resolveFilename(`open '${r}'`,r),n=this.entries.get(a);if(typeof n>"u")throw ar.EINVAL(`open '${r}'`);let u=this.getFileSource(n),A=Buffer.alloc(o,0);return u.copy(A),this.writeFileSync(r,A)}async ftruncatePromise(r,o){return this.truncatePromise(this.fdToPath(r,"ftruncate"),o)}ftruncateSync(r,o){return this.truncateSync(this.fdToPath(r,"ftruncateSync"),o)}watch(r,o,a){let n;switch(typeof o){case"function":case"string":case"undefined":n=!0;break;default:({persistent:n=!0}=o);break}if(!n)return{on:()=>{},close:()=>{}};let u=setInterval(()=>{},24*60*60*1e3);return{on:()=>{},close:()=>{clearInterval(u)}}}watchFile(r,o,a){let n=K.resolve(Bt.root,r);return ry(this,n,o,a)}unwatchFile(r,o){let a=K.resolve(Bt.root,r);return Mg(this,a,o)}}});function jle(t,e,r=Buffer.alloc(0),o){let a=new zi(r),n=I=>I===e||I.startsWith(`${e}/`)?I.slice(0,e.length):null,u=async(I,v)=>()=>a,A=(I,v)=>a,p={...t},h=new Rn(p),E=new _p({baseFs:h,getMountPoint:n,factoryPromise:u,factorySync:A,magicByte:21,maxAge:1/0,typeCheck:o?.typeCheck});return Ww(Hle.default,new Hp(E)),a}var Hle,qle=Et(()=>{Pt();Hle=$e(Be("fs"));aU()});var Gle=Et(()=>{Ole();aU();qle()});var x1={};Kt(x1,{DEFAULT_COMPRESSION_LEVEL:()=>_le,LibzipError:()=>Rx,ZipFS:()=>zi,ZipOpenFS:()=>Jl,getArchivePart:()=>iU,getLibzipPromise:()=>got,getLibzipSync:()=>hot,makeEmptyArchive:()=>Tx,mountMemoryDrive:()=>jle});function hot(){return S1()}async function got(){return S1()}var Yle,nA=Et(()=>{tU();Yle=$e(Rle());Mle();Gle();Tle(()=>{let t=(0,Yle.default)();return Lle(t)})});var FE,Wle=Et(()=>{Pt();qt();b1();FE=class extends nt{constructor(){super(...arguments);this.cwd=ge.String("--cwd",process.cwd(),{description:"The directory to run the command in"});this.commandName=ge.String();this.args=ge.Proxy()}async execute(){let r=this.args.length>0?`${this.commandName} ${this.args.join(" ")}`:this.commandName;return await TE(r,[],{cwd:ue.toPortablePath(this.cwd),stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})}};FE.usage={description:"run a command using yarn's portable shell",details:` + This command will run a command using Yarn's portable shell. + + Make sure to escape glob patterns, redirections, and other features that might be expanded by your own shell. + + Note: To escape something from Yarn's shell, you might have to escape it twice, the first time from your own shell. + + Note: Don't use this command in Yarn scripts, as Yarn's shell is automatically used. + + For a list of features, visit: https://github.com/yarnpkg/berry/blob/master/packages/yarnpkg-shell/README.md. + `,examples:[["Run a simple command","$0 echo Hello"],["Run a command with a glob pattern","$0 echo '*.js'"],["Run a command with a redirection","$0 echo Hello World '>' hello.txt"],["Run a command with an escaped glob pattern (The double escape is needed in Unix shells)",`$0 echo '"*.js"'`],["Run a command with a variable (Double quotes are needed in Unix shells, to prevent them from expanding the variable)",'$0 "GREETING=Hello echo $GREETING World"']]}});var al,Vle=Et(()=>{al=class extends Error{constructor(e){super(e),this.name="ShellError"}}});var Mx={};Kt(Mx,{fastGlobOptions:()=>zle,isBraceExpansion:()=>lU,isGlobPattern:()=>dot,match:()=>mot,micromatchOptions:()=>Lx});function dot(t){if(!Nx.default.scan(t,Lx).isGlob)return!1;try{Nx.default.parse(t,Lx)}catch{return!1}return!0}function mot(t,{cwd:e,baseFs:r}){return(0,Kle.default)(t,{...zle,cwd:ue.fromPortablePath(e),fs:TD(Jle.default,new Hp(r))})}function lU(t){return Nx.default.scan(t,Lx).isBrace}var Kle,Jle,Nx,Lx,zle,Xle=Et(()=>{Pt();Kle=$e(RS()),Jle=$e(Be("fs")),Nx=$e(Zo()),Lx={strictBrackets:!0},zle={onlyDirectories:!1,onlyFiles:!1}});function cU(){}function uU(){for(let t of bd)t.kill()}function tce(t,e,r,o){return a=>{let n=a[0]instanceof iA.Transform?"pipe":a[0],u=a[1]instanceof iA.Transform?"pipe":a[1],A=a[2]instanceof iA.Transform?"pipe":a[2],p=(0,$le.default)(t,e,{...o,stdio:[n,u,A]});return bd.add(p),bd.size===1&&(process.on("SIGINT",cU),process.on("SIGTERM",uU)),a[0]instanceof iA.Transform&&a[0].pipe(p.stdin),a[1]instanceof iA.Transform&&p.stdout.pipe(a[1],{end:!1}),a[2]instanceof iA.Transform&&p.stderr.pipe(a[2],{end:!1}),{stdin:p.stdin,promise:new Promise(h=>{p.on("error",E=>{switch(bd.delete(p),bd.size===0&&(process.off("SIGINT",cU),process.off("SIGTERM",uU)),E.code){case"ENOENT":a[2].write(`command not found: ${t} +`),h(127);break;case"EACCES":a[2].write(`permission denied: ${t} +`),h(128);break;default:a[2].write(`uncaught error: ${E.message} +`),h(1);break}}),p.on("close",E=>{bd.delete(p),bd.size===0&&(process.off("SIGINT",cU),process.off("SIGTERM",uU)),h(E!==null?E:129)})})}}}function rce(t){return e=>{let r=e[0]==="pipe"?new iA.PassThrough:e[0];return{stdin:r,promise:Promise.resolve().then(()=>t({stdin:r,stdout:e[1],stderr:e[2]}))}}}function Ox(t,e){return RE.start(t,e)}function Zle(t,e=null){let r=new iA.PassThrough,o=new ece.StringDecoder,a="";return r.on("data",n=>{let u=o.write(n),A;do if(A=u.indexOf(` +`),A!==-1){let p=a+u.substring(0,A);u=u.substring(A+1),a="",t(e!==null?`${e} ${p}`:p)}while(A!==-1);a+=u}),r.on("end",()=>{let n=o.end();n!==""&&t(e!==null?`${e} ${n}`:n)}),r}function nce(t,{prefix:e}){return{stdout:Zle(r=>t.stdout.write(`${r} +`),t.stdout.isTTY?e:null),stderr:Zle(r=>t.stderr.write(`${r} +`),t.stderr.isTTY?e:null)}}var $le,iA,ece,bd,zl,AU,RE,fU=Et(()=>{$le=$e(aR()),iA=Be("stream"),ece=Be("string_decoder"),bd=new Set;zl=class{constructor(e){this.stream=e}close(){}get(){return this.stream}},AU=class{constructor(){this.stream=null}close(){if(this.stream===null)throw new Error("Assertion failed: No stream attached");this.stream.end()}attach(e){this.stream=e}get(){if(this.stream===null)throw new Error("Assertion failed: No stream attached");return this.stream}},RE=class{constructor(e,r){this.stdin=null;this.stdout=null;this.stderr=null;this.pipe=null;this.ancestor=e,this.implementation=r}static start(e,{stdin:r,stdout:o,stderr:a}){let n=new RE(null,e);return n.stdin=r,n.stdout=o,n.stderr=a,n}pipeTo(e,r=1){let o=new RE(this,e),a=new AU;return o.pipe=a,o.stdout=this.stdout,o.stderr=this.stderr,(r&1)===1?this.stdout=a:this.ancestor!==null&&(this.stderr=this.ancestor.stdout),(r&2)===2?this.stderr=a:this.ancestor!==null&&(this.stderr=this.ancestor.stderr),o}async exec(){let e=["ignore","ignore","ignore"];if(this.pipe)e[0]="pipe";else{if(this.stdin===null)throw new Error("Assertion failed: No input stream registered");e[0]=this.stdin.get()}let r;if(this.stdout===null)throw new Error("Assertion failed: No output stream registered");r=this.stdout,e[1]=r.get();let o;if(this.stderr===null)throw new Error("Assertion failed: No error stream registered");o=this.stderr,e[2]=o.get();let a=this.implementation(e);return this.pipe&&this.pipe.attach(a.stdin),await a.promise.then(n=>(r.close(),o.close(),n))}async run(){let e=[];for(let o=this;o;o=o.ancestor)e.push(o.exec());return(await Promise.all(e))[0]}}});var T1={};Kt(T1,{EntryCommand:()=>FE,ShellError:()=>al,execute:()=>TE,globUtils:()=>Mx});function ice(t,e,r){let o=new ll.PassThrough({autoDestroy:!0});switch(t){case 0:(e&1)===1&&r.stdin.pipe(o,{end:!1}),(e&2)===2&&r.stdin instanceof ll.Writable&&o.pipe(r.stdin,{end:!1});break;case 1:(e&1)===1&&r.stdout.pipe(o,{end:!1}),(e&2)===2&&o.pipe(r.stdout,{end:!1});break;case 2:(e&1)===1&&r.stderr.pipe(o,{end:!1}),(e&2)===2&&o.pipe(r.stderr,{end:!1});break;default:throw new al(`Bad file descriptor: "${t}"`)}return o}function _x(t,e={}){let r={...t,...e};return r.environment={...t.environment,...e.environment},r.variables={...t.variables,...e.variables},r}async function Eot(t,e,r){let o=[],a=new ll.PassThrough;return a.on("data",n=>o.push(n)),await Hx(t,e,_x(r,{stdout:a})),Buffer.concat(o).toString().replace(/[\r\n]+$/,"")}async function sce(t,e,r){let o=t.map(async n=>{let u=await kd(n.args,e,r);return{name:n.name,value:u.join(" ")}});return(await Promise.all(o)).reduce((n,u)=>(n[u.name]=u.value,n),{})}function Ux(t){return t.match(/[^ \r\n\t]+/g)||[]}async function Ace(t,e,r,o,a=o){switch(t.name){case"$":o(String(process.pid));break;case"#":o(String(e.args.length));break;case"@":if(t.quoted)for(let n of e.args)a(n);else for(let n of e.args){let u=Ux(n);for(let A=0;A<u.length-1;++A)a(u[A]);o(u[u.length-1])}break;case"*":{let n=e.args.join(" ");if(t.quoted)o(n);else for(let u of Ux(n))a(u)}break;case"PPID":o(String(process.ppid));break;case"RANDOM":o(String(Math.floor(Math.random()*32768)));break;default:{let n=parseInt(t.name,10),u,A=Number.isFinite(n);if(A?n>=0&&n<e.args.length&&(u=e.args[n]):Object.hasOwn(r.variables,t.name)?u=r.variables[t.name]:Object.hasOwn(r.environment,t.name)&&(u=r.environment[t.name]),typeof u<"u"&&t.alternativeValue?u=(await kd(t.alternativeValue,e,r)).join(" "):typeof u>"u"&&(t.defaultValue?u=(await kd(t.defaultValue,e,r)).join(" "):t.alternativeValue&&(u="")),typeof u>"u")throw A?new al(`Unbound argument #${n}`):new al(`Unbound variable "${t.name}"`);if(t.quoted)o(u);else{let p=Ux(u);for(let E=0;E<p.length-1;++E)a(p[E]);let h=p[p.length-1];typeof h<"u"&&o(h)}}break}}async function k1(t,e,r){if(t.type==="number"){if(Number.isInteger(t.value))return t.value;throw new Error(`Invalid number: "${t.value}", only integers are allowed`)}else if(t.type==="variable"){let o=[];await Ace({...t,quoted:!0},e,r,n=>o.push(n));let a=Number(o.join(" "));return Number.isNaN(a)?k1({type:"variable",name:o.join(" ")},e,r):k1({type:"number",value:a},e,r)}else return Cot[t.type](await k1(t.left,e,r),await k1(t.right,e,r))}async function kd(t,e,r){let o=new Map,a=[],n=[],u=E=>{n.push(E)},A=()=>{n.length>0&&a.push(n.join("")),n=[]},p=E=>{u(E),A()},h=(E,I,v)=>{let b=JSON.stringify({type:E,fd:I}),C=o.get(b);typeof C>"u"&&o.set(b,C=[]),C.push(v)};for(let E of t){let I=!1;switch(E.type){case"redirection":{let v=await kd(E.args,e,r);for(let b of v)h(E.subtype,E.fd,b)}break;case"argument":for(let v of E.segments)switch(v.type){case"text":u(v.text);break;case"glob":u(v.pattern),I=!0;break;case"shell":{let b=await Eot(v.shell,e,r);if(v.quoted)u(b);else{let C=Ux(b);for(let T=0;T<C.length-1;++T)p(C[T]);u(C[C.length-1])}}break;case"variable":await Ace(v,e,r,u,p);break;case"arithmetic":u(String(await k1(v.arithmetic,e,r)));break}break}if(A(),I){let v=a.pop();if(typeof v>"u")throw new Error("Assertion failed: Expected a glob pattern to have been set");let b=await e.glob.match(v,{cwd:r.cwd,baseFs:e.baseFs});if(b.length===0){let C=lU(v)?". Note: Brace expansion of arbitrary strings isn't currently supported. For more details, please read this issue: https://github.com/yarnpkg/berry/issues/22":"";throw new al(`No matches found: "${v}"${C}`)}for(let C of b.sort())p(C)}}if(o.size>0){let E=[];for(let[I,v]of o.entries())E.splice(E.length,0,I,String(v.length),...v);a.splice(0,0,"__ysh_set_redirects",...E,"--")}return a}function Q1(t,e,r){e.builtins.has(t[0])||(t=["command",...t]);let o=ue.fromPortablePath(r.cwd),a=r.environment;typeof a.PWD<"u"&&(a={...a,PWD:o});let[n,...u]=t;if(n==="command")return tce(u[0],u.slice(1),e,{cwd:o,env:a});let A=e.builtins.get(n);if(typeof A>"u")throw new Error(`Assertion failed: A builtin should exist for "${n}"`);return rce(async({stdin:p,stdout:h,stderr:E})=>{let{stdin:I,stdout:v,stderr:b}=r;r.stdin=p,r.stdout=h,r.stderr=E;try{return await A(u,e,r)}finally{r.stdin=I,r.stdout=v,r.stderr=b}})}function wot(t,e,r){return o=>{let a=new ll.PassThrough,n=Hx(t,e,_x(r,{stdin:a}));return{stdin:a,promise:n}}}function Iot(t,e,r){return o=>{let a=new ll.PassThrough,n=Hx(t,e,r);return{stdin:a,promise:n}}}function oce(t,e,r,o){if(e.length===0)return t;{let a;do a=String(Math.random());while(Object.hasOwn(o.procedures,a));return o.procedures={...o.procedures},o.procedures[a]=t,Q1([...e,"__ysh_run_procedure",a],r,o)}}async function ace(t,e,r){let o=t,a=null,n=null;for(;o;){let u=o.then?{...r}:r,A;switch(o.type){case"command":{let p=await kd(o.args,e,r),h=await sce(o.envs,e,r);A=o.envs.length?Q1(p,e,_x(u,{environment:h})):Q1(p,e,u)}break;case"subshell":{let p=await kd(o.args,e,r),h=wot(o.subshell,e,u);A=oce(h,p,e,u)}break;case"group":{let p=await kd(o.args,e,r),h=Iot(o.group,e,u);A=oce(h,p,e,u)}break;case"envs":{let p=await sce(o.envs,e,r);u.environment={...u.environment,...p},A=Q1(["true"],e,u)}break}if(typeof A>"u")throw new Error("Assertion failed: An action should have been generated");if(a===null)n=Ox(A,{stdin:new zl(u.stdin),stdout:new zl(u.stdout),stderr:new zl(u.stderr)});else{if(n===null)throw new Error("Assertion failed: The execution pipeline should have been setup");switch(a){case"|":n=n.pipeTo(A,1);break;case"|&":n=n.pipeTo(A,3);break}}o.then?(a=o.then.type,o=o.then.chain):o=null}if(n===null)throw new Error("Assertion failed: The execution pipeline should have been setup");return await n.run()}async function Bot(t,e,r,{background:o=!1}={}){function a(n){let u=["#2E86AB","#A23B72","#F18F01","#C73E1D","#CCE2A3"],A=u[n%u.length];return lce.default.hex(A)}if(o){let n=r.nextBackgroundJobIndex++,u=a(n),A=`[${n}]`,p=u(A),{stdout:h,stderr:E}=nce(r,{prefix:p});return r.backgroundJobs.push(ace(t,e,_x(r,{stdout:h,stderr:E})).catch(I=>E.write(`${I.message} +`)).finally(()=>{r.stdout.isTTY&&r.stdout.write(`Job ${p}, '${u(cy(t))}' has ended +`)})),0}return await ace(t,e,r)}async function vot(t,e,r,{background:o=!1}={}){let a,n=A=>{a=A,r.variables["?"]=String(A)},u=async A=>{try{return await Bot(A.chain,e,r,{background:o&&typeof A.then>"u"})}catch(p){if(!(p instanceof al))throw p;return r.stderr.write(`${p.message} +`),1}};for(n(await u(t));t.then;){if(r.exitCode!==null)return r.exitCode;switch(t.then.type){case"&&":a===0&&n(await u(t.then.line));break;case"||":a!==0&&n(await u(t.then.line));break;default:throw new Error(`Assertion failed: Unsupported command type: "${t.then.type}"`)}t=t.then.line}return a}async function Hx(t,e,r){let o=r.backgroundJobs;r.backgroundJobs=[];let a=0;for(let{command:n,type:u}of t){if(a=await vot(n,e,r,{background:u==="&"}),r.exitCode!==null)return r.exitCode;r.variables["?"]=String(a)}return await Promise.all(r.backgroundJobs),r.backgroundJobs=o,a}function fce(t){switch(t.type){case"variable":return t.name==="@"||t.name==="#"||t.name==="*"||Number.isFinite(parseInt(t.name,10))||"defaultValue"in t&&!!t.defaultValue&&t.defaultValue.some(e=>F1(e))||"alternativeValue"in t&&!!t.alternativeValue&&t.alternativeValue.some(e=>F1(e));case"arithmetic":return pU(t.arithmetic);case"shell":return hU(t.shell);default:return!1}}function F1(t){switch(t.type){case"redirection":return t.args.some(e=>F1(e));case"argument":return t.segments.some(e=>fce(e));default:throw new Error(`Assertion failed: Unsupported argument type: "${t.type}"`)}}function pU(t){switch(t.type){case"variable":return fce(t);case"number":return!1;default:return pU(t.left)||pU(t.right)}}function hU(t){return t.some(({command:e})=>{for(;e;){let r=e.chain;for(;r;){let o;switch(r.type){case"subshell":o=hU(r.subshell);break;case"command":o=r.envs.some(a=>a.args.some(n=>F1(n)))||r.args.some(a=>F1(a));break}if(o)return!0;if(!r.then)break;r=r.then.chain}if(!e.then)break;e=e.then.line}return!1})}async function TE(t,e=[],{baseFs:r=new Rn,builtins:o={},cwd:a=ue.toPortablePath(process.cwd()),env:n=process.env,stdin:u=process.stdin,stdout:A=process.stdout,stderr:p=process.stderr,variables:h={},glob:E=Mx}={}){let I={};for(let[C,T]of Object.entries(n))typeof T<"u"&&(I[C]=T);let v=new Map(yot);for(let[C,T]of Object.entries(o))v.set(C,T);u===null&&(u=new ll.PassThrough,u.end());let b=LD(t,E);if(!hU(b)&&b.length>0&&e.length>0){let{command:C}=b[b.length-1];for(;C.then;)C=C.then.line;let T=C.chain;for(;T.then;)T=T.then.chain;T.type==="command"&&(T.args=T.args.concat(e.map(L=>({type:"argument",segments:[{type:"text",text:L}]}))))}return await Hx(b,{args:e,baseFs:r,builtins:v,initialStdin:u,initialStdout:A,initialStderr:p,glob:E},{cwd:a,environment:I,exitCode:null,procedures:{},stdin:u,stdout:A,stderr:p,variables:Object.assign({},h,{["?"]:0}),nextBackgroundJobIndex:1,backgroundJobs:[]})}var lce,cce,ll,uce,yot,Cot,b1=Et(()=>{Pt();Nl();lce=$e(vN()),cce=Be("os"),ll=Be("stream"),uce=Be("timers/promises");Wle();Vle();Xle();fU();fU();yot=new Map([["cd",async([t=(0,cce.homedir)(),...e],r,o)=>{let a=K.resolve(o.cwd,ue.toPortablePath(t));if(!(await r.baseFs.statPromise(a).catch(u=>{throw u.code==="ENOENT"?new al(`cd: no such file or directory: ${t}`):u})).isDirectory())throw new al(`cd: not a directory: ${t}`);return o.cwd=a,0}],["pwd",async(t,e,r)=>(r.stdout.write(`${ue.fromPortablePath(r.cwd)} +`),0)],[":",async(t,e,r)=>0],["true",async(t,e,r)=>0],["false",async(t,e,r)=>1],["exit",async([t,...e],r,o)=>o.exitCode=parseInt(t??o.variables["?"],10)],["echo",async(t,e,r)=>(r.stdout.write(`${t.join(" ")} +`),0)],["sleep",async([t],e,r)=>{if(typeof t>"u")throw new al("sleep: missing operand");let o=Number(t);if(Number.isNaN(o))throw new al(`sleep: invalid time interval '${t}'`);return await(0,uce.setTimeout)(1e3*o,0)}],["__ysh_run_procedure",async(t,e,r)=>{let o=r.procedures[t[0]];return await Ox(o,{stdin:new zl(r.stdin),stdout:new zl(r.stdout),stderr:new zl(r.stderr)}).run()}],["__ysh_set_redirects",async(t,e,r)=>{let o=r.stdin,a=r.stdout,n=r.stderr,u=[],A=[],p=[],h=0;for(;t[h]!=="--";){let I=t[h++],{type:v,fd:b}=JSON.parse(I),C=J=>{switch(b){case null:case 0:u.push(J);break;default:throw new Error(`Unsupported file descriptor: "${b}"`)}},T=J=>{switch(b){case null:case 1:A.push(J);break;case 2:p.push(J);break;default:throw new Error(`Unsupported file descriptor: "${b}"`)}},L=Number(t[h++]),U=h+L;for(let J=h;J<U;++h,++J)switch(v){case"<":C(()=>e.baseFs.createReadStream(K.resolve(r.cwd,ue.toPortablePath(t[J]))));break;case"<<<":C(()=>{let te=new ll.PassThrough;return process.nextTick(()=>{te.write(`${t[J]} +`),te.end()}),te});break;case"<&":C(()=>ice(Number(t[J]),1,r));break;case">":case">>":{let te=K.resolve(r.cwd,ue.toPortablePath(t[J]));T(te==="/dev/null"?new ll.Writable({autoDestroy:!0,emitClose:!0,write(le,pe,Ae){setImmediate(Ae)}}):e.baseFs.createWriteStream(te,v===">>"?{flags:"a"}:void 0))}break;case">&":T(ice(Number(t[J]),2,r));break;default:throw new Error(`Assertion failed: Unsupported redirection type: "${v}"`)}}if(u.length>0){let I=new ll.PassThrough;o=I;let v=b=>{if(b===u.length)I.end();else{let C=u[b]();C.pipe(I,{end:!1}),C.on("end",()=>{v(b+1)})}};v(0)}if(A.length>0){let I=new ll.PassThrough;a=I;for(let v of A)I.pipe(v)}if(p.length>0){let I=new ll.PassThrough;n=I;for(let v of p)I.pipe(v)}let E=await Ox(Q1(t.slice(h+1),e,r),{stdin:new zl(o),stdout:new zl(a),stderr:new zl(n)}).run();return await Promise.all(A.map(I=>new Promise((v,b)=>{I.on("error",C=>{b(C)}),I.on("close",()=>{v()}),I.end()}))),await Promise.all(p.map(I=>new Promise((v,b)=>{I.on("error",C=>{b(C)}),I.on("close",()=>{v()}),I.end()}))),E}]]);Cot={addition:(t,e)=>t+e,subtraction:(t,e)=>t-e,multiplication:(t,e)=>t*e,division:(t,e)=>Math.trunc(t/e)}});var jx=_((n4t,pce)=>{function Dot(t,e){for(var r=-1,o=t==null?0:t.length,a=Array(o);++r<o;)a[r]=e(t[r],r,t);return a}pce.exports=Dot});var Ece=_((i4t,yce)=>{var hce=fd(),Pot=jx(),Sot=Hl(),xot=fE(),bot=1/0,gce=hce?hce.prototype:void 0,dce=gce?gce.toString:void 0;function mce(t){if(typeof t=="string")return t;if(Sot(t))return Pot(t,mce)+"";if(xot(t))return dce?dce.call(t):"";var e=t+"";return e=="0"&&1/t==-bot?"-0":e}yce.exports=mce});var R1=_((s4t,Cce)=>{var kot=Ece();function Qot(t){return t==null?"":kot(t)}Cce.exports=Qot});var gU=_((o4t,wce)=>{function Fot(t,e,r){var o=-1,a=t.length;e<0&&(e=-e>a?0:a+e),r=r>a?a:r,r<0&&(r+=a),a=e>r?0:r-e>>>0,e>>>=0;for(var n=Array(a);++o<a;)n[o]=t[o+e];return n}wce.exports=Fot});var Bce=_((a4t,Ice)=>{var Tot=gU();function Rot(t,e,r){var o=t.length;return r=r===void 0?o:r,!e&&r>=o?t:Tot(t,e,r)}Ice.exports=Rot});var dU=_((l4t,vce)=>{var Not="\\ud800-\\udfff",Lot="\\u0300-\\u036f",Mot="\\ufe20-\\ufe2f",Oot="\\u20d0-\\u20ff",Uot=Lot+Mot+Oot,_ot="\\ufe0e\\ufe0f",Hot="\\u200d",jot=RegExp("["+Hot+Not+Uot+_ot+"]");function qot(t){return jot.test(t)}vce.exports=qot});var Pce=_((c4t,Dce)=>{function Got(t){return t.split("")}Dce.exports=Got});var Rce=_((u4t,Tce)=>{var Sce="\\ud800-\\udfff",Yot="\\u0300-\\u036f",Wot="\\ufe20-\\ufe2f",Vot="\\u20d0-\\u20ff",Kot=Yot+Wot+Vot,Jot="\\ufe0e\\ufe0f",zot="["+Sce+"]",mU="["+Kot+"]",yU="\\ud83c[\\udffb-\\udfff]",Xot="(?:"+mU+"|"+yU+")",xce="[^"+Sce+"]",bce="(?:\\ud83c[\\udde6-\\uddff]){2}",kce="[\\ud800-\\udbff][\\udc00-\\udfff]",Zot="\\u200d",Qce=Xot+"?",Fce="["+Jot+"]?",$ot="(?:"+Zot+"(?:"+[xce,bce,kce].join("|")+")"+Fce+Qce+")*",eat=Fce+Qce+$ot,tat="(?:"+[xce+mU+"?",mU,bce,kce,zot].join("|")+")",rat=RegExp(yU+"(?="+yU+")|"+tat+eat,"g");function nat(t){return t.match(rat)||[]}Tce.exports=nat});var Lce=_((A4t,Nce)=>{var iat=Pce(),sat=dU(),oat=Rce();function aat(t){return sat(t)?oat(t):iat(t)}Nce.exports=aat});var Oce=_((f4t,Mce)=>{var lat=Bce(),cat=dU(),uat=Lce(),Aat=R1();function fat(t){return function(e){e=Aat(e);var r=cat(e)?uat(e):void 0,o=r?r[0]:e.charAt(0),a=r?lat(r,1).join(""):e.slice(1);return o[t]()+a}}Mce.exports=fat});var _ce=_((p4t,Uce)=>{var pat=Oce(),hat=pat("toUpperCase");Uce.exports=hat});var EU=_((h4t,Hce)=>{var gat=R1(),dat=_ce();function mat(t){return dat(gat(t).toLowerCase())}Hce.exports=mat});var jce=_((g4t,qx)=>{function yat(){var t=0,e=1,r=2,o=3,a=4,n=5,u=6,A=7,p=8,h=9,E=10,I=11,v=12,b=13,C=14,T=15,L=16,U=17,J=0,te=1,le=2,pe=3,Ae=4;function ye(g,Ee){return 55296<=g.charCodeAt(Ee)&&g.charCodeAt(Ee)<=56319&&56320<=g.charCodeAt(Ee+1)&&g.charCodeAt(Ee+1)<=57343}function ae(g,Ee){Ee===void 0&&(Ee=0);var De=g.charCodeAt(Ee);if(55296<=De&&De<=56319&&Ee<g.length-1){var ce=De,ne=g.charCodeAt(Ee+1);return 56320<=ne&&ne<=57343?(ce-55296)*1024+(ne-56320)+65536:ce}if(56320<=De&&De<=57343&&Ee>=1){var ce=g.charCodeAt(Ee-1),ne=De;return 55296<=ce&&ce<=56319?(ce-55296)*1024+(ne-56320)+65536:ne}return De}function we(g,Ee,De){var ce=[g].concat(Ee).concat([De]),ne=ce[ce.length-2],ee=De,Ie=ce.lastIndexOf(C);if(Ie>1&&ce.slice(1,Ie).every(function(H){return H==o})&&[o,b,U].indexOf(g)==-1)return le;var ke=ce.lastIndexOf(a);if(ke>0&&ce.slice(1,ke).every(function(H){return H==a})&&[v,a].indexOf(ne)==-1)return ce.filter(function(H){return H==a}).length%2==1?pe:Ae;if(ne==t&&ee==e)return J;if(ne==r||ne==t||ne==e)return ee==C&&Ee.every(function(H){return H==o})?le:te;if(ee==r||ee==t||ee==e)return te;if(ne==u&&(ee==u||ee==A||ee==h||ee==E))return J;if((ne==h||ne==A)&&(ee==A||ee==p))return J;if((ne==E||ne==p)&&ee==p)return J;if(ee==o||ee==T)return J;if(ee==n)return J;if(ne==v)return J;var ht=ce.indexOf(o)!=-1?ce.lastIndexOf(o)-1:ce.length-2;return[b,U].indexOf(ce[ht])!=-1&&ce.slice(ht+1,-1).every(function(H){return H==o})&&ee==C||ne==T&&[L,U].indexOf(ee)!=-1?J:Ee.indexOf(a)!=-1?le:ne==a&&ee==a?J:te}this.nextBreak=function(g,Ee){if(Ee===void 0&&(Ee=0),Ee<0)return 0;if(Ee>=g.length-1)return g.length;for(var De=Pe(ae(g,Ee)),ce=[],ne=Ee+1;ne<g.length;ne++)if(!ye(g,ne-1)){var ee=Pe(ae(g,ne));if(we(De,ce,ee))return ne;ce.push(ee)}return g.length},this.splitGraphemes=function(g){for(var Ee=[],De=0,ce;(ce=this.nextBreak(g,De))<g.length;)Ee.push(g.slice(De,ce)),De=ce;return De<g.length&&Ee.push(g.slice(De)),Ee},this.iterateGraphemes=function(g){var Ee=0,De={next:function(){var ce,ne;return(ne=this.nextBreak(g,Ee))<g.length?(ce=g.slice(Ee,ne),Ee=ne,{value:ce,done:!1}):Ee<g.length?(ce=g.slice(Ee),Ee=g.length,{value:ce,done:!1}):{value:void 0,done:!0}}.bind(this)};return typeof Symbol<"u"&&Symbol.iterator&&(De[Symbol.iterator]=function(){return De}),De},this.countGraphemes=function(g){for(var Ee=0,De=0,ce;(ce=this.nextBreak(g,De))<g.length;)De=ce,Ee++;return De<g.length&&Ee++,Ee};function Pe(g){return 1536<=g&&g<=1541||g==1757||g==1807||g==2274||g==3406||g==69821||70082<=g&&g<=70083||g==72250||72326<=g&&g<=72329||g==73030?v:g==13?t:g==10?e:0<=g&&g<=9||11<=g&&g<=12||14<=g&&g<=31||127<=g&&g<=159||g==173||g==1564||g==6158||g==8203||8206<=g&&g<=8207||g==8232||g==8233||8234<=g&&g<=8238||8288<=g&&g<=8292||g==8293||8294<=g&&g<=8303||55296<=g&&g<=57343||g==65279||65520<=g&&g<=65528||65529<=g&&g<=65531||113824<=g&&g<=113827||119155<=g&&g<=119162||g==917504||g==917505||917506<=g&&g<=917535||917632<=g&&g<=917759||918e3<=g&&g<=921599?r:768<=g&&g<=879||1155<=g&&g<=1159||1160<=g&&g<=1161||1425<=g&&g<=1469||g==1471||1473<=g&&g<=1474||1476<=g&&g<=1477||g==1479||1552<=g&&g<=1562||1611<=g&&g<=1631||g==1648||1750<=g&&g<=1756||1759<=g&&g<=1764||1767<=g&&g<=1768||1770<=g&&g<=1773||g==1809||1840<=g&&g<=1866||1958<=g&&g<=1968||2027<=g&&g<=2035||2070<=g&&g<=2073||2075<=g&&g<=2083||2085<=g&&g<=2087||2089<=g&&g<=2093||2137<=g&&g<=2139||2260<=g&&g<=2273||2275<=g&&g<=2306||g==2362||g==2364||2369<=g&&g<=2376||g==2381||2385<=g&&g<=2391||2402<=g&&g<=2403||g==2433||g==2492||g==2494||2497<=g&&g<=2500||g==2509||g==2519||2530<=g&&g<=2531||2561<=g&&g<=2562||g==2620||2625<=g&&g<=2626||2631<=g&&g<=2632||2635<=g&&g<=2637||g==2641||2672<=g&&g<=2673||g==2677||2689<=g&&g<=2690||g==2748||2753<=g&&g<=2757||2759<=g&&g<=2760||g==2765||2786<=g&&g<=2787||2810<=g&&g<=2815||g==2817||g==2876||g==2878||g==2879||2881<=g&&g<=2884||g==2893||g==2902||g==2903||2914<=g&&g<=2915||g==2946||g==3006||g==3008||g==3021||g==3031||g==3072||3134<=g&&g<=3136||3142<=g&&g<=3144||3146<=g&&g<=3149||3157<=g&&g<=3158||3170<=g&&g<=3171||g==3201||g==3260||g==3263||g==3266||g==3270||3276<=g&&g<=3277||3285<=g&&g<=3286||3298<=g&&g<=3299||3328<=g&&g<=3329||3387<=g&&g<=3388||g==3390||3393<=g&&g<=3396||g==3405||g==3415||3426<=g&&g<=3427||g==3530||g==3535||3538<=g&&g<=3540||g==3542||g==3551||g==3633||3636<=g&&g<=3642||3655<=g&&g<=3662||g==3761||3764<=g&&g<=3769||3771<=g&&g<=3772||3784<=g&&g<=3789||3864<=g&&g<=3865||g==3893||g==3895||g==3897||3953<=g&&g<=3966||3968<=g&&g<=3972||3974<=g&&g<=3975||3981<=g&&g<=3991||3993<=g&&g<=4028||g==4038||4141<=g&&g<=4144||4146<=g&&g<=4151||4153<=g&&g<=4154||4157<=g&&g<=4158||4184<=g&&g<=4185||4190<=g&&g<=4192||4209<=g&&g<=4212||g==4226||4229<=g&&g<=4230||g==4237||g==4253||4957<=g&&g<=4959||5906<=g&&g<=5908||5938<=g&&g<=5940||5970<=g&&g<=5971||6002<=g&&g<=6003||6068<=g&&g<=6069||6071<=g&&g<=6077||g==6086||6089<=g&&g<=6099||g==6109||6155<=g&&g<=6157||6277<=g&&g<=6278||g==6313||6432<=g&&g<=6434||6439<=g&&g<=6440||g==6450||6457<=g&&g<=6459||6679<=g&&g<=6680||g==6683||g==6742||6744<=g&&g<=6750||g==6752||g==6754||6757<=g&&g<=6764||6771<=g&&g<=6780||g==6783||6832<=g&&g<=6845||g==6846||6912<=g&&g<=6915||g==6964||6966<=g&&g<=6970||g==6972||g==6978||7019<=g&&g<=7027||7040<=g&&g<=7041||7074<=g&&g<=7077||7080<=g&&g<=7081||7083<=g&&g<=7085||g==7142||7144<=g&&g<=7145||g==7149||7151<=g&&g<=7153||7212<=g&&g<=7219||7222<=g&&g<=7223||7376<=g&&g<=7378||7380<=g&&g<=7392||7394<=g&&g<=7400||g==7405||g==7412||7416<=g&&g<=7417||7616<=g&&g<=7673||7675<=g&&g<=7679||g==8204||8400<=g&&g<=8412||8413<=g&&g<=8416||g==8417||8418<=g&&g<=8420||8421<=g&&g<=8432||11503<=g&&g<=11505||g==11647||11744<=g&&g<=11775||12330<=g&&g<=12333||12334<=g&&g<=12335||12441<=g&&g<=12442||g==42607||42608<=g&&g<=42610||42612<=g&&g<=42621||42654<=g&&g<=42655||42736<=g&&g<=42737||g==43010||g==43014||g==43019||43045<=g&&g<=43046||43204<=g&&g<=43205||43232<=g&&g<=43249||43302<=g&&g<=43309||43335<=g&&g<=43345||43392<=g&&g<=43394||g==43443||43446<=g&&g<=43449||g==43452||g==43493||43561<=g&&g<=43566||43569<=g&&g<=43570||43573<=g&&g<=43574||g==43587||g==43596||g==43644||g==43696||43698<=g&&g<=43700||43703<=g&&g<=43704||43710<=g&&g<=43711||g==43713||43756<=g&&g<=43757||g==43766||g==44005||g==44008||g==44013||g==64286||65024<=g&&g<=65039||65056<=g&&g<=65071||65438<=g&&g<=65439||g==66045||g==66272||66422<=g&&g<=66426||68097<=g&&g<=68099||68101<=g&&g<=68102||68108<=g&&g<=68111||68152<=g&&g<=68154||g==68159||68325<=g&&g<=68326||g==69633||69688<=g&&g<=69702||69759<=g&&g<=69761||69811<=g&&g<=69814||69817<=g&&g<=69818||69888<=g&&g<=69890||69927<=g&&g<=69931||69933<=g&&g<=69940||g==70003||70016<=g&&g<=70017||70070<=g&&g<=70078||70090<=g&&g<=70092||70191<=g&&g<=70193||g==70196||70198<=g&&g<=70199||g==70206||g==70367||70371<=g&&g<=70378||70400<=g&&g<=70401||g==70460||g==70462||g==70464||g==70487||70502<=g&&g<=70508||70512<=g&&g<=70516||70712<=g&&g<=70719||70722<=g&&g<=70724||g==70726||g==70832||70835<=g&&g<=70840||g==70842||g==70845||70847<=g&&g<=70848||70850<=g&&g<=70851||g==71087||71090<=g&&g<=71093||71100<=g&&g<=71101||71103<=g&&g<=71104||71132<=g&&g<=71133||71219<=g&&g<=71226||g==71229||71231<=g&&g<=71232||g==71339||g==71341||71344<=g&&g<=71349||g==71351||71453<=g&&g<=71455||71458<=g&&g<=71461||71463<=g&&g<=71467||72193<=g&&g<=72198||72201<=g&&g<=72202||72243<=g&&g<=72248||72251<=g&&g<=72254||g==72263||72273<=g&&g<=72278||72281<=g&&g<=72283||72330<=g&&g<=72342||72344<=g&&g<=72345||72752<=g&&g<=72758||72760<=g&&g<=72765||g==72767||72850<=g&&g<=72871||72874<=g&&g<=72880||72882<=g&&g<=72883||72885<=g&&g<=72886||73009<=g&&g<=73014||g==73018||73020<=g&&g<=73021||73023<=g&&g<=73029||g==73031||92912<=g&&g<=92916||92976<=g&&g<=92982||94095<=g&&g<=94098||113821<=g&&g<=113822||g==119141||119143<=g&&g<=119145||119150<=g&&g<=119154||119163<=g&&g<=119170||119173<=g&&g<=119179||119210<=g&&g<=119213||119362<=g&&g<=119364||121344<=g&&g<=121398||121403<=g&&g<=121452||g==121461||g==121476||121499<=g&&g<=121503||121505<=g&&g<=121519||122880<=g&&g<=122886||122888<=g&&g<=122904||122907<=g&&g<=122913||122915<=g&&g<=122916||122918<=g&&g<=122922||125136<=g&&g<=125142||125252<=g&&g<=125258||917536<=g&&g<=917631||917760<=g&&g<=917999?o:127462<=g&&g<=127487?a:g==2307||g==2363||2366<=g&&g<=2368||2377<=g&&g<=2380||2382<=g&&g<=2383||2434<=g&&g<=2435||2495<=g&&g<=2496||2503<=g&&g<=2504||2507<=g&&g<=2508||g==2563||2622<=g&&g<=2624||g==2691||2750<=g&&g<=2752||g==2761||2763<=g&&g<=2764||2818<=g&&g<=2819||g==2880||2887<=g&&g<=2888||2891<=g&&g<=2892||g==3007||3009<=g&&g<=3010||3014<=g&&g<=3016||3018<=g&&g<=3020||3073<=g&&g<=3075||3137<=g&&g<=3140||3202<=g&&g<=3203||g==3262||3264<=g&&g<=3265||3267<=g&&g<=3268||3271<=g&&g<=3272||3274<=g&&g<=3275||3330<=g&&g<=3331||3391<=g&&g<=3392||3398<=g&&g<=3400||3402<=g&&g<=3404||3458<=g&&g<=3459||3536<=g&&g<=3537||3544<=g&&g<=3550||3570<=g&&g<=3571||g==3635||g==3763||3902<=g&&g<=3903||g==3967||g==4145||4155<=g&&g<=4156||4182<=g&&g<=4183||g==4228||g==6070||6078<=g&&g<=6085||6087<=g&&g<=6088||6435<=g&&g<=6438||6441<=g&&g<=6443||6448<=g&&g<=6449||6451<=g&&g<=6456||6681<=g&&g<=6682||g==6741||g==6743||6765<=g&&g<=6770||g==6916||g==6965||g==6971||6973<=g&&g<=6977||6979<=g&&g<=6980||g==7042||g==7073||7078<=g&&g<=7079||g==7082||g==7143||7146<=g&&g<=7148||g==7150||7154<=g&&g<=7155||7204<=g&&g<=7211||7220<=g&&g<=7221||g==7393||7410<=g&&g<=7411||g==7415||43043<=g&&g<=43044||g==43047||43136<=g&&g<=43137||43188<=g&&g<=43203||43346<=g&&g<=43347||g==43395||43444<=g&&g<=43445||43450<=g&&g<=43451||43453<=g&&g<=43456||43567<=g&&g<=43568||43571<=g&&g<=43572||g==43597||g==43755||43758<=g&&g<=43759||g==43765||44003<=g&&g<=44004||44006<=g&&g<=44007||44009<=g&&g<=44010||g==44012||g==69632||g==69634||g==69762||69808<=g&&g<=69810||69815<=g&&g<=69816||g==69932||g==70018||70067<=g&&g<=70069||70079<=g&&g<=70080||70188<=g&&g<=70190||70194<=g&&g<=70195||g==70197||70368<=g&&g<=70370||70402<=g&&g<=70403||g==70463||70465<=g&&g<=70468||70471<=g&&g<=70472||70475<=g&&g<=70477||70498<=g&&g<=70499||70709<=g&&g<=70711||70720<=g&&g<=70721||g==70725||70833<=g&&g<=70834||g==70841||70843<=g&&g<=70844||g==70846||g==70849||71088<=g&&g<=71089||71096<=g&&g<=71099||g==71102||71216<=g&&g<=71218||71227<=g&&g<=71228||g==71230||g==71340||71342<=g&&g<=71343||g==71350||71456<=g&&g<=71457||g==71462||72199<=g&&g<=72200||g==72249||72279<=g&&g<=72280||g==72343||g==72751||g==72766||g==72873||g==72881||g==72884||94033<=g&&g<=94078||g==119142||g==119149?n:4352<=g&&g<=4447||43360<=g&&g<=43388?u:4448<=g&&g<=4519||55216<=g&&g<=55238?A:4520<=g&&g<=4607||55243<=g&&g<=55291?p:g==44032||g==44060||g==44088||g==44116||g==44144||g==44172||g==44200||g==44228||g==44256||g==44284||g==44312||g==44340||g==44368||g==44396||g==44424||g==44452||g==44480||g==44508||g==44536||g==44564||g==44592||g==44620||g==44648||g==44676||g==44704||g==44732||g==44760||g==44788||g==44816||g==44844||g==44872||g==44900||g==44928||g==44956||g==44984||g==45012||g==45040||g==45068||g==45096||g==45124||g==45152||g==45180||g==45208||g==45236||g==45264||g==45292||g==45320||g==45348||g==45376||g==45404||g==45432||g==45460||g==45488||g==45516||g==45544||g==45572||g==45600||g==45628||g==45656||g==45684||g==45712||g==45740||g==45768||g==45796||g==45824||g==45852||g==45880||g==45908||g==45936||g==45964||g==45992||g==46020||g==46048||g==46076||g==46104||g==46132||g==46160||g==46188||g==46216||g==46244||g==46272||g==46300||g==46328||g==46356||g==46384||g==46412||g==46440||g==46468||g==46496||g==46524||g==46552||g==46580||g==46608||g==46636||g==46664||g==46692||g==46720||g==46748||g==46776||g==46804||g==46832||g==46860||g==46888||g==46916||g==46944||g==46972||g==47e3||g==47028||g==47056||g==47084||g==47112||g==47140||g==47168||g==47196||g==47224||g==47252||g==47280||g==47308||g==47336||g==47364||g==47392||g==47420||g==47448||g==47476||g==47504||g==47532||g==47560||g==47588||g==47616||g==47644||g==47672||g==47700||g==47728||g==47756||g==47784||g==47812||g==47840||g==47868||g==47896||g==47924||g==47952||g==47980||g==48008||g==48036||g==48064||g==48092||g==48120||g==48148||g==48176||g==48204||g==48232||g==48260||g==48288||g==48316||g==48344||g==48372||g==48400||g==48428||g==48456||g==48484||g==48512||g==48540||g==48568||g==48596||g==48624||g==48652||g==48680||g==48708||g==48736||g==48764||g==48792||g==48820||g==48848||g==48876||g==48904||g==48932||g==48960||g==48988||g==49016||g==49044||g==49072||g==49100||g==49128||g==49156||g==49184||g==49212||g==49240||g==49268||g==49296||g==49324||g==49352||g==49380||g==49408||g==49436||g==49464||g==49492||g==49520||g==49548||g==49576||g==49604||g==49632||g==49660||g==49688||g==49716||g==49744||g==49772||g==49800||g==49828||g==49856||g==49884||g==49912||g==49940||g==49968||g==49996||g==50024||g==50052||g==50080||g==50108||g==50136||g==50164||g==50192||g==50220||g==50248||g==50276||g==50304||g==50332||g==50360||g==50388||g==50416||g==50444||g==50472||g==50500||g==50528||g==50556||g==50584||g==50612||g==50640||g==50668||g==50696||g==50724||g==50752||g==50780||g==50808||g==50836||g==50864||g==50892||g==50920||g==50948||g==50976||g==51004||g==51032||g==51060||g==51088||g==51116||g==51144||g==51172||g==51200||g==51228||g==51256||g==51284||g==51312||g==51340||g==51368||g==51396||g==51424||g==51452||g==51480||g==51508||g==51536||g==51564||g==51592||g==51620||g==51648||g==51676||g==51704||g==51732||g==51760||g==51788||g==51816||g==51844||g==51872||g==51900||g==51928||g==51956||g==51984||g==52012||g==52040||g==52068||g==52096||g==52124||g==52152||g==52180||g==52208||g==52236||g==52264||g==52292||g==52320||g==52348||g==52376||g==52404||g==52432||g==52460||g==52488||g==52516||g==52544||g==52572||g==52600||g==52628||g==52656||g==52684||g==52712||g==52740||g==52768||g==52796||g==52824||g==52852||g==52880||g==52908||g==52936||g==52964||g==52992||g==53020||g==53048||g==53076||g==53104||g==53132||g==53160||g==53188||g==53216||g==53244||g==53272||g==53300||g==53328||g==53356||g==53384||g==53412||g==53440||g==53468||g==53496||g==53524||g==53552||g==53580||g==53608||g==53636||g==53664||g==53692||g==53720||g==53748||g==53776||g==53804||g==53832||g==53860||g==53888||g==53916||g==53944||g==53972||g==54e3||g==54028||g==54056||g==54084||g==54112||g==54140||g==54168||g==54196||g==54224||g==54252||g==54280||g==54308||g==54336||g==54364||g==54392||g==54420||g==54448||g==54476||g==54504||g==54532||g==54560||g==54588||g==54616||g==54644||g==54672||g==54700||g==54728||g==54756||g==54784||g==54812||g==54840||g==54868||g==54896||g==54924||g==54952||g==54980||g==55008||g==55036||g==55064||g==55092||g==55120||g==55148||g==55176?h:44033<=g&&g<=44059||44061<=g&&g<=44087||44089<=g&&g<=44115||44117<=g&&g<=44143||44145<=g&&g<=44171||44173<=g&&g<=44199||44201<=g&&g<=44227||44229<=g&&g<=44255||44257<=g&&g<=44283||44285<=g&&g<=44311||44313<=g&&g<=44339||44341<=g&&g<=44367||44369<=g&&g<=44395||44397<=g&&g<=44423||44425<=g&&g<=44451||44453<=g&&g<=44479||44481<=g&&g<=44507||44509<=g&&g<=44535||44537<=g&&g<=44563||44565<=g&&g<=44591||44593<=g&&g<=44619||44621<=g&&g<=44647||44649<=g&&g<=44675||44677<=g&&g<=44703||44705<=g&&g<=44731||44733<=g&&g<=44759||44761<=g&&g<=44787||44789<=g&&g<=44815||44817<=g&&g<=44843||44845<=g&&g<=44871||44873<=g&&g<=44899||44901<=g&&g<=44927||44929<=g&&g<=44955||44957<=g&&g<=44983||44985<=g&&g<=45011||45013<=g&&g<=45039||45041<=g&&g<=45067||45069<=g&&g<=45095||45097<=g&&g<=45123||45125<=g&&g<=45151||45153<=g&&g<=45179||45181<=g&&g<=45207||45209<=g&&g<=45235||45237<=g&&g<=45263||45265<=g&&g<=45291||45293<=g&&g<=45319||45321<=g&&g<=45347||45349<=g&&g<=45375||45377<=g&&g<=45403||45405<=g&&g<=45431||45433<=g&&g<=45459||45461<=g&&g<=45487||45489<=g&&g<=45515||45517<=g&&g<=45543||45545<=g&&g<=45571||45573<=g&&g<=45599||45601<=g&&g<=45627||45629<=g&&g<=45655||45657<=g&&g<=45683||45685<=g&&g<=45711||45713<=g&&g<=45739||45741<=g&&g<=45767||45769<=g&&g<=45795||45797<=g&&g<=45823||45825<=g&&g<=45851||45853<=g&&g<=45879||45881<=g&&g<=45907||45909<=g&&g<=45935||45937<=g&&g<=45963||45965<=g&&g<=45991||45993<=g&&g<=46019||46021<=g&&g<=46047||46049<=g&&g<=46075||46077<=g&&g<=46103||46105<=g&&g<=46131||46133<=g&&g<=46159||46161<=g&&g<=46187||46189<=g&&g<=46215||46217<=g&&g<=46243||46245<=g&&g<=46271||46273<=g&&g<=46299||46301<=g&&g<=46327||46329<=g&&g<=46355||46357<=g&&g<=46383||46385<=g&&g<=46411||46413<=g&&g<=46439||46441<=g&&g<=46467||46469<=g&&g<=46495||46497<=g&&g<=46523||46525<=g&&g<=46551||46553<=g&&g<=46579||46581<=g&&g<=46607||46609<=g&&g<=46635||46637<=g&&g<=46663||46665<=g&&g<=46691||46693<=g&&g<=46719||46721<=g&&g<=46747||46749<=g&&g<=46775||46777<=g&&g<=46803||46805<=g&&g<=46831||46833<=g&&g<=46859||46861<=g&&g<=46887||46889<=g&&g<=46915||46917<=g&&g<=46943||46945<=g&&g<=46971||46973<=g&&g<=46999||47001<=g&&g<=47027||47029<=g&&g<=47055||47057<=g&&g<=47083||47085<=g&&g<=47111||47113<=g&&g<=47139||47141<=g&&g<=47167||47169<=g&&g<=47195||47197<=g&&g<=47223||47225<=g&&g<=47251||47253<=g&&g<=47279||47281<=g&&g<=47307||47309<=g&&g<=47335||47337<=g&&g<=47363||47365<=g&&g<=47391||47393<=g&&g<=47419||47421<=g&&g<=47447||47449<=g&&g<=47475||47477<=g&&g<=47503||47505<=g&&g<=47531||47533<=g&&g<=47559||47561<=g&&g<=47587||47589<=g&&g<=47615||47617<=g&&g<=47643||47645<=g&&g<=47671||47673<=g&&g<=47699||47701<=g&&g<=47727||47729<=g&&g<=47755||47757<=g&&g<=47783||47785<=g&&g<=47811||47813<=g&&g<=47839||47841<=g&&g<=47867||47869<=g&&g<=47895||47897<=g&&g<=47923||47925<=g&&g<=47951||47953<=g&&g<=47979||47981<=g&&g<=48007||48009<=g&&g<=48035||48037<=g&&g<=48063||48065<=g&&g<=48091||48093<=g&&g<=48119||48121<=g&&g<=48147||48149<=g&&g<=48175||48177<=g&&g<=48203||48205<=g&&g<=48231||48233<=g&&g<=48259||48261<=g&&g<=48287||48289<=g&&g<=48315||48317<=g&&g<=48343||48345<=g&&g<=48371||48373<=g&&g<=48399||48401<=g&&g<=48427||48429<=g&&g<=48455||48457<=g&&g<=48483||48485<=g&&g<=48511||48513<=g&&g<=48539||48541<=g&&g<=48567||48569<=g&&g<=48595||48597<=g&&g<=48623||48625<=g&&g<=48651||48653<=g&&g<=48679||48681<=g&&g<=48707||48709<=g&&g<=48735||48737<=g&&g<=48763||48765<=g&&g<=48791||48793<=g&&g<=48819||48821<=g&&g<=48847||48849<=g&&g<=48875||48877<=g&&g<=48903||48905<=g&&g<=48931||48933<=g&&g<=48959||48961<=g&&g<=48987||48989<=g&&g<=49015||49017<=g&&g<=49043||49045<=g&&g<=49071||49073<=g&&g<=49099||49101<=g&&g<=49127||49129<=g&&g<=49155||49157<=g&&g<=49183||49185<=g&&g<=49211||49213<=g&&g<=49239||49241<=g&&g<=49267||49269<=g&&g<=49295||49297<=g&&g<=49323||49325<=g&&g<=49351||49353<=g&&g<=49379||49381<=g&&g<=49407||49409<=g&&g<=49435||49437<=g&&g<=49463||49465<=g&&g<=49491||49493<=g&&g<=49519||49521<=g&&g<=49547||49549<=g&&g<=49575||49577<=g&&g<=49603||49605<=g&&g<=49631||49633<=g&&g<=49659||49661<=g&&g<=49687||49689<=g&&g<=49715||49717<=g&&g<=49743||49745<=g&&g<=49771||49773<=g&&g<=49799||49801<=g&&g<=49827||49829<=g&&g<=49855||49857<=g&&g<=49883||49885<=g&&g<=49911||49913<=g&&g<=49939||49941<=g&&g<=49967||49969<=g&&g<=49995||49997<=g&&g<=50023||50025<=g&&g<=50051||50053<=g&&g<=50079||50081<=g&&g<=50107||50109<=g&&g<=50135||50137<=g&&g<=50163||50165<=g&&g<=50191||50193<=g&&g<=50219||50221<=g&&g<=50247||50249<=g&&g<=50275||50277<=g&&g<=50303||50305<=g&&g<=50331||50333<=g&&g<=50359||50361<=g&&g<=50387||50389<=g&&g<=50415||50417<=g&&g<=50443||50445<=g&&g<=50471||50473<=g&&g<=50499||50501<=g&&g<=50527||50529<=g&&g<=50555||50557<=g&&g<=50583||50585<=g&&g<=50611||50613<=g&&g<=50639||50641<=g&&g<=50667||50669<=g&&g<=50695||50697<=g&&g<=50723||50725<=g&&g<=50751||50753<=g&&g<=50779||50781<=g&&g<=50807||50809<=g&&g<=50835||50837<=g&&g<=50863||50865<=g&&g<=50891||50893<=g&&g<=50919||50921<=g&&g<=50947||50949<=g&&g<=50975||50977<=g&&g<=51003||51005<=g&&g<=51031||51033<=g&&g<=51059||51061<=g&&g<=51087||51089<=g&&g<=51115||51117<=g&&g<=51143||51145<=g&&g<=51171||51173<=g&&g<=51199||51201<=g&&g<=51227||51229<=g&&g<=51255||51257<=g&&g<=51283||51285<=g&&g<=51311||51313<=g&&g<=51339||51341<=g&&g<=51367||51369<=g&&g<=51395||51397<=g&&g<=51423||51425<=g&&g<=51451||51453<=g&&g<=51479||51481<=g&&g<=51507||51509<=g&&g<=51535||51537<=g&&g<=51563||51565<=g&&g<=51591||51593<=g&&g<=51619||51621<=g&&g<=51647||51649<=g&&g<=51675||51677<=g&&g<=51703||51705<=g&&g<=51731||51733<=g&&g<=51759||51761<=g&&g<=51787||51789<=g&&g<=51815||51817<=g&&g<=51843||51845<=g&&g<=51871||51873<=g&&g<=51899||51901<=g&&g<=51927||51929<=g&&g<=51955||51957<=g&&g<=51983||51985<=g&&g<=52011||52013<=g&&g<=52039||52041<=g&&g<=52067||52069<=g&&g<=52095||52097<=g&&g<=52123||52125<=g&&g<=52151||52153<=g&&g<=52179||52181<=g&&g<=52207||52209<=g&&g<=52235||52237<=g&&g<=52263||52265<=g&&g<=52291||52293<=g&&g<=52319||52321<=g&&g<=52347||52349<=g&&g<=52375||52377<=g&&g<=52403||52405<=g&&g<=52431||52433<=g&&g<=52459||52461<=g&&g<=52487||52489<=g&&g<=52515||52517<=g&&g<=52543||52545<=g&&g<=52571||52573<=g&&g<=52599||52601<=g&&g<=52627||52629<=g&&g<=52655||52657<=g&&g<=52683||52685<=g&&g<=52711||52713<=g&&g<=52739||52741<=g&&g<=52767||52769<=g&&g<=52795||52797<=g&&g<=52823||52825<=g&&g<=52851||52853<=g&&g<=52879||52881<=g&&g<=52907||52909<=g&&g<=52935||52937<=g&&g<=52963||52965<=g&&g<=52991||52993<=g&&g<=53019||53021<=g&&g<=53047||53049<=g&&g<=53075||53077<=g&&g<=53103||53105<=g&&g<=53131||53133<=g&&g<=53159||53161<=g&&g<=53187||53189<=g&&g<=53215||53217<=g&&g<=53243||53245<=g&&g<=53271||53273<=g&&g<=53299||53301<=g&&g<=53327||53329<=g&&g<=53355||53357<=g&&g<=53383||53385<=g&&g<=53411||53413<=g&&g<=53439||53441<=g&&g<=53467||53469<=g&&g<=53495||53497<=g&&g<=53523||53525<=g&&g<=53551||53553<=g&&g<=53579||53581<=g&&g<=53607||53609<=g&&g<=53635||53637<=g&&g<=53663||53665<=g&&g<=53691||53693<=g&&g<=53719||53721<=g&&g<=53747||53749<=g&&g<=53775||53777<=g&&g<=53803||53805<=g&&g<=53831||53833<=g&&g<=53859||53861<=g&&g<=53887||53889<=g&&g<=53915||53917<=g&&g<=53943||53945<=g&&g<=53971||53973<=g&&g<=53999||54001<=g&&g<=54027||54029<=g&&g<=54055||54057<=g&&g<=54083||54085<=g&&g<=54111||54113<=g&&g<=54139||54141<=g&&g<=54167||54169<=g&&g<=54195||54197<=g&&g<=54223||54225<=g&&g<=54251||54253<=g&&g<=54279||54281<=g&&g<=54307||54309<=g&&g<=54335||54337<=g&&g<=54363||54365<=g&&g<=54391||54393<=g&&g<=54419||54421<=g&&g<=54447||54449<=g&&g<=54475||54477<=g&&g<=54503||54505<=g&&g<=54531||54533<=g&&g<=54559||54561<=g&&g<=54587||54589<=g&&g<=54615||54617<=g&&g<=54643||54645<=g&&g<=54671||54673<=g&&g<=54699||54701<=g&&g<=54727||54729<=g&&g<=54755||54757<=g&&g<=54783||54785<=g&&g<=54811||54813<=g&&g<=54839||54841<=g&&g<=54867||54869<=g&&g<=54895||54897<=g&&g<=54923||54925<=g&&g<=54951||54953<=g&&g<=54979||54981<=g&&g<=55007||55009<=g&&g<=55035||55037<=g&&g<=55063||55065<=g&&g<=55091||55093<=g&&g<=55119||55121<=g&&g<=55147||55149<=g&&g<=55175||55177<=g&&g<=55203?E:g==9757||g==9977||9994<=g&&g<=9997||g==127877||127938<=g&&g<=127940||g==127943||127946<=g&&g<=127948||128066<=g&&g<=128067||128070<=g&&g<=128080||g==128110||128112<=g&&g<=128120||g==128124||128129<=g&&g<=128131||128133<=g&&g<=128135||g==128170||128372<=g&&g<=128373||g==128378||g==128400||128405<=g&&g<=128406||128581<=g&&g<=128583||128587<=g&&g<=128591||g==128675||128692<=g&&g<=128694||g==128704||g==128716||129304<=g&&g<=129308||129310<=g&&g<=129311||g==129318||129328<=g&&g<=129337||129341<=g&&g<=129342||129489<=g&&g<=129501?b:127995<=g&&g<=127999?C:g==8205?T:g==9792||g==9794||9877<=g&&g<=9878||g==9992||g==10084||g==127752||g==127806||g==127859||g==127891||g==127908||g==127912||g==127979||g==127981||g==128139||128187<=g&&g<=128188||g==128295||g==128300||g==128488||g==128640||g==128658?L:128102<=g&&g<=128105?U:I}return this}typeof qx<"u"&&qx.exports&&(qx.exports=yat)});var Gce=_((d4t,qce)=>{var Eat=/^(.*?)(\x1b\[[^m]+m|\x1b\]8;;.*?(\x1b\\|\u0007))/,Gx;function Cat(){if(Gx)return Gx;if(typeof Intl.Segmenter<"u"){let t=new Intl.Segmenter("en",{granularity:"grapheme"});return Gx=e=>Array.from(t.segment(e),({segment:r})=>r)}else{let t=jce(),e=new t;return Gx=r=>e.splitGraphemes(r)}}qce.exports=(t,e=0,r=t.length)=>{if(e<0||r<0)throw new RangeError("Negative indices aren't supported by this implementation");let o=r-e,a="",n=0,u=0;for(;t.length>0;){let A=t.match(Eat)||[t,t,void 0],p=Cat()(A[1]),h=Math.min(e-n,p.length);p=p.slice(h);let E=Math.min(o-u,p.length);a+=p.slice(0,E).join(""),n+=h,u+=E,typeof A[2]<"u"&&(a+=A[2]),t=t.slice(A[0].length)}return a}});var tn,N1=Et(()=>{tn=process.env.YARN_IS_TEST_ENV?"0.0.0":"4.0.2"});function zce(t,{configuration:e,json:r}){if(!e.get("enableMessageNames"))return"";let a=Wu(t===null?0:t);return!r&&t===null?Ot(e,a,"grey"):a}function CU(t,{configuration:e,json:r}){let o=zce(t,{configuration:e,json:r});if(!o||t===null||t===0)return o;let a=wr[t],n=`https://yarnpkg.com/advanced/error-codes#${o}---${a}`.toLowerCase();return Xy(e,o,n)}async function NE({configuration:t,stdout:e,forceError:r},o){let a=await Nt.start({configuration:t,stdout:e,includeFooter:!1},async n=>{let u=!1,A=!1;for(let p of o)typeof p.option<"u"&&(p.error||r?(A=!0,n.reportError(50,p.message)):(u=!0,n.reportWarning(50,p.message)),p.callback?.());u&&!A&&n.reportSeparator()});return a.hasErrors()?a.exitCode():null}var Kce,Yx,wat,Yce,Wce,uh,Jce,Vce,Iat,Bat,Wx,vat,Nt,L1=Et(()=>{Kce=$e(Gce()),Yx=$e(ed());pP();Yl();N1();ql();wat="\xB7",Yce=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],Wce=80,uh=Yx.default.GITHUB_ACTIONS?{start:t=>`::group::${t} +`,end:t=>`::endgroup:: +`}:Yx.default.TRAVIS?{start:t=>`travis_fold:start:${t} +`,end:t=>`travis_fold:end:${t} +`}:Yx.default.GITLAB?{start:t=>`section_start:${Math.floor(Date.now()/1e3)}:${t.toLowerCase().replace(/\W+/g,"_")}[collapsed=true]\r\x1B[0K${t} +`,end:t=>`section_end:${Math.floor(Date.now()/1e3)}:${t.toLowerCase().replace(/\W+/g,"_")}\r\x1B[0K`}:null,Jce=uh!==null,Vce=new Date,Iat=["iTerm.app","Apple_Terminal","WarpTerminal","vscode"].includes(process.env.TERM_PROGRAM)||!!process.env.WT_SESSION,Bat=t=>t,Wx=Bat({patrick:{date:[17,3],chars:["\u{1F340}","\u{1F331}"],size:40},simba:{date:[19,7],chars:["\u{1F981}","\u{1F334}"],size:40},jack:{date:[31,10],chars:["\u{1F383}","\u{1F987}"],size:40},hogsfather:{date:[31,12],chars:["\u{1F389}","\u{1F384}"],size:40},default:{chars:["=","-"],size:80}}),vat=Iat&&Object.keys(Wx).find(t=>{let e=Wx[t];return!(e.date&&(e.date[0]!==Vce.getDate()||e.date[1]!==Vce.getMonth()+1))})||"default";Nt=class extends Xs{constructor({configuration:r,stdout:o,json:a=!1,forceSectionAlignment:n=!1,includeNames:u=!0,includePrefix:A=!0,includeFooter:p=!0,includeLogs:h=!a,includeInfos:E=h,includeWarnings:I=h}){super();this.uncommitted=new Set;this.warningCount=0;this.errorCount=0;this.timerFooter=[];this.startTime=Date.now();this.indent=0;this.level=0;this.progress=new Map;this.progressTime=0;this.progressFrame=0;this.progressTimeout=null;this.progressStyle=null;this.progressMaxScaledSize=null;if(zI(this,{configuration:r}),this.configuration=r,this.forceSectionAlignment=n,this.includeNames=u,this.includePrefix=A,this.includeFooter=p,this.includeInfos=E,this.includeWarnings=I,this.json=a,this.stdout=o,r.get("enableProgressBars")&&!a&&o.isTTY&&o.columns>22){let v=r.get("progressBarStyle")||vat;if(!Object.hasOwn(Wx,v))throw new Error("Assertion failed: Invalid progress bar style");this.progressStyle=Wx[v];let b=Math.min(this.getRecommendedLength(),80);this.progressMaxScaledSize=Math.floor(this.progressStyle.size*b/80)}}static async start(r,o){let a=new this(r),n=process.emitWarning;process.emitWarning=(u,A)=>{if(typeof u!="string"){let h=u;u=h.message,A=A??h.name}let p=typeof A<"u"?`${A}: ${u}`:u;a.reportWarning(0,p)},r.includeVersion&&a.reportInfo(0,md(r.configuration,`Yarn ${tn}`,2));try{await o(a)}catch(u){a.reportExceptionOnce(u)}finally{await a.finalize(),process.emitWarning=n}return a}hasErrors(){return this.errorCount>0}exitCode(){return this.hasErrors()?1:0}getRecommendedLength(){let o=this.progressStyle!==null?this.stdout.columns-1:super.getRecommendedLength();return Math.max(40,o-12-this.indent*2)}startSectionSync({reportHeader:r,reportFooter:o,skipIfEmpty:a},n){let u={committed:!1,action:()=>{r?.()}};a?this.uncommitted.add(u):(u.action(),u.committed=!0);let A=Date.now();try{return n()}catch(p){throw this.reportExceptionOnce(p),p}finally{let p=Date.now();this.uncommitted.delete(u),u.committed&&o?.(p-A)}}async startSectionPromise({reportHeader:r,reportFooter:o,skipIfEmpty:a},n){let u={committed:!1,action:()=>{r?.()}};a?this.uncommitted.add(u):(u.action(),u.committed=!0);let A=Date.now();try{return await n()}catch(p){throw this.reportExceptionOnce(p),p}finally{let p=Date.now();this.uncommitted.delete(u),u.committed&&o?.(p-A)}}startTimerImpl(r,o,a){return{cb:typeof o=="function"?o:a,reportHeader:()=>{this.level+=1,this.reportInfo(null,`\u250C ${r}`),this.indent+=1,uh!==null&&!this.json&&this.includeInfos&&this.stdout.write(uh.start(r))},reportFooter:A=>{if(this.indent-=1,uh!==null&&!this.json&&this.includeInfos){this.stdout.write(uh.end(r));for(let p of this.timerFooter)p()}this.configuration.get("enableTimers")&&A>200?this.reportInfo(null,`\u2514 Completed in ${Ot(this.configuration,A,yt.DURATION)}`):this.reportInfo(null,"\u2514 Completed"),this.level-=1},skipIfEmpty:(typeof o=="function"?{}:o).skipIfEmpty}}startTimerSync(r,o,a){let{cb:n,...u}=this.startTimerImpl(r,o,a);return this.startSectionSync(u,n)}async startTimerPromise(r,o,a){let{cb:n,...u}=this.startTimerImpl(r,o,a);return this.startSectionPromise(u,n)}reportSeparator(){this.indent===0?this.writeLine(""):this.reportInfo(null,"")}reportInfo(r,o){if(!this.includeInfos)return;this.commit();let a=this.formatNameWithHyperlink(r),n=a?`${a}: `:"",u=`${this.formatPrefix(n,"blueBright")}${o}`;this.json?this.reportJson({type:"info",name:r,displayName:this.formatName(r),indent:this.formatIndent(),data:o}):this.writeLine(u)}reportWarning(r,o){if(this.warningCount+=1,!this.includeWarnings)return;this.commit();let a=this.formatNameWithHyperlink(r),n=a?`${a}: `:"";this.json?this.reportJson({type:"warning",name:r,displayName:this.formatName(r),indent:this.formatIndent(),data:o}):this.writeLine(`${this.formatPrefix(n,"yellowBright")}${o}`)}reportError(r,o){this.errorCount+=1,this.timerFooter.push(()=>this.reportErrorImpl(r,o)),this.reportErrorImpl(r,o)}reportErrorImpl(r,o){this.commit();let a=this.formatNameWithHyperlink(r),n=a?`${a}: `:"";this.json?this.reportJson({type:"error",name:r,displayName:this.formatName(r),indent:this.formatIndent(),data:o}):this.writeLine(`${this.formatPrefix(n,"redBright")}${o}`,{truncate:!1})}reportFold(r,o){if(!uh)return;let a=`${uh.start(r)}${o}${uh.end(r)}`;this.timerFooter.push(()=>this.stdout.write(a))}reportProgress(r){if(this.progressStyle===null)return{...Promise.resolve(),stop:()=>{}};if(r.hasProgress&&r.hasTitle)throw new Error("Unimplemented: Progress bars can't have both progress and titles.");let o=!1,a=Promise.resolve().then(async()=>{let u={progress:r.hasProgress?0:void 0,title:r.hasTitle?"":void 0};this.progress.set(r,{definition:u,lastScaledSize:r.hasProgress?-1:void 0,lastTitle:void 0}),this.refreshProgress({delta:-1});for await(let{progress:A,title:p}of r)o||u.progress===A&&u.title===p||(u.progress=A,u.title=p,this.refreshProgress());n()}),n=()=>{o||(o=!0,this.progress.delete(r),this.refreshProgress({delta:1}))};return{...a,stop:n}}reportJson(r){this.json&&this.writeLine(`${JSON.stringify(r)}`)}async finalize(){if(!this.includeFooter)return;let r="";this.errorCount>0?r="Failed with errors":this.warningCount>0?r="Done with warnings":r="Done";let o=Ot(this.configuration,Date.now()-this.startTime,yt.DURATION),a=this.configuration.get("enableTimers")?`${r} in ${o}`:r;this.errorCount>0?this.reportError(0,a):this.warningCount>0?this.reportWarning(0,a):this.reportInfo(0,a)}writeLine(r,{truncate:o}={}){this.clearProgress({clear:!0}),this.stdout.write(`${this.truncate(r,{truncate:o})} +`),this.writeProgress()}writeLines(r,{truncate:o}={}){this.clearProgress({delta:r.length});for(let a of r)this.stdout.write(`${this.truncate(a,{truncate:o})} +`);this.writeProgress()}commit(){let r=this.uncommitted;this.uncommitted=new Set;for(let o of r)o.committed=!0,o.action()}clearProgress({delta:r=0,clear:o=!1}){this.progressStyle!==null&&this.progress.size+r>0&&(this.stdout.write(`\x1B[${this.progress.size+r}A`),(r>0||o)&&this.stdout.write("\x1B[0J"))}writeProgress(){if(this.progressStyle===null||(this.progressTimeout!==null&&clearTimeout(this.progressTimeout),this.progressTimeout=null,this.progress.size===0))return;let r=Date.now();r-this.progressTime>Wce&&(this.progressFrame=(this.progressFrame+1)%Yce.length,this.progressTime=r);let o=Yce[this.progressFrame];for(let a of this.progress.values()){let n="";if(typeof a.lastScaledSize<"u"){let h=this.progressStyle.chars[0].repeat(a.lastScaledSize),E=this.progressStyle.chars[1].repeat(this.progressMaxScaledSize-a.lastScaledSize);n=` ${h}${E}`}let u=this.formatName(null),A=u?`${u}: `:"",p=a.definition.title?` ${a.definition.title}`:"";this.stdout.write(`${Ot(this.configuration,"\u27A4","blueBright")} ${A}${o}${n}${p} +`)}this.progressTimeout=setTimeout(()=>{this.refreshProgress({force:!0})},Wce)}refreshProgress({delta:r=0,force:o=!1}={}){let a=!1,n=!1;if(o||this.progress.size===0)a=!0;else for(let u of this.progress.values()){let A=typeof u.definition.progress<"u"?Math.trunc(this.progressMaxScaledSize*u.definition.progress):void 0,p=u.lastScaledSize;u.lastScaledSize=A;let h=u.lastTitle;if(u.lastTitle=u.definition.title,A!==p||(n=h!==u.definition.title)){a=!0;break}}a&&(this.clearProgress({delta:r,clear:n}),this.writeProgress())}truncate(r,{truncate:o}={}){return this.progressStyle===null&&(o=!1),typeof o>"u"&&(o=this.configuration.get("preferTruncatedLines")),o&&(r=(0,Kce.default)(r,0,this.stdout.columns-1)),r}formatName(r){return this.includeNames?zce(r,{configuration:this.configuration,json:this.json}):""}formatPrefix(r,o){return this.includePrefix?`${Ot(this.configuration,"\u27A4",o)} ${r}${this.formatIndent()}`:""}formatNameWithHyperlink(r){return this.includeNames?CU(r,{configuration:this.configuration,json:this.json}):""}formatIndent(){return this.level>0||!this.forceSectionAlignment?"\u2502 ".repeat(this.indent):`${wat} `}}});var un={};Kt(un,{PackageManager:()=>$ce,detectPackageManager:()=>eue,executePackageAccessibleBinary:()=>sue,executePackageScript:()=>Vx,executePackageShellcode:()=>wU,executeWorkspaceAccessibleBinary:()=>Qat,executeWorkspaceLifecycleScript:()=>nue,executeWorkspaceScript:()=>rue,getPackageAccessibleBinaries:()=>Kx,getWorkspaceAccessibleBinaries:()=>iue,hasPackageScript:()=>xat,hasWorkspaceScript:()=>IU,isNodeScript:()=>BU,makeScriptEnv:()=>M1,maybeExecuteWorkspaceLifecycleScript:()=>kat,prepareExternalProject:()=>Sat});async function Ah(t,e,r,o=[]){if(process.platform==="win32"){let a=`@goto #_undefined_# 2>NUL || @title %COMSPEC% & @setlocal & @"${r}" ${o.map(n=>`"${n.replace('"','""')}"`).join(" ")} %*`;await oe.writeFilePromise(K.format({dir:t,name:e,ext:".cmd"}),a)}await oe.writeFilePromise(K.join(t,e),`#!/bin/sh +exec "${r}" ${o.map(a=>`'${a.replace(/'/g,`'"'"'`)}'`).join(" ")} "$@" +`,{mode:493})}async function eue(t){let e=await Mt.tryFind(t);if(e?.packageManager){let o=_S(e.packageManager);if(o?.name){let a=`found ${JSON.stringify({packageManager:e.packageManager})} in manifest`,[n]=o.reference.split(".");switch(o.name){case"yarn":return{packageManagerField:!0,packageManager:Number(n)===1?"Yarn Classic":"Yarn",reason:a};case"npm":return{packageManagerField:!0,packageManager:"npm",reason:a};case"pnpm":return{packageManagerField:!0,packageManager:"pnpm",reason:a}}}}let r;try{r=await oe.readFilePromise(K.join(t,dr.lockfile),"utf8")}catch{}return r!==void 0?r.match(/^__metadata:$/m)?{packageManager:"Yarn",reason:'"__metadata" key found in yarn.lock'}:{packageManager:"Yarn Classic",reason:'"__metadata" key not found in yarn.lock, must be a Yarn classic lockfile'}:oe.existsSync(K.join(t,"package-lock.json"))?{packageManager:"npm",reason:`found npm's "package-lock.json" lockfile`}:oe.existsSync(K.join(t,"pnpm-lock.yaml"))?{packageManager:"pnpm",reason:`found pnpm's "pnpm-lock.yaml" lockfile`}:null}async function M1({project:t,locator:e,binFolder:r,ignoreCorepack:o,lifecycleScript:a,baseEnv:n=t?.configuration.env??process.env}){let u={};for(let[E,I]of Object.entries(n))typeof I<"u"&&(u[E.toLowerCase()!=="path"?E:"PATH"]=I);let A=ue.fromPortablePath(r);u.BERRY_BIN_FOLDER=ue.fromPortablePath(A);let p=process.env.COREPACK_ROOT&&!o?ue.join(process.env.COREPACK_ROOT,"dist/yarn.js"):process.argv[1];if(await Promise.all([Ah(r,"node",process.execPath),...tn!==null?[Ah(r,"run",process.execPath,[p,"run"]),Ah(r,"yarn",process.execPath,[p]),Ah(r,"yarnpkg",process.execPath,[p]),Ah(r,"node-gyp",process.execPath,[p,"run","--top-level","node-gyp"])]:[]]),t&&(u.INIT_CWD=ue.fromPortablePath(t.configuration.startingCwd),u.PROJECT_CWD=ue.fromPortablePath(t.cwd)),u.PATH=u.PATH?`${A}${ue.delimiter}${u.PATH}`:`${A}`,u.npm_execpath=`${A}${ue.sep}yarn`,u.npm_node_execpath=`${A}${ue.sep}node`,e){if(!t)throw new Error("Assertion failed: Missing project");let E=t.tryWorkspaceByLocator(e),I=E?E.manifest.version??"":t.storedPackages.get(e.locatorHash).version??"";u.npm_package_name=fn(e),u.npm_package_version=I;let v;if(E)v=E.cwd;else{let b=t.storedPackages.get(e.locatorHash);if(!b)throw new Error(`Package for ${jr(t.configuration,e)} not found in the project`);let C=t.configuration.getLinkers(),T={project:t,report:new Nt({stdout:new fh.PassThrough,configuration:t.configuration})},L=C.find(U=>U.supportsPackage(b,T));if(!L)throw new Error(`The package ${jr(t.configuration,b)} isn't supported by any of the available linkers`);v=await L.findPackageLocation(b,T)}u.npm_package_json=ue.fromPortablePath(K.join(v,dr.manifest))}let h=tn!==null?`yarn/${tn}`:`yarn/${vf("@yarnpkg/core").version}-core`;return u.npm_config_user_agent=`${h} npm/? node/${process.version} ${process.platform} ${process.arch}`,a&&(u.npm_lifecycle_event=a),t&&await t.configuration.triggerHook(E=>E.setupScriptEnvironment,t,u,async(E,I,v)=>await Ah(r,E,I,v)),u}async function Sat(t,e,{configuration:r,report:o,workspace:a=null,locator:n=null}){await Pat(async()=>{await oe.mktempPromise(async u=>{let A=K.join(u,"pack.log"),p=null,{stdout:h,stderr:E}=r.getSubprocessStreams(A,{prefix:ue.fromPortablePath(t),report:o}),I=n&&Hc(n)?t1(n):n,v=I?xa(I):"an external project";h.write(`Packing ${v} from sources +`);let b=await eue(t),C;b!==null?(h.write(`Using ${b.packageManager} for bootstrap. Reason: ${b.reason} + +`),C=b.packageManager):(h.write(`No package manager configuration detected; defaulting to Yarn + +`),C="Yarn");let T=C==="Yarn"&&!b?.packageManagerField;await oe.mktempPromise(async L=>{let U=await M1({binFolder:L,ignoreCorepack:T}),te=new Map([["Yarn Classic",async()=>{let pe=a!==null?["workspace",a]:[],Ae=K.join(t,dr.manifest),ye=await oe.readFilePromise(Ae),ae=await Gc(process.execPath,[process.argv[1],"set","version","classic","--only-if-needed","--yarn-path"],{cwd:t,env:U,stdin:p,stdout:h,stderr:E,end:1});if(ae.code!==0)return ae.code;await oe.writeFilePromise(Ae,ye),await oe.appendFilePromise(K.join(t,".npmignore"),`/.yarn +`),h.write(` +`),delete U.NODE_ENV;let we=await Gc("yarn",["install"],{cwd:t,env:U,stdin:p,stdout:h,stderr:E,end:1});if(we.code!==0)return we.code;h.write(` +`);let Pe=await Gc("yarn",[...pe,"pack","--filename",ue.fromPortablePath(e)],{cwd:t,env:U,stdin:p,stdout:h,stderr:E});return Pe.code!==0?Pe.code:0}],["Yarn",async()=>{let pe=a!==null?["workspace",a]:[];U.YARN_ENABLE_INLINE_BUILDS="1";let Ae=K.join(t,dr.lockfile);await oe.existsPromise(Ae)||await oe.writeFilePromise(Ae,"");let ye=await Gc("yarn",[...pe,"pack","--install-if-needed","--filename",ue.fromPortablePath(e)],{cwd:t,env:U,stdin:p,stdout:h,stderr:E});return ye.code!==0?ye.code:0}],["npm",async()=>{if(a!==null){let Ee=new fh.PassThrough,De=Vy(Ee);Ee.pipe(h,{end:!1});let ce=await Gc("npm",["--version"],{cwd:t,env:U,stdin:p,stdout:Ee,stderr:E,end:0});if(Ee.end(),ce.code!==0)return h.end(),E.end(),ce.code;let ne=(await De).toString().trim();if(!bf(ne,">=7.x")){let ee=eA(null,"npm"),Ie=In(ee,ne),ke=In(ee,">=7.x");throw new Error(`Workspaces aren't supported by ${qn(r,Ie)}; please upgrade to ${qn(r,ke)} (npm has been detected as the primary package manager for ${Ot(r,t,yt.PATH)})`)}}let pe=a!==null?["--workspace",a]:[];delete U.npm_config_user_agent,delete U.npm_config_production,delete U.NPM_CONFIG_PRODUCTION,delete U.NODE_ENV;let Ae=await Gc("npm",["install","--legacy-peer-deps"],{cwd:t,env:U,stdin:p,stdout:h,stderr:E,end:1});if(Ae.code!==0)return Ae.code;let ye=new fh.PassThrough,ae=Vy(ye);ye.pipe(h);let we=await Gc("npm",["pack","--silent",...pe],{cwd:t,env:U,stdin:p,stdout:ye,stderr:E});if(we.code!==0)return we.code;let Pe=(await ae).toString().trim().replace(/^.*\n/s,""),g=K.resolve(t,ue.toPortablePath(Pe));return await oe.renamePromise(g,e),0}]]).get(C);if(typeof te>"u")throw new Error("Assertion failed: Unsupported workflow");let le=await te();if(!(le===0||typeof le>"u"))throw oe.detachTemp(u),new zt(58,`Packing the package failed (exit code ${le}, logs can be found here: ${Ot(r,A,yt.PATH)})`)})})})}async function xat(t,e,{project:r}){let o=r.tryWorkspaceByLocator(t);if(o!==null)return IU(o,e);let a=r.storedPackages.get(t.locatorHash);if(!a)throw new Error(`Package for ${jr(r.configuration,t)} not found in the project`);return await Jl.openPromise(async n=>{let u=r.configuration,A=r.configuration.getLinkers(),p={project:r,report:new Nt({stdout:new fh.PassThrough,configuration:u})},h=A.find(b=>b.supportsPackage(a,p));if(!h)throw new Error(`The package ${jr(r.configuration,a)} isn't supported by any of the available linkers`);let E=await h.findPackageLocation(a,p),I=new gn(E,{baseFs:n});return(await Mt.find(Bt.dot,{baseFs:I})).scripts.has(e)})}async function Vx(t,e,r,{cwd:o,project:a,stdin:n,stdout:u,stderr:A}){return await oe.mktempPromise(async p=>{let{manifest:h,env:E,cwd:I}=await tue(t,{project:a,binFolder:p,cwd:o,lifecycleScript:e}),v=h.scripts.get(e);if(typeof v>"u")return 1;let b=async()=>await TE(v,r,{cwd:I,env:E,stdin:n,stdout:u,stderr:A});return await(await a.configuration.reduceHook(T=>T.wrapScriptExecution,b,a,t,e,{script:v,args:r,cwd:I,env:E,stdin:n,stdout:u,stderr:A}))()})}async function wU(t,e,r,{cwd:o,project:a,stdin:n,stdout:u,stderr:A}){return await oe.mktempPromise(async p=>{let{env:h,cwd:E}=await tue(t,{project:a,binFolder:p,cwd:o});return await TE(e,r,{cwd:E,env:h,stdin:n,stdout:u,stderr:A})})}async function bat(t,{binFolder:e,cwd:r,lifecycleScript:o}){let a=await M1({project:t.project,locator:t.anchoredLocator,binFolder:e,lifecycleScript:o});return await vU(e,await iue(t)),typeof r>"u"&&(r=K.dirname(await oe.realpathPromise(K.join(t.cwd,"package.json")))),{manifest:t.manifest,binFolder:e,env:a,cwd:r}}async function tue(t,{project:e,binFolder:r,cwd:o,lifecycleScript:a}){let n=e.tryWorkspaceByLocator(t);if(n!==null)return bat(n,{binFolder:r,cwd:o,lifecycleScript:a});let u=e.storedPackages.get(t.locatorHash);if(!u)throw new Error(`Package for ${jr(e.configuration,t)} not found in the project`);return await Jl.openPromise(async A=>{let p=e.configuration,h=e.configuration.getLinkers(),E={project:e,report:new Nt({stdout:new fh.PassThrough,configuration:p})},I=h.find(L=>L.supportsPackage(u,E));if(!I)throw new Error(`The package ${jr(e.configuration,u)} isn't supported by any of the available linkers`);let v=await M1({project:e,locator:t,binFolder:r,lifecycleScript:a});await vU(r,await Kx(t,{project:e}));let b=await I.findPackageLocation(u,E),C=new gn(b,{baseFs:A}),T=await Mt.find(Bt.dot,{baseFs:C});return typeof o>"u"&&(o=b),{manifest:T,binFolder:r,env:v,cwd:o}})}async function rue(t,e,r,{cwd:o,stdin:a,stdout:n,stderr:u}){return await Vx(t.anchoredLocator,e,r,{cwd:o,project:t.project,stdin:a,stdout:n,stderr:u})}function IU(t,e){return t.manifest.scripts.has(e)}async function nue(t,e,{cwd:r,report:o}){let{configuration:a}=t.project,n=null;await oe.mktempPromise(async u=>{let A=K.join(u,`${e}.log`),p=`# This file contains the result of Yarn calling the "${e}" lifecycle script inside a workspace ("${ue.fromPortablePath(t.cwd)}") +`,{stdout:h,stderr:E}=a.getSubprocessStreams(A,{report:o,prefix:jr(a,t.anchoredLocator),header:p});o.reportInfo(36,`Calling the "${e}" lifecycle script`);let I=await rue(t,e,[],{cwd:r,stdin:n,stdout:h,stderr:E});if(h.end(),E.end(),I!==0)throw oe.detachTemp(u),new zt(36,`${(0,Xce.default)(e)} script failed (exit code ${Ot(a,I,yt.NUMBER)}, logs can be found here: ${Ot(a,A,yt.PATH)}); run ${Ot(a,`yarn ${e}`,yt.CODE)} to investigate`)})}async function kat(t,e,r){IU(t,e)&&await nue(t,e,r)}function BU(t){let e=K.extname(t);if(e.match(/\.[cm]?[jt]sx?$/))return!0;if(e===".exe"||e===".bin")return!1;let r=Buffer.alloc(4),o;try{o=oe.openSync(t,"r")}catch{return!0}try{oe.readSync(o,r,0,r.length,0)}finally{oe.closeSync(o)}let a=r.readUint32BE();return!(a===3405691582||a===3489328638||a===2135247942||(a&4294901760)===1297743872)}async function Kx(t,{project:e}){let r=e.configuration,o=new Map,a=e.storedPackages.get(t.locatorHash);if(!a)throw new Error(`Package for ${jr(r,t)} not found in the project`);let n=new fh.Writable,u=r.getLinkers(),A={project:e,report:new Nt({configuration:r,stdout:n})},p=new Set([t.locatorHash]);for(let E of a.dependencies.values()){let I=e.storedResolutions.get(E.descriptorHash);if(!I)throw new Error(`Assertion failed: The resolution (${qn(r,E)}) should have been registered`);p.add(I)}let h=await Promise.all(Array.from(p,async E=>{let I=e.storedPackages.get(E);if(!I)throw new Error(`Assertion failed: The package (${E}) should have been registered`);if(I.bin.size===0)return sl.skip;let v=u.find(C=>C.supportsPackage(I,A));if(!v)return sl.skip;let b=null;try{b=await v.findPackageLocation(I,A)}catch(C){if(C.code==="LOCATOR_NOT_INSTALLED")return sl.skip;throw C}return{dependency:I,packageLocation:b}}));for(let E of h){if(E===sl.skip)continue;let{dependency:I,packageLocation:v}=E;for(let[b,C]of I.bin){let T=K.resolve(v,C);o.set(b,[I,ue.fromPortablePath(T),BU(T)])}}return o}async function iue(t){return await Kx(t.anchoredLocator,{project:t.project})}async function vU(t,e){await Promise.all(Array.from(e,([r,[,o,a]])=>a?Ah(t,r,process.execPath,[o]):Ah(t,r,o,[])))}async function sue(t,e,r,{cwd:o,project:a,stdin:n,stdout:u,stderr:A,nodeArgs:p=[],packageAccessibleBinaries:h}){h??=await Kx(t,{project:a});let E=h.get(e);if(!E)throw new Error(`Binary not found (${e}) for ${jr(a.configuration,t)}`);return await oe.mktempPromise(async I=>{let[,v]=E,b=await M1({project:a,locator:t,binFolder:I});await vU(b.BERRY_BIN_FOLDER,h);let C=BU(ue.toPortablePath(v))?Gc(process.execPath,[...p,v,...r],{cwd:o,env:b,stdin:n,stdout:u,stderr:A}):Gc(v,r,{cwd:o,env:b,stdin:n,stdout:u,stderr:A}),T;try{T=await C}finally{await oe.removePromise(b.BERRY_BIN_FOLDER)}return T.code})}async function Qat(t,e,r,{cwd:o,stdin:a,stdout:n,stderr:u,packageAccessibleBinaries:A}){return await sue(t.anchoredLocator,e,r,{project:t.project,cwd:o,stdin:a,stdout:n,stderr:u,packageAccessibleBinaries:A})}var Xce,Zce,fh,$ce,Dat,Pat,DU=Et(()=>{Pt();Pt();nA();b1();Xce=$e(EU()),Zce=$e(nd()),fh=Be("stream");AE();Yl();L1();N1();Px();ql();jl();kf();xo();$ce=(a=>(a.Yarn1="Yarn Classic",a.Yarn2="Yarn",a.Npm="npm",a.Pnpm="pnpm",a))($ce||{});Dat=2,Pat=(0,Zce.default)(Dat)});var LE=_((M4t,aue)=>{"use strict";var oue=new Map([["C","cwd"],["f","file"],["z","gzip"],["P","preservePaths"],["U","unlink"],["strip-components","strip"],["stripComponents","strip"],["keep-newer","newer"],["keepNewer","newer"],["keep-newer-files","newer"],["keepNewerFiles","newer"],["k","keep"],["keep-existing","keep"],["keepExisting","keep"],["m","noMtime"],["no-mtime","noMtime"],["p","preserveOwner"],["L","follow"],["h","follow"]]);aue.exports=t=>t?Object.keys(t).map(e=>[oue.has(e)?oue.get(e):e,t[e]]).reduce((e,r)=>(e[r[0]]=r[1],e),Object.create(null)):{}});var OE=_((O4t,due)=>{"use strict";var lue=typeof process=="object"&&process?process:{stdout:null,stderr:null},Fat=Be("events"),cue=Be("stream"),uue=Be("string_decoder").StringDecoder,Mf=Symbol("EOF"),Of=Symbol("maybeEmitEnd"),ph=Symbol("emittedEnd"),Jx=Symbol("emittingEnd"),O1=Symbol("emittedError"),zx=Symbol("closed"),Aue=Symbol("read"),Xx=Symbol("flush"),fue=Symbol("flushChunk"),ka=Symbol("encoding"),Uf=Symbol("decoder"),Zx=Symbol("flowing"),U1=Symbol("paused"),ME=Symbol("resume"),Fs=Symbol("bufferLength"),PU=Symbol("bufferPush"),SU=Symbol("bufferShift"),Fo=Symbol("objectMode"),To=Symbol("destroyed"),xU=Symbol("emitData"),pue=Symbol("emitEnd"),bU=Symbol("emitEnd2"),_f=Symbol("async"),_1=t=>Promise.resolve().then(t),hue=global._MP_NO_ITERATOR_SYMBOLS_!=="1",Tat=hue&&Symbol.asyncIterator||Symbol("asyncIterator not implemented"),Rat=hue&&Symbol.iterator||Symbol("iterator not implemented"),Nat=t=>t==="end"||t==="finish"||t==="prefinish",Lat=t=>t instanceof ArrayBuffer||typeof t=="object"&&t.constructor&&t.constructor.name==="ArrayBuffer"&&t.byteLength>=0,Mat=t=>!Buffer.isBuffer(t)&&ArrayBuffer.isView(t),$x=class{constructor(e,r,o){this.src=e,this.dest=r,this.opts=o,this.ondrain=()=>e[ME](),r.on("drain",this.ondrain)}unpipe(){this.dest.removeListener("drain",this.ondrain)}proxyErrors(){}end(){this.unpipe(),this.opts.end&&this.dest.end()}},kU=class extends $x{unpipe(){this.src.removeListener("error",this.proxyErrors),super.unpipe()}constructor(e,r,o){super(e,r,o),this.proxyErrors=a=>r.emit("error",a),e.on("error",this.proxyErrors)}};due.exports=class gue extends cue{constructor(e){super(),this[Zx]=!1,this[U1]=!1,this.pipes=[],this.buffer=[],this[Fo]=e&&e.objectMode||!1,this[Fo]?this[ka]=null:this[ka]=e&&e.encoding||null,this[ka]==="buffer"&&(this[ka]=null),this[_f]=e&&!!e.async||!1,this[Uf]=this[ka]?new uue(this[ka]):null,this[Mf]=!1,this[ph]=!1,this[Jx]=!1,this[zx]=!1,this[O1]=null,this.writable=!0,this.readable=!0,this[Fs]=0,this[To]=!1}get bufferLength(){return this[Fs]}get encoding(){return this[ka]}set encoding(e){if(this[Fo])throw new Error("cannot set encoding in objectMode");if(this[ka]&&e!==this[ka]&&(this[Uf]&&this[Uf].lastNeed||this[Fs]))throw new Error("cannot change encoding");this[ka]!==e&&(this[Uf]=e?new uue(e):null,this.buffer.length&&(this.buffer=this.buffer.map(r=>this[Uf].write(r)))),this[ka]=e}setEncoding(e){this.encoding=e}get objectMode(){return this[Fo]}set objectMode(e){this[Fo]=this[Fo]||!!e}get async(){return this[_f]}set async(e){this[_f]=this[_f]||!!e}write(e,r,o){if(this[Mf])throw new Error("write after end");if(this[To])return this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0;typeof r=="function"&&(o=r,r="utf8"),r||(r="utf8");let a=this[_f]?_1:n=>n();return!this[Fo]&&!Buffer.isBuffer(e)&&(Mat(e)?e=Buffer.from(e.buffer,e.byteOffset,e.byteLength):Lat(e)?e=Buffer.from(e):typeof e!="string"&&(this.objectMode=!0)),this[Fo]?(this.flowing&&this[Fs]!==0&&this[Xx](!0),this.flowing?this.emit("data",e):this[PU](e),this[Fs]!==0&&this.emit("readable"),o&&a(o),this.flowing):e.length?(typeof e=="string"&&!(r===this[ka]&&!this[Uf].lastNeed)&&(e=Buffer.from(e,r)),Buffer.isBuffer(e)&&this[ka]&&(e=this[Uf].write(e)),this.flowing&&this[Fs]!==0&&this[Xx](!0),this.flowing?this.emit("data",e):this[PU](e),this[Fs]!==0&&this.emit("readable"),o&&a(o),this.flowing):(this[Fs]!==0&&this.emit("readable"),o&&a(o),this.flowing)}read(e){if(this[To])return null;if(this[Fs]===0||e===0||e>this[Fs])return this[Of](),null;this[Fo]&&(e=null),this.buffer.length>1&&!this[Fo]&&(this.encoding?this.buffer=[this.buffer.join("")]:this.buffer=[Buffer.concat(this.buffer,this[Fs])]);let r=this[Aue](e||null,this.buffer[0]);return this[Of](),r}[Aue](e,r){return e===r.length||e===null?this[SU]():(this.buffer[0]=r.slice(e),r=r.slice(0,e),this[Fs]-=e),this.emit("data",r),!this.buffer.length&&!this[Mf]&&this.emit("drain"),r}end(e,r,o){return typeof e=="function"&&(o=e,e=null),typeof r=="function"&&(o=r,r="utf8"),e&&this.write(e,r),o&&this.once("end",o),this[Mf]=!0,this.writable=!1,(this.flowing||!this[U1])&&this[Of](),this}[ME](){this[To]||(this[U1]=!1,this[Zx]=!0,this.emit("resume"),this.buffer.length?this[Xx]():this[Mf]?this[Of]():this.emit("drain"))}resume(){return this[ME]()}pause(){this[Zx]=!1,this[U1]=!0}get destroyed(){return this[To]}get flowing(){return this[Zx]}get paused(){return this[U1]}[PU](e){this[Fo]?this[Fs]+=1:this[Fs]+=e.length,this.buffer.push(e)}[SU](){return this.buffer.length&&(this[Fo]?this[Fs]-=1:this[Fs]-=this.buffer[0].length),this.buffer.shift()}[Xx](e){do;while(this[fue](this[SU]()));!e&&!this.buffer.length&&!this[Mf]&&this.emit("drain")}[fue](e){return e?(this.emit("data",e),this.flowing):!1}pipe(e,r){if(this[To])return;let o=this[ph];return r=r||{},e===lue.stdout||e===lue.stderr?r.end=!1:r.end=r.end!==!1,r.proxyErrors=!!r.proxyErrors,o?r.end&&e.end():(this.pipes.push(r.proxyErrors?new kU(this,e,r):new $x(this,e,r)),this[_f]?_1(()=>this[ME]()):this[ME]()),e}unpipe(e){let r=this.pipes.find(o=>o.dest===e);r&&(this.pipes.splice(this.pipes.indexOf(r),1),r.unpipe())}addListener(e,r){return this.on(e,r)}on(e,r){let o=super.on(e,r);return e==="data"&&!this.pipes.length&&!this.flowing?this[ME]():e==="readable"&&this[Fs]!==0?super.emit("readable"):Nat(e)&&this[ph]?(super.emit(e),this.removeAllListeners(e)):e==="error"&&this[O1]&&(this[_f]?_1(()=>r.call(this,this[O1])):r.call(this,this[O1])),o}get emittedEnd(){return this[ph]}[Of](){!this[Jx]&&!this[ph]&&!this[To]&&this.buffer.length===0&&this[Mf]&&(this[Jx]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[zx]&&this.emit("close"),this[Jx]=!1)}emit(e,r,...o){if(e!=="error"&&e!=="close"&&e!==To&&this[To])return;if(e==="data")return r?this[_f]?_1(()=>this[xU](r)):this[xU](r):!1;if(e==="end")return this[pue]();if(e==="close"){if(this[zx]=!0,!this[ph]&&!this[To])return;let n=super.emit("close");return this.removeAllListeners("close"),n}else if(e==="error"){this[O1]=r;let n=super.emit("error",r);return this[Of](),n}else if(e==="resume"){let n=super.emit("resume");return this[Of](),n}else if(e==="finish"||e==="prefinish"){let n=super.emit(e);return this.removeAllListeners(e),n}let a=super.emit(e,r,...o);return this[Of](),a}[xU](e){for(let o of this.pipes)o.dest.write(e)===!1&&this.pause();let r=super.emit("data",e);return this[Of](),r}[pue](){this[ph]||(this[ph]=!0,this.readable=!1,this[_f]?_1(()=>this[bU]()):this[bU]())}[bU](){if(this[Uf]){let r=this[Uf].end();if(r){for(let o of this.pipes)o.dest.write(r);super.emit("data",r)}}for(let r of this.pipes)r.end();let e=super.emit("end");return this.removeAllListeners("end"),e}collect(){let e=[];this[Fo]||(e.dataLength=0);let r=this.promise();return this.on("data",o=>{e.push(o),this[Fo]||(e.dataLength+=o.length)}),r.then(()=>e)}concat(){return this[Fo]?Promise.reject(new Error("cannot concat in objectMode")):this.collect().then(e=>this[Fo]?Promise.reject(new Error("cannot concat in objectMode")):this[ka]?e.join(""):Buffer.concat(e,e.dataLength))}promise(){return new Promise((e,r)=>{this.on(To,()=>r(new Error("stream destroyed"))),this.on("error",o=>r(o)),this.on("end",()=>e())})}[Tat](){return{next:()=>{let r=this.read();if(r!==null)return Promise.resolve({done:!1,value:r});if(this[Mf])return Promise.resolve({done:!0});let o=null,a=null,n=h=>{this.removeListener("data",u),this.removeListener("end",A),a(h)},u=h=>{this.removeListener("error",n),this.removeListener("end",A),this.pause(),o({value:h,done:!!this[Mf]})},A=()=>{this.removeListener("error",n),this.removeListener("data",u),o({done:!0})},p=()=>n(new Error("stream destroyed"));return new Promise((h,E)=>{a=E,o=h,this.once(To,p),this.once("error",n),this.once("end",A),this.once("data",u)})}}}[Rat](){return{next:()=>{let r=this.read();return{value:r,done:r===null}}}}destroy(e){return this[To]?(e?this.emit("error",e):this.emit(To),this):(this[To]=!0,this.buffer.length=0,this[Fs]=0,typeof this.close=="function"&&!this[zx]&&this.close(),e?this.emit("error",e):this.emit(To),this)}static isStream(e){return!!e&&(e instanceof gue||e instanceof cue||e instanceof Fat&&(typeof e.pipe=="function"||typeof e.write=="function"&&typeof e.end=="function"))}}});var yue=_((U4t,mue)=>{var Oat=Be("zlib").constants||{ZLIB_VERNUM:4736};mue.exports=Object.freeze(Object.assign(Object.create(null),{Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_VERSION_ERROR:-6,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,DEFLATE:1,INFLATE:2,GZIP:3,GUNZIP:4,DEFLATERAW:5,INFLATERAW:6,UNZIP:7,BROTLI_DECODE:8,BROTLI_ENCODE:9,Z_MIN_WINDOWBITS:8,Z_MAX_WINDOWBITS:15,Z_DEFAULT_WINDOWBITS:15,Z_MIN_CHUNK:64,Z_MAX_CHUNK:1/0,Z_DEFAULT_CHUNK:16384,Z_MIN_MEMLEVEL:1,Z_MAX_MEMLEVEL:9,Z_DEFAULT_MEMLEVEL:8,Z_MIN_LEVEL:-1,Z_MAX_LEVEL:9,Z_DEFAULT_LEVEL:-1,BROTLI_OPERATION_PROCESS:0,BROTLI_OPERATION_FLUSH:1,BROTLI_OPERATION_FINISH:2,BROTLI_OPERATION_EMIT_METADATA:3,BROTLI_MODE_GENERIC:0,BROTLI_MODE_TEXT:1,BROTLI_MODE_FONT:2,BROTLI_DEFAULT_MODE:0,BROTLI_MIN_QUALITY:0,BROTLI_MAX_QUALITY:11,BROTLI_DEFAULT_QUALITY:11,BROTLI_MIN_WINDOW_BITS:10,BROTLI_MAX_WINDOW_BITS:24,BROTLI_LARGE_MAX_WINDOW_BITS:30,BROTLI_DEFAULT_WINDOW:22,BROTLI_MIN_INPUT_BLOCK_BITS:16,BROTLI_MAX_INPUT_BLOCK_BITS:24,BROTLI_PARAM_MODE:0,BROTLI_PARAM_QUALITY:1,BROTLI_PARAM_LGWIN:2,BROTLI_PARAM_LGBLOCK:3,BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:4,BROTLI_PARAM_SIZE_HINT:5,BROTLI_PARAM_LARGE_WINDOW:6,BROTLI_PARAM_NPOSTFIX:7,BROTLI_PARAM_NDIRECT:8,BROTLI_DECODER_RESULT_ERROR:0,BROTLI_DECODER_RESULT_SUCCESS:1,BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:2,BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:0,BROTLI_DECODER_PARAM_LARGE_WINDOW:1,BROTLI_DECODER_NO_ERROR:0,BROTLI_DECODER_SUCCESS:1,BROTLI_DECODER_NEEDS_MORE_INPUT:2,BROTLI_DECODER_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:-1,BROTLI_DECODER_ERROR_FORMAT_RESERVED:-2,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:-3,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:-4,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:-5,BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:-6,BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:-7,BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:-8,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:-9,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:-10,BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:-11,BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:-12,BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:-13,BROTLI_DECODER_ERROR_FORMAT_PADDING_1:-14,BROTLI_DECODER_ERROR_FORMAT_PADDING_2:-15,BROTLI_DECODER_ERROR_FORMAT_DISTANCE:-16,BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:-19,BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:-20,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:-21,BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:-22,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:-25,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:-26,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:-27,BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:-30,BROTLI_DECODER_ERROR_UNREACHABLE:-31},Oat))});var WU=_(cl=>{"use strict";var NU=Be("assert"),hh=Be("buffer").Buffer,wue=Be("zlib"),Qd=cl.constants=yue(),Uat=OE(),Eue=hh.concat,Fd=Symbol("_superWrite"),_E=class extends Error{constructor(e){super("zlib: "+e.message),this.code=e.code,this.errno=e.errno,this.code||(this.code="ZLIB_ERROR"),this.message="zlib: "+e.message,Error.captureStackTrace(this,this.constructor)}get name(){return"ZlibError"}},_at=Symbol("opts"),H1=Symbol("flushFlag"),Cue=Symbol("finishFlushFlag"),YU=Symbol("fullFlushFlag"),ti=Symbol("handle"),eb=Symbol("onError"),UE=Symbol("sawError"),QU=Symbol("level"),FU=Symbol("strategy"),TU=Symbol("ended"),_4t=Symbol("_defaultFullFlush"),tb=class extends Uat{constructor(e,r){if(!e||typeof e!="object")throw new TypeError("invalid options for ZlibBase constructor");super(e),this[UE]=!1,this[TU]=!1,this[_at]=e,this[H1]=e.flush,this[Cue]=e.finishFlush;try{this[ti]=new wue[r](e)}catch(o){throw new _E(o)}this[eb]=o=>{this[UE]||(this[UE]=!0,this.close(),this.emit("error",o))},this[ti].on("error",o=>this[eb](new _E(o))),this.once("end",()=>this.close)}close(){this[ti]&&(this[ti].close(),this[ti]=null,this.emit("close"))}reset(){if(!this[UE])return NU(this[ti],"zlib binding closed"),this[ti].reset()}flush(e){this.ended||(typeof e!="number"&&(e=this[YU]),this.write(Object.assign(hh.alloc(0),{[H1]:e})))}end(e,r,o){return e&&this.write(e,r),this.flush(this[Cue]),this[TU]=!0,super.end(null,null,o)}get ended(){return this[TU]}write(e,r,o){if(typeof r=="function"&&(o=r,r="utf8"),typeof e=="string"&&(e=hh.from(e,r)),this[UE])return;NU(this[ti],"zlib binding closed");let a=this[ti]._handle,n=a.close;a.close=()=>{};let u=this[ti].close;this[ti].close=()=>{},hh.concat=h=>h;let A;try{let h=typeof e[H1]=="number"?e[H1]:this[H1];A=this[ti]._processChunk(e,h),hh.concat=Eue}catch(h){hh.concat=Eue,this[eb](new _E(h))}finally{this[ti]&&(this[ti]._handle=a,a.close=n,this[ti].close=u,this[ti].removeAllListeners("error"))}this[ti]&&this[ti].on("error",h=>this[eb](new _E(h)));let p;if(A)if(Array.isArray(A)&&A.length>0){p=this[Fd](hh.from(A[0]));for(let h=1;h<A.length;h++)p=this[Fd](A[h])}else p=this[Fd](hh.from(A));return o&&o(),p}[Fd](e){return super.write(e)}},Hf=class extends tb{constructor(e,r){e=e||{},e.flush=e.flush||Qd.Z_NO_FLUSH,e.finishFlush=e.finishFlush||Qd.Z_FINISH,super(e,r),this[YU]=Qd.Z_FULL_FLUSH,this[QU]=e.level,this[FU]=e.strategy}params(e,r){if(!this[UE]){if(!this[ti])throw new Error("cannot switch params when binding is closed");if(!this[ti].params)throw new Error("not supported in this implementation");if(this[QU]!==e||this[FU]!==r){this.flush(Qd.Z_SYNC_FLUSH),NU(this[ti],"zlib binding closed");let o=this[ti].flush;this[ti].flush=(a,n)=>{this.flush(a),n()};try{this[ti].params(e,r)}finally{this[ti].flush=o}this[ti]&&(this[QU]=e,this[FU]=r)}}}},LU=class extends Hf{constructor(e){super(e,"Deflate")}},MU=class extends Hf{constructor(e){super(e,"Inflate")}},RU=Symbol("_portable"),OU=class extends Hf{constructor(e){super(e,"Gzip"),this[RU]=e&&!!e.portable}[Fd](e){return this[RU]?(this[RU]=!1,e[9]=255,super[Fd](e)):super[Fd](e)}},UU=class extends Hf{constructor(e){super(e,"Gunzip")}},_U=class extends Hf{constructor(e){super(e,"DeflateRaw")}},HU=class extends Hf{constructor(e){super(e,"InflateRaw")}},jU=class extends Hf{constructor(e){super(e,"Unzip")}},rb=class extends tb{constructor(e,r){e=e||{},e.flush=e.flush||Qd.BROTLI_OPERATION_PROCESS,e.finishFlush=e.finishFlush||Qd.BROTLI_OPERATION_FINISH,super(e,r),this[YU]=Qd.BROTLI_OPERATION_FLUSH}},qU=class extends rb{constructor(e){super(e,"BrotliCompress")}},GU=class extends rb{constructor(e){super(e,"BrotliDecompress")}};cl.Deflate=LU;cl.Inflate=MU;cl.Gzip=OU;cl.Gunzip=UU;cl.DeflateRaw=_U;cl.InflateRaw=HU;cl.Unzip=jU;typeof wue.BrotliCompress=="function"?(cl.BrotliCompress=qU,cl.BrotliDecompress=GU):cl.BrotliCompress=cl.BrotliDecompress=class{constructor(){throw new Error("Brotli is not supported in this version of Node.js")}}});var HE=_((q4t,Iue)=>{var Hat=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform;Iue.exports=Hat!=="win32"?t=>t:t=>t&&t.replace(/\\/g,"/")});var nb=_((Y4t,Bue)=>{"use strict";var jat=OE(),VU=HE(),KU=Symbol("slurp");Bue.exports=class extends jat{constructor(e,r,o){switch(super(),this.pause(),this.extended=r,this.globalExtended=o,this.header=e,this.startBlockSize=512*Math.ceil(e.size/512),this.blockRemain=this.startBlockSize,this.remain=e.size,this.type=e.type,this.meta=!1,this.ignore=!1,this.type){case"File":case"OldFile":case"Link":case"SymbolicLink":case"CharacterDevice":case"BlockDevice":case"Directory":case"FIFO":case"ContiguousFile":case"GNUDumpDir":break;case"NextFileHasLongLinkpath":case"NextFileHasLongPath":case"OldGnuLongPath":case"GlobalExtendedHeader":case"ExtendedHeader":case"OldExtendedHeader":this.meta=!0;break;default:this.ignore=!0}this.path=VU(e.path),this.mode=e.mode,this.mode&&(this.mode=this.mode&4095),this.uid=e.uid,this.gid=e.gid,this.uname=e.uname,this.gname=e.gname,this.size=e.size,this.mtime=e.mtime,this.atime=e.atime,this.ctime=e.ctime,this.linkpath=VU(e.linkpath),this.uname=e.uname,this.gname=e.gname,r&&this[KU](r),o&&this[KU](o,!0)}write(e){let r=e.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");let o=this.remain,a=this.blockRemain;return this.remain=Math.max(0,o-r),this.blockRemain=Math.max(0,a-r),this.ignore?!0:o>=r?super.write(e):super.write(e.slice(0,o))}[KU](e,r){for(let o in e)e[o]!==null&&e[o]!==void 0&&!(r&&o==="path")&&(this[o]=o==="path"||o==="linkpath"?VU(e[o]):e[o])}}});var JU=_(ib=>{"use strict";ib.name=new Map([["0","File"],["","OldFile"],["1","Link"],["2","SymbolicLink"],["3","CharacterDevice"],["4","BlockDevice"],["5","Directory"],["6","FIFO"],["7","ContiguousFile"],["g","GlobalExtendedHeader"],["x","ExtendedHeader"],["A","SolarisACL"],["D","GNUDumpDir"],["I","Inode"],["K","NextFileHasLongLinkpath"],["L","NextFileHasLongPath"],["M","ContinuationFile"],["N","OldGnuLongPath"],["S","SparseFile"],["V","TapeVolumeHeader"],["X","OldExtendedHeader"]]);ib.code=new Map(Array.from(ib.name).map(t=>[t[1],t[0]]))});var Sue=_((V4t,Pue)=>{"use strict";var qat=(t,e)=>{if(Number.isSafeInteger(t))t<0?Yat(t,e):Gat(t,e);else throw Error("cannot encode number outside of javascript safe integer range");return e},Gat=(t,e)=>{e[0]=128;for(var r=e.length;r>1;r--)e[r-1]=t&255,t=Math.floor(t/256)},Yat=(t,e)=>{e[0]=255;var r=!1;t=t*-1;for(var o=e.length;o>1;o--){var a=t&255;t=Math.floor(t/256),r?e[o-1]=vue(a):a===0?e[o-1]=0:(r=!0,e[o-1]=Due(a))}},Wat=t=>{let e=t[0],r=e===128?Kat(t.slice(1,t.length)):e===255?Vat(t):null;if(r===null)throw Error("invalid base256 encoding");if(!Number.isSafeInteger(r))throw Error("parsed number outside of javascript safe integer range");return r},Vat=t=>{for(var e=t.length,r=0,o=!1,a=e-1;a>-1;a--){var n=t[a],u;o?u=vue(n):n===0?u=n:(o=!0,u=Due(n)),u!==0&&(r-=u*Math.pow(256,e-a-1))}return r},Kat=t=>{for(var e=t.length,r=0,o=e-1;o>-1;o--){var a=t[o];a!==0&&(r+=a*Math.pow(256,e-o-1))}return r},vue=t=>(255^t)&255,Due=t=>(255^t)+1&255;Pue.exports={encode:qat,parse:Wat}});var qE=_((K4t,bue)=>{"use strict";var zU=JU(),jE=Be("path").posix,xue=Sue(),XU=Symbol("slurp"),ul=Symbol("type"),e3=class{constructor(e,r,o,a){this.cksumValid=!1,this.needPax=!1,this.nullBlock=!1,this.block=null,this.path=null,this.mode=null,this.uid=null,this.gid=null,this.size=null,this.mtime=null,this.cksum=null,this[ul]="0",this.linkpath=null,this.uname=null,this.gname=null,this.devmaj=0,this.devmin=0,this.atime=null,this.ctime=null,Buffer.isBuffer(e)?this.decode(e,r||0,o,a):e&&this.set(e)}decode(e,r,o,a){if(r||(r=0),!e||!(e.length>=r+512))throw new Error("need 512 bytes for header");if(this.path=Td(e,r,100),this.mode=gh(e,r+100,8),this.uid=gh(e,r+108,8),this.gid=gh(e,r+116,8),this.size=gh(e,r+124,12),this.mtime=ZU(e,r+136,12),this.cksum=gh(e,r+148,12),this[XU](o),this[XU](a,!0),this[ul]=Td(e,r+156,1),this[ul]===""&&(this[ul]="0"),this[ul]==="0"&&this.path.substr(-1)==="/"&&(this[ul]="5"),this[ul]==="5"&&(this.size=0),this.linkpath=Td(e,r+157,100),e.slice(r+257,r+265).toString()==="ustar\x0000")if(this.uname=Td(e,r+265,32),this.gname=Td(e,r+297,32),this.devmaj=gh(e,r+329,8),this.devmin=gh(e,r+337,8),e[r+475]!==0){let u=Td(e,r+345,155);this.path=u+"/"+this.path}else{let u=Td(e,r+345,130);u&&(this.path=u+"/"+this.path),this.atime=ZU(e,r+476,12),this.ctime=ZU(e,r+488,12)}let n=8*32;for(let u=r;u<r+148;u++)n+=e[u];for(let u=r+156;u<r+512;u++)n+=e[u];this.cksumValid=n===this.cksum,this.cksum===null&&n===8*32&&(this.nullBlock=!0)}[XU](e,r){for(let o in e)e[o]!==null&&e[o]!==void 0&&!(r&&o==="path")&&(this[o]=e[o])}encode(e,r){if(e||(e=this.block=Buffer.alloc(512),r=0),r||(r=0),!(e.length>=r+512))throw new Error("need 512 bytes for header");let o=this.ctime||this.atime?130:155,a=Jat(this.path||"",o),n=a[0],u=a[1];this.needPax=a[2],this.needPax=Rd(e,r,100,n)||this.needPax,this.needPax=dh(e,r+100,8,this.mode)||this.needPax,this.needPax=dh(e,r+108,8,this.uid)||this.needPax,this.needPax=dh(e,r+116,8,this.gid)||this.needPax,this.needPax=dh(e,r+124,12,this.size)||this.needPax,this.needPax=$U(e,r+136,12,this.mtime)||this.needPax,e[r+156]=this[ul].charCodeAt(0),this.needPax=Rd(e,r+157,100,this.linkpath)||this.needPax,e.write("ustar\x0000",r+257,8),this.needPax=Rd(e,r+265,32,this.uname)||this.needPax,this.needPax=Rd(e,r+297,32,this.gname)||this.needPax,this.needPax=dh(e,r+329,8,this.devmaj)||this.needPax,this.needPax=dh(e,r+337,8,this.devmin)||this.needPax,this.needPax=Rd(e,r+345,o,u)||this.needPax,e[r+475]!==0?this.needPax=Rd(e,r+345,155,u)||this.needPax:(this.needPax=Rd(e,r+345,130,u)||this.needPax,this.needPax=$U(e,r+476,12,this.atime)||this.needPax,this.needPax=$U(e,r+488,12,this.ctime)||this.needPax);let A=8*32;for(let p=r;p<r+148;p++)A+=e[p];for(let p=r+156;p<r+512;p++)A+=e[p];return this.cksum=A,dh(e,r+148,8,this.cksum),this.cksumValid=!0,this.needPax}set(e){for(let r in e)e[r]!==null&&e[r]!==void 0&&(this[r]=e[r])}get type(){return zU.name.get(this[ul])||this[ul]}get typeKey(){return this[ul]}set type(e){zU.code.has(e)?this[ul]=zU.code.get(e):this[ul]=e}},Jat=(t,e)=>{let o=t,a="",n,u=jE.parse(t).root||".";if(Buffer.byteLength(o)<100)n=[o,a,!1];else{a=jE.dirname(o),o=jE.basename(o);do Buffer.byteLength(o)<=100&&Buffer.byteLength(a)<=e?n=[o,a,!1]:Buffer.byteLength(o)>100&&Buffer.byteLength(a)<=e?n=[o.substr(0,100-1),a,!0]:(o=jE.join(jE.basename(a),o),a=jE.dirname(a));while(a!==u&&!n);n||(n=[t.substr(0,100-1),"",!0])}return n},Td=(t,e,r)=>t.slice(e,e+r).toString("utf8").replace(/\0.*/,""),ZU=(t,e,r)=>zat(gh(t,e,r)),zat=t=>t===null?null:new Date(t*1e3),gh=(t,e,r)=>t[e]&128?xue.parse(t.slice(e,e+r)):Zat(t,e,r),Xat=t=>isNaN(t)?null:t,Zat=(t,e,r)=>Xat(parseInt(t.slice(e,e+r).toString("utf8").replace(/\0.*$/,"").trim(),8)),$at={12:8589934591,8:2097151},dh=(t,e,r,o)=>o===null?!1:o>$at[r]||o<0?(xue.encode(o,t.slice(e,e+r)),!0):(elt(t,e,r,o),!1),elt=(t,e,r,o)=>t.write(tlt(o,r),e,r,"ascii"),tlt=(t,e)=>rlt(Math.floor(t).toString(8),e),rlt=(t,e)=>(t.length===e-1?t:new Array(e-t.length-1).join("0")+t+" ")+"\0",$U=(t,e,r,o)=>o===null?!1:dh(t,e,r,o.getTime()/1e3),nlt=new Array(156).join("\0"),Rd=(t,e,r,o)=>o===null?!1:(t.write(o+nlt,e,r,"utf8"),o.length!==Buffer.byteLength(o)||o.length>r);bue.exports=e3});var sb=_((J4t,kue)=>{"use strict";var ilt=qE(),slt=Be("path"),j1=class{constructor(e,r){this.atime=e.atime||null,this.charset=e.charset||null,this.comment=e.comment||null,this.ctime=e.ctime||null,this.gid=e.gid||null,this.gname=e.gname||null,this.linkpath=e.linkpath||null,this.mtime=e.mtime||null,this.path=e.path||null,this.size=e.size||null,this.uid=e.uid||null,this.uname=e.uname||null,this.dev=e.dev||null,this.ino=e.ino||null,this.nlink=e.nlink||null,this.global=r||!1}encode(){let e=this.encodeBody();if(e==="")return null;let r=Buffer.byteLength(e),o=512*Math.ceil(1+r/512),a=Buffer.allocUnsafe(o);for(let n=0;n<512;n++)a[n]=0;new ilt({path:("PaxHeader/"+slt.basename(this.path)).slice(0,99),mode:this.mode||420,uid:this.uid||null,gid:this.gid||null,size:r,mtime:this.mtime||null,type:this.global?"GlobalExtendedHeader":"ExtendedHeader",linkpath:"",uname:this.uname||"",gname:this.gname||"",devmaj:0,devmin:0,atime:this.atime||null,ctime:this.ctime||null}).encode(a),a.write(e,512,r,"utf8");for(let n=r+512;n<a.length;n++)a[n]=0;return a}encodeBody(){return this.encodeField("path")+this.encodeField("ctime")+this.encodeField("atime")+this.encodeField("dev")+this.encodeField("ino")+this.encodeField("nlink")+this.encodeField("charset")+this.encodeField("comment")+this.encodeField("gid")+this.encodeField("gname")+this.encodeField("linkpath")+this.encodeField("mtime")+this.encodeField("size")+this.encodeField("uid")+this.encodeField("uname")}encodeField(e){if(this[e]===null||this[e]===void 0)return"";let r=this[e]instanceof Date?this[e].getTime()/1e3:this[e],o=" "+(e==="dev"||e==="ino"||e==="nlink"?"SCHILY.":"")+e+"="+r+` +`,a=Buffer.byteLength(o),n=Math.floor(Math.log(a)/Math.log(10))+1;return a+n>=Math.pow(10,n)&&(n+=1),n+a+o}};j1.parse=(t,e,r)=>new j1(olt(alt(t),e),r);var olt=(t,e)=>e?Object.keys(t).reduce((r,o)=>(r[o]=t[o],r),e):t,alt=t=>t.replace(/\n$/,"").split(` +`).reduce(llt,Object.create(null)),llt=(t,e)=>{let r=parseInt(e,10);if(r!==Buffer.byteLength(e)+1)return t;e=e.substr((r+" ").length);let o=e.split("="),a=o.shift().replace(/^SCHILY\.(dev|ino|nlink)/,"$1");if(!a)return t;let n=o.join("=");return t[a]=/^([A-Z]+\.)?([mac]|birth|creation)time$/.test(a)?new Date(n*1e3):/^[0-9]+$/.test(n)?+n:n,t};kue.exports=j1});var GE=_((z4t,Que)=>{Que.exports=t=>{let e=t.length-1,r=-1;for(;e>-1&&t.charAt(e)==="/";)r=e,e--;return r===-1?t:t.slice(0,r)}});var ob=_((X4t,Fue)=>{"use strict";Fue.exports=t=>class extends t{warn(e,r,o={}){this.file&&(o.file=this.file),this.cwd&&(o.cwd=this.cwd),o.code=r instanceof Error&&r.code||e,o.tarCode=e,!this.strict&&o.recoverable!==!1?(r instanceof Error&&(o=Object.assign(r,o),r=r.message),this.emit("warn",o.tarCode,r,o)):r instanceof Error?this.emit("error",Object.assign(r,o)):this.emit("error",Object.assign(new Error(`${e}: ${r}`),o))}}});var r3=_(($4t,Tue)=>{"use strict";var ab=["|","<",">","?",":"],t3=ab.map(t=>String.fromCharCode(61440+t.charCodeAt(0))),clt=new Map(ab.map((t,e)=>[t,t3[e]])),ult=new Map(t3.map((t,e)=>[t,ab[e]]));Tue.exports={encode:t=>ab.reduce((e,r)=>e.split(r).join(clt.get(r)),t),decode:t=>t3.reduce((e,r)=>e.split(r).join(ult.get(r)),t)}});var n3=_((eUt,Nue)=>{var{isAbsolute:Alt,parse:Rue}=Be("path").win32;Nue.exports=t=>{let e="",r=Rue(t);for(;Alt(t)||r.root;){let o=t.charAt(0)==="/"&&t.slice(0,4)!=="//?/"?"/":r.root;t=t.substr(o.length),e+=o,r=Rue(t)}return[e,t]}});var Mue=_((tUt,Lue)=>{"use strict";Lue.exports=(t,e,r)=>(t&=4095,r&&(t=(t|384)&-19),e&&(t&256&&(t|=64),t&32&&(t|=8),t&4&&(t|=1)),t)});var p3=_((iUt,Xue)=>{"use strict";var Gue=OE(),Yue=sb(),Wue=qE(),oA=Be("fs"),Oue=Be("path"),sA=HE(),flt=GE(),Vue=(t,e)=>e?(t=sA(t).replace(/^\.(\/|$)/,""),flt(e)+"/"+t):sA(t),plt=16*1024*1024,Uue=Symbol("process"),_ue=Symbol("file"),Hue=Symbol("directory"),s3=Symbol("symlink"),jue=Symbol("hardlink"),q1=Symbol("header"),lb=Symbol("read"),o3=Symbol("lstat"),ub=Symbol("onlstat"),a3=Symbol("onread"),l3=Symbol("onreadlink"),c3=Symbol("openfile"),u3=Symbol("onopenfile"),mh=Symbol("close"),Ab=Symbol("mode"),A3=Symbol("awaitDrain"),i3=Symbol("ondrain"),aA=Symbol("prefix"),que=Symbol("hadError"),Kue=ob(),hlt=r3(),Jue=n3(),zue=Mue(),fb=Kue(class extends Gue{constructor(e,r){if(r=r||{},super(r),typeof e!="string")throw new TypeError("path is required");this.path=sA(e),this.portable=!!r.portable,this.myuid=process.getuid&&process.getuid()||0,this.myuser=process.env.USER||"",this.maxReadSize=r.maxReadSize||plt,this.linkCache=r.linkCache||new Map,this.statCache=r.statCache||new Map,this.preservePaths=!!r.preservePaths,this.cwd=sA(r.cwd||process.cwd()),this.strict=!!r.strict,this.noPax=!!r.noPax,this.noMtime=!!r.noMtime,this.mtime=r.mtime||null,this.prefix=r.prefix?sA(r.prefix):null,this.fd=null,this.blockLen=null,this.blockRemain=null,this.buf=null,this.offset=null,this.length=null,this.pos=null,this.remain=null,typeof r.onwarn=="function"&&this.on("warn",r.onwarn);let o=!1;if(!this.preservePaths){let[a,n]=Jue(this.path);a&&(this.path=n,o=a)}this.win32=!!r.win32||process.platform==="win32",this.win32&&(this.path=hlt.decode(this.path.replace(/\\/g,"/")),e=e.replace(/\\/g,"/")),this.absolute=sA(r.absolute||Oue.resolve(this.cwd,e)),this.path===""&&(this.path="./"),o&&this.warn("TAR_ENTRY_INFO",`stripping ${o} from absolute path`,{entry:this,path:o+this.path}),this.statCache.has(this.absolute)?this[ub](this.statCache.get(this.absolute)):this[o3]()}emit(e,...r){return e==="error"&&(this[que]=!0),super.emit(e,...r)}[o3](){oA.lstat(this.absolute,(e,r)=>{if(e)return this.emit("error",e);this[ub](r)})}[ub](e){this.statCache.set(this.absolute,e),this.stat=e,e.isFile()||(e.size=0),this.type=dlt(e),this.emit("stat",e),this[Uue]()}[Uue](){switch(this.type){case"File":return this[_ue]();case"Directory":return this[Hue]();case"SymbolicLink":return this[s3]();default:return this.end()}}[Ab](e){return zue(e,this.type==="Directory",this.portable)}[aA](e){return Vue(e,this.prefix)}[q1](){this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.header=new Wue({path:this[aA](this.path),linkpath:this.type==="Link"?this[aA](this.linkpath):this.linkpath,mode:this[Ab](this.stat.mode),uid:this.portable?null:this.stat.uid,gid:this.portable?null:this.stat.gid,size:this.stat.size,mtime:this.noMtime?null:this.mtime||this.stat.mtime,type:this.type,uname:this.portable?null:this.stat.uid===this.myuid?this.myuser:"",atime:this.portable?null:this.stat.atime,ctime:this.portable?null:this.stat.ctime}),this.header.encode()&&!this.noPax&&super.write(new Yue({atime:this.portable?null:this.header.atime,ctime:this.portable?null:this.header.ctime,gid:this.portable?null:this.header.gid,mtime:this.noMtime?null:this.mtime||this.header.mtime,path:this[aA](this.path),linkpath:this.type==="Link"?this[aA](this.linkpath):this.linkpath,size:this.header.size,uid:this.portable?null:this.header.uid,uname:this.portable?null:this.header.uname,dev:this.portable?null:this.stat.dev,ino:this.portable?null:this.stat.ino,nlink:this.portable?null:this.stat.nlink}).encode()),super.write(this.header.block)}[Hue](){this.path.substr(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[q1](),this.end()}[s3](){oA.readlink(this.absolute,(e,r)=>{if(e)return this.emit("error",e);this[l3](r)})}[l3](e){this.linkpath=sA(e),this[q1](),this.end()}[jue](e){this.type="Link",this.linkpath=sA(Oue.relative(this.cwd,e)),this.stat.size=0,this[q1](),this.end()}[_ue](){if(this.stat.nlink>1){let e=this.stat.dev+":"+this.stat.ino;if(this.linkCache.has(e)){let r=this.linkCache.get(e);if(r.indexOf(this.cwd)===0)return this[jue](r)}this.linkCache.set(e,this.absolute)}if(this[q1](),this.stat.size===0)return this.end();this[c3]()}[c3](){oA.open(this.absolute,"r",(e,r)=>{if(e)return this.emit("error",e);this[u3](r)})}[u3](e){if(this.fd=e,this[que])return this[mh]();this.blockLen=512*Math.ceil(this.stat.size/512),this.blockRemain=this.blockLen;let r=Math.min(this.blockLen,this.maxReadSize);this.buf=Buffer.allocUnsafe(r),this.offset=0,this.pos=0,this.remain=this.stat.size,this.length=this.buf.length,this[lb]()}[lb](){let{fd:e,buf:r,offset:o,length:a,pos:n}=this;oA.read(e,r,o,a,n,(u,A)=>{if(u)return this[mh](()=>this.emit("error",u));this[a3](A)})}[mh](e){oA.close(this.fd,e)}[a3](e){if(e<=0&&this.remain>0){let a=new Error("encountered unexpected EOF");return a.path=this.absolute,a.syscall="read",a.code="EOF",this[mh](()=>this.emit("error",a))}if(e>this.remain){let a=new Error("did not encounter expected EOF");return a.path=this.absolute,a.syscall="read",a.code="EOF",this[mh](()=>this.emit("error",a))}if(e===this.remain)for(let a=e;a<this.length&&e<this.blockRemain;a++)this.buf[a+this.offset]=0,e++,this.remain++;let r=this.offset===0&&e===this.buf.length?this.buf:this.buf.slice(this.offset,this.offset+e);this.write(r)?this[i3]():this[A3](()=>this[i3]())}[A3](e){this.once("drain",e)}write(e){if(this.blockRemain<e.length){let r=new Error("writing more data than expected");return r.path=this.absolute,this.emit("error",r)}return this.remain-=e.length,this.blockRemain-=e.length,this.pos+=e.length,this.offset+=e.length,super.write(e)}[i3](){if(!this.remain)return this.blockRemain&&super.write(Buffer.alloc(this.blockRemain)),this[mh](e=>e?this.emit("error",e):this.end());this.offset>=this.length&&(this.buf=Buffer.allocUnsafe(Math.min(this.blockRemain,this.buf.length)),this.offset=0),this.length=this.buf.length-this.offset,this[lb]()}}),f3=class extends fb{[o3](){this[ub](oA.lstatSync(this.absolute))}[s3](){this[l3](oA.readlinkSync(this.absolute))}[c3](){this[u3](oA.openSync(this.absolute,"r"))}[lb](){let e=!0;try{let{fd:r,buf:o,offset:a,length:n,pos:u}=this,A=oA.readSync(r,o,a,n,u);this[a3](A),e=!1}finally{if(e)try{this[mh](()=>{})}catch{}}}[A3](e){e()}[mh](e){oA.closeSync(this.fd),e()}},glt=Kue(class extends Gue{constructor(e,r){r=r||{},super(r),this.preservePaths=!!r.preservePaths,this.portable=!!r.portable,this.strict=!!r.strict,this.noPax=!!r.noPax,this.noMtime=!!r.noMtime,this.readEntry=e,this.type=e.type,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.prefix=r.prefix||null,this.path=sA(e.path),this.mode=this[Ab](e.mode),this.uid=this.portable?null:e.uid,this.gid=this.portable?null:e.gid,this.uname=this.portable?null:e.uname,this.gname=this.portable?null:e.gname,this.size=e.size,this.mtime=this.noMtime?null:r.mtime||e.mtime,this.atime=this.portable?null:e.atime,this.ctime=this.portable?null:e.ctime,this.linkpath=sA(e.linkpath),typeof r.onwarn=="function"&&this.on("warn",r.onwarn);let o=!1;if(!this.preservePaths){let[a,n]=Jue(this.path);a&&(this.path=n,o=a)}this.remain=e.size,this.blockRemain=e.startBlockSize,this.header=new Wue({path:this[aA](this.path),linkpath:this.type==="Link"?this[aA](this.linkpath):this.linkpath,mode:this.mode,uid:this.portable?null:this.uid,gid:this.portable?null:this.gid,size:this.size,mtime:this.noMtime?null:this.mtime,type:this.type,uname:this.portable?null:this.uname,atime:this.portable?null:this.atime,ctime:this.portable?null:this.ctime}),o&&this.warn("TAR_ENTRY_INFO",`stripping ${o} from absolute path`,{entry:this,path:o+this.path}),this.header.encode()&&!this.noPax&&super.write(new Yue({atime:this.portable?null:this.atime,ctime:this.portable?null:this.ctime,gid:this.portable?null:this.gid,mtime:this.noMtime?null:this.mtime,path:this[aA](this.path),linkpath:this.type==="Link"?this[aA](this.linkpath):this.linkpath,size:this.size,uid:this.portable?null:this.uid,uname:this.portable?null:this.uname,dev:this.portable?null:this.readEntry.dev,ino:this.portable?null:this.readEntry.ino,nlink:this.portable?null:this.readEntry.nlink}).encode()),super.write(this.header.block),e.pipe(this)}[aA](e){return Vue(e,this.prefix)}[Ab](e){return zue(e,this.type==="Directory",this.portable)}write(e){let r=e.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=r,super.write(e)}end(){return this.blockRemain&&super.write(Buffer.alloc(this.blockRemain)),super.end()}});fb.Sync=f3;fb.Tar=glt;var dlt=t=>t.isFile()?"File":t.isDirectory()?"Directory":t.isSymbolicLink()?"SymbolicLink":"Unsupported";Xue.exports=fb});var wb=_((oUt,iAe)=>{"use strict";var Eb=class{constructor(e,r){this.path=e||"./",this.absolute=r,this.entry=null,this.stat=null,this.readdir=null,this.pending=!1,this.ignore=!1,this.piped=!1}},mlt=OE(),ylt=WU(),Elt=nb(),I3=p3(),Clt=I3.Sync,wlt=I3.Tar,Ilt=BP(),Zue=Buffer.alloc(1024),gb=Symbol("onStat"),pb=Symbol("ended"),lA=Symbol("queue"),YE=Symbol("current"),Nd=Symbol("process"),hb=Symbol("processing"),$ue=Symbol("processJob"),cA=Symbol("jobs"),h3=Symbol("jobDone"),db=Symbol("addFSEntry"),eAe=Symbol("addTarEntry"),y3=Symbol("stat"),E3=Symbol("readdir"),mb=Symbol("onreaddir"),yb=Symbol("pipe"),tAe=Symbol("entry"),g3=Symbol("entryOpt"),C3=Symbol("writeEntryClass"),nAe=Symbol("write"),d3=Symbol("ondrain"),Cb=Be("fs"),rAe=Be("path"),Blt=ob(),m3=HE(),B3=Blt(class extends mlt{constructor(e){super(e),e=e||Object.create(null),this.opt=e,this.file=e.file||"",this.cwd=e.cwd||process.cwd(),this.maxReadSize=e.maxReadSize,this.preservePaths=!!e.preservePaths,this.strict=!!e.strict,this.noPax=!!e.noPax,this.prefix=m3(e.prefix||""),this.linkCache=e.linkCache||new Map,this.statCache=e.statCache||new Map,this.readdirCache=e.readdirCache||new Map,this[C3]=I3,typeof e.onwarn=="function"&&this.on("warn",e.onwarn),this.portable=!!e.portable,this.zip=null,e.gzip?(typeof e.gzip!="object"&&(e.gzip={}),this.portable&&(e.gzip.portable=!0),this.zip=new ylt.Gzip(e.gzip),this.zip.on("data",r=>super.write(r)),this.zip.on("end",r=>super.end()),this.zip.on("drain",r=>this[d3]()),this.on("resume",r=>this.zip.resume())):this.on("drain",this[d3]),this.noDirRecurse=!!e.noDirRecurse,this.follow=!!e.follow,this.noMtime=!!e.noMtime,this.mtime=e.mtime||null,this.filter=typeof e.filter=="function"?e.filter:r=>!0,this[lA]=new Ilt,this[cA]=0,this.jobs=+e.jobs||4,this[hb]=!1,this[pb]=!1}[nAe](e){return super.write(e)}add(e){return this.write(e),this}end(e){return e&&this.write(e),this[pb]=!0,this[Nd](),this}write(e){if(this[pb])throw new Error("write after end");return e instanceof Elt?this[eAe](e):this[db](e),this.flowing}[eAe](e){let r=m3(rAe.resolve(this.cwd,e.path));if(!this.filter(e.path,e))e.resume();else{let o=new Eb(e.path,r,!1);o.entry=new wlt(e,this[g3](o)),o.entry.on("end",a=>this[h3](o)),this[cA]+=1,this[lA].push(o)}this[Nd]()}[db](e){let r=m3(rAe.resolve(this.cwd,e));this[lA].push(new Eb(e,r)),this[Nd]()}[y3](e){e.pending=!0,this[cA]+=1;let r=this.follow?"stat":"lstat";Cb[r](e.absolute,(o,a)=>{e.pending=!1,this[cA]-=1,o?this.emit("error",o):this[gb](e,a)})}[gb](e,r){this.statCache.set(e.absolute,r),e.stat=r,this.filter(e.path,r)||(e.ignore=!0),this[Nd]()}[E3](e){e.pending=!0,this[cA]+=1,Cb.readdir(e.absolute,(r,o)=>{if(e.pending=!1,this[cA]-=1,r)return this.emit("error",r);this[mb](e,o)})}[mb](e,r){this.readdirCache.set(e.absolute,r),e.readdir=r,this[Nd]()}[Nd](){if(!this[hb]){this[hb]=!0;for(let e=this[lA].head;e!==null&&this[cA]<this.jobs;e=e.next)if(this[$ue](e.value),e.value.ignore){let r=e.next;this[lA].removeNode(e),e.next=r}this[hb]=!1,this[pb]&&!this[lA].length&&this[cA]===0&&(this.zip?this.zip.end(Zue):(super.write(Zue),super.end()))}}get[YE](){return this[lA]&&this[lA].head&&this[lA].head.value}[h3](e){this[lA].shift(),this[cA]-=1,this[Nd]()}[$ue](e){if(!e.pending){if(e.entry){e===this[YE]&&!e.piped&&this[yb](e);return}if(e.stat||(this.statCache.has(e.absolute)?this[gb](e,this.statCache.get(e.absolute)):this[y3](e)),!!e.stat&&!e.ignore&&!(!this.noDirRecurse&&e.stat.isDirectory()&&!e.readdir&&(this.readdirCache.has(e.absolute)?this[mb](e,this.readdirCache.get(e.absolute)):this[E3](e),!e.readdir))){if(e.entry=this[tAe](e),!e.entry){e.ignore=!0;return}e===this[YE]&&!e.piped&&this[yb](e)}}}[g3](e){return{onwarn:(r,o,a)=>this.warn(r,o,a),noPax:this.noPax,cwd:this.cwd,absolute:e.absolute,preservePaths:this.preservePaths,maxReadSize:this.maxReadSize,strict:this.strict,portable:this.portable,linkCache:this.linkCache,statCache:this.statCache,noMtime:this.noMtime,mtime:this.mtime,prefix:this.prefix}}[tAe](e){this[cA]+=1;try{return new this[C3](e.path,this[g3](e)).on("end",()=>this[h3](e)).on("error",r=>this.emit("error",r))}catch(r){this.emit("error",r)}}[d3](){this[YE]&&this[YE].entry&&this[YE].entry.resume()}[yb](e){e.piped=!0,e.readdir&&e.readdir.forEach(a=>{let n=e.path,u=n==="./"?"":n.replace(/\/*$/,"/");this[db](u+a)});let r=e.entry,o=this.zip;o?r.on("data",a=>{o.write(a)||r.pause()}):r.on("data",a=>{super.write(a)||r.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}}),w3=class extends B3{constructor(e){super(e),this[C3]=Clt}pause(){}resume(){}[y3](e){let r=this.follow?"statSync":"lstatSync";this[gb](e,Cb[r](e.absolute))}[E3](e,r){this[mb](e,Cb.readdirSync(e.absolute))}[yb](e){let r=e.entry,o=this.zip;e.readdir&&e.readdir.forEach(a=>{let n=e.path,u=n==="./"?"":n.replace(/\/*$/,"/");this[db](u+a)}),o?r.on("data",a=>{o.write(a)}):r.on("data",a=>{super[nAe](a)})}};B3.Sync=w3;iAe.exports=B3});var $E=_(Y1=>{"use strict";var vlt=OE(),Dlt=Be("events").EventEmitter,Qa=Be("fs"),P3=Qa.writev;if(!P3){let t=process.binding("fs"),e=t.FSReqWrap||t.FSReqCallback;P3=(r,o,a,n)=>{let u=(p,h)=>n(p,h,o),A=new e;A.oncomplete=u,t.writeBuffers(r,o,a,A)}}var XE=Symbol("_autoClose"),Yc=Symbol("_close"),G1=Symbol("_ended"),Gn=Symbol("_fd"),sAe=Symbol("_finished"),Eh=Symbol("_flags"),v3=Symbol("_flush"),S3=Symbol("_handleChunk"),x3=Symbol("_makeBuf"),Pb=Symbol("_mode"),Ib=Symbol("_needDrain"),JE=Symbol("_onerror"),ZE=Symbol("_onopen"),D3=Symbol("_onread"),VE=Symbol("_onwrite"),Ch=Symbol("_open"),jf=Symbol("_path"),Ld=Symbol("_pos"),uA=Symbol("_queue"),KE=Symbol("_read"),oAe=Symbol("_readSize"),yh=Symbol("_reading"),Bb=Symbol("_remain"),aAe=Symbol("_size"),vb=Symbol("_write"),WE=Symbol("_writing"),Db=Symbol("_defaultFlag"),zE=Symbol("_errored"),Sb=class extends vlt{constructor(e,r){if(r=r||{},super(r),this.readable=!0,this.writable=!1,typeof e!="string")throw new TypeError("path must be a string");this[zE]=!1,this[Gn]=typeof r.fd=="number"?r.fd:null,this[jf]=e,this[oAe]=r.readSize||16*1024*1024,this[yh]=!1,this[aAe]=typeof r.size=="number"?r.size:1/0,this[Bb]=this[aAe],this[XE]=typeof r.autoClose=="boolean"?r.autoClose:!0,typeof this[Gn]=="number"?this[KE]():this[Ch]()}get fd(){return this[Gn]}get path(){return this[jf]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[Ch](){Qa.open(this[jf],"r",(e,r)=>this[ZE](e,r))}[ZE](e,r){e?this[JE](e):(this[Gn]=r,this.emit("open",r),this[KE]())}[x3](){return Buffer.allocUnsafe(Math.min(this[oAe],this[Bb]))}[KE](){if(!this[yh]){this[yh]=!0;let e=this[x3]();if(e.length===0)return process.nextTick(()=>this[D3](null,0,e));Qa.read(this[Gn],e,0,e.length,null,(r,o,a)=>this[D3](r,o,a))}}[D3](e,r,o){this[yh]=!1,e?this[JE](e):this[S3](r,o)&&this[KE]()}[Yc](){if(this[XE]&&typeof this[Gn]=="number"){let e=this[Gn];this[Gn]=null,Qa.close(e,r=>r?this.emit("error",r):this.emit("close"))}}[JE](e){this[yh]=!0,this[Yc](),this.emit("error",e)}[S3](e,r){let o=!1;return this[Bb]-=e,e>0&&(o=super.write(e<r.length?r.slice(0,e):r)),(e===0||this[Bb]<=0)&&(o=!1,this[Yc](),super.end()),o}emit(e,r){switch(e){case"prefinish":case"finish":break;case"drain":typeof this[Gn]=="number"&&this[KE]();break;case"error":return this[zE]?void 0:(this[zE]=!0,super.emit(e,r));default:return super.emit(e,r)}}},b3=class extends Sb{[Ch](){let e=!0;try{this[ZE](null,Qa.openSync(this[jf],"r")),e=!1}finally{e&&this[Yc]()}}[KE](){let e=!0;try{if(!this[yh]){this[yh]=!0;do{let r=this[x3](),o=r.length===0?0:Qa.readSync(this[Gn],r,0,r.length,null);if(!this[S3](o,r))break}while(!0);this[yh]=!1}e=!1}finally{e&&this[Yc]()}}[Yc](){if(this[XE]&&typeof this[Gn]=="number"){let e=this[Gn];this[Gn]=null,Qa.closeSync(e),this.emit("close")}}},xb=class extends Dlt{constructor(e,r){r=r||{},super(r),this.readable=!1,this.writable=!0,this[zE]=!1,this[WE]=!1,this[G1]=!1,this[Ib]=!1,this[uA]=[],this[jf]=e,this[Gn]=typeof r.fd=="number"?r.fd:null,this[Pb]=r.mode===void 0?438:r.mode,this[Ld]=typeof r.start=="number"?r.start:null,this[XE]=typeof r.autoClose=="boolean"?r.autoClose:!0;let o=this[Ld]!==null?"r+":"w";this[Db]=r.flags===void 0,this[Eh]=this[Db]?o:r.flags,this[Gn]===null&&this[Ch]()}emit(e,r){if(e==="error"){if(this[zE])return;this[zE]=!0}return super.emit(e,r)}get fd(){return this[Gn]}get path(){return this[jf]}[JE](e){this[Yc](),this[WE]=!0,this.emit("error",e)}[Ch](){Qa.open(this[jf],this[Eh],this[Pb],(e,r)=>this[ZE](e,r))}[ZE](e,r){this[Db]&&this[Eh]==="r+"&&e&&e.code==="ENOENT"?(this[Eh]="w",this[Ch]()):e?this[JE](e):(this[Gn]=r,this.emit("open",r),this[v3]())}end(e,r){return e&&this.write(e,r),this[G1]=!0,!this[WE]&&!this[uA].length&&typeof this[Gn]=="number"&&this[VE](null,0),this}write(e,r){return typeof e=="string"&&(e=Buffer.from(e,r)),this[G1]?(this.emit("error",new Error("write() after end()")),!1):this[Gn]===null||this[WE]||this[uA].length?(this[uA].push(e),this[Ib]=!0,!1):(this[WE]=!0,this[vb](e),!0)}[vb](e){Qa.write(this[Gn],e,0,e.length,this[Ld],(r,o)=>this[VE](r,o))}[VE](e,r){e?this[JE](e):(this[Ld]!==null&&(this[Ld]+=r),this[uA].length?this[v3]():(this[WE]=!1,this[G1]&&!this[sAe]?(this[sAe]=!0,this[Yc](),this.emit("finish")):this[Ib]&&(this[Ib]=!1,this.emit("drain"))))}[v3](){if(this[uA].length===0)this[G1]&&this[VE](null,0);else if(this[uA].length===1)this[vb](this[uA].pop());else{let e=this[uA];this[uA]=[],P3(this[Gn],e,this[Ld],(r,o)=>this[VE](r,o))}}[Yc](){if(this[XE]&&typeof this[Gn]=="number"){let e=this[Gn];this[Gn]=null,Qa.close(e,r=>r?this.emit("error",r):this.emit("close"))}}},k3=class extends xb{[Ch](){let e;if(this[Db]&&this[Eh]==="r+")try{e=Qa.openSync(this[jf],this[Eh],this[Pb])}catch(r){if(r.code==="ENOENT")return this[Eh]="w",this[Ch]();throw r}else e=Qa.openSync(this[jf],this[Eh],this[Pb]);this[ZE](null,e)}[Yc](){if(this[XE]&&typeof this[Gn]=="number"){let e=this[Gn];this[Gn]=null,Qa.closeSync(e),this.emit("close")}}[vb](e){let r=!0;try{this[VE](null,Qa.writeSync(this[Gn],e,0,e.length,this[Ld])),r=!1}finally{if(r)try{this[Yc]()}catch{}}}};Y1.ReadStream=Sb;Y1.ReadStreamSync=b3;Y1.WriteStream=xb;Y1.WriteStreamSync=k3});var Nb=_((cUt,hAe)=>{"use strict";var Plt=ob(),Slt=qE(),xlt=Be("events"),blt=BP(),klt=1024*1024,Qlt=nb(),lAe=sb(),Flt=WU(),Q3=Buffer.from([31,139]),Xl=Symbol("state"),Md=Symbol("writeEntry"),qf=Symbol("readEntry"),F3=Symbol("nextEntry"),cAe=Symbol("processEntry"),Zl=Symbol("extendedHeader"),W1=Symbol("globalExtendedHeader"),wh=Symbol("meta"),uAe=Symbol("emitMeta"),fi=Symbol("buffer"),Gf=Symbol("queue"),Od=Symbol("ended"),AAe=Symbol("emittedEnd"),Ud=Symbol("emit"),Fa=Symbol("unzip"),bb=Symbol("consumeChunk"),kb=Symbol("consumeChunkSub"),T3=Symbol("consumeBody"),fAe=Symbol("consumeMeta"),pAe=Symbol("consumeHeader"),Qb=Symbol("consuming"),R3=Symbol("bufferConcat"),N3=Symbol("maybeEnd"),V1=Symbol("writing"),Ih=Symbol("aborted"),Fb=Symbol("onDone"),_d=Symbol("sawValidEntry"),Tb=Symbol("sawNullBlock"),Rb=Symbol("sawEOF"),Tlt=t=>!0;hAe.exports=Plt(class extends xlt{constructor(e){e=e||{},super(e),this.file=e.file||"",this[_d]=null,this.on(Fb,r=>{(this[Xl]==="begin"||this[_d]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),e.ondone?this.on(Fb,e.ondone):this.on(Fb,r=>{this.emit("prefinish"),this.emit("finish"),this.emit("end"),this.emit("close")}),this.strict=!!e.strict,this.maxMetaEntrySize=e.maxMetaEntrySize||klt,this.filter=typeof e.filter=="function"?e.filter:Tlt,this.writable=!0,this.readable=!1,this[Gf]=new blt,this[fi]=null,this[qf]=null,this[Md]=null,this[Xl]="begin",this[wh]="",this[Zl]=null,this[W1]=null,this[Od]=!1,this[Fa]=null,this[Ih]=!1,this[Tb]=!1,this[Rb]=!1,typeof e.onwarn=="function"&&this.on("warn",e.onwarn),typeof e.onentry=="function"&&this.on("entry",e.onentry)}[pAe](e,r){this[_d]===null&&(this[_d]=!1);let o;try{o=new Slt(e,r,this[Zl],this[W1])}catch(a){return this.warn("TAR_ENTRY_INVALID",a)}if(o.nullBlock)this[Tb]?(this[Rb]=!0,this[Xl]==="begin"&&(this[Xl]="header"),this[Ud]("eof")):(this[Tb]=!0,this[Ud]("nullBlock"));else if(this[Tb]=!1,!o.cksumValid)this.warn("TAR_ENTRY_INVALID","checksum failure",{header:o});else if(!o.path)this.warn("TAR_ENTRY_INVALID","path is required",{header:o});else{let a=o.type;if(/^(Symbolic)?Link$/.test(a)&&!o.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath required",{header:o});else if(!/^(Symbolic)?Link$/.test(a)&&o.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath forbidden",{header:o});else{let n=this[Md]=new Qlt(o,this[Zl],this[W1]);if(!this[_d])if(n.remain){let u=()=>{n.invalid||(this[_d]=!0)};n.on("end",u)}else this[_d]=!0;n.meta?n.size>this.maxMetaEntrySize?(n.ignore=!0,this[Ud]("ignoredEntry",n),this[Xl]="ignore",n.resume()):n.size>0&&(this[wh]="",n.on("data",u=>this[wh]+=u),this[Xl]="meta"):(this[Zl]=null,n.ignore=n.ignore||!this.filter(n.path,n),n.ignore?(this[Ud]("ignoredEntry",n),this[Xl]=n.remain?"ignore":"header",n.resume()):(n.remain?this[Xl]="body":(this[Xl]="header",n.end()),this[qf]?this[Gf].push(n):(this[Gf].push(n),this[F3]())))}}}[cAe](e){let r=!0;return e?Array.isArray(e)?this.emit.apply(this,e):(this[qf]=e,this.emit("entry",e),e.emittedEnd||(e.on("end",o=>this[F3]()),r=!1)):(this[qf]=null,r=!1),r}[F3](){do;while(this[cAe](this[Gf].shift()));if(!this[Gf].length){let e=this[qf];!e||e.flowing||e.size===e.remain?this[V1]||this.emit("drain"):e.once("drain",o=>this.emit("drain"))}}[T3](e,r){let o=this[Md],a=o.blockRemain,n=a>=e.length&&r===0?e:e.slice(r,r+a);return o.write(n),o.blockRemain||(this[Xl]="header",this[Md]=null,o.end()),n.length}[fAe](e,r){let o=this[Md],a=this[T3](e,r);return this[Md]||this[uAe](o),a}[Ud](e,r,o){!this[Gf].length&&!this[qf]?this.emit(e,r,o):this[Gf].push([e,r,o])}[uAe](e){switch(this[Ud]("meta",this[wh]),e.type){case"ExtendedHeader":case"OldExtendedHeader":this[Zl]=lAe.parse(this[wh],this[Zl],!1);break;case"GlobalExtendedHeader":this[W1]=lAe.parse(this[wh],this[W1],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":this[Zl]=this[Zl]||Object.create(null),this[Zl].path=this[wh].replace(/\0.*/,"");break;case"NextFileHasLongLinkpath":this[Zl]=this[Zl]||Object.create(null),this[Zl].linkpath=this[wh].replace(/\0.*/,"");break;default:throw new Error("unknown meta: "+e.type)}}abort(e){this[Ih]=!0,this.emit("abort",e),this.warn("TAR_ABORT",e,{recoverable:!1})}write(e){if(this[Ih])return;if(this[Fa]===null&&e){if(this[fi]&&(e=Buffer.concat([this[fi],e]),this[fi]=null),e.length<Q3.length)return this[fi]=e,!0;for(let o=0;this[Fa]===null&&o<Q3.length;o++)e[o]!==Q3[o]&&(this[Fa]=!1);if(this[Fa]===null){let o=this[Od];this[Od]=!1,this[Fa]=new Flt.Unzip,this[Fa].on("data",n=>this[bb](n)),this[Fa].on("error",n=>this.abort(n)),this[Fa].on("end",n=>{this[Od]=!0,this[bb]()}),this[V1]=!0;let a=this[Fa][o?"end":"write"](e);return this[V1]=!1,a}}this[V1]=!0,this[Fa]?this[Fa].write(e):this[bb](e),this[V1]=!1;let r=this[Gf].length?!1:this[qf]?this[qf].flowing:!0;return!r&&!this[Gf].length&&this[qf].once("drain",o=>this.emit("drain")),r}[R3](e){e&&!this[Ih]&&(this[fi]=this[fi]?Buffer.concat([this[fi],e]):e)}[N3](){if(this[Od]&&!this[AAe]&&!this[Ih]&&!this[Qb]){this[AAe]=!0;let e=this[Md];if(e&&e.blockRemain){let r=this[fi]?this[fi].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${e.blockRemain} more bytes, only ${r} available)`,{entry:e}),this[fi]&&e.write(this[fi]),e.end()}this[Ud](Fb)}}[bb](e){if(this[Qb])this[R3](e);else if(!e&&!this[fi])this[N3]();else{if(this[Qb]=!0,this[fi]){this[R3](e);let r=this[fi];this[fi]=null,this[kb](r)}else this[kb](e);for(;this[fi]&&this[fi].length>=512&&!this[Ih]&&!this[Rb];){let r=this[fi];this[fi]=null,this[kb](r)}this[Qb]=!1}(!this[fi]||this[Od])&&this[N3]()}[kb](e){let r=0,o=e.length;for(;r+512<=o&&!this[Ih]&&!this[Rb];)switch(this[Xl]){case"begin":case"header":this[pAe](e,r),r+=512;break;case"ignore":case"body":r+=this[T3](e,r);break;case"meta":r+=this[fAe](e,r);break;default:throw new Error("invalid state: "+this[Xl])}r<o&&(this[fi]?this[fi]=Buffer.concat([e.slice(r),this[fi]]):this[fi]=e.slice(r))}end(e){this[Ih]||(this[Fa]?this[Fa].end(e):(this[Od]=!0,this.write(e)))}})});var Lb=_((uUt,yAe)=>{"use strict";var Rlt=LE(),dAe=Nb(),eC=Be("fs"),Nlt=$E(),gAe=Be("path"),L3=GE();yAe.exports=(t,e,r)=>{typeof t=="function"?(r=t,e=null,t={}):Array.isArray(t)&&(e=t,t={}),typeof e=="function"&&(r=e,e=null),e?e=Array.from(e):e=[];let o=Rlt(t);if(o.sync&&typeof r=="function")throw new TypeError("callback not supported for sync tar functions");if(!o.file&&typeof r=="function")throw new TypeError("callback only supported with file option");return e.length&&Mlt(o,e),o.noResume||Llt(o),o.file&&o.sync?Olt(o):o.file?Ult(o,r):mAe(o)};var Llt=t=>{let e=t.onentry;t.onentry=e?r=>{e(r),r.resume()}:r=>r.resume()},Mlt=(t,e)=>{let r=new Map(e.map(n=>[L3(n),!0])),o=t.filter,a=(n,u)=>{let A=u||gAe.parse(n).root||".",p=n===A?!1:r.has(n)?r.get(n):a(gAe.dirname(n),A);return r.set(n,p),p};t.filter=o?(n,u)=>o(n,u)&&a(L3(n)):n=>a(L3(n))},Olt=t=>{let e=mAe(t),r=t.file,o=!0,a;try{let n=eC.statSync(r),u=t.maxReadSize||16*1024*1024;if(n.size<u)e.end(eC.readFileSync(r));else{let A=0,p=Buffer.allocUnsafe(u);for(a=eC.openSync(r,"r");A<n.size;){let h=eC.readSync(a,p,0,u,A);A+=h,e.write(p.slice(0,h))}e.end()}o=!1}finally{if(o&&a)try{eC.closeSync(a)}catch{}}},Ult=(t,e)=>{let r=new dAe(t),o=t.maxReadSize||16*1024*1024,a=t.file,n=new Promise((u,A)=>{r.on("error",A),r.on("end",u),eC.stat(a,(p,h)=>{if(p)A(p);else{let E=new Nlt.ReadStream(a,{readSize:o,size:h.size});E.on("error",A),E.pipe(r)}})});return e?n.then(e,e):n},mAe=t=>new dAe(t)});var vAe=_((AUt,BAe)=>{"use strict";var _lt=LE(),Mb=wb(),EAe=$E(),CAe=Lb(),wAe=Be("path");BAe.exports=(t,e,r)=>{if(typeof e=="function"&&(r=e),Array.isArray(t)&&(e=t,t={}),!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");e=Array.from(e);let o=_lt(t);if(o.sync&&typeof r=="function")throw new TypeError("callback not supported for sync tar functions");if(!o.file&&typeof r=="function")throw new TypeError("callback only supported with file option");return o.file&&o.sync?Hlt(o,e):o.file?jlt(o,e,r):o.sync?qlt(o,e):Glt(o,e)};var Hlt=(t,e)=>{let r=new Mb.Sync(t),o=new EAe.WriteStreamSync(t.file,{mode:t.mode||438});r.pipe(o),IAe(r,e)},jlt=(t,e,r)=>{let o=new Mb(t),a=new EAe.WriteStream(t.file,{mode:t.mode||438});o.pipe(a);let n=new Promise((u,A)=>{a.on("error",A),a.on("close",u),o.on("error",A)});return M3(o,e),r?n.then(r,r):n},IAe=(t,e)=>{e.forEach(r=>{r.charAt(0)==="@"?CAe({file:wAe.resolve(t.cwd,r.substr(1)),sync:!0,noResume:!0,onentry:o=>t.add(o)}):t.add(r)}),t.end()},M3=(t,e)=>{for(;e.length;){let r=e.shift();if(r.charAt(0)==="@")return CAe({file:wAe.resolve(t.cwd,r.substr(1)),noResume:!0,onentry:o=>t.add(o)}).then(o=>M3(t,e));t.add(r)}t.end()},qlt=(t,e)=>{let r=new Mb.Sync(t);return IAe(r,e),r},Glt=(t,e)=>{let r=new Mb(t);return M3(r,e),r}});var O3=_((fUt,QAe)=>{"use strict";var Ylt=LE(),DAe=wb(),Al=Be("fs"),PAe=$E(),SAe=Lb(),xAe=Be("path"),bAe=qE();QAe.exports=(t,e,r)=>{let o=Ylt(t);if(!o.file)throw new TypeError("file is required");if(o.gzip)throw new TypeError("cannot append to compressed archives");if(!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");return e=Array.from(e),o.sync?Wlt(o,e):Klt(o,e,r)};var Wlt=(t,e)=>{let r=new DAe.Sync(t),o=!0,a,n;try{try{a=Al.openSync(t.file,"r+")}catch(p){if(p.code==="ENOENT")a=Al.openSync(t.file,"w+");else throw p}let u=Al.fstatSync(a),A=Buffer.alloc(512);e:for(n=0;n<u.size;n+=512){for(let E=0,I=0;E<512;E+=I){if(I=Al.readSync(a,A,E,A.length-E,n+E),n===0&&A[0]===31&&A[1]===139)throw new Error("cannot append to compressed archives");if(!I)break e}let p=new bAe(A);if(!p.cksumValid)break;let h=512*Math.ceil(p.size/512);if(n+h+512>u.size)break;n+=h,t.mtimeCache&&t.mtimeCache.set(p.path,p.mtime)}o=!1,Vlt(t,r,n,a,e)}finally{if(o)try{Al.closeSync(a)}catch{}}},Vlt=(t,e,r,o,a)=>{let n=new PAe.WriteStreamSync(t.file,{fd:o,start:r});e.pipe(n),Jlt(e,a)},Klt=(t,e,r)=>{e=Array.from(e);let o=new DAe(t),a=(u,A,p)=>{let h=(C,T)=>{C?Al.close(u,L=>p(C)):p(null,T)},E=0;if(A===0)return h(null,0);let I=0,v=Buffer.alloc(512),b=(C,T)=>{if(C)return h(C);if(I+=T,I<512&&T)return Al.read(u,v,I,v.length-I,E+I,b);if(E===0&&v[0]===31&&v[1]===139)return h(new Error("cannot append to compressed archives"));if(I<512)return h(null,E);let L=new bAe(v);if(!L.cksumValid)return h(null,E);let U=512*Math.ceil(L.size/512);if(E+U+512>A||(E+=U+512,E>=A))return h(null,E);t.mtimeCache&&t.mtimeCache.set(L.path,L.mtime),I=0,Al.read(u,v,0,512,E,b)};Al.read(u,v,0,512,E,b)},n=new Promise((u,A)=>{o.on("error",A);let p="r+",h=(E,I)=>{if(E&&E.code==="ENOENT"&&p==="r+")return p="w+",Al.open(t.file,p,h);if(E)return A(E);Al.fstat(I,(v,b)=>{if(v)return Al.close(I,()=>A(v));a(I,b.size,(C,T)=>{if(C)return A(C);let L=new PAe.WriteStream(t.file,{fd:I,start:T});o.pipe(L),L.on("error",A),L.on("close",u),kAe(o,e)})})};Al.open(t.file,p,h)});return r?n.then(r,r):n},Jlt=(t,e)=>{e.forEach(r=>{r.charAt(0)==="@"?SAe({file:xAe.resolve(t.cwd,r.substr(1)),sync:!0,noResume:!0,onentry:o=>t.add(o)}):t.add(r)}),t.end()},kAe=(t,e)=>{for(;e.length;){let r=e.shift();if(r.charAt(0)==="@")return SAe({file:xAe.resolve(t.cwd,r.substr(1)),noResume:!0,onentry:o=>t.add(o)}).then(o=>kAe(t,e));t.add(r)}t.end()}});var TAe=_((pUt,FAe)=>{"use strict";var zlt=LE(),Xlt=O3();FAe.exports=(t,e,r)=>{let o=zlt(t);if(!o.file)throw new TypeError("file is required");if(o.gzip)throw new TypeError("cannot append to compressed archives");if(!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");return e=Array.from(e),Zlt(o),Xlt(o,e,r)};var Zlt=t=>{let e=t.filter;t.mtimeCache||(t.mtimeCache=new Map),t.filter=e?(r,o)=>e(r,o)&&!(t.mtimeCache.get(r)>o.mtime):(r,o)=>!(t.mtimeCache.get(r)>o.mtime)}});var LAe=_((hUt,NAe)=>{var{promisify:RAe}=Be("util"),Bh=Be("fs"),$lt=t=>{if(!t)t={mode:511,fs:Bh};else if(typeof t=="object")t={mode:511,fs:Bh,...t};else if(typeof t=="number")t={mode:t,fs:Bh};else if(typeof t=="string")t={mode:parseInt(t,8),fs:Bh};else throw new TypeError("invalid options argument");return t.mkdir=t.mkdir||t.fs.mkdir||Bh.mkdir,t.mkdirAsync=RAe(t.mkdir),t.stat=t.stat||t.fs.stat||Bh.stat,t.statAsync=RAe(t.stat),t.statSync=t.statSync||t.fs.statSync||Bh.statSync,t.mkdirSync=t.mkdirSync||t.fs.mkdirSync||Bh.mkdirSync,t};NAe.exports=$lt});var OAe=_((gUt,MAe)=>{var ect=process.platform,{resolve:tct,parse:rct}=Be("path"),nct=t=>{if(/\0/.test(t))throw Object.assign(new TypeError("path must be a string without null bytes"),{path:t,code:"ERR_INVALID_ARG_VALUE"});if(t=tct(t),ect==="win32"){let e=/[*|"<>?:]/,{root:r}=rct(t);if(e.test(t.substr(r.length)))throw Object.assign(new Error("Illegal characters in path."),{path:t,code:"EINVAL"})}return t};MAe.exports=nct});var qAe=_((dUt,jAe)=>{var{dirname:UAe}=Be("path"),_Ae=(t,e,r=void 0)=>r===e?Promise.resolve():t.statAsync(e).then(o=>o.isDirectory()?r:void 0,o=>o.code==="ENOENT"?_Ae(t,UAe(e),e):void 0),HAe=(t,e,r=void 0)=>{if(r!==e)try{return t.statSync(e).isDirectory()?r:void 0}catch(o){return o.code==="ENOENT"?HAe(t,UAe(e),e):void 0}};jAe.exports={findMade:_Ae,findMadeSync:HAe}});var H3=_((mUt,YAe)=>{var{dirname:GAe}=Be("path"),U3=(t,e,r)=>{e.recursive=!1;let o=GAe(t);return o===t?e.mkdirAsync(t,e).catch(a=>{if(a.code!=="EISDIR")throw a}):e.mkdirAsync(t,e).then(()=>r||t,a=>{if(a.code==="ENOENT")return U3(o,e).then(n=>U3(t,e,n));if(a.code!=="EEXIST"&&a.code!=="EROFS")throw a;return e.statAsync(t).then(n=>{if(n.isDirectory())return r;throw a},()=>{throw a})})},_3=(t,e,r)=>{let o=GAe(t);if(e.recursive=!1,o===t)try{return e.mkdirSync(t,e)}catch(a){if(a.code!=="EISDIR")throw a;return}try{return e.mkdirSync(t,e),r||t}catch(a){if(a.code==="ENOENT")return _3(t,e,_3(o,e,r));if(a.code!=="EEXIST"&&a.code!=="EROFS")throw a;try{if(!e.statSync(t).isDirectory())throw a}catch{throw a}}};YAe.exports={mkdirpManual:U3,mkdirpManualSync:_3}});var KAe=_((yUt,VAe)=>{var{dirname:WAe}=Be("path"),{findMade:ict,findMadeSync:sct}=qAe(),{mkdirpManual:oct,mkdirpManualSync:act}=H3(),lct=(t,e)=>(e.recursive=!0,WAe(t)===t?e.mkdirAsync(t,e):ict(e,t).then(o=>e.mkdirAsync(t,e).then(()=>o).catch(a=>{if(a.code==="ENOENT")return oct(t,e);throw a}))),cct=(t,e)=>{if(e.recursive=!0,WAe(t)===t)return e.mkdirSync(t,e);let o=sct(e,t);try{return e.mkdirSync(t,e),o}catch(a){if(a.code==="ENOENT")return act(t,e);throw a}};VAe.exports={mkdirpNative:lct,mkdirpNativeSync:cct}});var ZAe=_((EUt,XAe)=>{var JAe=Be("fs"),uct=process.version,j3=uct.replace(/^v/,"").split("."),zAe=+j3[0]>10||+j3[0]==10&&+j3[1]>=12,Act=zAe?t=>t.mkdir===JAe.mkdir:()=>!1,fct=zAe?t=>t.mkdirSync===JAe.mkdirSync:()=>!1;XAe.exports={useNative:Act,useNativeSync:fct}});var ife=_((CUt,nfe)=>{var tC=LAe(),rC=OAe(),{mkdirpNative:$Ae,mkdirpNativeSync:efe}=KAe(),{mkdirpManual:tfe,mkdirpManualSync:rfe}=H3(),{useNative:pct,useNativeSync:hct}=ZAe(),nC=(t,e)=>(t=rC(t),e=tC(e),pct(e)?$Ae(t,e):tfe(t,e)),gct=(t,e)=>(t=rC(t),e=tC(e),hct(e)?efe(t,e):rfe(t,e));nC.sync=gct;nC.native=(t,e)=>$Ae(rC(t),tC(e));nC.manual=(t,e)=>tfe(rC(t),tC(e));nC.nativeSync=(t,e)=>efe(rC(t),tC(e));nC.manualSync=(t,e)=>rfe(rC(t),tC(e));nfe.exports=nC});var Afe=_((wUt,ufe)=>{"use strict";var $l=Be("fs"),Hd=Be("path"),dct=$l.lchown?"lchown":"chown",mct=$l.lchownSync?"lchownSync":"chownSync",ofe=$l.lchown&&!process.version.match(/v1[1-9]+\./)&&!process.version.match(/v10\.[6-9]/),sfe=(t,e,r)=>{try{return $l[mct](t,e,r)}catch(o){if(o.code!=="ENOENT")throw o}},yct=(t,e,r)=>{try{return $l.chownSync(t,e,r)}catch(o){if(o.code!=="ENOENT")throw o}},Ect=ofe?(t,e,r,o)=>a=>{!a||a.code!=="EISDIR"?o(a):$l.chown(t,e,r,o)}:(t,e,r,o)=>o,q3=ofe?(t,e,r)=>{try{return sfe(t,e,r)}catch(o){if(o.code!=="EISDIR")throw o;yct(t,e,r)}}:(t,e,r)=>sfe(t,e,r),Cct=process.version,afe=(t,e,r)=>$l.readdir(t,e,r),wct=(t,e)=>$l.readdirSync(t,e);/^v4\./.test(Cct)&&(afe=(t,e,r)=>$l.readdir(t,r));var Ob=(t,e,r,o)=>{$l[dct](t,e,r,Ect(t,e,r,a=>{o(a&&a.code!=="ENOENT"?a:null)}))},lfe=(t,e,r,o,a)=>{if(typeof e=="string")return $l.lstat(Hd.resolve(t,e),(n,u)=>{if(n)return a(n.code!=="ENOENT"?n:null);u.name=e,lfe(t,u,r,o,a)});if(e.isDirectory())G3(Hd.resolve(t,e.name),r,o,n=>{if(n)return a(n);let u=Hd.resolve(t,e.name);Ob(u,r,o,a)});else{let n=Hd.resolve(t,e.name);Ob(n,r,o,a)}},G3=(t,e,r,o)=>{afe(t,{withFileTypes:!0},(a,n)=>{if(a){if(a.code==="ENOENT")return o();if(a.code!=="ENOTDIR"&&a.code!=="ENOTSUP")return o(a)}if(a||!n.length)return Ob(t,e,r,o);let u=n.length,A=null,p=h=>{if(!A){if(h)return o(A=h);if(--u===0)return Ob(t,e,r,o)}};n.forEach(h=>lfe(t,h,e,r,p))})},Ict=(t,e,r,o)=>{if(typeof e=="string")try{let a=$l.lstatSync(Hd.resolve(t,e));a.name=e,e=a}catch(a){if(a.code==="ENOENT")return;throw a}e.isDirectory()&&cfe(Hd.resolve(t,e.name),r,o),q3(Hd.resolve(t,e.name),r,o)},cfe=(t,e,r)=>{let o;try{o=wct(t,{withFileTypes:!0})}catch(a){if(a.code==="ENOENT")return;if(a.code==="ENOTDIR"||a.code==="ENOTSUP")return q3(t,e,r);throw a}return o&&o.length&&o.forEach(a=>Ict(t,a,e,r)),q3(t,e,r)};ufe.exports=G3;G3.sync=cfe});var gfe=_((IUt,Y3)=>{"use strict";var ffe=ife(),ec=Be("fs"),Ub=Be("path"),pfe=Afe(),Wc=HE(),_b=class extends Error{constructor(e,r){super("Cannot extract through symbolic link"),this.path=r,this.symlink=e}get name(){return"SylinkError"}},Hb=class extends Error{constructor(e,r){super(r+": Cannot cd into '"+e+"'"),this.path=e,this.code=r}get name(){return"CwdError"}},jb=(t,e)=>t.get(Wc(e)),K1=(t,e,r)=>t.set(Wc(e),r),Bct=(t,e)=>{ec.stat(t,(r,o)=>{(r||!o.isDirectory())&&(r=new Hb(t,r&&r.code||"ENOTDIR")),e(r)})};Y3.exports=(t,e,r)=>{t=Wc(t);let o=e.umask,a=e.mode|448,n=(a&o)!==0,u=e.uid,A=e.gid,p=typeof u=="number"&&typeof A=="number"&&(u!==e.processUid||A!==e.processGid),h=e.preserve,E=e.unlink,I=e.cache,v=Wc(e.cwd),b=(L,U)=>{L?r(L):(K1(I,t,!0),U&&p?pfe(U,u,A,J=>b(J)):n?ec.chmod(t,a,r):r())};if(I&&jb(I,t)===!0)return b();if(t===v)return Bct(t,b);if(h)return ffe(t,{mode:a}).then(L=>b(null,L),b);let T=Wc(Ub.relative(v,t)).split("/");qb(v,T,a,I,E,v,null,b)};var qb=(t,e,r,o,a,n,u,A)=>{if(!e.length)return A(null,u);let p=e.shift(),h=Wc(Ub.resolve(t+"/"+p));if(jb(o,h))return qb(h,e,r,o,a,n,u,A);ec.mkdir(h,r,hfe(h,e,r,o,a,n,u,A))},hfe=(t,e,r,o,a,n,u,A)=>p=>{p?ec.lstat(t,(h,E)=>{if(h)h.path=h.path&&Wc(h.path),A(h);else if(E.isDirectory())qb(t,e,r,o,a,n,u,A);else if(a)ec.unlink(t,I=>{if(I)return A(I);ec.mkdir(t,r,hfe(t,e,r,o,a,n,u,A))});else{if(E.isSymbolicLink())return A(new _b(t,t+"/"+e.join("/")));A(p)}}):(u=u||t,qb(t,e,r,o,a,n,u,A))},vct=t=>{let e=!1,r="ENOTDIR";try{e=ec.statSync(t).isDirectory()}catch(o){r=o.code}finally{if(!e)throw new Hb(t,r)}};Y3.exports.sync=(t,e)=>{t=Wc(t);let r=e.umask,o=e.mode|448,a=(o&r)!==0,n=e.uid,u=e.gid,A=typeof n=="number"&&typeof u=="number"&&(n!==e.processUid||u!==e.processGid),p=e.preserve,h=e.unlink,E=e.cache,I=Wc(e.cwd),v=L=>{K1(E,t,!0),L&&A&&pfe.sync(L,n,u),a&&ec.chmodSync(t,o)};if(E&&jb(E,t)===!0)return v();if(t===I)return vct(I),v();if(p)return v(ffe.sync(t,o));let C=Wc(Ub.relative(I,t)).split("/"),T=null;for(let L=C.shift(),U=I;L&&(U+="/"+L);L=C.shift())if(U=Wc(Ub.resolve(U)),!jb(E,U))try{ec.mkdirSync(U,o),T=T||U,K1(E,U,!0)}catch{let te=ec.lstatSync(U);if(te.isDirectory()){K1(E,U,!0);continue}else if(h){ec.unlinkSync(U),ec.mkdirSync(U,o),T=T||U,K1(E,U,!0);continue}else if(te.isSymbolicLink())return new _b(U,U+"/"+C.join("/"))}return v(T)}});var V3=_((BUt,dfe)=>{var W3=Object.create(null),{hasOwnProperty:Dct}=Object.prototype;dfe.exports=t=>(Dct.call(W3,t)||(W3[t]=t.normalize("NFKD")),W3[t])});var Cfe=_((vUt,Efe)=>{var mfe=Be("assert"),Pct=V3(),Sct=GE(),{join:yfe}=Be("path"),xct=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,bct=xct==="win32";Efe.exports=()=>{let t=new Map,e=new Map,r=h=>h.split("/").slice(0,-1).reduce((I,v)=>(I.length&&(v=yfe(I[I.length-1],v)),I.push(v||"/"),I),[]),o=new Set,a=h=>{let E=e.get(h);if(!E)throw new Error("function does not have any path reservations");return{paths:E.paths.map(I=>t.get(I)),dirs:[...E.dirs].map(I=>t.get(I))}},n=h=>{let{paths:E,dirs:I}=a(h);return E.every(v=>v[0]===h)&&I.every(v=>v[0]instanceof Set&&v[0].has(h))},u=h=>o.has(h)||!n(h)?!1:(o.add(h),h(()=>A(h)),!0),A=h=>{if(!o.has(h))return!1;let{paths:E,dirs:I}=e.get(h),v=new Set;return E.forEach(b=>{let C=t.get(b);mfe.equal(C[0],h),C.length===1?t.delete(b):(C.shift(),typeof C[0]=="function"?v.add(C[0]):C[0].forEach(T=>v.add(T)))}),I.forEach(b=>{let C=t.get(b);mfe(C[0]instanceof Set),C[0].size===1&&C.length===1?t.delete(b):C[0].size===1?(C.shift(),v.add(C[0])):C[0].delete(h)}),o.delete(h),v.forEach(b=>u(b)),!0};return{check:n,reserve:(h,E)=>{h=bct?["win32 parallelization disabled"]:h.map(v=>Pct(Sct(yfe(v))).toLowerCase());let I=new Set(h.map(v=>r(v)).reduce((v,b)=>v.concat(b)));return e.set(E,{dirs:I,paths:h}),h.forEach(v=>{let b=t.get(v);b?b.push(E):t.set(v,[E])}),I.forEach(v=>{let b=t.get(v);b?b[b.length-1]instanceof Set?b[b.length-1].add(E):b.push(new Set([E])):t.set(v,[new Set([E])])}),u(E)}}}});var Bfe=_((DUt,Ife)=>{var kct=process.platform,Qct=kct==="win32",Fct=global.__FAKE_TESTING_FS__||Be("fs"),{O_CREAT:Tct,O_TRUNC:Rct,O_WRONLY:Nct,UV_FS_O_FILEMAP:wfe=0}=Fct.constants,Lct=Qct&&!!wfe,Mct=512*1024,Oct=wfe|Rct|Tct|Nct;Ife.exports=Lct?t=>t<Mct?Oct:"w":()=>"w"});var r_=_((PUt,Mfe)=>{"use strict";var Uct=Be("assert"),_ct=Nb(),vn=Be("fs"),Hct=$E(),Yf=Be("path"),Rfe=gfe(),vfe=r3(),jct=Cfe(),qct=n3(),fl=HE(),Gct=GE(),Yct=V3(),Dfe=Symbol("onEntry"),z3=Symbol("checkFs"),Pfe=Symbol("checkFs2"),Wb=Symbol("pruneCache"),X3=Symbol("isReusable"),tc=Symbol("makeFs"),Z3=Symbol("file"),$3=Symbol("directory"),Vb=Symbol("link"),Sfe=Symbol("symlink"),xfe=Symbol("hardlink"),bfe=Symbol("unsupported"),kfe=Symbol("checkPath"),vh=Symbol("mkdir"),Ro=Symbol("onError"),Gb=Symbol("pending"),Qfe=Symbol("pend"),iC=Symbol("unpend"),K3=Symbol("ended"),J3=Symbol("maybeClose"),e_=Symbol("skip"),J1=Symbol("doChown"),z1=Symbol("uid"),X1=Symbol("gid"),Z1=Symbol("checkedCwd"),Nfe=Be("crypto"),Lfe=Bfe(),Wct=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,$1=Wct==="win32",Vct=(t,e)=>{if(!$1)return vn.unlink(t,e);let r=t+".DELETE."+Nfe.randomBytes(16).toString("hex");vn.rename(t,r,o=>{if(o)return e(o);vn.unlink(r,e)})},Kct=t=>{if(!$1)return vn.unlinkSync(t);let e=t+".DELETE."+Nfe.randomBytes(16).toString("hex");vn.renameSync(t,e),vn.unlinkSync(e)},Ffe=(t,e,r)=>t===t>>>0?t:e===e>>>0?e:r,Tfe=t=>Yct(Gct(fl(t))).toLowerCase(),Jct=(t,e)=>{e=Tfe(e);for(let r of t.keys()){let o=Tfe(r);(o===e||o.indexOf(e+"/")===0)&&t.delete(r)}},zct=t=>{for(let e of t.keys())t.delete(e)},e2=class extends _ct{constructor(e){if(e||(e={}),e.ondone=r=>{this[K3]=!0,this[J3]()},super(e),this[Z1]=!1,this.reservations=jct(),this.transform=typeof e.transform=="function"?e.transform:null,this.writable=!0,this.readable=!1,this[Gb]=0,this[K3]=!1,this.dirCache=e.dirCache||new Map,typeof e.uid=="number"||typeof e.gid=="number"){if(typeof e.uid!="number"||typeof e.gid!="number")throw new TypeError("cannot set owner without number uid and gid");if(e.preserveOwner)throw new TypeError("cannot preserve owner in archive and also set owner explicitly");this.uid=e.uid,this.gid=e.gid,this.setOwner=!0}else this.uid=null,this.gid=null,this.setOwner=!1;e.preserveOwner===void 0&&typeof e.uid!="number"?this.preserveOwner=process.getuid&&process.getuid()===0:this.preserveOwner=!!e.preserveOwner,this.processUid=(this.preserveOwner||this.setOwner)&&process.getuid?process.getuid():null,this.processGid=(this.preserveOwner||this.setOwner)&&process.getgid?process.getgid():null,this.forceChown=e.forceChown===!0,this.win32=!!e.win32||$1,this.newer=!!e.newer,this.keep=!!e.keep,this.noMtime=!!e.noMtime,this.preservePaths=!!e.preservePaths,this.unlink=!!e.unlink,this.cwd=fl(Yf.resolve(e.cwd||process.cwd())),this.strip=+e.strip||0,this.processUmask=e.noChmod?0:process.umask(),this.umask=typeof e.umask=="number"?e.umask:this.processUmask,this.dmode=e.dmode||511&~this.umask,this.fmode=e.fmode||438&~this.umask,this.on("entry",r=>this[Dfe](r))}warn(e,r,o={}){return(e==="TAR_BAD_ARCHIVE"||e==="TAR_ABORT")&&(o.recoverable=!1),super.warn(e,r,o)}[J3](){this[K3]&&this[Gb]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"),this.emit("close"))}[kfe](e){if(this.strip){let r=fl(e.path).split("/");if(r.length<this.strip)return!1;if(e.path=r.slice(this.strip).join("/"),e.type==="Link"){let o=fl(e.linkpath).split("/");if(o.length>=this.strip)e.linkpath=o.slice(this.strip).join("/");else return!1}}if(!this.preservePaths){let r=fl(e.path),o=r.split("/");if(o.includes("..")||$1&&/^[a-z]:\.\.$/i.test(o[0]))return this.warn("TAR_ENTRY_ERROR","path contains '..'",{entry:e,path:r}),!1;let[a,n]=qct(r);a&&(e.path=n,this.warn("TAR_ENTRY_INFO",`stripping ${a} from absolute path`,{entry:e,path:r}))}if(Yf.isAbsolute(e.path)?e.absolute=fl(Yf.resolve(e.path)):e.absolute=fl(Yf.resolve(this.cwd,e.path)),!this.preservePaths&&e.absolute.indexOf(this.cwd+"/")!==0&&e.absolute!==this.cwd)return this.warn("TAR_ENTRY_ERROR","path escaped extraction target",{entry:e,path:fl(e.path),resolvedPath:e.absolute,cwd:this.cwd}),!1;if(e.absolute===this.cwd&&e.type!=="Directory"&&e.type!=="GNUDumpDir")return!1;if(this.win32){let{root:r}=Yf.win32.parse(e.absolute);e.absolute=r+vfe.encode(e.absolute.substr(r.length));let{root:o}=Yf.win32.parse(e.path);e.path=o+vfe.encode(e.path.substr(o.length))}return!0}[Dfe](e){if(!this[kfe](e))return e.resume();switch(Uct.equal(typeof e.absolute,"string"),e.type){case"Directory":case"GNUDumpDir":e.mode&&(e.mode=e.mode|448);case"File":case"OldFile":case"ContiguousFile":case"Link":case"SymbolicLink":return this[z3](e);case"CharacterDevice":case"BlockDevice":case"FIFO":default:return this[bfe](e)}}[Ro](e,r){e.name==="CwdError"?this.emit("error",e):(this.warn("TAR_ENTRY_ERROR",e,{entry:r}),this[iC](),r.resume())}[vh](e,r,o){Rfe(fl(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cache:this.dirCache,cwd:this.cwd,mode:r,noChmod:this.noChmod},o)}[J1](e){return this.forceChown||this.preserveOwner&&(typeof e.uid=="number"&&e.uid!==this.processUid||typeof e.gid=="number"&&e.gid!==this.processGid)||typeof this.uid=="number"&&this.uid!==this.processUid||typeof this.gid=="number"&&this.gid!==this.processGid}[z1](e){return Ffe(this.uid,e.uid,this.processUid)}[X1](e){return Ffe(this.gid,e.gid,this.processGid)}[Z3](e,r){let o=e.mode&4095||this.fmode,a=new Hct.WriteStream(e.absolute,{flags:Lfe(e.size),mode:o,autoClose:!1});a.on("error",p=>{a.fd&&vn.close(a.fd,()=>{}),a.write=()=>!0,this[Ro](p,e),r()});let n=1,u=p=>{if(p){a.fd&&vn.close(a.fd,()=>{}),this[Ro](p,e),r();return}--n===0&&vn.close(a.fd,h=>{h?this[Ro](h,e):this[iC](),r()})};a.on("finish",p=>{let h=e.absolute,E=a.fd;if(e.mtime&&!this.noMtime){n++;let I=e.atime||new Date,v=e.mtime;vn.futimes(E,I,v,b=>b?vn.utimes(h,I,v,C=>u(C&&b)):u())}if(this[J1](e)){n++;let I=this[z1](e),v=this[X1](e);vn.fchown(E,I,v,b=>b?vn.chown(h,I,v,C=>u(C&&b)):u())}u()});let A=this.transform&&this.transform(e)||e;A!==e&&(A.on("error",p=>{this[Ro](p,e),r()}),e.pipe(A)),A.pipe(a)}[$3](e,r){let o=e.mode&4095||this.dmode;this[vh](e.absolute,o,a=>{if(a){this[Ro](a,e),r();return}let n=1,u=A=>{--n===0&&(r(),this[iC](),e.resume())};e.mtime&&!this.noMtime&&(n++,vn.utimes(e.absolute,e.atime||new Date,e.mtime,u)),this[J1](e)&&(n++,vn.chown(e.absolute,this[z1](e),this[X1](e),u)),u()})}[bfe](e){e.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${e.type}`,{entry:e}),e.resume()}[Sfe](e,r){this[Vb](e,e.linkpath,"symlink",r)}[xfe](e,r){let o=fl(Yf.resolve(this.cwd,e.linkpath));this[Vb](e,o,"link",r)}[Qfe](){this[Gb]++}[iC](){this[Gb]--,this[J3]()}[e_](e){this[iC](),e.resume()}[X3](e,r){return e.type==="File"&&!this.unlink&&r.isFile()&&r.nlink<=1&&!$1}[z3](e){this[Qfe]();let r=[e.path];e.linkpath&&r.push(e.linkpath),this.reservations.reserve(r,o=>this[Pfe](e,o))}[Wb](e){e.type==="SymbolicLink"?zct(this.dirCache):e.type!=="Directory"&&Jct(this.dirCache,e.absolute)}[Pfe](e,r){this[Wb](e);let o=A=>{this[Wb](e),r(A)},a=()=>{this[vh](this.cwd,this.dmode,A=>{if(A){this[Ro](A,e),o();return}this[Z1]=!0,n()})},n=()=>{if(e.absolute!==this.cwd){let A=fl(Yf.dirname(e.absolute));if(A!==this.cwd)return this[vh](A,this.dmode,p=>{if(p){this[Ro](p,e),o();return}u()})}u()},u=()=>{vn.lstat(e.absolute,(A,p)=>{if(p&&(this.keep||this.newer&&p.mtime>e.mtime)){this[e_](e),o();return}if(A||this[X3](e,p))return this[tc](null,e,o);if(p.isDirectory()){if(e.type==="Directory"){let h=!this.noChmod&&e.mode&&(p.mode&4095)!==e.mode,E=I=>this[tc](I,e,o);return h?vn.chmod(e.absolute,e.mode,E):E()}if(e.absolute!==this.cwd)return vn.rmdir(e.absolute,h=>this[tc](h,e,o))}if(e.absolute===this.cwd)return this[tc](null,e,o);Vct(e.absolute,h=>this[tc](h,e,o))})};this[Z1]?n():a()}[tc](e,r,o){if(e){this[Ro](e,r),o();return}switch(r.type){case"File":case"OldFile":case"ContiguousFile":return this[Z3](r,o);case"Link":return this[xfe](r,o);case"SymbolicLink":return this[Sfe](r,o);case"Directory":case"GNUDumpDir":return this[$3](r,o)}}[Vb](e,r,o,a){vn[o](r,e.absolute,n=>{n?this[Ro](n,e):(this[iC](),e.resume()),a()})}},Yb=t=>{try{return[null,t()]}catch(e){return[e,null]}},t_=class extends e2{[tc](e,r){return super[tc](e,r,()=>{})}[z3](e){if(this[Wb](e),!this[Z1]){let n=this[vh](this.cwd,this.dmode);if(n)return this[Ro](n,e);this[Z1]=!0}if(e.absolute!==this.cwd){let n=fl(Yf.dirname(e.absolute));if(n!==this.cwd){let u=this[vh](n,this.dmode);if(u)return this[Ro](u,e)}}let[r,o]=Yb(()=>vn.lstatSync(e.absolute));if(o&&(this.keep||this.newer&&o.mtime>e.mtime))return this[e_](e);if(r||this[X3](e,o))return this[tc](null,e);if(o.isDirectory()){if(e.type==="Directory"){let u=!this.noChmod&&e.mode&&(o.mode&4095)!==e.mode,[A]=u?Yb(()=>{vn.chmodSync(e.absolute,e.mode)}):[];return this[tc](A,e)}let[n]=Yb(()=>vn.rmdirSync(e.absolute));this[tc](n,e)}let[a]=e.absolute===this.cwd?[]:Yb(()=>Kct(e.absolute));this[tc](a,e)}[Z3](e,r){let o=e.mode&4095||this.fmode,a=A=>{let p;try{vn.closeSync(n)}catch(h){p=h}(A||p)&&this[Ro](A||p,e),r()},n;try{n=vn.openSync(e.absolute,Lfe(e.size),o)}catch(A){return a(A)}let u=this.transform&&this.transform(e)||e;u!==e&&(u.on("error",A=>this[Ro](A,e)),e.pipe(u)),u.on("data",A=>{try{vn.writeSync(n,A,0,A.length)}catch(p){a(p)}}),u.on("end",A=>{let p=null;if(e.mtime&&!this.noMtime){let h=e.atime||new Date,E=e.mtime;try{vn.futimesSync(n,h,E)}catch(I){try{vn.utimesSync(e.absolute,h,E)}catch{p=I}}}if(this[J1](e)){let h=this[z1](e),E=this[X1](e);try{vn.fchownSync(n,h,E)}catch(I){try{vn.chownSync(e.absolute,h,E)}catch{p=p||I}}}a(p)})}[$3](e,r){let o=e.mode&4095||this.dmode,a=this[vh](e.absolute,o);if(a){this[Ro](a,e),r();return}if(e.mtime&&!this.noMtime)try{vn.utimesSync(e.absolute,e.atime||new Date,e.mtime)}catch{}if(this[J1](e))try{vn.chownSync(e.absolute,this[z1](e),this[X1](e))}catch{}r(),e.resume()}[vh](e,r){try{return Rfe.sync(fl(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cache:this.dirCache,cwd:this.cwd,mode:r})}catch(o){return o}}[Vb](e,r,o,a){try{vn[o+"Sync"](r,e.absolute),a(),e.resume()}catch(n){return this[Ro](n,e)}}};e2.Sync=t_;Mfe.exports=e2});var jfe=_((SUt,Hfe)=>{"use strict";var Xct=LE(),Kb=r_(),Ufe=Be("fs"),_fe=$E(),Ofe=Be("path"),n_=GE();Hfe.exports=(t,e,r)=>{typeof t=="function"?(r=t,e=null,t={}):Array.isArray(t)&&(e=t,t={}),typeof e=="function"&&(r=e,e=null),e?e=Array.from(e):e=[];let o=Xct(t);if(o.sync&&typeof r=="function")throw new TypeError("callback not supported for sync tar functions");if(!o.file&&typeof r=="function")throw new TypeError("callback only supported with file option");return e.length&&Zct(o,e),o.file&&o.sync?$ct(o):o.file?eut(o,r):o.sync?tut(o):rut(o)};var Zct=(t,e)=>{let r=new Map(e.map(n=>[n_(n),!0])),o=t.filter,a=(n,u)=>{let A=u||Ofe.parse(n).root||".",p=n===A?!1:r.has(n)?r.get(n):a(Ofe.dirname(n),A);return r.set(n,p),p};t.filter=o?(n,u)=>o(n,u)&&a(n_(n)):n=>a(n_(n))},$ct=t=>{let e=new Kb.Sync(t),r=t.file,o=Ufe.statSync(r),a=t.maxReadSize||16*1024*1024;new _fe.ReadStreamSync(r,{readSize:a,size:o.size}).pipe(e)},eut=(t,e)=>{let r=new Kb(t),o=t.maxReadSize||16*1024*1024,a=t.file,n=new Promise((u,A)=>{r.on("error",A),r.on("close",u),Ufe.stat(a,(p,h)=>{if(p)A(p);else{let E=new _fe.ReadStream(a,{readSize:o,size:h.size});E.on("error",A),E.pipe(r)}})});return e?n.then(e,e):n},tut=t=>new Kb.Sync(t),rut=t=>new Kb(t)});var qfe=_(us=>{"use strict";us.c=us.create=vAe();us.r=us.replace=O3();us.t=us.list=Lb();us.u=us.update=TAe();us.x=us.extract=jfe();us.Pack=wb();us.Unpack=r_();us.Parse=Nb();us.ReadEntry=nb();us.WriteEntry=p3();us.Header=qE();us.Pax=sb();us.types=JU()});var i_,Gfe,Dh,t2,r2,Yfe=Et(()=>{i_=$e(nd()),Gfe=Be("worker_threads"),Dh=Symbol("kTaskInfo"),t2=class{constructor(e,r){this.fn=e;this.limit=(0,i_.default)(r.poolSize)}run(e){return this.limit(()=>this.fn(e))}},r2=class{constructor(e,r){this.source=e;this.workers=[];this.limit=(0,i_.default)(r.poolSize),this.cleanupInterval=setInterval(()=>{if(this.limit.pendingCount===0&&this.limit.activeCount===0){let o=this.workers.pop();o?o.terminate():clearInterval(this.cleanupInterval)}},5e3).unref()}createWorker(){this.cleanupInterval.refresh();let e=new Gfe.Worker(this.source,{eval:!0,execArgv:[...process.execArgv,"--unhandled-rejections=strict"]});return e.on("message",r=>{if(!e[Dh])throw new Error("Assertion failed: Worker sent a result without having a task assigned");e[Dh].resolve(r),e[Dh]=null,e.unref(),this.workers.push(e)}),e.on("error",r=>{e[Dh]?.reject(r),e[Dh]=null}),e.on("exit",r=>{r!==0&&e[Dh]?.reject(new Error(`Worker exited with code ${r}`)),e[Dh]=null}),e}run(e){return this.limit(()=>{let r=this.workers.pop()??this.createWorker();return r.ref(),new Promise((o,a)=>{r[Dh]={resolve:o,reject:a},r.postMessage(e)})})}}});var Vfe=_((QUt,Wfe)=>{var s_;Wfe.exports.getContent=()=>(typeof s_>"u"&&(s_=Be("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),s_)});var Xi={};Kt(Xi,{convertToZip:()=>out,convertToZipWorker:()=>l_,extractArchiveTo:()=>Zfe,getDefaultTaskPool:()=>zfe,getTaskPoolForConfiguration:()=>Xfe,makeArchiveFromDirectory:()=>sut});function nut(t,e){switch(t){case"async":return new t2(l_,{poolSize:e});case"workers":return new r2((0,a_.getContent)(),{poolSize:e});default:throw new Error(`Assertion failed: Unknown value ${t} for taskPoolMode`)}}function zfe(){return typeof o_>"u"&&(o_=nut("workers",Ji.availableParallelism())),o_}function Xfe(t){return typeof t>"u"?zfe():ol(iut,t,()=>{let e=t.get("taskPoolMode"),r=t.get("taskPoolConcurrency");switch(e){case"async":return new t2(l_,{poolSize:r});case"workers":return new r2((0,a_.getContent)(),{poolSize:r});default:throw new Error(`Assertion failed: Unknown value ${e} for taskPoolMode`)}})}async function l_(t){let{tmpFile:e,tgz:r,compressionLevel:o,extractBufferOpts:a}=t,n=new zi(e,{create:!0,level:o,stats:Ea.makeDefaultStats()}),u=Buffer.from(r.buffer,r.byteOffset,r.byteLength);return await Zfe(u,n,a),n.saveAndClose(),e}async function sut(t,{baseFs:e=new Rn,prefixPath:r=Bt.root,compressionLevel:o,inMemory:a=!1}={}){let n;if(a)n=new zi(null,{level:o});else{let A=await oe.mktempPromise(),p=K.join(A,"archive.zip");n=new zi(p,{create:!0,level:o})}let u=K.resolve(Bt.root,r);return await n.copyPromise(u,t,{baseFs:e,stableTime:!0,stableSort:!0}),n}async function out(t,e={}){let r=await oe.mktempPromise(),o=K.join(r,"archive.zip"),a=e.compressionLevel??e.configuration?.get("compressionLevel")??"mixed",n={prefixPath:e.prefixPath,stripComponents:e.stripComponents};return await(e.taskPool??Xfe(e.configuration)).run({tmpFile:o,tgz:t,compressionLevel:a,extractBufferOpts:n}),new zi(o,{level:e.compressionLevel})}async function*aut(t){let e=new Jfe.default.Parse,r=new Kfe.PassThrough({objectMode:!0,autoDestroy:!0,emitClose:!0});e.on("entry",o=>{r.write(o)}),e.on("error",o=>{r.destroy(o)}),e.on("close",()=>{r.destroyed||r.end()}),e.end(t);for await(let o of r){let a=o;yield a,a.resume()}}async function Zfe(t,e,{stripComponents:r=0,prefixPath:o=Bt.dot}={}){function a(n){if(n.path[0]==="/")return!0;let u=n.path.split(/\//g);return!!(u.some(A=>A==="..")||u.length<=r)}for await(let n of aut(t)){if(a(n))continue;let u=K.normalize(ue.toPortablePath(n.path)).replace(/\/$/,"").split(/\//g);if(u.length<=r)continue;let A=u.slice(r).join("/"),p=K.join(o,A),h=420;switch((n.type==="Directory"||((n.mode??0)&73)!==0)&&(h|=73),n.type){case"Directory":e.mkdirpSync(K.dirname(p),{chmod:493,utimes:[vi.SAFE_TIME,vi.SAFE_TIME]}),e.mkdirSync(p,{mode:h}),e.utimesSync(p,vi.SAFE_TIME,vi.SAFE_TIME);break;case"OldFile":case"File":e.mkdirpSync(K.dirname(p),{chmod:493,utimes:[vi.SAFE_TIME,vi.SAFE_TIME]}),e.writeFileSync(p,await Vy(n),{mode:h}),e.utimesSync(p,vi.SAFE_TIME,vi.SAFE_TIME);break;case"SymbolicLink":e.mkdirpSync(K.dirname(p),{chmod:493,utimes:[vi.SAFE_TIME,vi.SAFE_TIME]}),e.symlinkSync(n.linkpath,p),e.lutimesSync(p,vi.SAFE_TIME,vi.SAFE_TIME);break}}return e}var Kfe,Jfe,a_,o_,iut,$fe=Et(()=>{Ye();Pt();nA();Kfe=Be("stream"),Jfe=$e(qfe());Yfe();jl();a_=$e(Vfe());iut=new WeakMap});var tpe=_((c_,epe)=>{(function(t,e){typeof c_=="object"?epe.exports=e():typeof define=="function"&&define.amd?define(e):t.treeify=e()})(c_,function(){function t(a,n){var u=n?"\u2514":"\u251C";return a?u+="\u2500 ":u+="\u2500\u2500\u2510",u}function e(a,n){var u=[];for(var A in a)!a.hasOwnProperty(A)||n&&typeof a[A]=="function"||u.push(A);return u}function r(a,n,u,A,p,h,E){var I="",v=0,b,C,T=A.slice(0);if(T.push([n,u])&&A.length>0&&(A.forEach(function(U,J){J>0&&(I+=(U[1]?" ":"\u2502")+" "),!C&&U[0]===n&&(C=!0)}),I+=t(a,u)+a,p&&(typeof n!="object"||n instanceof Date)&&(I+=": "+n),C&&(I+=" (circular ref.)"),E(I)),!C&&typeof n=="object"){var L=e(n,h);L.forEach(function(U){b=++v===L.length,r(U,n[U],b,T,p,h,E)})}}var o={};return o.asLines=function(a,n,u,A){var p=typeof u!="function"?u:!1;r(".",a,!1,[],n,p,A||u)},o.asTree=function(a,n,u){var A="";return r(".",a,!1,[],n,u,function(p){A+=p+` +`}),A},o})});var $s={};Kt($s,{emitList:()=>lut,emitTree:()=>spe,treeNodeToJson:()=>ipe,treeNodeToTreeify:()=>npe});function npe(t,{configuration:e}){let r={},o=0,a=(n,u)=>{let A=Array.isArray(n)?n.entries():Object.entries(n);for(let[p,h]of A){if(!h)continue;let{label:E,value:I,children:v}=h,b=[];typeof E<"u"&&b.push(md(e,E,2)),typeof I<"u"&&b.push(Ot(e,I[0],I[1])),b.length===0&&b.push(md(e,`${p}`,2));let C=b.join(": ").trim(),T=`\0${o++}\0`,L=u[`${T}${C}`]={};typeof v<"u"&&a(v,L)}};if(typeof t.children>"u")throw new Error("The root node must only contain children");return a(t.children,r),r}function ipe(t){let e=r=>{if(typeof r.children>"u"){if(typeof r.value>"u")throw new Error("Assertion failed: Expected a value to be set if the children are missing");return yd(r.value[0],r.value[1])}let o=Array.isArray(r.children)?r.children.entries():Object.entries(r.children??{}),a=Array.isArray(r.children)?[]:{};for(let[n,u]of o)u&&(a[cut(n)]=e(u));return typeof r.value>"u"?a:{value:yd(r.value[0],r.value[1]),children:a}};return e(t)}function lut(t,{configuration:e,stdout:r,json:o}){let a=t.map(n=>({value:n}));spe({children:a},{configuration:e,stdout:r,json:o})}function spe(t,{configuration:e,stdout:r,json:o,separators:a=0}){if(o){let u=Array.isArray(t.children)?t.children.values():Object.values(t.children??{});for(let A of u)A&&r.write(`${JSON.stringify(ipe(A))} +`);return}let n=(0,rpe.asTree)(npe(t,{configuration:e}),!1,!1);if(n=n.replace(/\0[0-9]+\0/g,""),a>=1&&(n=n.replace(/^([├└]─)/gm,`\u2502 +$1`).replace(/^│\n/,"")),a>=2)for(let u=0;u<2;++u)n=n.replace(/^([│ ].{2}[├│ ].{2}[^\n]+\n)(([│ ]).{2}[├└].{2}[^\n]*\n[│ ].{2}[│ ].{2}[├└]─)/gm,`$1$3 \u2502 +$2`).replace(/^│\n/,"");if(a>=3)throw new Error("Only the first two levels are accepted by treeUtils.emitTree");r.write(n)}function cut(t){return typeof t=="string"?t.replace(/^\0[0-9]+\0/,""):t}var rpe,ope=Et(()=>{rpe=$e(tpe());ql()});function n2(t){let e=t.match(uut);if(!e?.groups)throw new Error("Assertion failed: Expected the checksum to match the requested pattern");let r=e.groups.cacheVersion?parseInt(e.groups.cacheVersion):null;return{cacheKey:e.groups.cacheKey??null,cacheVersion:r,cacheSpec:e.groups.cacheSpec??null,hash:e.groups.hash}}var ape,u_,A_,Jb,Lr,uut,f_=Et(()=>{Ye();Pt();Pt();nA();ape=Be("crypto"),u_=$e(Be("fs"));Yl();rh();jl();xo();A_=Ky(process.env.YARN_CACHE_CHECKPOINT_OVERRIDE??process.env.YARN_CACHE_VERSION_OVERRIDE??9),Jb=Ky(process.env.YARN_CACHE_VERSION_OVERRIDE??10),Lr=class{constructor(e,{configuration:r,immutable:o=r.get("enableImmutableCache"),check:a=!1}){this.markedFiles=new Set;this.mutexes=new Map;this.cacheId=`-${(0,ape.randomBytes)(8).toString("hex")}.tmp`;this.configuration=r,this.cwd=e,this.immutable=o,this.check=a;let{cacheSpec:n,cacheKey:u}=Lr.getCacheKey(r);this.cacheSpec=n,this.cacheKey=u}static async find(e,{immutable:r,check:o}={}){let a=new Lr(e.get("cacheFolder"),{configuration:e,immutable:r,check:o});return await a.setup(),a}static getCacheKey(e){let r=e.get("compressionLevel"),o=r!=="mixed"?`c${r}`:"";return{cacheKey:[Jb,o].join(""),cacheSpec:o}}get mirrorCwd(){if(!this.configuration.get("enableMirror"))return null;let e=`${this.configuration.get("globalFolder")}/cache`;return e!==this.cwd?e:null}getVersionFilename(e){return`${aE(e)}-${this.cacheKey}.zip`}getChecksumFilename(e,r){let a=n2(r).hash.slice(0,10);return`${aE(e)}-${a}.zip`}isChecksumCompatible(e){if(e===null)return!1;let{cacheVersion:r,cacheSpec:o}=n2(e);if(r===null||r<A_)return!1;let a=this.configuration.get("cacheMigrationMode");return!(r<Jb&&a==="always"||o!==this.cacheSpec&&a!=="required-only")}getLocatorPath(e,r){return this.mirrorCwd===null?K.resolve(this.cwd,this.getVersionFilename(e)):r===null?K.resolve(this.cwd,this.getVersionFilename(e)):K.resolve(this.cwd,this.getChecksumFilename(e,r))}getLocatorMirrorPath(e){let r=this.mirrorCwd;return r!==null?K.resolve(r,this.getVersionFilename(e)):null}async setup(){if(!this.configuration.get("enableGlobalCache"))if(this.immutable){if(!await oe.existsPromise(this.cwd))throw new zt(56,"Cache path does not exist.")}else{await oe.mkdirPromise(this.cwd,{recursive:!0});let e=K.resolve(this.cwd,".gitignore");await oe.changeFilePromise(e,`/.gitignore +*.flock +*.tmp +`)}(this.mirrorCwd||!this.immutable)&&await oe.mkdirPromise(this.mirrorCwd||this.cwd,{recursive:!0})}async fetchPackageFromCache(e,r,{onHit:o,onMiss:a,loader:n,...u}){let A=this.getLocatorMirrorPath(e),p=new Rn,h=()=>{let ae=new zi,we=K.join(Bt.root,sO(e));return ae.mkdirSync(we,{recursive:!0}),ae.writeJsonSync(K.join(we,dr.manifest),{name:fn(e),mocked:!0}),ae},E=async(ae,{isColdHit:we,controlPath:Pe=null})=>{if(Pe===null&&u.unstablePackages?.has(e.locatorHash))return{isValid:!0,hash:null};let g=r&&!we?n2(r).cacheKey:this.cacheKey,Ee=!u.skipIntegrityCheck||!r?`${g}/${await LS(ae)}`:r;if(Pe!==null){let ce=!u.skipIntegrityCheck||!r?`${this.cacheKey}/${await LS(Pe)}`:r;if(Ee!==ce)throw new zt(18,"The remote archive doesn't match the local checksum - has the local cache been corrupted?")}let De=null;switch(r!==null&&Ee!==r&&(this.check?De="throw":n2(r).cacheKey!==n2(Ee).cacheKey?De="update":De=this.configuration.get("checksumBehavior")),De){case null:case"update":return{isValid:!0,hash:Ee};case"ignore":return{isValid:!0,hash:r};case"reset":return{isValid:!1,hash:r};default:case"throw":throw new zt(18,"The remote archive doesn't match the expected checksum")}},I=async ae=>{if(!n)throw new Error(`Cache check required but no loader configured for ${jr(this.configuration,e)}`);let we=await n(),Pe=we.getRealPath();we.saveAndClose(),await oe.chmodPromise(Pe,420);let g=await E(ae,{controlPath:Pe,isColdHit:!1});if(!g.isValid)throw new Error("Assertion failed: Expected a valid checksum");return g.hash},v=async()=>{if(A===null||!await oe.existsPromise(A)){let ae=await n(),we=ae.getRealPath();return ae.saveAndClose(),{source:"loader",path:we}}return{source:"mirror",path:A}},b=async()=>{if(!n)throw new Error(`Cache entry required but missing for ${jr(this.configuration,e)}`);if(this.immutable)throw new zt(56,`Cache entry required but missing for ${jr(this.configuration,e)}`);let{path:ae,source:we}=await v(),{hash:Pe}=await E(ae,{isColdHit:!0}),g=this.getLocatorPath(e,Pe),Ee=[];we!=="mirror"&&A!==null&&Ee.push(async()=>{let ce=`${A}${this.cacheId}`;await oe.copyFilePromise(ae,ce,u_.default.constants.COPYFILE_FICLONE),await oe.chmodPromise(ce,420),await oe.renamePromise(ce,A)}),(!u.mirrorWriteOnly||A===null)&&Ee.push(async()=>{let ce=`${g}${this.cacheId}`;await oe.copyFilePromise(ae,ce,u_.default.constants.COPYFILE_FICLONE),await oe.chmodPromise(ce,420),await oe.renamePromise(ce,g)});let De=u.mirrorWriteOnly?A??g:g;return await Promise.all(Ee.map(ce=>ce())),[!1,De,Pe]},C=async()=>{let we=(async()=>{let Pe=u.unstablePackages?.has(e.locatorHash),g=Pe||!r||this.isChecksumCompatible(r)?this.getLocatorPath(e,r):null,Ee=g!==null?this.markedFiles.has(g)||await p.existsPromise(g):!1,De=!!u.mockedPackages?.has(e.locatorHash)&&(!this.check||!Ee),ce=De||Ee,ne=ce?o:a;if(ne&&ne(),ce){let ee=null,Ie=g;if(!De)if(this.check)ee=await I(Ie);else{let ke=await E(Ie,{isColdHit:!1});if(ke.isValid)ee=ke.hash;else return b()}return[De,Ie,ee]}else{if(this.immutable&&Pe)throw new zt(56,`Cache entry required but missing for ${jr(this.configuration,e)}; consider defining ${de.pretty(this.configuration,"supportedArchitectures",de.Type.CODE)} to cache packages for multiple systems`);return b()}})();this.mutexes.set(e.locatorHash,we);try{return await we}finally{this.mutexes.delete(e.locatorHash)}};for(let ae;ae=this.mutexes.get(e.locatorHash);)await ae;let[T,L,U]=await C();T||this.markedFiles.add(L);let J,te=T?()=>h():()=>new zi(L,{baseFs:p,readOnly:!0}),le=new ny(()=>wL(()=>J=te(),ae=>`Failed to open the cache entry for ${jr(this.configuration,e)}: ${ae}`),K),pe=new Uu(L,{baseFs:le,pathUtils:K}),Ae=()=>{J?.discardAndClose()},ye=u.unstablePackages?.has(e.locatorHash)?null:U;return[pe,Ae,ye]}},uut=/^(?:(?<cacheKey>(?<cacheVersion>[0-9]+)(?<cacheSpec>.*))\/)?(?<hash>.*)$/});var zb,lpe=Et(()=>{zb=(r=>(r[r.SCRIPT=0]="SCRIPT",r[r.SHELLCODE=1]="SHELLCODE",r))(zb||{})});var Aut,sC,p_=Et(()=>{Pt();Nl();kf();xo();Aut=[[/^(git(?:\+(?:https|ssh))?:\/\/.*(?:\.git)?)#(.*)$/,(t,e,r,o)=>`${r}#commit=${o}`],[/^https:\/\/((?:[^/]+?)@)?codeload\.github\.com\/([^/]+\/[^/]+)\/tar\.gz\/([0-9a-f]+)$/,(t,e,r="",o,a)=>`https://${r}github.com/${o}.git#commit=${a}`],[/^https:\/\/((?:[^/]+?)@)?github\.com\/([^/]+\/[^/]+?)(?:\.git)?#([0-9a-f]+)$/,(t,e,r="",o,a)=>`https://${r}github.com/${o}.git#commit=${a}`],[/^https?:\/\/[^/]+\/(?:[^/]+\/)*(?:@.+(?:\/|(?:%2f)))?([^/]+)\/(?:-|download)\/\1-[^/]+\.tgz(?:#|$)/,t=>`npm:${t}`],[/^https:\/\/npm\.pkg\.github\.com\/download\/(?:@[^/]+)\/(?:[^/]+)\/(?:[^/]+)\/(?:[0-9a-f]+)(?:#|$)/,t=>`npm:${t}`],[/^https:\/\/npm\.fontawesome\.com\/(?:@[^/]+)\/([^/]+)\/-\/([^/]+)\/\1-\2.tgz(?:#|$)/,t=>`npm:${t}`],[/^https?:\/\/[^/]+\/.*\/(@[^/]+)\/([^/]+)\/-\/\1\/\2-(?:[.\d\w-]+)\.tgz(?:#|$)/,(t,e)=>HS({protocol:"npm:",source:null,selector:t,params:{__archiveUrl:e}})],[/^[^/]+\.tgz#[0-9a-f]+$/,t=>`npm:${t}`]],sC=class{constructor(e){this.resolver=e;this.resolutions=null}async setup(e,{report:r}){let o=K.join(e.cwd,dr.lockfile);if(!oe.existsSync(o))return;let a=await oe.readFilePromise(o,"utf8"),n=Vi(a);if(Object.hasOwn(n,"__metadata"))return;let u=this.resolutions=new Map;for(let A of Object.keys(n)){let p=i1(A);if(!p){r.reportWarning(14,`Failed to parse the string "${A}" into a proper descriptor`);continue}let h=ba(p.range)?In(p,`npm:${p.range}`):p,{version:E,resolved:I}=n[A];if(!I)continue;let v;for(let[C,T]of Aut){let L=I.match(C);if(L){v=T(E,...L);break}}if(!v){r.reportWarning(14,`${qn(e.configuration,h)}: Only some patterns can be imported from legacy lockfiles (not "${I}")`);continue}let b=h;try{let C=Id(h.range),T=i1(C.selector,!0);T&&(b=T)}catch{}u.set(h.descriptorHash,Qs(b,v))}}supportsDescriptor(e,r){return this.resolutions?this.resolutions.has(e.descriptorHash):!1}supportsLocator(e,r){return!1}shouldPersistResolution(e,r){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){if(!this.resolutions)throw new Error("Assertion failed: The resolution store should have been setup");let a=this.resolutions.get(e.descriptorHash);if(!a)throw new Error("Assertion failed: The resolution should have been registered");let n=tO(a),u=o.project.configuration.normalizeDependency(n);return await this.resolver.getCandidates(u,r,o)}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}}});var AA,cpe=Et(()=>{Yl();L1();ql();AA=class extends Xs{constructor({configuration:r,stdout:o,suggestInstall:a=!0}){super();this.errorCount=0;zI(this,{configuration:r}),this.configuration=r,this.stdout=o,this.suggestInstall=a}static async start(r,o){let a=new this(r);try{await o(a)}catch(n){a.reportExceptionOnce(n)}finally{await a.finalize()}return a}hasErrors(){return this.errorCount>0}exitCode(){return this.hasErrors()?1:0}reportCacheHit(r){}reportCacheMiss(r){}startSectionSync(r,o){return o()}async startSectionPromise(r,o){return await o()}startTimerSync(r,o,a){return(typeof o=="function"?o:a)()}async startTimerPromise(r,o,a){return await(typeof o=="function"?o:a)()}reportSeparator(){}reportInfo(r,o){}reportWarning(r,o){}reportError(r,o){this.errorCount+=1,this.stdout.write(`${Ot(this.configuration,"\u27A4","redBright")} ${this.formatNameWithHyperlink(r)}: ${o} +`)}reportProgress(r){return{...Promise.resolve().then(async()=>{for await(let{}of r);}),stop:()=>{}}}reportJson(r){}reportFold(r,o){}async finalize(){this.errorCount>0&&(this.stdout.write(` +`),this.stdout.write(`${Ot(this.configuration,"\u27A4","redBright")} Errors happened when preparing the environment required to run this command. +`),this.suggestInstall&&this.stdout.write(`${Ot(this.configuration,"\u27A4","redBright")} This might be caused by packages being missing from the lockfile, in which case running "yarn install" might help. +`))}formatNameWithHyperlink(r){return CU(r,{configuration:this.configuration,json:!1})}}});var oC,h_=Et(()=>{xo();oC=class{constructor(e){this.resolver=e}supportsDescriptor(e,r){return!!(r.project.storedResolutions.get(e.descriptorHash)||r.project.originalPackages.has(OS(e).locatorHash))}supportsLocator(e,r){return!!(r.project.originalPackages.has(e.locatorHash)&&!r.project.lockfileNeedsRefresh)}shouldPersistResolution(e,r){throw new Error("The shouldPersistResolution method shouldn't be called on the lockfile resolver, which would always answer yes")}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return this.resolver.getResolutionDependencies(e,r)}async getCandidates(e,r,o){let a=o.project.storedResolutions.get(e.descriptorHash);if(a){let u=o.project.originalPackages.get(a);if(u)return[u]}let n=o.project.originalPackages.get(OS(e).locatorHash);if(n)return[n];throw new Error("Resolution expected from the lockfile data")}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){let o=r.project.originalPackages.get(e.locatorHash);if(!o)throw new Error("The lockfile resolver isn't meant to resolve packages - they should already have been stored into a cache");return o}}});function Wf(){}function fut(t,e,r,o,a){for(var n=0,u=e.length,A=0,p=0;n<u;n++){var h=e[n];if(h.removed){if(h.value=t.join(o.slice(p,p+h.count)),p+=h.count,n&&e[n-1].added){var I=e[n-1];e[n-1]=e[n],e[n]=I}}else{if(!h.added&&a){var E=r.slice(A,A+h.count);E=E.map(function(b,C){var T=o[p+C];return T.length>b.length?T:b}),h.value=t.join(E)}else h.value=t.join(r.slice(A,A+h.count));A+=h.count,h.added||(p+=h.count)}}var v=e[u-1];return u>1&&typeof v.value=="string"&&(v.added||v.removed)&&t.equals("",v.value)&&(e[u-2].value+=v.value,e.pop()),e}function put(t){return{newPos:t.newPos,components:t.components.slice(0)}}function hut(t,e){if(typeof t=="function")e.callback=t;else if(t)for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e}function fpe(t,e,r){return r=hut(r,{ignoreWhitespace:!0}),E_.diff(t,e,r)}function gut(t,e,r){return C_.diff(t,e,r)}function Xb(t){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Xb=function(e){return typeof e}:Xb=function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Xb(t)}function g_(t){return yut(t)||Eut(t)||Cut(t)||wut()}function yut(t){if(Array.isArray(t))return d_(t)}function Eut(t){if(typeof Symbol<"u"&&Symbol.iterator in Object(t))return Array.from(t)}function Cut(t,e){if(!!t){if(typeof t=="string")return d_(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);if(r==="Object"&&t.constructor&&(r=t.constructor.name),r==="Map"||r==="Set")return Array.from(t);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return d_(t,e)}}function d_(t,e){(e==null||e>t.length)&&(e=t.length);for(var r=0,o=new Array(e);r<e;r++)o[r]=t[r];return o}function wut(){throw new TypeError(`Invalid attempt to spread non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function m_(t,e,r,o,a){e=e||[],r=r||[],o&&(t=o(a,t));var n;for(n=0;n<e.length;n+=1)if(e[n]===t)return r[n];var u;if(Iut.call(t)==="[object Array]"){for(e.push(t),u=new Array(t.length),r.push(u),n=0;n<t.length;n+=1)u[n]=m_(t[n],e,r,o,a);return e.pop(),r.pop(),u}if(t&&t.toJSON&&(t=t.toJSON()),Xb(t)==="object"&&t!==null){e.push(t),u={},r.push(u);var A=[],p;for(p in t)t.hasOwnProperty(p)&&A.push(p);for(A.sort(),n=0;n<A.length;n+=1)p=A[n],u[p]=m_(t[p],e,r,o,p);e.pop(),r.pop()}else u=t;return u}function ppe(t,e,r,o,a,n,u){u||(u={}),typeof u.context>"u"&&(u.context=4);var A=gut(r,o,u);if(!A)return;A.push({value:"",lines:[]});function p(U){return U.map(function(J){return" "+J})}for(var h=[],E=0,I=0,v=[],b=1,C=1,T=function(J){var te=A[J],le=te.lines||te.value.replace(/\n$/,"").split(` +`);if(te.lines=le,te.added||te.removed){var pe;if(!E){var Ae=A[J-1];E=b,I=C,Ae&&(v=u.context>0?p(Ae.lines.slice(-u.context)):[],E-=v.length,I-=v.length)}(pe=v).push.apply(pe,g_(le.map(function(ce){return(te.added?"+":"-")+ce}))),te.added?C+=le.length:b+=le.length}else{if(E)if(le.length<=u.context*2&&J<A.length-2){var ye;(ye=v).push.apply(ye,g_(p(le)))}else{var ae,we=Math.min(le.length,u.context);(ae=v).push.apply(ae,g_(p(le.slice(0,we))));var Pe={oldStart:E,oldLines:b-E+we,newStart:I,newLines:C-I+we,lines:v};if(J>=A.length-2&&le.length<=u.context){var g=/\n$/.test(r),Ee=/\n$/.test(o),De=le.length==0&&v.length>Pe.oldLines;!g&&De&&r.length>0&&v.splice(Pe.oldLines,0,"\\ No newline at end of file"),(!g&&!De||!Ee)&&v.push("\\ No newline at end of file")}h.push(Pe),E=0,I=0,v=[]}b+=le.length,C+=le.length}},L=0;L<A.length;L++)T(L);return{oldFileName:t,newFileName:e,oldHeader:a,newHeader:n,hunks:h}}var i3t,upe,Ape,E_,C_,dut,mut,Iut,i2,y_,w_=Et(()=>{Wf.prototype={diff:function(e,r){var o=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},a=o.callback;typeof o=="function"&&(a=o,o={}),this.options=o;var n=this;function u(T){return a?(setTimeout(function(){a(void 0,T)},0),!0):T}e=this.castInput(e),r=this.castInput(r),e=this.removeEmpty(this.tokenize(e)),r=this.removeEmpty(this.tokenize(r));var A=r.length,p=e.length,h=1,E=A+p;o.maxEditLength&&(E=Math.min(E,o.maxEditLength));var I=[{newPos:-1,components:[]}],v=this.extractCommon(I[0],r,e,0);if(I[0].newPos+1>=A&&v+1>=p)return u([{value:this.join(r),count:r.length}]);function b(){for(var T=-1*h;T<=h;T+=2){var L=void 0,U=I[T-1],J=I[T+1],te=(J?J.newPos:0)-T;U&&(I[T-1]=void 0);var le=U&&U.newPos+1<A,pe=J&&0<=te&&te<p;if(!le&&!pe){I[T]=void 0;continue}if(!le||pe&&U.newPos<J.newPos?(L=put(J),n.pushComponent(L.components,void 0,!0)):(L=U,L.newPos++,n.pushComponent(L.components,!0,void 0)),te=n.extractCommon(L,r,e,T),L.newPos+1>=A&&te+1>=p)return u(fut(n,L.components,r,e,n.useLongestToken));I[T]=L}h++}if(a)(function T(){setTimeout(function(){if(h>E)return a();b()||T()},0)})();else for(;h<=E;){var C=b();if(C)return C}},pushComponent:function(e,r,o){var a=e[e.length-1];a&&a.added===r&&a.removed===o?e[e.length-1]={count:a.count+1,added:r,removed:o}:e.push({count:1,added:r,removed:o})},extractCommon:function(e,r,o,a){for(var n=r.length,u=o.length,A=e.newPos,p=A-a,h=0;A+1<n&&p+1<u&&this.equals(r[A+1],o[p+1]);)A++,p++,h++;return h&&e.components.push({count:h}),e.newPos=A,p},equals:function(e,r){return this.options.comparator?this.options.comparator(e,r):e===r||this.options.ignoreCase&&e.toLowerCase()===r.toLowerCase()},removeEmpty:function(e){for(var r=[],o=0;o<e.length;o++)e[o]&&r.push(e[o]);return r},castInput:function(e){return e},tokenize:function(e){return e.split("")},join:function(e){return e.join("")}};i3t=new Wf;upe=/^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/,Ape=/\S/,E_=new Wf;E_.equals=function(t,e){return this.options.ignoreCase&&(t=t.toLowerCase(),e=e.toLowerCase()),t===e||this.options.ignoreWhitespace&&!Ape.test(t)&&!Ape.test(e)};E_.tokenize=function(t){for(var e=t.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/),r=0;r<e.length-1;r++)!e[r+1]&&e[r+2]&&upe.test(e[r])&&upe.test(e[r+2])&&(e[r]+=e[r+2],e.splice(r+1,2),r--);return e};C_=new Wf;C_.tokenize=function(t){var e=[],r=t.split(/(\n|\r\n)/);r[r.length-1]||r.pop();for(var o=0;o<r.length;o++){var a=r[o];o%2&&!this.options.newlineIsToken?e[e.length-1]+=a:(this.options.ignoreWhitespace&&(a=a.trim()),e.push(a))}return e};dut=new Wf;dut.tokenize=function(t){return t.split(/(\S.+?[.!?])(?=\s+|$)/)};mut=new Wf;mut.tokenize=function(t){return t.split(/([{}:;,]|\s+)/)};Iut=Object.prototype.toString,i2=new Wf;i2.useLongestToken=!0;i2.tokenize=C_.tokenize;i2.castInput=function(t){var e=this.options,r=e.undefinedReplacement,o=e.stringifyReplacer,a=o===void 0?function(n,u){return typeof u>"u"?r:u}:o;return typeof t=="string"?t:JSON.stringify(m_(t,null,null,a),a," ")};i2.equals=function(t,e){return Wf.prototype.equals.call(i2,t.replace(/,([\r\n])/g,"$1"),e.replace(/,([\r\n])/g,"$1"))};y_=new Wf;y_.tokenize=function(t){return t.slice()};y_.join=y_.removeEmpty=function(t){return t}});var gpe=_((o3t,hpe)=>{var But=Hl(),vut=fE(),Dut=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Put=/^\w*$/;function Sut(t,e){if(But(t))return!1;var r=typeof t;return r=="number"||r=="symbol"||r=="boolean"||t==null||vut(t)?!0:Put.test(t)||!Dut.test(t)||e!=null&&t in Object(e)}hpe.exports=Sut});var ype=_((a3t,mpe)=>{var dpe=_P(),xut="Expected a function";function I_(t,e){if(typeof t!="function"||e!=null&&typeof e!="function")throw new TypeError(xut);var r=function(){var o=arguments,a=e?e.apply(this,o):o[0],n=r.cache;if(n.has(a))return n.get(a);var u=t.apply(this,o);return r.cache=n.set(a,u)||n,u};return r.cache=new(I_.Cache||dpe),r}I_.Cache=dpe;mpe.exports=I_});var Cpe=_((l3t,Epe)=>{var but=ype(),kut=500;function Qut(t){var e=but(t,function(o){return r.size===kut&&r.clear(),o}),r=e.cache;return e}Epe.exports=Qut});var B_=_((c3t,wpe)=>{var Fut=Cpe(),Tut=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Rut=/\\(\\)?/g,Nut=Fut(function(t){var e=[];return t.charCodeAt(0)===46&&e.push(""),t.replace(Tut,function(r,o,a,n){e.push(a?n.replace(Rut,"$1"):o||r)}),e});wpe.exports=Nut});var jd=_((u3t,Ipe)=>{var Lut=Hl(),Mut=gpe(),Out=B_(),Uut=R1();function _ut(t,e){return Lut(t)?t:Mut(t,e)?[t]:Out(Uut(t))}Ipe.exports=_ut});var aC=_((A3t,Bpe)=>{var Hut=fE(),jut=1/0;function qut(t){if(typeof t=="string"||Hut(t))return t;var e=t+"";return e=="0"&&1/t==-jut?"-0":e}Bpe.exports=qut});var Zb=_((f3t,vpe)=>{var Gut=jd(),Yut=aC();function Wut(t,e){e=Gut(e,t);for(var r=0,o=e.length;t!=null&&r<o;)t=t[Yut(e[r++])];return r&&r==o?t:void 0}vpe.exports=Wut});var v_=_((p3t,Ppe)=>{var Vut=rS(),Kut=jd(),Jut=UI(),Dpe=il(),zut=aC();function Xut(t,e,r,o){if(!Dpe(t))return t;e=Kut(e,t);for(var a=-1,n=e.length,u=n-1,A=t;A!=null&&++a<n;){var p=zut(e[a]),h=r;if(p==="__proto__"||p==="constructor"||p==="prototype")return t;if(a!=u){var E=A[p];h=o?o(E,p,A):void 0,h===void 0&&(h=Dpe(E)?E:Jut(e[a+1])?[]:{})}Vut(A,p,h),A=A[p]}return t}Ppe.exports=Xut});var xpe=_((h3t,Spe)=>{var Zut=Zb(),$ut=v_(),eAt=jd();function tAt(t,e,r){for(var o=-1,a=e.length,n={};++o<a;){var u=e[o],A=Zut(t,u);r(A,u)&&$ut(n,eAt(u,t),A)}return n}Spe.exports=tAt});var kpe=_((g3t,bpe)=>{function rAt(t,e){return t!=null&&e in Object(t)}bpe.exports=rAt});var D_=_((d3t,Qpe)=>{var nAt=jd(),iAt=LI(),sAt=Hl(),oAt=UI(),aAt=YP(),lAt=aC();function cAt(t,e,r){e=nAt(e,t);for(var o=-1,a=e.length,n=!1;++o<a;){var u=lAt(e[o]);if(!(n=t!=null&&r(t,u)))break;t=t[u]}return n||++o!=a?n:(a=t==null?0:t.length,!!a&&aAt(a)&&oAt(u,a)&&(sAt(t)||iAt(t)))}Qpe.exports=cAt});var Tpe=_((m3t,Fpe)=>{var uAt=kpe(),AAt=D_();function fAt(t,e){return t!=null&&AAt(t,e,uAt)}Fpe.exports=fAt});var Npe=_((y3t,Rpe)=>{var pAt=xpe(),hAt=Tpe();function gAt(t,e){return pAt(t,e,function(r,o){return hAt(t,o)})}Rpe.exports=gAt});var Upe=_((E3t,Ope)=>{var Lpe=fd(),dAt=LI(),mAt=Hl(),Mpe=Lpe?Lpe.isConcatSpreadable:void 0;function yAt(t){return mAt(t)||dAt(t)||!!(Mpe&&t&&t[Mpe])}Ope.exports=yAt});var jpe=_((C3t,Hpe)=>{var EAt=qP(),CAt=Upe();function _pe(t,e,r,o,a){var n=-1,u=t.length;for(r||(r=CAt),a||(a=[]);++n<u;){var A=t[n];e>0&&r(A)?e>1?_pe(A,e-1,r,o,a):EAt(a,A):o||(a[a.length]=A)}return a}Hpe.exports=_pe});var Gpe=_((w3t,qpe)=>{var wAt=jpe();function IAt(t){var e=t==null?0:t.length;return e?wAt(t,1):[]}qpe.exports=IAt});var P_=_((I3t,Ype)=>{var BAt=Gpe(),vAt=pL(),DAt=hL();function PAt(t){return DAt(vAt(t,void 0,BAt),t+"")}Ype.exports=PAt});var S_=_((B3t,Wpe)=>{var SAt=Npe(),xAt=P_(),bAt=xAt(function(t,e){return t==null?{}:SAt(t,e)});Wpe.exports=bAt});var $b,Vpe=Et(()=>{Yl();$b=class{constructor(e){this.resolver=e}supportsDescriptor(e,r){return this.resolver.supportsDescriptor(e,r)}supportsLocator(e,r){return this.resolver.supportsLocator(e,r)}shouldPersistResolution(e,r){return this.resolver.shouldPersistResolution(e,r)}bindDescriptor(e,r,o){return this.resolver.bindDescriptor(e,r,o)}getResolutionDependencies(e,r){return this.resolver.getResolutionDependencies(e,r)}async getCandidates(e,r,o){throw new zt(20,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}async getSatisfying(e,r,o,a){throw new zt(20,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}async resolve(e,r){throw new zt(20,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}}});var Qi,x_=Et(()=>{Yl();Qi=class extends Xs{reportCacheHit(e){}reportCacheMiss(e){}startSectionSync(e,r){return r()}async startSectionPromise(e,r){return await r()}startTimerSync(e,r,o){return(typeof r=="function"?r:o)()}async startTimerPromise(e,r,o){return await(typeof r=="function"?r:o)()}reportSeparator(){}reportInfo(e,r){}reportWarning(e,r){}reportError(e,r){}reportProgress(e){return{...Promise.resolve().then(async()=>{for await(let{}of e);}),stop:()=>{}}}reportJson(e){}reportFold(e,r){}async finalize(){}}});var Kpe,lC,b_=Et(()=>{Pt();Kpe=$e(RS());AE();Bd();ql();rh();kf();xo();lC=class{constructor(e,{project:r}){this.workspacesCwds=new Set;this.project=r,this.cwd=e}async setup(){this.manifest=await Mt.tryFind(this.cwd)??new Mt,this.relativeCwd=K.relative(this.project.cwd,this.cwd)||Bt.dot;let e=this.manifest.name?this.manifest.name:eA(null,`${this.computeCandidateName()}-${zs(this.relativeCwd).substring(0,6)}`);this.anchoredDescriptor=In(e,`${Xn.protocol}${this.relativeCwd}`),this.anchoredLocator=Qs(e,`${Xn.protocol}${this.relativeCwd}`);let r=this.manifest.workspaceDefinitions.map(({pattern:a})=>a);if(r.length===0)return;let o=await(0,Kpe.default)(r,{cwd:ue.fromPortablePath(this.cwd),onlyDirectories:!0,ignore:["**/node_modules","**/.git","**/.yarn"]});o.sort(),await o.reduce(async(a,n)=>{let u=K.resolve(this.cwd,ue.toPortablePath(n)),A=await oe.existsPromise(K.join(u,"package.json"));await a,A&&this.workspacesCwds.add(u)},Promise.resolve())}get anchoredPackage(){let e=this.project.storedPackages.get(this.anchoredLocator.locatorHash);if(!e)throw new Error(`Assertion failed: Expected workspace ${o1(this.project.configuration,this)} (${Ot(this.project.configuration,K.join(this.cwd,dr.manifest),yt.PATH)}) to have been resolved. Run "yarn install" to update the lockfile`);return e}accepts(e){let r=e.indexOf(":"),o=r!==-1?e.slice(0,r+1):null,a=r!==-1?e.slice(r+1):e;if(o===Xn.protocol&&K.normalize(a)===this.relativeCwd||o===Xn.protocol&&(a==="*"||a==="^"||a==="~"))return!0;let n=ba(a);return n?o===Xn.protocol?n.test(this.manifest.version??"0.0.0"):this.project.configuration.get("enableTransparentWorkspaces")&&this.manifest.version!==null?n.test(this.manifest.version):!1:!1}computeCandidateName(){return this.cwd===this.project.cwd?"root-workspace":`${K.basename(this.cwd)}`||"unnamed-workspace"}getRecursiveWorkspaceDependencies({dependencies:e=Mt.hardDependencies}={}){let r=new Set,o=a=>{for(let n of e)for(let u of a.manifest[n].values()){let A=this.project.tryWorkspaceByDescriptor(u);A===null||r.has(A)||(r.add(A),o(A))}};return o(this),r}getRecursiveWorkspaceDependents({dependencies:e=Mt.hardDependencies}={}){let r=new Set,o=a=>{for(let n of this.project.workspaces)e.some(A=>[...n.manifest[A].values()].some(p=>{let h=this.project.tryWorkspaceByDescriptor(p);return h!==null&&n1(h.anchoredLocator,a.anchoredLocator)}))&&!r.has(n)&&(r.add(n),o(n))};return o(this),r}getRecursiveWorkspaceChildren(){let e=new Set([this]);for(let r of e)for(let o of r.workspacesCwds){let a=this.project.workspacesByCwd.get(o);a&&e.add(a)}return e.delete(this),Array.from(e)}async persistManifest(){let e={};this.manifest.exportTo(e);let r=K.join(this.cwd,Mt.fileName),o=`${JSON.stringify(e,null,this.manifest.indent)} +`;await oe.changeFilePromise(r,o,{automaticNewlines:!0}),this.manifest.raw=e}}});function NAt({project:t,allDescriptors:e,allResolutions:r,allPackages:o,accessibleLocators:a=new Set,optionalBuilds:n=new Set,peerRequirements:u=new Map,peerWarnings:A=[],volatileDescriptors:p=new Set}){let h=new Map,E=[],I=new Map,v=new Map,b=new Map,C=new Map,T=new Map,L=new Map(t.workspaces.map(Ae=>{let ye=Ae.anchoredLocator.locatorHash,ae=o.get(ye);if(typeof ae>"u")throw new Error("Assertion failed: The workspace should have an associated package");return[ye,$I(ae)]})),U=()=>{let Ae=oe.mktempSync(),ye=K.join(Ae,"stacktrace.log"),ae=String(E.length+1).length,we=E.map((Pe,g)=>`${`${g+1}.`.padStart(ae," ")} ${xa(Pe)} +`).join("");throw oe.writeFileSync(ye,we),oe.detachTemp(Ae),new zt(45,`Encountered a stack overflow when resolving peer dependencies; cf ${ue.fromPortablePath(ye)}`)},J=Ae=>{let ye=r.get(Ae.descriptorHash);if(typeof ye>"u")throw new Error("Assertion failed: The resolution should have been registered");let ae=o.get(ye);if(!ae)throw new Error("Assertion failed: The package could not be found");return ae},te=(Ae,ye,ae,{top:we,optional:Pe})=>{E.length>1e3&&U(),E.push(ye);let g=le(Ae,ye,ae,{top:we,optional:Pe});return E.pop(),g},le=(Ae,ye,ae,{top:we,optional:Pe})=>{if(a.has(ye.locatorHash))return;a.add(ye.locatorHash),Pe||n.delete(ye.locatorHash);let g=o.get(ye.locatorHash);if(!g)throw new Error(`Assertion failed: The package (${jr(t.configuration,ye)}) should have been registered`);let Ee=[],De=[],ce=[],ne=[],ee=[];for(let ke of Array.from(g.dependencies.values())){if(g.peerDependencies.has(ke.identHash)&&g.locatorHash!==we)continue;if(Sf(ke))throw new Error("Assertion failed: Virtual packages shouldn't be encountered when virtualizing a branch");p.delete(ke.descriptorHash);let ht=Pe;if(!ht){let Te=g.dependenciesMeta.get(fn(ke));if(typeof Te<"u"){let Je=Te.get(null);typeof Je<"u"&&Je.optional&&(ht=!0)}}let H=r.get(ke.descriptorHash);if(!H)throw new Error(`Assertion failed: The resolution (${qn(t.configuration,ke)}) should have been registered`);let lt=L.get(H)||o.get(H);if(!lt)throw new Error(`Assertion failed: The package (${H}, resolved from ${qn(t.configuration,ke)}) should have been registered`);if(lt.peerDependencies.size===0){te(ke,lt,new Map,{top:we,optional:ht});continue}let Re,Qe,be=new Set,_e;De.push(()=>{Re=nO(ke,ye.locatorHash),Qe=iO(lt,ye.locatorHash),g.dependencies.delete(ke.identHash),g.dependencies.set(Re.identHash,Re),r.set(Re.descriptorHash,Qe.locatorHash),e.set(Re.descriptorHash,Re),o.set(Qe.locatorHash,Qe),Ee.push([lt,Re,Qe])}),ce.push(()=>{_e=new Map;for(let Te of Qe.peerDependencies.values()){let Je=g.dependencies.get(Te.identHash);if(!Je&&r1(ye,Te)&&(Ae.identHash===ye.identHash?Je=Ae:(Je=In(ye,Ae.range),e.set(Je.descriptorHash,Je),r.set(Je.descriptorHash,ye.locatorHash),p.delete(Je.descriptorHash))),(!Je||Je.range==="missing:")&&Qe.dependencies.has(Te.identHash)){Qe.peerDependencies.delete(Te.identHash);continue}Je||(Je=In(Te,"missing:")),Qe.dependencies.set(Je.identHash,Je),Sf(Je)&&dd(b,Je.descriptorHash).add(Qe.locatorHash),I.set(Je.identHash,Je),Je.range==="missing:"&&be.add(Je.identHash),_e.set(Te.identHash,ae.get(Te.identHash)??Qe.locatorHash)}Qe.dependencies=new Map(ks(Qe.dependencies,([Te,Je])=>fn(Je)))}),ne.push(()=>{if(!o.has(Qe.locatorHash))return;let Te=h.get(lt.locatorHash);typeof Te=="number"&&Te>=2&&U();let Je=h.get(lt.locatorHash),He=typeof Je<"u"?Je+1:1;h.set(lt.locatorHash,He),te(Re,Qe,_e,{top:we,optional:ht}),h.set(lt.locatorHash,He-1)}),ee.push(()=>{let Te=g.dependencies.get(ke.identHash);if(typeof Te>"u")throw new Error("Assertion failed: Expected the peer dependency to have been turned into a dependency");let Je=r.get(Te.descriptorHash);if(typeof Je>"u")throw new Error("Assertion failed: Expected the descriptor to be registered");if(dd(T,Je).add(ye.locatorHash),!!o.has(Qe.locatorHash)){for(let He of Qe.peerDependencies.values()){let x=_e.get(He.identHash);if(typeof x>"u")throw new Error("Assertion failed: Expected the peer dependency ident to be registered");Gy(Yy(C,x),fn(He)).push(Qe.locatorHash)}for(let He of be)Qe.dependencies.delete(He)}})}for(let ke of[...De,...ce])ke();let Ie;do{Ie=!0;for(let[ke,ht,H]of Ee){let lt=Yy(v,ke.locatorHash),Re=zs(...[...H.dependencies.values()].map(Te=>{let Je=Te.range!=="missing:"?r.get(Te.descriptorHash):"missing:";if(typeof Je>"u")throw new Error(`Assertion failed: Expected the resolution for ${qn(t.configuration,Te)} to have been registered`);return Je===we?`${Je} (top)`:Je}),ht.identHash),Qe=lt.get(Re);if(typeof Qe>"u"){lt.set(Re,ht);continue}if(Qe===ht)continue;o.delete(H.locatorHash),e.delete(ht.descriptorHash),r.delete(ht.descriptorHash),a.delete(H.locatorHash);let be=b.get(ht.descriptorHash)||[],_e=[g.locatorHash,...be];b.delete(ht.descriptorHash);for(let Te of _e){let Je=o.get(Te);typeof Je>"u"||(Je.dependencies.get(ht.identHash).descriptorHash!==Qe.descriptorHash&&(Ie=!1),Je.dependencies.set(ht.identHash,Qe))}}}while(!Ie);for(let ke of[...ne,...ee])ke()};for(let Ae of t.workspaces){let ye=Ae.anchoredLocator;p.delete(Ae.anchoredDescriptor.descriptorHash),te(Ae.anchoredDescriptor,ye,new Map,{top:ye.locatorHash,optional:!1})}let pe=new Map;for(let[Ae,ye]of T){let ae=o.get(Ae);if(typeof ae>"u")throw new Error("Assertion failed: Expected the root to be registered");let we=C.get(Ae);if(!(typeof we>"u"))for(let Pe of ye){let g=o.get(Pe);if(!(typeof g>"u")&&!!t.tryWorkspaceByLocator(g))for(let[Ee,De]of we){let ce=Js(Ee);if(g.peerDependencies.has(ce.identHash))continue;let ne=`p${zs(Pe,Ee,Ae).slice(0,5)}`;u.set(ne,{subject:Pe,requested:ce,rootRequester:Ae,allRequesters:De});let ee=ae.dependencies.get(ce.identHash);if(typeof ee<"u"){let Ie=J(ee),ke=Ie.version??"0.0.0",ht=new Set;for(let lt of De){let Re=o.get(lt);if(typeof Re>"u")throw new Error("Assertion failed: Expected the link to be registered");let Qe=Re.peerDependencies.get(ce.identHash);if(typeof Qe>"u")throw new Error("Assertion failed: Expected the ident to be registered");ht.add(Qe.range)}if(![...ht].every(lt=>{if(lt.startsWith(Xn.protocol)){if(!t.tryWorkspaceByLocator(Ie))return!1;lt=lt.slice(Xn.protocol.length),(lt==="^"||lt==="~")&&(lt="*")}return bf(ke,lt)})){let lt=ol(pe,Ie.locatorHash,()=>({type:2,requested:ce,subject:Ie,dependents:new Map,requesters:new Map,links:new Map,version:ke,hash:`p${Ie.locatorHash.slice(0,5)}`}));lt.dependents.set(g.locatorHash,g),lt.requesters.set(ae.locatorHash,ae);for(let Re of De)lt.links.set(Re,o.get(Re));A.push({type:1,subject:g,requested:ce,requester:ae,version:ke,hash:ne,requirementCount:De.length})}}else ae.peerDependenciesMeta.get(Ee)?.optional||A.push({type:0,subject:g,requested:ce,requester:ae,hash:ne})}}}A.push(...pe.values())}function LAt(t,e){let r=BL(t.peerWarnings,"type"),o=r[2]?.map(n=>{let u=Array.from(n.links.values(),E=>{let I=t.storedPackages.get(E.locatorHash);if(typeof I>"u")throw new Error("Assertion failed: Expected the package to be registered");let v=I.peerDependencies.get(n.requested.identHash);if(typeof v>"u")throw new Error("Assertion failed: Expected the ident to be registered");return v.range}),A=n.links.size>1?"and other dependencies request":"requests",p=aO(u),h=p?lE(t.configuration,p):Ot(t.configuration,"but they have non-overlapping ranges!","redBright");return`${cs(t.configuration,n.requested)} is listed by your project with version ${s1(t.configuration,n.version)}, which doesn't satisfy what ${cs(t.configuration,n.requesters.values().next().value)} (${Ot(t.configuration,n.hash,yt.CODE)}) ${A} (${h}).`})??[],a=r[0]?.map(n=>`${jr(t.configuration,n.subject)} doesn't provide ${cs(t.configuration,n.requested)} (${Ot(t.configuration,n.hash,yt.CODE)}), requested by ${cs(t.configuration,n.requester)}.`)??[];e.startSectionSync({reportFooter:()=>{e.reportWarning(86,`Some peer dependencies are incorrectly met; run ${Ot(t.configuration,"yarn explain peer-requirements <hash>",yt.CODE)} for details, where ${Ot(t.configuration,"<hash>",yt.CODE)} is the six-letter p-prefixed code.`)},skipIfEmpty:!0},()=>{for(let n of ks(o,u=>zy.default(u)))e.reportWarning(60,n);for(let n of ks(a,u=>zy.default(u)))e.reportWarning(2,n)})}var ek,tk,rk,Xpe,F_,Q_,T_,nk,kAt,QAt,Jpe,FAt,TAt,RAt,pl,k_,ik,zpe,St,Zpe=Et(()=>{Pt();Pt();Nl();qt();ek=Be("crypto");w_();tk=$e(S_()),rk=$e(nd()),Xpe=$e(zn()),F_=Be("util"),Q_=$e(Be("v8")),T_=$e(Be("zlib"));f_();D1();p_();h_();AE();fO();Yl();Vpe();L1();x_();Bd();b_();VS();ql();rh();jl();Dx();DU();kf();xo();nk=Ky(process.env.YARN_LOCKFILE_VERSION_OVERRIDE??8),kAt=3,QAt=/ *, */g,Jpe=/\/$/,FAt=32,TAt=(0,F_.promisify)(T_.default.gzip),RAt=(0,F_.promisify)(T_.default.gunzip),pl=(r=>(r.UpdateLockfile="update-lockfile",r.SkipBuild="skip-build",r))(pl||{}),k_={restoreLinkersCustomData:["linkersCustomData"],restoreResolutions:["accessibleLocators","conditionalLocators","disabledLocators","optionalBuilds","storedDescriptors","storedResolutions","storedPackages","lockFileChecksum"],restoreBuildState:["skippedBuilds","storedBuildState"]},ik=(o=>(o[o.NotProvided=0]="NotProvided",o[o.NotCompatible=1]="NotCompatible",o[o.NotCompatibleAggregate=2]="NotCompatibleAggregate",o))(ik||{}),zpe=t=>zs(`${kAt}`,t),St=class{constructor(e,{configuration:r}){this.resolutionAliases=new Map;this.workspaces=[];this.workspacesByCwd=new Map;this.workspacesByIdent=new Map;this.storedResolutions=new Map;this.storedDescriptors=new Map;this.storedPackages=new Map;this.storedChecksums=new Map;this.storedBuildState=new Map;this.accessibleLocators=new Set;this.conditionalLocators=new Set;this.disabledLocators=new Set;this.originalPackages=new Map;this.optionalBuilds=new Set;this.skippedBuilds=new Set;this.lockfileLastVersion=null;this.lockfileNeedsRefresh=!1;this.peerRequirements=new Map;this.peerWarnings=[];this.linkersCustomData=new Map;this.lockFileChecksum=null;this.installStateChecksum=null;this.configuration=r,this.cwd=e}static async find(e,r){if(!e.projectCwd)throw new it(`No project found in ${r}`);let o=e.projectCwd,a=r,n=null;for(;n!==e.projectCwd;){if(n=a,oe.existsSync(K.join(n,dr.manifest))){o=n;break}a=K.dirname(n)}let u=new St(e.projectCwd,{configuration:e});Ve.telemetry?.reportProject(u.cwd),await u.setupResolutions(),await u.setupWorkspaces(),Ve.telemetry?.reportWorkspaceCount(u.workspaces.length),Ve.telemetry?.reportDependencyCount(u.workspaces.reduce((C,T)=>C+T.manifest.dependencies.size+T.manifest.devDependencies.size,0));let A=u.tryWorkspaceByCwd(o);if(A)return{project:u,workspace:A,locator:A.anchoredLocator};let p=await u.findLocatorForLocation(`${o}/`,{strict:!0});if(p)return{project:u,locator:p,workspace:null};let h=Ot(e,u.cwd,yt.PATH),E=Ot(e,K.relative(u.cwd,o),yt.PATH),I=`- If ${h} isn't intended to be a project, remove any yarn.lock and/or package.json file there.`,v=`- If ${h} is intended to be a project, it might be that you forgot to list ${E} in its workspace configuration.`,b=`- Finally, if ${h} is fine and you intend ${E} to be treated as a completely separate project (not even a workspace), create an empty yarn.lock file in it.`;throw new it(`The nearest package directory (${Ot(e,o,yt.PATH)}) doesn't seem to be part of the project declared in ${Ot(e,u.cwd,yt.PATH)}. + +${[I,v,b].join(` +`)}`)}async setupResolutions(){this.storedResolutions=new Map,this.storedDescriptors=new Map,this.storedPackages=new Map,this.lockFileChecksum=null;let e=K.join(this.cwd,dr.lockfile),r=this.configuration.get("defaultLanguageName");if(oe.existsSync(e)){let o=await oe.readFilePromise(e,"utf8");this.lockFileChecksum=zpe(o);let a=Vi(o);if(a.__metadata){let n=a.__metadata.version,u=a.__metadata.cacheKey;this.lockfileLastVersion=n,this.lockfileNeedsRefresh=n<nk;for(let A of Object.keys(a)){if(A==="__metadata")continue;let p=a[A];if(typeof p.resolution>"u")throw new Error(`Assertion failed: Expected the lockfile entry to have a resolution field (${A})`);let h=xf(p.resolution,!0),E=new Mt;E.load(p,{yamlCompatibilityMode:!0});let I=E.version,v=E.languageName||r,b=p.linkType.toUpperCase(),C=p.conditions??null,T=E.dependencies,L=E.peerDependencies,U=E.dependenciesMeta,J=E.peerDependenciesMeta,te=E.bin;if(p.checksum!=null){let pe=typeof u<"u"&&!p.checksum.includes("/")?`${u}/${p.checksum}`:p.checksum;this.storedChecksums.set(h.locatorHash,pe)}let le={...h,version:I,languageName:v,linkType:b,conditions:C,dependencies:T,peerDependencies:L,dependenciesMeta:U,peerDependenciesMeta:J,bin:te};this.originalPackages.set(le.locatorHash,le);for(let pe of A.split(QAt)){let Ae=nh(pe);n<=6&&(Ae=this.configuration.normalizeDependency(Ae),Ae=In(Ae,Ae.range.replace(/^patch:[^@]+@(?!npm(:|%3A))/,"$1npm%3A"))),this.storedDescriptors.set(Ae.descriptorHash,Ae),this.storedResolutions.set(Ae.descriptorHash,h.locatorHash)}}}else o.includes("yarn lockfile v1")&&(this.lockfileLastVersion=-1)}}async setupWorkspaces(){this.workspaces=[],this.workspacesByCwd=new Map,this.workspacesByIdent=new Map;let e=new Set,r=(0,rk.default)(4),o=async(a,n)=>{if(e.has(n))return a;e.add(n);let u=new lC(n,{project:this});await r(()=>u.setup());let A=a.then(()=>{this.addWorkspace(u)});return Array.from(u.workspacesCwds).reduce(o,A)};await o(Promise.resolve(),this.cwd)}addWorkspace(e){let r=this.workspacesByIdent.get(e.anchoredLocator.identHash);if(typeof r<"u")throw new Error(`Duplicate workspace name ${cs(this.configuration,e.anchoredLocator)}: ${ue.fromPortablePath(e.cwd)} conflicts with ${ue.fromPortablePath(r.cwd)}`);this.workspaces.push(e),this.workspacesByCwd.set(e.cwd,e),this.workspacesByIdent.set(e.anchoredLocator.identHash,e)}get topLevelWorkspace(){return this.getWorkspaceByCwd(this.cwd)}tryWorkspaceByCwd(e){K.isAbsolute(e)||(e=K.resolve(this.cwd,e)),e=K.normalize(e).replace(/\/+$/,"");let r=this.workspacesByCwd.get(e);return r||null}getWorkspaceByCwd(e){let r=this.tryWorkspaceByCwd(e);if(!r)throw new Error(`Workspace not found (${e})`);return r}tryWorkspaceByFilePath(e){let r=null;for(let o of this.workspaces)K.relative(o.cwd,e).startsWith("../")||r&&r.cwd.length>=o.cwd.length||(r=o);return r||null}getWorkspaceByFilePath(e){let r=this.tryWorkspaceByFilePath(e);if(!r)throw new Error(`Workspace not found (${e})`);return r}tryWorkspaceByIdent(e){let r=this.workspacesByIdent.get(e.identHash);return typeof r>"u"?null:r}getWorkspaceByIdent(e){let r=this.tryWorkspaceByIdent(e);if(!r)throw new Error(`Workspace not found (${cs(this.configuration,e)})`);return r}tryWorkspaceByDescriptor(e){if(e.range.startsWith(Xn.protocol)){let o=e.range.slice(Xn.protocol.length);if(o!=="^"&&o!=="~"&&o!=="*"&&!ba(o))return this.tryWorkspaceByCwd(o)}let r=this.tryWorkspaceByIdent(e);return r===null||(Sf(e)&&(e=e1(e)),!r.accepts(e.range))?null:r}getWorkspaceByDescriptor(e){let r=this.tryWorkspaceByDescriptor(e);if(r===null)throw new Error(`Workspace not found (${qn(this.configuration,e)})`);return r}tryWorkspaceByLocator(e){let r=this.tryWorkspaceByIdent(e);return r===null||(Hc(e)&&(e=t1(e)),r.anchoredLocator.locatorHash!==e.locatorHash)?null:r}getWorkspaceByLocator(e){let r=this.tryWorkspaceByLocator(e);if(!r)throw new Error(`Workspace not found (${jr(this.configuration,e)})`);return r}deleteDescriptor(e){this.storedResolutions.delete(e),this.storedDescriptors.delete(e)}deleteLocator(e){this.originalPackages.delete(e),this.storedPackages.delete(e),this.accessibleLocators.delete(e)}forgetResolution(e){if("descriptorHash"in e){let r=this.storedResolutions.get(e.descriptorHash);this.deleteDescriptor(e.descriptorHash);let o=new Set(this.storedResolutions.values());typeof r<"u"&&!o.has(r)&&this.deleteLocator(r)}if("locatorHash"in e){this.deleteLocator(e.locatorHash);for(let[r,o]of this.storedResolutions)o===e.locatorHash&&this.deleteDescriptor(r)}}forgetTransientResolutions(){let e=this.configuration.makeResolver(),r=new Map;for(let[o,a]of this.storedResolutions.entries()){let n=r.get(a);n||r.set(a,n=new Set),n.add(o)}for(let o of this.originalPackages.values()){let a;try{a=e.shouldPersistResolution(o,{project:this,resolver:e})}catch{a=!1}if(!a){this.deleteLocator(o.locatorHash);let n=r.get(o.locatorHash);if(n){r.delete(o.locatorHash);for(let u of n)this.deleteDescriptor(u)}}}}forgetVirtualResolutions(){for(let e of this.storedPackages.values())for(let[r,o]of e.dependencies)Sf(o)&&e.dependencies.set(r,e1(o))}getDependencyMeta(e,r){let o={},n=this.topLevelWorkspace.manifest.dependenciesMeta.get(fn(e));if(!n)return o;let u=n.get(null);if(u&&Object.assign(o,u),r===null||!Xpe.default.valid(r))return o;for(let[A,p]of n)A!==null&&A===r&&Object.assign(o,p);return o}async findLocatorForLocation(e,{strict:r=!1}={}){let o=new Qi,a=this.configuration.getLinkers(),n={project:this,report:o};for(let u of a){let A=await u.findPackageLocator(e,n);if(A){if(r&&(await u.findPackageLocation(A,n)).replace(Jpe,"")!==e.replace(Jpe,""))continue;return A}}return null}async loadUserConfig(){let e=K.join(this.cwd,".pnp.cjs");await oe.existsPromise(e)&&vf(e).setup();let r=K.join(this.cwd,"yarn.config.cjs");return await oe.existsPromise(r)?vf(r):null}async preparePackage(e,{resolver:r,resolveOptions:o}){let a=await this.configuration.getPackageExtensions(),n=this.configuration.normalizePackage(e,{packageExtensions:a});for(let[u,A]of n.dependencies){let p=await this.configuration.reduceHook(E=>E.reduceDependency,A,this,n,A,{resolver:r,resolveOptions:o});if(!r1(A,p))throw new Error("Assertion failed: The descriptor ident cannot be changed through aliases");let h=r.bindDescriptor(p,n,o);n.dependencies.set(u,h)}return n}async resolveEverything(e){if(!this.workspacesByCwd||!this.workspacesByIdent)throw new Error("Workspaces must have been setup before calling this function");this.forgetVirtualResolutions();let r=new Map(this.originalPackages),o=[];e.lockfileOnly||this.forgetTransientResolutions();let a=e.resolver||this.configuration.makeResolver(),n=new sC(a);await n.setup(this,{report:e.report});let u=e.lockfileOnly?[new $b(a)]:[n,a],A=new vd([new oC(a),...u]),p=new vd([...u]),h=this.configuration.makeFetcher(),E=e.lockfileOnly?{project:this,report:e.report,resolver:A}:{project:this,report:e.report,resolver:A,fetchOptions:{project:this,cache:e.cache,checksums:this.storedChecksums,report:e.report,fetcher:h,cacheOptions:{mirrorWriteOnly:!0}}},I=new Map,v=new Map,b=new Map,C=new Map,T=new Map,L=new Map,U=this.topLevelWorkspace.anchoredLocator,J=new Set,te=[],le=_4(),pe=this.configuration.getSupportedArchitectures();await e.report.startProgressPromise(Xs.progressViaTitle(),async ce=>{let ne=async H=>{let lt=await Wy(async()=>await A.resolve(H,E),_e=>`${jr(this.configuration,H)}: ${_e}`);if(!n1(H,lt))throw new Error(`Assertion failed: The locator cannot be changed by the resolver (went from ${jr(this.configuration,H)} to ${jr(this.configuration,lt)})`);C.set(lt.locatorHash,lt),!r.delete(lt.locatorHash)&&!this.tryWorkspaceByLocator(lt)&&o.push(lt);let Qe=await this.preparePackage(lt,{resolver:A,resolveOptions:E}),be=Uc([...Qe.dependencies.values()].map(_e=>ht(_e)));return te.push(be),be.catch(()=>{}),v.set(Qe.locatorHash,Qe),Qe},ee=async H=>{let lt=T.get(H.locatorHash);if(typeof lt<"u")return lt;let Re=Promise.resolve().then(()=>ne(H));return T.set(H.locatorHash,Re),Re},Ie=async(H,lt)=>{let Re=await ht(lt);return I.set(H.descriptorHash,H),b.set(H.descriptorHash,Re.locatorHash),Re},ke=async H=>{ce.setTitle(qn(this.configuration,H));let lt=this.resolutionAliases.get(H.descriptorHash);if(typeof lt<"u")return Ie(H,this.storedDescriptors.get(lt));let Re=A.getResolutionDependencies(H,E),Qe=Object.fromEntries(await Uc(Object.entries(Re).map(async([Te,Je])=>{let He=A.bindDescriptor(Je,U,E),x=await ht(He);return J.add(x.locatorHash),[Te,x]}))),_e=(await Wy(async()=>await A.getCandidates(H,Qe,E),Te=>`${qn(this.configuration,H)}: ${Te}`))[0];if(typeof _e>"u")throw new zt(82,`${qn(this.configuration,H)}: No candidates found`);if(e.checkResolutions){let{locators:Te}=await p.getSatisfying(H,Qe,[_e],{...E,resolver:p});if(!Te.find(Je=>Je.locatorHash===_e.locatorHash))throw new zt(78,`Invalid resolution ${XI(this.configuration,H,_e)}`)}return I.set(H.descriptorHash,H),b.set(H.descriptorHash,_e.locatorHash),ee(_e)},ht=H=>{let lt=L.get(H.descriptorHash);if(typeof lt<"u")return lt;I.set(H.descriptorHash,H);let Re=Promise.resolve().then(()=>ke(H));return L.set(H.descriptorHash,Re),Re};for(let H of this.workspaces){let lt=H.anchoredDescriptor;te.push(ht(lt))}for(;te.length>0;){let H=[...te];te.length=0,await Uc(H)}});let Ae=sl(r.values(),ce=>this.tryWorkspaceByLocator(ce)?sl.skip:ce);if(o.length>0||Ae.length>0){let ce=new Set(this.workspaces.flatMap(H=>{let lt=v.get(H.anchoredLocator.locatorHash);if(!lt)throw new Error("Assertion failed: The workspace should have been resolved");return Array.from(lt.dependencies.values(),Re=>{let Qe=b.get(Re.descriptorHash);if(!Qe)throw new Error("Assertion failed: The resolution should have been registered");return Qe})})),ne=H=>ce.has(H.locatorHash)?"0":"1",ee=H=>xa(H),Ie=ks(o,[ne,ee]),ke=ks(Ae,[ne,ee]),ht=e.report.getRecommendedLength();Ie.length>0&&e.report.reportInfo(85,`${Ot(this.configuration,"+",yt.ADDED)} ${cS(this.configuration,Ie,ht)}`),ke.length>0&&e.report.reportInfo(85,`${Ot(this.configuration,"-",yt.REMOVED)} ${cS(this.configuration,ke,ht)}`)}let ye=new Set(this.resolutionAliases.values()),ae=new Set(v.keys()),we=new Set,Pe=new Map,g=[];NAt({project:this,accessibleLocators:we,volatileDescriptors:ye,optionalBuilds:ae,peerRequirements:Pe,peerWarnings:g,allDescriptors:I,allResolutions:b,allPackages:v});for(let ce of J)ae.delete(ce);for(let ce of ye)I.delete(ce),b.delete(ce);let Ee=new Set,De=new Set;for(let ce of v.values())ce.conditions!=null&&(!ae.has(ce.locatorHash)||(qS(ce,pe)||(qS(ce,le)&&e.report.reportWarningOnce(77,`${jr(this.configuration,ce)}: Your current architecture (${process.platform}-${process.arch}) is supported by this package, but is missing from the ${Ot(this.configuration,"supportedArchitectures",yt.SETTING)} setting`),De.add(ce.locatorHash)),Ee.add(ce.locatorHash)));this.storedResolutions=b,this.storedDescriptors=I,this.storedPackages=v,this.accessibleLocators=we,this.conditionalLocators=Ee,this.disabledLocators=De,this.originalPackages=C,this.optionalBuilds=ae,this.peerRequirements=Pe,this.peerWarnings=g}async fetchEverything({cache:e,report:r,fetcher:o,mode:a,persistProject:n=!0}){let u={mockedPackages:this.disabledLocators,unstablePackages:this.conditionalLocators},A=o||this.configuration.makeFetcher(),p={checksums:this.storedChecksums,project:this,cache:e,fetcher:A,report:r,cacheOptions:u},h=Array.from(new Set(ks(this.storedResolutions.values(),[C=>{let T=this.storedPackages.get(C);if(!T)throw new Error("Assertion failed: The locator should have been registered");return xa(T)}])));a==="update-lockfile"&&(h=h.filter(C=>!this.storedChecksums.has(C)));let E=!1,I=Xs.progressViaCounter(h.length);await r.reportProgress(I);let v=(0,rk.default)(FAt);if(await Uc(h.map(C=>v(async()=>{let T=this.storedPackages.get(C);if(!T)throw new Error("Assertion failed: The locator should have been registered");if(Hc(T))return;let L;try{L=await A.fetch(T,p)}catch(U){U.message=`${jr(this.configuration,T)}: ${U.message}`,r.reportExceptionOnce(U),E=U;return}L.checksum!=null?this.storedChecksums.set(T.locatorHash,L.checksum):this.storedChecksums.delete(T.locatorHash),L.releaseFs&&L.releaseFs()}).finally(()=>{I.tick()}))),E)throw E;let b=n&&a!=="update-lockfile"?await this.cacheCleanup({cache:e,report:r}):null;if(r.cacheMisses.size>0||b){let T=(await Promise.all([...r.cacheMisses].map(async Ae=>{let ye=this.storedPackages.get(Ae),ae=this.storedChecksums.get(Ae)??null,we=e.getLocatorPath(ye,ae);return(await oe.statPromise(we)).size}))).reduce((Ae,ye)=>Ae+ye,0)-(b?.size??0),L=r.cacheMisses.size,U=b?.count??0,J=`${nS(L,{zero:"No new packages",one:"A package was",more:`${Ot(this.configuration,L,yt.NUMBER)} packages were`})} added to the project`,te=`${nS(U,{zero:"none were",one:"one was",more:`${Ot(this.configuration,U,yt.NUMBER)} were`})} removed`,le=T!==0?` (${Ot(this.configuration,T,yt.SIZE_DIFF)})`:"",pe=U>0?L>0?`${J}, and ${te}${le}.`:`${J}, but ${te}${le}.`:`${J}${le}.`;r.reportInfo(13,pe)}}async linkEverything({cache:e,report:r,fetcher:o,mode:a}){let n={mockedPackages:this.disabledLocators,unstablePackages:this.conditionalLocators,skipIntegrityCheck:!0},u=o||this.configuration.makeFetcher(),A={checksums:this.storedChecksums,project:this,cache:e,fetcher:u,report:r,cacheOptions:n},p=this.configuration.getLinkers(),h={project:this,report:r},E=new Map(p.map(ce=>{let ne=ce.makeInstaller(h),ee=ce.getCustomDataKey(),Ie=this.linkersCustomData.get(ee);return typeof Ie<"u"&&ne.attachCustomData(Ie),[ce,ne]})),I=new Map,v=new Map,b=new Map,C=new Map(await Uc([...this.accessibleLocators].map(async ce=>{let ne=this.storedPackages.get(ce);if(!ne)throw new Error("Assertion failed: The locator should have been registered");return[ce,await u.fetch(ne,A)]}))),T=[],L=new Set,U=[];for(let ce of this.accessibleLocators){let ne=this.storedPackages.get(ce);if(typeof ne>"u")throw new Error("Assertion failed: The locator should have been registered");let ee=C.get(ne.locatorHash);if(typeof ee>"u")throw new Error("Assertion failed: The fetch result should have been registered");let Ie=[],ke=H=>{Ie.push(H)},ht=this.tryWorkspaceByLocator(ne);if(ht!==null){let H=[],{scripts:lt}=ht.manifest;for(let Qe of["preinstall","install","postinstall"])lt.has(Qe)&&H.push({type:0,script:Qe});try{for(let[Qe,be]of E)if(Qe.supportsPackage(ne,h)&&(await be.installPackage(ne,ee,{holdFetchResult:ke})).buildRequest!==null)throw new Error("Assertion failed: Linkers can't return build directives for workspaces; this responsibility befalls to the Yarn core")}finally{Ie.length===0?ee.releaseFs?.():T.push(Uc(Ie).catch(()=>{}).then(()=>{ee.releaseFs?.()}))}let Re=K.join(ee.packageFs.getRealPath(),ee.prefixPath);v.set(ne.locatorHash,Re),!Hc(ne)&&H.length>0&&b.set(ne.locatorHash,{buildDirectives:H,buildLocations:[Re]})}else{let H=p.find(Qe=>Qe.supportsPackage(ne,h));if(!H)throw new zt(12,`${jr(this.configuration,ne)} isn't supported by any available linker`);let lt=E.get(H);if(!lt)throw new Error("Assertion failed: The installer should have been registered");let Re;try{Re=await lt.installPackage(ne,ee,{holdFetchResult:ke})}finally{Ie.length===0?ee.releaseFs?.():T.push(Uc(Ie).then(()=>{}).then(()=>{ee.releaseFs?.()}))}I.set(ne.locatorHash,H),v.set(ne.locatorHash,Re.packageLocation),Re.buildRequest&&Re.packageLocation&&(Re.buildRequest.skipped?(L.add(ne.locatorHash),this.skippedBuilds.has(ne.locatorHash)||U.push([ne,Re.buildRequest.explain])):b.set(ne.locatorHash,{buildDirectives:Re.buildRequest.directives,buildLocations:[Re.packageLocation]}))}}let J=new Map;for(let ce of this.accessibleLocators){let ne=this.storedPackages.get(ce);if(!ne)throw new Error("Assertion failed: The locator should have been registered");let ee=this.tryWorkspaceByLocator(ne)!==null,Ie=async(ke,ht)=>{let H=v.get(ne.locatorHash);if(typeof H>"u")throw new Error(`Assertion failed: The package (${jr(this.configuration,ne)}) should have been registered`);let lt=[];for(let Re of ne.dependencies.values()){let Qe=this.storedResolutions.get(Re.descriptorHash);if(typeof Qe>"u")throw new Error(`Assertion failed: The resolution (${qn(this.configuration,Re)}, from ${jr(this.configuration,ne)})should have been registered`);let be=this.storedPackages.get(Qe);if(typeof be>"u")throw new Error(`Assertion failed: The package (${Qe}, resolved from ${qn(this.configuration,Re)}) should have been registered`);let _e=this.tryWorkspaceByLocator(be)===null?I.get(Qe):null;if(typeof _e>"u")throw new Error(`Assertion failed: The package (${Qe}, resolved from ${qn(this.configuration,Re)}) should have been registered`);_e===ke||_e===null?v.get(be.locatorHash)!==null&<.push([Re,be]):!ee&&H!==null&&Gy(J,Qe).push(H)}H!==null&&await ht.attachInternalDependencies(ne,lt)};if(ee)for(let[ke,ht]of E)ke.supportsPackage(ne,h)&&await Ie(ke,ht);else{let ke=I.get(ne.locatorHash);if(!ke)throw new Error("Assertion failed: The linker should have been found");let ht=E.get(ke);if(!ht)throw new Error("Assertion failed: The installer should have been registered");await Ie(ke,ht)}}for(let[ce,ne]of J){let ee=this.storedPackages.get(ce);if(!ee)throw new Error("Assertion failed: The package should have been registered");let Ie=I.get(ee.locatorHash);if(!Ie)throw new Error("Assertion failed: The linker should have been found");let ke=E.get(Ie);if(!ke)throw new Error("Assertion failed: The installer should have been registered");await ke.attachExternalDependents(ee,ne)}let te=new Map;for(let[ce,ne]of E){let ee=await ne.finalizeInstall();for(let Ie of ee?.records??[])Ie.buildRequest.skipped?(L.add(Ie.locator.locatorHash),this.skippedBuilds.has(Ie.locator.locatorHash)||U.push([Ie.locator,Ie.buildRequest.explain])):b.set(Ie.locator.locatorHash,{buildDirectives:Ie.buildRequest.directives,buildLocations:Ie.buildLocations});typeof ee?.customData<"u"&&te.set(ce.getCustomDataKey(),ee.customData)}if(this.linkersCustomData=te,await Uc(T),a==="skip-build")return;for(let[,ce]of ks(U,([ne])=>xa(ne)))ce(r);let le=new Set(this.storedPackages.keys()),pe=new Set(b.keys());for(let ce of pe)le.delete(ce);let Ae=(0,ek.createHash)("sha512");Ae.update(process.versions.node),await this.configuration.triggerHook(ce=>ce.globalHashGeneration,this,ce=>{Ae.update("\0"),Ae.update(ce)});let ye=Ae.digest("hex"),ae=new Map,we=ce=>{let ne=ae.get(ce.locatorHash);if(typeof ne<"u")return ne;let ee=this.storedPackages.get(ce.locatorHash);if(typeof ee>"u")throw new Error("Assertion failed: The package should have been registered");let Ie=(0,ek.createHash)("sha512");Ie.update(ce.locatorHash),ae.set(ce.locatorHash,"<recursive>");for(let ke of ee.dependencies.values()){let ht=this.storedResolutions.get(ke.descriptorHash);if(typeof ht>"u")throw new Error(`Assertion failed: The resolution (${qn(this.configuration,ke)}) should have been registered`);let H=this.storedPackages.get(ht);if(typeof H>"u")throw new Error("Assertion failed: The package should have been registered");Ie.update(we(H))}return ne=Ie.digest("hex"),ae.set(ce.locatorHash,ne),ne},Pe=(ce,ne)=>{let ee=(0,ek.createHash)("sha512");ee.update(ye),ee.update(we(ce));for(let Ie of ne)ee.update(Ie);return ee.digest("hex")},g=new Map,Ee=!1,De=ce=>{let ne=new Set([ce.locatorHash]);for(let ee of ne){let Ie=this.storedPackages.get(ee);if(!Ie)throw new Error("Assertion failed: The package should have been registered");for(let ke of Ie.dependencies.values()){let ht=this.storedResolutions.get(ke.descriptorHash);if(!ht)throw new Error(`Assertion failed: The resolution (${qn(this.configuration,ke)}) should have been registered`);if(ht!==ce.locatorHash&&pe.has(ht))return!1;let H=this.storedPackages.get(ht);if(!H)throw new Error("Assertion failed: The package should have been registered");let lt=this.tryWorkspaceByLocator(H);if(lt){if(lt.anchoredLocator.locatorHash!==ce.locatorHash&&pe.has(lt.anchoredLocator.locatorHash))return!1;ne.add(lt.anchoredLocator.locatorHash)}ne.add(ht)}}return!0};for(;pe.size>0;){let ce=pe.size,ne=[];for(let ee of pe){let Ie=this.storedPackages.get(ee);if(!Ie)throw new Error("Assertion failed: The package should have been registered");if(!De(Ie))continue;let ke=b.get(Ie.locatorHash);if(!ke)throw new Error("Assertion failed: The build directive should have been registered");let ht=Pe(Ie,ke.buildLocations);if(this.storedBuildState.get(Ie.locatorHash)===ht){g.set(Ie.locatorHash,ht),pe.delete(ee);continue}Ee||(await this.persistInstallStateFile(),Ee=!0),this.storedBuildState.has(Ie.locatorHash)?r.reportInfo(8,`${jr(this.configuration,Ie)} must be rebuilt because its dependency tree changed`):r.reportInfo(7,`${jr(this.configuration,Ie)} must be built because it never has been before or the last one failed`);let H=ke.buildLocations.map(async lt=>{if(!K.isAbsolute(lt))throw new Error(`Assertion failed: Expected the build location to be absolute (not ${lt})`);for(let Re of ke.buildDirectives){let Qe=`# This file contains the result of Yarn building a package (${xa(Ie)}) +`;switch(Re.type){case 0:Qe+=`# Script name: ${Re.script} +`;break;case 1:Qe+=`# Script code: ${Re.script} +`;break}let be=null;if(!await oe.mktempPromise(async Te=>{let Je=K.join(Te,"build.log"),{stdout:He,stderr:x}=this.configuration.getSubprocessStreams(Je,{header:Qe,prefix:jr(this.configuration,Ie),report:r}),w;try{switch(Re.type){case 0:w=await Vx(Ie,Re.script,[],{cwd:lt,project:this,stdin:be,stdout:He,stderr:x});break;case 1:w=await wU(Ie,Re.script,[],{cwd:lt,project:this,stdin:be,stdout:He,stderr:x});break}}catch(F){x.write(F.stack),w=1}if(He.end(),x.end(),w===0)return!0;oe.detachTemp(Te);let S=`${jr(this.configuration,Ie)} couldn't be built successfully (exit code ${Ot(this.configuration,w,yt.NUMBER)}, logs can be found here: ${Ot(this.configuration,Je,yt.PATH)})`,y=this.optionalBuilds.has(Ie.locatorHash);return y?r.reportInfo(9,S):r.reportError(9,S),Jce&&r.reportFold(ue.fromPortablePath(Je),oe.readFileSync(Je,"utf8")),y}))return!1}return!0});ne.push(...H,Promise.allSettled(H).then(lt=>{pe.delete(ee),lt.every(Re=>Re.status==="fulfilled"&&Re.value===!0)&&g.set(Ie.locatorHash,ht)}))}if(await Uc(ne),ce===pe.size){let ee=Array.from(pe).map(Ie=>{let ke=this.storedPackages.get(Ie);if(!ke)throw new Error("Assertion failed: The package should have been registered");return jr(this.configuration,ke)}).join(", ");r.reportError(3,`Some packages have circular dependencies that make their build order unsatisfiable - as a result they won't be built (affected packages are: ${ee})`);break}}this.storedBuildState=g,this.skippedBuilds=L}async installWithNewReport(e,r){return(await Nt.start({configuration:this.configuration,json:e.json,stdout:e.stdout,forceSectionAlignment:!0,includeLogs:!e.json&&!e.quiet,includeVersion:!0},async a=>{await this.install({...r,report:a})})).exitCode()}async install(e){let r=this.configuration.get("nodeLinker");Ve.telemetry?.reportInstall(r);let o=!1;if(await e.report.startTimerPromise("Project validation",{skipIfEmpty:!0},async()=>{this.configuration.get("enableOfflineMode")&&e.report.reportWarning(90,"Offline work is enabled; Yarn won't fetch packages from the remote registry if it can avoid it"),await this.configuration.triggerHook(E=>E.validateProject,this,{reportWarning:(E,I)=>{e.report.reportWarning(E,I)},reportError:(E,I)=>{e.report.reportError(E,I),o=!0}})}),o)return;let a=await this.configuration.getPackageExtensions();for(let E of a.values())for(let[,I]of E)for(let v of I)v.status="inactive";let n=K.join(this.cwd,dr.lockfile),u=null;if(e.immutable)try{u=await oe.readFilePromise(n,"utf8")}catch(E){throw E.code==="ENOENT"?new zt(28,"The lockfile would have been created by this install, which is explicitly forbidden."):E}await e.report.startTimerPromise("Resolution step",async()=>{await this.resolveEverything(e)}),await e.report.startTimerPromise("Post-resolution validation",{skipIfEmpty:!0},async()=>{LAt(this,e.report);for(let[,E]of a)for(let[,I]of E)for(let v of I)if(v.userProvided){let b=Ot(this.configuration,v,yt.PACKAGE_EXTENSION);switch(v.status){case"inactive":e.report.reportWarning(68,`${b}: No matching package in the dependency tree; you may not need this rule anymore.`);break;case"redundant":e.report.reportWarning(69,`${b}: This rule seems redundant when applied on the original package; the extension may have been applied upstream.`);break}}if(u!==null){let E=Ug(u,this.generateLockfile());if(E!==u){let I=ppe(n,n,u,E,void 0,void 0,{maxEditLength:100});if(I){e.report.reportSeparator();for(let v of I.hunks){e.report.reportInfo(null,`@@ -${v.oldStart},${v.oldLines} +${v.newStart},${v.newLines} @@`);for(let b of v.lines)b.startsWith("+")?e.report.reportError(28,Ot(this.configuration,b,yt.ADDED)):b.startsWith("-")?e.report.reportError(28,Ot(this.configuration,b,yt.REMOVED)):e.report.reportInfo(null,Ot(this.configuration,b,"grey"))}e.report.reportSeparator()}throw new zt(28,"The lockfile would have been modified by this install, which is explicitly forbidden.")}}});for(let E of a.values())for(let[,I]of E)for(let v of I)v.userProvided&&v.status==="active"&&Ve.telemetry?.reportPackageExtension(yd(v,yt.PACKAGE_EXTENSION));await e.report.startTimerPromise("Fetch step",async()=>{await this.fetchEverything(e)});let A=e.immutable?[...new Set(this.configuration.get("immutablePatterns"))].sort():[],p=await Promise.all(A.map(async E=>MS(E,{cwd:this.cwd})));(typeof e.persistProject>"u"||e.persistProject)&&await this.persist(),await e.report.startTimerPromise("Link step",async()=>{if(e.mode==="update-lockfile"){e.report.reportWarning(73,`Skipped due to ${Ot(this.configuration,"mode=update-lockfile",yt.CODE)}`);return}await this.linkEverything(e);let E=await Promise.all(A.map(async I=>MS(I,{cwd:this.cwd})));for(let I=0;I<A.length;++I)p[I]!==E[I]&&e.report.reportError(64,`The checksum for ${A[I]} has been modified by this install, which is explicitly forbidden.`)}),await this.persistInstallStateFile();let h=!1;await e.report.startTimerPromise("Post-install validation",{skipIfEmpty:!0},async()=>{await this.configuration.triggerHook(E=>E.validateProjectAfterInstall,this,{reportWarning:(E,I)=>{e.report.reportWarning(E,I)},reportError:(E,I)=>{e.report.reportError(E,I),h=!0}})}),!h&&await this.configuration.triggerHook(E=>E.afterAllInstalled,this,e)}generateLockfile(){let e=new Map;for(let[n,u]of this.storedResolutions.entries()){let A=e.get(u);A||e.set(u,A=new Set),A.add(n)}let r={},{cacheKey:o}=Lr.getCacheKey(this.configuration);r.__metadata={version:nk,cacheKey:o};for(let[n,u]of e.entries()){let A=this.originalPackages.get(n);if(!A)continue;let p=[];for(let b of u){let C=this.storedDescriptors.get(b);if(!C)throw new Error("Assertion failed: The descriptor should have been registered");p.push(C)}let h=p.map(b=>Sa(b)).sort().join(", "),E=new Mt;E.version=A.linkType==="HARD"?A.version:"0.0.0-use.local",E.languageName=A.languageName,E.dependencies=new Map(A.dependencies),E.peerDependencies=new Map(A.peerDependencies),E.dependenciesMeta=new Map(A.dependenciesMeta),E.peerDependenciesMeta=new Map(A.peerDependenciesMeta),E.bin=new Map(A.bin);let I,v=this.storedChecksums.get(A.locatorHash);if(typeof v<"u"){let b=v.indexOf("/");if(b===-1)throw new Error("Assertion failed: Expected the checksum to reference its cache key");let C=v.slice(0,b),T=v.slice(b+1);C===o?I=T:I=v}r[h]={...E.exportTo({},{compatibilityMode:!1}),linkType:A.linkType.toLowerCase(),resolution:xa(A),checksum:I,conditions:A.conditions||void 0}}return`${[`# This file is generated by running "yarn install" inside your project. +`,`# Manual changes might be lost - proceed with caution! +`].join("")} +`+Ba(r)}async persistLockfile(){let e=K.join(this.cwd,dr.lockfile),r="";try{r=await oe.readFilePromise(e,"utf8")}catch{}let o=this.generateLockfile(),a=Ug(r,o);a!==r&&(await oe.writeFilePromise(e,a),this.lockFileChecksum=zpe(a),this.lockfileNeedsRefresh=!1)}async persistInstallStateFile(){let e=[];for(let u of Object.values(k_))e.push(...u);let r=(0,tk.default)(this,e),o=Q_.default.serialize(r),a=zs(o);if(this.installStateChecksum===a)return;let n=this.configuration.get("installStatePath");await oe.mkdirPromise(K.dirname(n),{recursive:!0}),await oe.writeFilePromise(n,await TAt(o)),this.installStateChecksum=a}async restoreInstallState({restoreLinkersCustomData:e=!0,restoreResolutions:r=!0,restoreBuildState:o=!0}={}){let a=this.configuration.get("installStatePath"),n;try{let u=await RAt(await oe.readFilePromise(a));n=Q_.default.deserialize(u),this.installStateChecksum=zs(u)}catch{r&&await this.applyLightResolution();return}e&&typeof n.linkersCustomData<"u"&&(this.linkersCustomData=n.linkersCustomData),o&&Object.assign(this,(0,tk.default)(n,k_.restoreBuildState)),r&&(n.lockFileChecksum===this.lockFileChecksum?Object.assign(this,(0,tk.default)(n,k_.restoreResolutions)):await this.applyLightResolution())}async applyLightResolution(){await this.resolveEverything({lockfileOnly:!0,report:new Qi}),await this.persistInstallStateFile()}async persist(){let e=(0,rk.default)(4);await Promise.all([this.persistLockfile(),...this.workspaces.map(r=>e(()=>r.persistManifest()))])}async cacheCleanup({cache:e,report:r}){if(this.configuration.get("enableGlobalCache"))return null;let o=new Set([".gitignore"]);if(!IO(e.cwd,this.cwd)||!await oe.existsPromise(e.cwd))return null;let a=[];for(let u of await oe.readdirPromise(e.cwd)){if(o.has(u))continue;let A=K.resolve(e.cwd,u);e.markedFiles.has(A)||(e.immutable?r.reportError(56,`${Ot(this.configuration,K.basename(A),"magenta")} appears to be unused and would be marked for deletion, but the cache is immutable`):a.push(oe.lstatPromise(A).then(async p=>(await oe.removePromise(A),p.size))))}if(a.length===0)return null;let n=await Promise.all(a);return{count:a.length,size:n.reduce((u,A)=>u+A,0)}}}});function MAt(t){let o=Math.floor(t.timeNow/864e5),a=t.updateInterval*864e5,n=t.state.lastUpdate??t.timeNow+a+Math.floor(a*t.randomInitialInterval),u=n+a,A=t.state.lastTips??o*864e5,p=A+864e5+8*36e5-t.timeZone,h=u<=t.timeNow,E=p<=t.timeNow,I=null;return(h||E||!t.state.lastUpdate||!t.state.lastTips)&&(I={},I.lastUpdate=h?t.timeNow:n,I.lastTips=A,I.blocks=h?{}:t.state.blocks,I.displayedTips=t.state.displayedTips),{nextState:I,triggerUpdate:h,triggerTips:E,nextTips:E?o*864e5:A}}var cC,$pe=Et(()=>{Pt();N1();rh();Bx();jl();kf();cC=class{constructor(e,r){this.values=new Map;this.hits=new Map;this.enumerators=new Map;this.nextTips=0;this.displayedTips=[];this.shouldCommitTips=!1;this.configuration=e;let o=this.getRegistryPath();this.isNew=!oe.existsSync(o),this.shouldShowTips=!1,this.sendReport(r),this.startBuffer()}commitTips(){this.shouldShowTips&&(this.shouldCommitTips=!0)}selectTip(e){let r=new Set(this.displayedTips),o=A=>A&&tn?bf(tn,A):!1,a=e.map((A,p)=>p).filter(A=>e[A]&&o(e[A]?.selector));if(a.length===0)return null;let n=a.filter(A=>!r.has(A));if(n.length===0){let A=Math.floor(a.length*.2);this.displayedTips=A>0?this.displayedTips.slice(-A):[],n=a.filter(p=>!r.has(p))}let u=n[Math.floor(Math.random()*n.length)];return this.displayedTips.push(u),this.commitTips(),e[u]}reportVersion(e){this.reportValue("version",e.replace(/-git\..*/,"-git"))}reportCommandName(e){this.reportValue("commandName",e||"<none>")}reportPluginName(e){this.reportValue("pluginName",e)}reportProject(e){this.reportEnumerator("projectCount",e)}reportInstall(e){this.reportHit("installCount",e)}reportPackageExtension(e){this.reportValue("packageExtension",e)}reportWorkspaceCount(e){this.reportValue("workspaceCount",String(e))}reportDependencyCount(e){this.reportValue("dependencyCount",String(e))}reportValue(e,r){dd(this.values,e).add(r)}reportEnumerator(e,r){dd(this.enumerators,e).add(zs(r))}reportHit(e,r="*"){let o=Yy(this.hits,e),a=ol(o,r,()=>0);o.set(r,a+1)}getRegistryPath(){let e=this.configuration.get("globalFolder");return K.join(e,"telemetry.json")}sendReport(e){let r=this.getRegistryPath(),o;try{o=oe.readJsonSync(r)}catch{o={}}let{nextState:a,triggerUpdate:n,triggerTips:u,nextTips:A}=MAt({state:o,timeNow:Date.now(),timeZone:new Date().getTimezoneOffset()*60*1e3,randomInitialInterval:Math.random(),updateInterval:this.configuration.get("telemetryInterval")});if(this.nextTips=A,this.displayedTips=o.displayedTips??[],a!==null)try{oe.mkdirSync(K.dirname(r),{recursive:!0}),oe.writeJsonSync(r,a)}catch{return!1}if(u&&this.configuration.get("enableTips")&&(this.shouldShowTips=!0),n){let p=o.blocks??{};if(Object.keys(p).length===0){let h=`https://browser-http-intake.logs.datadoghq.eu/v1/input/${e}?ddsource=yarn`,E=I=>U4(h,I,{configuration:this.configuration}).catch(()=>{});for(let[I,v]of Object.entries(o.blocks??{})){if(Object.keys(v).length===0)continue;let b=v;b.userId=I,b.reportType="primary";for(let L of Object.keys(b.enumerators??{}))b.enumerators[L]=b.enumerators[L].length;E(b);let C=new Map,T=20;for(let[L,U]of Object.entries(b.values))U.length>0&&C.set(L,U.slice(0,T));for(;C.size>0;){let L={};L.userId=I,L.reportType="secondary",L.metrics={};for(let[U,J]of C)L.metrics[U]=J.shift(),J.length===0&&C.delete(U);E(L)}}}}return!0}applyChanges(){let e=this.getRegistryPath(),r;try{r=oe.readJsonSync(e)}catch{r={}}let o=this.configuration.get("telemetryUserId")??"*",a=r.blocks=r.blocks??{},n=a[o]=a[o]??{};for(let u of this.hits.keys()){let A=n.hits=n.hits??{},p=A[u]=A[u]??{};for(let[h,E]of this.hits.get(u))p[h]=(p[h]??0)+E}for(let u of["values","enumerators"])for(let A of this[u].keys()){let p=n[u]=n[u]??{};p[A]=[...new Set([...p[A]??[],...this[u].get(A)??[]])]}this.shouldCommitTips&&(r.lastTips=this.nextTips,r.displayedTips=this.displayedTips),oe.mkdirSync(K.dirname(e),{recursive:!0}),oe.writeJsonSync(e,r)}startBuffer(){process.on("exit",()=>{try{this.applyChanges()}catch{}})}}});var s2={};Kt(s2,{BuildDirectiveType:()=>zb,CACHE_CHECKPOINT:()=>A_,CACHE_VERSION:()=>Jb,Cache:()=>Lr,Configuration:()=>Ve,DEFAULT_RC_FILENAME:()=>W4,FormatType:()=>Qle,InstallMode:()=>pl,LEGACY_PLUGINS:()=>B1,LOCKFILE_VERSION:()=>nk,LegacyMigrationResolver:()=>sC,LightReport:()=>AA,LinkType:()=>Jy,LockfileResolver:()=>oC,Manifest:()=>Mt,MessageName:()=>wr,MultiFetcher:()=>pE,PackageExtensionStatus:()=>DL,PackageExtensionType:()=>vL,PeerWarningType:()=>ik,Project:()=>St,Report:()=>Xs,ReportError:()=>zt,SettingsType:()=>v1,StreamReport:()=>Nt,TAG_REGEXP:()=>QE,TelemetryManager:()=>cC,ThrowReport:()=>Qi,VirtualFetcher:()=>hE,WindowsLinkType:()=>kx,Workspace:()=>lC,WorkspaceFetcher:()=>dE,WorkspaceResolver:()=>Xn,YarnVersion:()=>tn,execUtils:()=>Ur,folderUtils:()=>WS,formatUtils:()=>de,hashUtils:()=>wn,httpUtils:()=>rn,miscUtils:()=>je,nodeUtils:()=>Ji,parseMessageName:()=>fP,reportOptionDeprecations:()=>NE,scriptUtils:()=>un,semverUtils:()=>kr,stringifyMessageName:()=>Wu,structUtils:()=>W,tgzUtils:()=>Xi,treeUtils:()=>$s});var Ye=Et(()=>{Px();VS();ql();rh();Bx();jl();Dx();DU();kf();xo();$fe();ope();f_();D1();D1();lpe();p_();cpe();h_();AE();pP();AO();Zpe();Yl();L1();$pe();x_();pO();hO();Bd();b_();N1();Ine()});var she=_((K_t,a2)=>{"use strict";var UAt=process.env.TERM_PROGRAM==="Hyper",_At=process.platform==="win32",rhe=process.platform==="linux",R_={ballotDisabled:"\u2612",ballotOff:"\u2610",ballotOn:"\u2611",bullet:"\u2022",bulletWhite:"\u25E6",fullBlock:"\u2588",heart:"\u2764",identicalTo:"\u2261",line:"\u2500",mark:"\u203B",middot:"\xB7",minus:"\uFF0D",multiplication:"\xD7",obelus:"\xF7",pencilDownRight:"\u270E",pencilRight:"\u270F",pencilUpRight:"\u2710",percent:"%",pilcrow2:"\u2761",pilcrow:"\xB6",plusMinus:"\xB1",section:"\xA7",starsOff:"\u2606",starsOn:"\u2605",upDownArrow:"\u2195"},nhe=Object.assign({},R_,{check:"\u221A",cross:"\xD7",ellipsisLarge:"...",ellipsis:"...",info:"i",question:"?",questionSmall:"?",pointer:">",pointerSmall:"\xBB",radioOff:"( )",radioOn:"(*)",warning:"\u203C"}),ihe=Object.assign({},R_,{ballotCross:"\u2718",check:"\u2714",cross:"\u2716",ellipsisLarge:"\u22EF",ellipsis:"\u2026",info:"\u2139",question:"?",questionFull:"\uFF1F",questionSmall:"\uFE56",pointer:rhe?"\u25B8":"\u276F",pointerSmall:rhe?"\u2023":"\u203A",radioOff:"\u25EF",radioOn:"\u25C9",warning:"\u26A0"});a2.exports=_At&&!UAt?nhe:ihe;Reflect.defineProperty(a2.exports,"common",{enumerable:!1,value:R_});Reflect.defineProperty(a2.exports,"windows",{enumerable:!1,value:nhe});Reflect.defineProperty(a2.exports,"other",{enumerable:!1,value:ihe})});var Vc=_((J_t,N_)=>{"use strict";var HAt=t=>t!==null&&typeof t=="object"&&!Array.isArray(t),jAt=/[\u001b\u009b][[\]#;?()]*(?:(?:(?:[^\W_]*;?[^\W_]*)\u0007)|(?:(?:[0-9]{1,4}(;[0-9]{0,4})*)?[~0-9=<>cf-nqrtyA-PRZ]))/g,ohe=()=>{let t={enabled:!0,visible:!0,styles:{},keys:{}};"FORCE_COLOR"in process.env&&(t.enabled=process.env.FORCE_COLOR!=="0");let e=n=>{let u=n.open=`\x1B[${n.codes[0]}m`,A=n.close=`\x1B[${n.codes[1]}m`,p=n.regex=new RegExp(`\\u001b\\[${n.codes[1]}m`,"g");return n.wrap=(h,E)=>{h.includes(A)&&(h=h.replace(p,A+u));let I=u+h+A;return E?I.replace(/\r*\n/g,`${A}$&${u}`):I},n},r=(n,u,A)=>typeof n=="function"?n(u):n.wrap(u,A),o=(n,u)=>{if(n===""||n==null)return"";if(t.enabled===!1)return n;if(t.visible===!1)return"";let A=""+n,p=A.includes(` +`),h=u.length;for(h>0&&u.includes("unstyle")&&(u=[...new Set(["unstyle",...u])].reverse());h-- >0;)A=r(t.styles[u[h]],A,p);return A},a=(n,u,A)=>{t.styles[n]=e({name:n,codes:u}),(t.keys[A]||(t.keys[A]=[])).push(n),Reflect.defineProperty(t,n,{configurable:!0,enumerable:!0,set(h){t.alias(n,h)},get(){let h=E=>o(E,h.stack);return Reflect.setPrototypeOf(h,t),h.stack=this.stack?this.stack.concat(n):[n],h}})};return a("reset",[0,0],"modifier"),a("bold",[1,22],"modifier"),a("dim",[2,22],"modifier"),a("italic",[3,23],"modifier"),a("underline",[4,24],"modifier"),a("inverse",[7,27],"modifier"),a("hidden",[8,28],"modifier"),a("strikethrough",[9,29],"modifier"),a("black",[30,39],"color"),a("red",[31,39],"color"),a("green",[32,39],"color"),a("yellow",[33,39],"color"),a("blue",[34,39],"color"),a("magenta",[35,39],"color"),a("cyan",[36,39],"color"),a("white",[37,39],"color"),a("gray",[90,39],"color"),a("grey",[90,39],"color"),a("bgBlack",[40,49],"bg"),a("bgRed",[41,49],"bg"),a("bgGreen",[42,49],"bg"),a("bgYellow",[43,49],"bg"),a("bgBlue",[44,49],"bg"),a("bgMagenta",[45,49],"bg"),a("bgCyan",[46,49],"bg"),a("bgWhite",[47,49],"bg"),a("blackBright",[90,39],"bright"),a("redBright",[91,39],"bright"),a("greenBright",[92,39],"bright"),a("yellowBright",[93,39],"bright"),a("blueBright",[94,39],"bright"),a("magentaBright",[95,39],"bright"),a("cyanBright",[96,39],"bright"),a("whiteBright",[97,39],"bright"),a("bgBlackBright",[100,49],"bgBright"),a("bgRedBright",[101,49],"bgBright"),a("bgGreenBright",[102,49],"bgBright"),a("bgYellowBright",[103,49],"bgBright"),a("bgBlueBright",[104,49],"bgBright"),a("bgMagentaBright",[105,49],"bgBright"),a("bgCyanBright",[106,49],"bgBright"),a("bgWhiteBright",[107,49],"bgBright"),t.ansiRegex=jAt,t.hasColor=t.hasAnsi=n=>(t.ansiRegex.lastIndex=0,typeof n=="string"&&n!==""&&t.ansiRegex.test(n)),t.alias=(n,u)=>{let A=typeof u=="string"?t[u]:u;if(typeof A!="function")throw new TypeError("Expected alias to be the name of an existing color (string) or a function");A.stack||(Reflect.defineProperty(A,"name",{value:n}),t.styles[n]=A,A.stack=[n]),Reflect.defineProperty(t,n,{configurable:!0,enumerable:!0,set(p){t.alias(n,p)},get(){let p=h=>o(h,p.stack);return Reflect.setPrototypeOf(p,t),p.stack=this.stack?this.stack.concat(A.stack):A.stack,p}})},t.theme=n=>{if(!HAt(n))throw new TypeError("Expected theme to be an object");for(let u of Object.keys(n))t.alias(u,n[u]);return t},t.alias("unstyle",n=>typeof n=="string"&&n!==""?(t.ansiRegex.lastIndex=0,n.replace(t.ansiRegex,"")):""),t.alias("noop",n=>n),t.none=t.clear=t.noop,t.stripColor=t.unstyle,t.symbols=she(),t.define=a,t};N_.exports=ohe();N_.exports.create=ohe});var No=_(nn=>{"use strict";var qAt=Object.prototype.toString,rc=Vc(),ahe=!1,L_=[],lhe={yellow:"blue",cyan:"red",green:"magenta",black:"white",blue:"yellow",red:"cyan",magenta:"green",white:"black"};nn.longest=(t,e)=>t.reduce((r,o)=>Math.max(r,e?o[e].length:o.length),0);nn.hasColor=t=>!!t&&rc.hasColor(t);var ok=nn.isObject=t=>t!==null&&typeof t=="object"&&!Array.isArray(t);nn.nativeType=t=>qAt.call(t).slice(8,-1).toLowerCase().replace(/\s/g,"");nn.isAsyncFn=t=>nn.nativeType(t)==="asyncfunction";nn.isPrimitive=t=>t!=null&&typeof t!="object"&&typeof t!="function";nn.resolve=(t,e,...r)=>typeof e=="function"?e.call(t,...r):e;nn.scrollDown=(t=[])=>[...t.slice(1),t[0]];nn.scrollUp=(t=[])=>[t.pop(),...t];nn.reorder=(t=[])=>{let e=t.slice();return e.sort((r,o)=>r.index>o.index?1:r.index<o.index?-1:0),e};nn.swap=(t,e,r)=>{let o=t.length,a=r===o?0:r<0?o-1:r,n=t[e];t[e]=t[a],t[a]=n};nn.width=(t,e=80)=>{let r=t&&t.columns?t.columns:e;return t&&typeof t.getWindowSize=="function"&&(r=t.getWindowSize()[0]),process.platform==="win32"?r-1:r};nn.height=(t,e=20)=>{let r=t&&t.rows?t.rows:e;return t&&typeof t.getWindowSize=="function"&&(r=t.getWindowSize()[1]),r};nn.wordWrap=(t,e={})=>{if(!t)return t;typeof e=="number"&&(e={width:e});let{indent:r="",newline:o=` +`+r,width:a=80}=e,n=(o+r).match(/[^\S\n]/g)||[];a-=n.length;let u=`.{1,${a}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`,A=t.trim(),p=new RegExp(u,"g"),h=A.match(p)||[];return h=h.map(E=>E.replace(/\n$/,"")),e.padEnd&&(h=h.map(E=>E.padEnd(a," "))),e.padStart&&(h=h.map(E=>E.padStart(a," "))),r+h.join(o)};nn.unmute=t=>{let e=t.stack.find(o=>rc.keys.color.includes(o));return e?rc[e]:t.stack.find(o=>o.slice(2)==="bg")?rc[e.slice(2)]:o=>o};nn.pascal=t=>t?t[0].toUpperCase()+t.slice(1):"";nn.inverse=t=>{if(!t||!t.stack)return t;let e=t.stack.find(o=>rc.keys.color.includes(o));if(e){let o=rc["bg"+nn.pascal(e)];return o?o.black:t}let r=t.stack.find(o=>o.slice(0,2)==="bg");return r?rc[r.slice(2).toLowerCase()]||t:rc.none};nn.complement=t=>{if(!t||!t.stack)return t;let e=t.stack.find(o=>rc.keys.color.includes(o)),r=t.stack.find(o=>o.slice(0,2)==="bg");if(e&&!r)return rc[lhe[e]||e];if(r){let o=r.slice(2).toLowerCase(),a=lhe[o];return a&&rc["bg"+nn.pascal(a)]||t}return rc.none};nn.meridiem=t=>{let e=t.getHours(),r=t.getMinutes(),o=e>=12?"pm":"am";e=e%12;let a=e===0?12:e,n=r<10?"0"+r:r;return a+":"+n+" "+o};nn.set=(t={},e="",r)=>e.split(".").reduce((o,a,n,u)=>{let A=u.length-1>n?o[a]||{}:r;return!nn.isObject(A)&&n<u.length-1&&(A={}),o[a]=A},t);nn.get=(t={},e="",r)=>{let o=t[e]==null?e.split(".").reduce((a,n)=>a&&a[n],t):t[e];return o??r};nn.mixin=(t,e)=>{if(!ok(t))return e;if(!ok(e))return t;for(let r of Object.keys(e)){let o=Object.getOwnPropertyDescriptor(e,r);if(o.hasOwnProperty("value"))if(t.hasOwnProperty(r)&&ok(o.value)){let a=Object.getOwnPropertyDescriptor(t,r);ok(a.value)?t[r]=nn.merge({},t[r],e[r]):Reflect.defineProperty(t,r,o)}else Reflect.defineProperty(t,r,o);else Reflect.defineProperty(t,r,o)}return t};nn.merge=(...t)=>{let e={};for(let r of t)nn.mixin(e,r);return e};nn.mixinEmitter=(t,e)=>{let r=e.constructor.prototype;for(let o of Object.keys(r)){let a=r[o];typeof a=="function"?nn.define(t,o,a.bind(e)):nn.define(t,o,a)}};nn.onExit=t=>{let e=(r,o)=>{ahe||(ahe=!0,L_.forEach(a=>a()),r===!0&&process.exit(128+o))};L_.length===0&&(process.once("SIGTERM",e.bind(null,!0,15)),process.once("SIGINT",e.bind(null,!0,2)),process.once("exit",e)),L_.push(t)};nn.define=(t,e,r)=>{Reflect.defineProperty(t,e,{value:r})};nn.defineExport=(t,e,r)=>{let o;Reflect.defineProperty(t,e,{enumerable:!0,configurable:!0,set(a){o=a},get(){return o?o():r()}})}});var che=_(pC=>{"use strict";pC.ctrl={a:"first",b:"backward",c:"cancel",d:"deleteForward",e:"last",f:"forward",g:"reset",i:"tab",k:"cutForward",l:"reset",n:"newItem",m:"cancel",j:"submit",p:"search",r:"remove",s:"save",u:"undo",w:"cutLeft",x:"toggleCursor",v:"paste"};pC.shift={up:"shiftUp",down:"shiftDown",left:"shiftLeft",right:"shiftRight",tab:"prev"};pC.fn={up:"pageUp",down:"pageDown",left:"pageLeft",right:"pageRight",delete:"deleteForward"};pC.option={b:"backward",f:"forward",d:"cutRight",left:"cutLeft",up:"altUp",down:"altDown"};pC.keys={pageup:"pageUp",pagedown:"pageDown",home:"home",end:"end",cancel:"cancel",delete:"deleteForward",backspace:"delete",down:"down",enter:"submit",escape:"cancel",left:"left",space:"space",number:"number",return:"submit",right:"right",tab:"next",up:"up"}});var fhe=_((Z_t,Ahe)=>{"use strict";var uhe=Be("readline"),GAt=che(),YAt=/^(?:\x1b)([a-zA-Z0-9])$/,WAt=/^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/,VAt={OP:"f1",OQ:"f2",OR:"f3",OS:"f4","[11~":"f1","[12~":"f2","[13~":"f3","[14~":"f4","[[A":"f1","[[B":"f2","[[C":"f3","[[D":"f4","[[E":"f5","[15~":"f5","[17~":"f6","[18~":"f7","[19~":"f8","[20~":"f9","[21~":"f10","[23~":"f11","[24~":"f12","[A":"up","[B":"down","[C":"right","[D":"left","[E":"clear","[F":"end","[H":"home",OA:"up",OB:"down",OC:"right",OD:"left",OE:"clear",OF:"end",OH:"home","[1~":"home","[2~":"insert","[3~":"delete","[4~":"end","[5~":"pageup","[6~":"pagedown","[[5~":"pageup","[[6~":"pagedown","[7~":"home","[8~":"end","[a":"up","[b":"down","[c":"right","[d":"left","[e":"clear","[2$":"insert","[3$":"delete","[5$":"pageup","[6$":"pagedown","[7$":"home","[8$":"end",Oa:"up",Ob:"down",Oc:"right",Od:"left",Oe:"clear","[2^":"insert","[3^":"delete","[5^":"pageup","[6^":"pagedown","[7^":"home","[8^":"end","[Z":"tab"};function KAt(t){return["[a","[b","[c","[d","[e","[2$","[3$","[5$","[6$","[7$","[8$","[Z"].includes(t)}function JAt(t){return["Oa","Ob","Oc","Od","Oe","[2^","[3^","[5^","[6^","[7^","[8^"].includes(t)}var ak=(t="",e={})=>{let r,o={name:e.name,ctrl:!1,meta:!1,shift:!1,option:!1,sequence:t,raw:t,...e};if(Buffer.isBuffer(t)?t[0]>127&&t[1]===void 0?(t[0]-=128,t="\x1B"+String(t)):t=String(t):t!==void 0&&typeof t!="string"?t=String(t):t||(t=o.sequence||""),o.sequence=o.sequence||t||o.name,t==="\r")o.raw=void 0,o.name="return";else if(t===` +`)o.name="enter";else if(t===" ")o.name="tab";else if(t==="\b"||t==="\x7F"||t==="\x1B\x7F"||t==="\x1B\b")o.name="backspace",o.meta=t.charAt(0)==="\x1B";else if(t==="\x1B"||t==="\x1B\x1B")o.name="escape",o.meta=t.length===2;else if(t===" "||t==="\x1B ")o.name="space",o.meta=t.length===2;else if(t<="")o.name=String.fromCharCode(t.charCodeAt(0)+"a".charCodeAt(0)-1),o.ctrl=!0;else if(t.length===1&&t>="0"&&t<="9")o.name="number";else if(t.length===1&&t>="a"&&t<="z")o.name=t;else if(t.length===1&&t>="A"&&t<="Z")o.name=t.toLowerCase(),o.shift=!0;else if(r=YAt.exec(t))o.meta=!0,o.shift=/^[A-Z]$/.test(r[1]);else if(r=WAt.exec(t)){let a=[...t];a[0]==="\x1B"&&a[1]==="\x1B"&&(o.option=!0);let n=[r[1],r[2],r[4],r[6]].filter(Boolean).join(""),u=(r[3]||r[5]||1)-1;o.ctrl=!!(u&4),o.meta=!!(u&10),o.shift=!!(u&1),o.code=n,o.name=VAt[n],o.shift=KAt(n)||o.shift,o.ctrl=JAt(n)||o.ctrl}return o};ak.listen=(t={},e)=>{let{stdin:r}=t;if(!r||r!==process.stdin&&!r.isTTY)throw new Error("Invalid stream passed");let o=uhe.createInterface({terminal:!0,input:r});uhe.emitKeypressEvents(r,o);let a=(A,p)=>e(A,ak(A,p),o),n=r.isRaw;return r.isTTY&&r.setRawMode(!0),r.on("keypress",a),o.resume(),()=>{r.isTTY&&r.setRawMode(n),r.removeListener("keypress",a),o.pause(),o.close()}};ak.action=(t,e,r)=>{let o={...GAt,...r};return e.ctrl?(e.action=o.ctrl[e.name],e):e.option&&o.option?(e.action=o.option[e.name],e):e.shift?(e.action=o.shift[e.name],e):(e.action=o.keys[e.name],e)};Ahe.exports=ak});var hhe=_(($_t,phe)=>{"use strict";phe.exports=t=>{t.timers=t.timers||{};let e=t.options.timers;if(!!e)for(let r of Object.keys(e)){let o=e[r];typeof o=="number"&&(o={interval:o}),zAt(t,r,o)}};function zAt(t,e,r={}){let o=t.timers[e]={name:e,start:Date.now(),ms:0,tick:0},a=r.interval||120;o.frames=r.frames||[],o.loading=!0;let n=setInterval(()=>{o.ms=Date.now()-o.start,o.tick++,t.render()},a);return o.stop=()=>{o.loading=!1,clearInterval(n)},Reflect.defineProperty(o,"interval",{value:n}),t.once("close",()=>o.stop()),o.stop}});var dhe=_((e8t,ghe)=>{"use strict";var{define:XAt,width:ZAt}=No(),M_=class{constructor(e){let r=e.options;XAt(this,"_prompt",e),this.type=e.type,this.name=e.name,this.message="",this.header="",this.footer="",this.error="",this.hint="",this.input="",this.cursor=0,this.index=0,this.lines=0,this.tick=0,this.prompt="",this.buffer="",this.width=ZAt(r.stdout||process.stdout),Object.assign(this,r),this.name=this.name||this.message,this.message=this.message||this.name,this.symbols=e.symbols,this.styles=e.styles,this.required=new Set,this.cancelled=!1,this.submitted=!1}clone(){let e={...this};return e.status=this.status,e.buffer=Buffer.from(e.buffer),delete e.clone,e}set color(e){this._color=e}get color(){let e=this.prompt.styles;if(this.cancelled)return e.cancelled;if(this.submitted)return e.submitted;let r=this._color||e[this.status];return typeof r=="function"?r:e.pending}set loading(e){this._loading=e}get loading(){return typeof this._loading=="boolean"?this._loading:this.loadingChoices?"choices":!1}get status(){return this.cancelled?"cancelled":this.submitted?"submitted":"pending"}};ghe.exports=M_});var yhe=_((t8t,mhe)=>{"use strict";var O_=No(),eo=Vc(),U_={default:eo.noop,noop:eo.noop,set inverse(t){this._inverse=t},get inverse(){return this._inverse||O_.inverse(this.primary)},set complement(t){this._complement=t},get complement(){return this._complement||O_.complement(this.primary)},primary:eo.cyan,success:eo.green,danger:eo.magenta,strong:eo.bold,warning:eo.yellow,muted:eo.dim,disabled:eo.gray,dark:eo.dim.gray,underline:eo.underline,set info(t){this._info=t},get info(){return this._info||this.primary},set em(t){this._em=t},get em(){return this._em||this.primary.underline},set heading(t){this._heading=t},get heading(){return this._heading||this.muted.underline},set pending(t){this._pending=t},get pending(){return this._pending||this.primary},set submitted(t){this._submitted=t},get submitted(){return this._submitted||this.success},set cancelled(t){this._cancelled=t},get cancelled(){return this._cancelled||this.danger},set typing(t){this._typing=t},get typing(){return this._typing||this.dim},set placeholder(t){this._placeholder=t},get placeholder(){return this._placeholder||this.primary.dim},set highlight(t){this._highlight=t},get highlight(){return this._highlight||this.inverse}};U_.merge=(t={})=>{t.styles&&typeof t.styles.enabled=="boolean"&&(eo.enabled=t.styles.enabled),t.styles&&typeof t.styles.visible=="boolean"&&(eo.visible=t.styles.visible);let e=O_.merge({},U_,t.styles);delete e.merge;for(let r of Object.keys(eo))e.hasOwnProperty(r)||Reflect.defineProperty(e,r,{get:()=>eo[r]});for(let r of Object.keys(eo.styles))e.hasOwnProperty(r)||Reflect.defineProperty(e,r,{get:()=>eo[r]});return e};mhe.exports=U_});var Che=_((r8t,Ehe)=>{"use strict";var __=process.platform==="win32",Vf=Vc(),$At=No(),H_={...Vf.symbols,upDownDoubleArrow:"\u21D5",upDownDoubleArrow2:"\u2B0D",upDownArrow:"\u2195",asterisk:"*",asterism:"\u2042",bulletWhite:"\u25E6",electricArrow:"\u2301",ellipsisLarge:"\u22EF",ellipsisSmall:"\u2026",fullBlock:"\u2588",identicalTo:"\u2261",indicator:Vf.symbols.check,leftAngle:"\u2039",mark:"\u203B",minus:"\u2212",multiplication:"\xD7",obelus:"\xF7",percent:"%",pilcrow:"\xB6",pilcrow2:"\u2761",pencilUpRight:"\u2710",pencilDownRight:"\u270E",pencilRight:"\u270F",plus:"+",plusMinus:"\xB1",pointRight:"\u261E",rightAngle:"\u203A",section:"\xA7",hexagon:{off:"\u2B21",on:"\u2B22",disabled:"\u2B22"},ballot:{on:"\u2611",off:"\u2610",disabled:"\u2612"},stars:{on:"\u2605",off:"\u2606",disabled:"\u2606"},folder:{on:"\u25BC",off:"\u25B6",disabled:"\u25B6"},prefix:{pending:Vf.symbols.question,submitted:Vf.symbols.check,cancelled:Vf.symbols.cross},separator:{pending:Vf.symbols.pointerSmall,submitted:Vf.symbols.middot,cancelled:Vf.symbols.middot},radio:{off:__?"( )":"\u25EF",on:__?"(*)":"\u25C9",disabled:__?"(|)":"\u24BE"},numbers:["\u24EA","\u2460","\u2461","\u2462","\u2463","\u2464","\u2465","\u2466","\u2467","\u2468","\u2469","\u246A","\u246B","\u246C","\u246D","\u246E","\u246F","\u2470","\u2471","\u2472","\u2473","\u3251","\u3252","\u3253","\u3254","\u3255","\u3256","\u3257","\u3258","\u3259","\u325A","\u325B","\u325C","\u325D","\u325E","\u325F","\u32B1","\u32B2","\u32B3","\u32B4","\u32B5","\u32B6","\u32B7","\u32B8","\u32B9","\u32BA","\u32BB","\u32BC","\u32BD","\u32BE","\u32BF"]};H_.merge=t=>{let e=$At.merge({},Vf.symbols,H_,t.symbols);return delete e.merge,e};Ehe.exports=H_});var Ihe=_((n8t,whe)=>{"use strict";var eft=yhe(),tft=Che(),rft=No();whe.exports=t=>{t.options=rft.merge({},t.options.theme,t.options),t.symbols=tft.merge(t.options),t.styles=eft.merge(t.options)}});var She=_((Dhe,Phe)=>{"use strict";var Bhe=process.env.TERM_PROGRAM==="Apple_Terminal",nft=Vc(),j_=No(),Kc=Phe.exports=Dhe,Di="\x1B[",vhe="\x07",q_=!1,Ph=Kc.code={bell:vhe,beep:vhe,beginning:`${Di}G`,down:`${Di}J`,esc:Di,getPosition:`${Di}6n`,hide:`${Di}?25l`,line:`${Di}2K`,lineEnd:`${Di}K`,lineStart:`${Di}1K`,restorePosition:Di+(Bhe?"8":"u"),savePosition:Di+(Bhe?"7":"s"),screen:`${Di}2J`,show:`${Di}?25h`,up:`${Di}1J`},qd=Kc.cursor={get hidden(){return q_},hide(){return q_=!0,Ph.hide},show(){return q_=!1,Ph.show},forward:(t=1)=>`${Di}${t}C`,backward:(t=1)=>`${Di}${t}D`,nextLine:(t=1)=>`${Di}E`.repeat(t),prevLine:(t=1)=>`${Di}F`.repeat(t),up:(t=1)=>t?`${Di}${t}A`:"",down:(t=1)=>t?`${Di}${t}B`:"",right:(t=1)=>t?`${Di}${t}C`:"",left:(t=1)=>t?`${Di}${t}D`:"",to(t,e){return e?`${Di}${e+1};${t+1}H`:`${Di}${t+1}G`},move(t=0,e=0){let r="";return r+=t<0?qd.left(-t):t>0?qd.right(t):"",r+=e<0?qd.up(-e):e>0?qd.down(e):"",r},restore(t={}){let{after:e,cursor:r,initial:o,input:a,prompt:n,size:u,value:A}=t;if(o=j_.isPrimitive(o)?String(o):"",a=j_.isPrimitive(a)?String(a):"",A=j_.isPrimitive(A)?String(A):"",u){let p=Kc.cursor.up(u)+Kc.cursor.to(n.length),h=a.length-r;return h>0&&(p+=Kc.cursor.left(h)),p}if(A||e){let p=!a&&!!o?-o.length:-a.length+r;return e&&(p-=e.length),a===""&&o&&!n.includes(o)&&(p+=o.length),Kc.cursor.move(p)}}},G_=Kc.erase={screen:Ph.screen,up:Ph.up,down:Ph.down,line:Ph.line,lineEnd:Ph.lineEnd,lineStart:Ph.lineStart,lines(t){let e="";for(let r=0;r<t;r++)e+=Kc.erase.line+(r<t-1?Kc.cursor.up(1):"");return t&&(e+=Kc.code.beginning),e}};Kc.clear=(t="",e=process.stdout.columns)=>{if(!e)return G_.line+qd.to(0);let r=n=>[...nft.unstyle(n)].length,o=t.split(/\r?\n/),a=0;for(let n of o)a+=1+Math.floor(Math.max(r(n)-1,0)/e);return(G_.line+qd.prevLine()).repeat(a-1)+G_.line+qd.to(0)}});var hC=_((i8t,bhe)=>{"use strict";var ift=Be("events"),xhe=Vc(),Y_=fhe(),sft=hhe(),oft=dhe(),aft=Ihe(),Ta=No(),Gd=She(),l2=class extends ift{constructor(e={}){super(),this.name=e.name,this.type=e.type,this.options=e,aft(this),sft(this),this.state=new oft(this),this.initial=[e.initial,e.default].find(r=>r!=null),this.stdout=e.stdout||process.stdout,this.stdin=e.stdin||process.stdin,this.scale=e.scale||1,this.term=this.options.term||process.env.TERM_PROGRAM,this.margin=cft(this.options.margin),this.setMaxListeners(0),lft(this)}async keypress(e,r={}){this.keypressed=!0;let o=Y_.action(e,Y_(e,r),this.options.actions);this.state.keypress=o,this.emit("keypress",e,o),this.emit("state",this.state.clone());let a=this.options[o.action]||this[o.action]||this.dispatch;if(typeof a=="function")return await a.call(this,e,o);this.alert()}alert(){delete this.state.alert,this.options.show===!1?this.emit("alert"):this.stdout.write(Gd.code.beep)}cursorHide(){this.stdout.write(Gd.cursor.hide()),Ta.onExit(()=>this.cursorShow())}cursorShow(){this.stdout.write(Gd.cursor.show())}write(e){!e||(this.stdout&&this.state.show!==!1&&this.stdout.write(e),this.state.buffer+=e)}clear(e=0){let r=this.state.buffer;this.state.buffer="",!(!r&&!e||this.options.show===!1)&&this.stdout.write(Gd.cursor.down(e)+Gd.clear(r,this.width))}restore(){if(this.state.closed||this.options.show===!1)return;let{prompt:e,after:r,rest:o}=this.sections(),{cursor:a,initial:n="",input:u="",value:A=""}=this,p=this.state.size=o.length,h={after:r,cursor:a,initial:n,input:u,prompt:e,size:p,value:A},E=Gd.cursor.restore(h);E&&this.stdout.write(E)}sections(){let{buffer:e,input:r,prompt:o}=this.state;o=xhe.unstyle(o);let a=xhe.unstyle(e),n=a.indexOf(o),u=a.slice(0,n),p=a.slice(n).split(` +`),h=p[0],E=p[p.length-1],v=(o+(r?" "+r:"")).length,b=v<h.length?h.slice(v+1):"";return{header:u,prompt:h,after:b,rest:p.slice(1),last:E}}async submit(){this.state.submitted=!0,this.state.validating=!0,this.options.onSubmit&&await this.options.onSubmit.call(this,this.name,this.value,this);let e=this.state.error||await this.validate(this.value,this.state);if(e!==!0){let r=` +`+this.symbols.pointer+" ";typeof e=="string"?r+=e.trim():r+="Invalid input",this.state.error=` +`+this.styles.danger(r),this.state.submitted=!1,await this.render(),await this.alert(),this.state.validating=!1,this.state.error=void 0;return}this.state.validating=!1,await this.render(),await this.close(),this.value=await this.result(this.value),this.emit("submit",this.value)}async cancel(e){this.state.cancelled=this.state.submitted=!0,await this.render(),await this.close(),typeof this.options.onCancel=="function"&&await this.options.onCancel.call(this,this.name,this.value,this),this.emit("cancel",await this.error(e))}async close(){this.state.closed=!0;try{let e=this.sections(),r=Math.ceil(e.prompt.length/this.width);e.rest&&this.write(Gd.cursor.down(e.rest.length)),this.write(` +`.repeat(r))}catch{}this.emit("close")}start(){!this.stop&&this.options.show!==!1&&(this.stop=Y_.listen(this,this.keypress.bind(this)),this.once("close",this.stop))}async skip(){return this.skipped=this.options.skip===!0,typeof this.options.skip=="function"&&(this.skipped=await this.options.skip.call(this,this.name,this.value)),this.skipped}async initialize(){let{format:e,options:r,result:o}=this;if(this.format=()=>e.call(this,this.value),this.result=()=>o.call(this,this.value),typeof r.initial=="function"&&(this.initial=await r.initial.call(this,this)),typeof r.onRun=="function"&&await r.onRun.call(this,this),typeof r.onSubmit=="function"){let a=r.onSubmit.bind(this),n=this.submit.bind(this);delete this.options.onSubmit,this.submit=async()=>(await a(this.name,this.value,this),n())}await this.start(),await this.render()}render(){throw new Error("expected prompt to have a custom render method")}run(){return new Promise(async(e,r)=>{if(this.once("submit",e),this.once("cancel",r),await this.skip())return this.render=()=>{},this.submit();await this.initialize(),this.emit("run")})}async element(e,r,o){let{options:a,state:n,symbols:u,timers:A}=this,p=A&&A[e];n.timer=p;let h=a[e]||n[e]||u[e],E=r&&r[e]!=null?r[e]:await h;if(E==="")return E;let I=await this.resolve(E,n,r,o);return!I&&r&&r[e]?this.resolve(h,n,r,o):I}async prefix(){let e=await this.element("prefix")||this.symbols,r=this.timers&&this.timers.prefix,o=this.state;return o.timer=r,Ta.isObject(e)&&(e=e[o.status]||e.pending),Ta.hasColor(e)?e:(this.styles[o.status]||this.styles.pending)(e)}async message(){let e=await this.element("message");return Ta.hasColor(e)?e:this.styles.strong(e)}async separator(){let e=await this.element("separator")||this.symbols,r=this.timers&&this.timers.separator,o=this.state;o.timer=r;let a=e[o.status]||e.pending||o.separator,n=await this.resolve(a,o);return Ta.isObject(n)&&(n=n[o.status]||n.pending),Ta.hasColor(n)?n:this.styles.muted(n)}async pointer(e,r){let o=await this.element("pointer",e,r);if(typeof o=="string"&&Ta.hasColor(o))return o;if(o){let a=this.styles,n=this.index===r,u=n?a.primary:h=>h,A=await this.resolve(o[n?"on":"off"]||o,this.state),p=Ta.hasColor(A)?A:u(A);return n?p:" ".repeat(A.length)}}async indicator(e,r){let o=await this.element("indicator",e,r);if(typeof o=="string"&&Ta.hasColor(o))return o;if(o){let a=this.styles,n=e.enabled===!0,u=n?a.success:a.dark,A=o[n?"on":"off"]||o;return Ta.hasColor(A)?A:u(A)}return""}body(){return null}footer(){if(this.state.status==="pending")return this.element("footer")}header(){if(this.state.status==="pending")return this.element("header")}async hint(){if(this.state.status==="pending"&&!this.isValue(this.state.input)){let e=await this.element("hint");return Ta.hasColor(e)?e:this.styles.muted(e)}}error(e){return this.state.submitted?"":e||this.state.error}format(e){return e}result(e){return e}validate(e){return this.options.required===!0?this.isValue(e):!0}isValue(e){return e!=null&&e!==""}resolve(e,...r){return Ta.resolve(this,e,...r)}get base(){return l2.prototype}get style(){return this.styles[this.state.status]}get height(){return this.options.rows||Ta.height(this.stdout,25)}get width(){return this.options.columns||Ta.width(this.stdout,80)}get size(){return{width:this.width,height:this.height}}set cursor(e){this.state.cursor=e}get cursor(){return this.state.cursor}set input(e){this.state.input=e}get input(){return this.state.input}set value(e){this.state.value=e}get value(){let{input:e,value:r}=this.state,o=[r,e].find(this.isValue.bind(this));return this.isValue(o)?o:this.initial}static get prompt(){return e=>new this(e).run()}};function lft(t){let e=a=>t[a]===void 0||typeof t[a]=="function",r=["actions","choices","initial","margin","roles","styles","symbols","theme","timers","value"],o=["body","footer","error","header","hint","indicator","message","prefix","separator","skip"];for(let a of Object.keys(t.options)){if(r.includes(a)||/^on[A-Z]/.test(a))continue;let n=t.options[a];typeof n=="function"&&e(a)?o.includes(a)||(t[a]=n.bind(t)):typeof t[a]!="function"&&(t[a]=n)}}function cft(t){typeof t=="number"&&(t=[t,t,t,t]);let e=[].concat(t||[]),r=a=>a%2===0?` +`:" ",o=[];for(let a=0;a<4;a++){let n=r(a);e[a]?o.push(n.repeat(e[a])):o.push("")}return o}bhe.exports=l2});var Fhe=_((s8t,Qhe)=>{"use strict";var uft=No(),khe={default(t,e){return e},checkbox(t,e){throw new Error("checkbox role is not implemented yet")},editable(t,e){throw new Error("editable role is not implemented yet")},expandable(t,e){throw new Error("expandable role is not implemented yet")},heading(t,e){return e.disabled="",e.indicator=[e.indicator," "].find(r=>r!=null),e.message=e.message||"",e},input(t,e){throw new Error("input role is not implemented yet")},option(t,e){return khe.default(t,e)},radio(t,e){throw new Error("radio role is not implemented yet")},separator(t,e){return e.disabled="",e.indicator=[e.indicator," "].find(r=>r!=null),e.message=e.message||t.symbols.line.repeat(5),e},spacer(t,e){return e}};Qhe.exports=(t,e={})=>{let r=uft.merge({},khe,e.roles);return r[t]||r.default}});var c2=_((o8t,Nhe)=>{"use strict";var Aft=Vc(),fft=hC(),pft=Fhe(),lk=No(),{reorder:W_,scrollUp:hft,scrollDown:gft,isObject:The,swap:dft}=lk,V_=class extends fft{constructor(e){super(e),this.cursorHide(),this.maxSelected=e.maxSelected||1/0,this.multiple=e.multiple||!1,this.initial=e.initial||0,this.delay=e.delay||0,this.longest=0,this.num=""}async initialize(){typeof this.options.initial=="function"&&(this.initial=await this.options.initial.call(this)),await this.reset(!0),await super.initialize()}async reset(){let{choices:e,initial:r,autofocus:o,suggest:a}=this.options;if(this.state._choices=[],this.state.choices=[],this.choices=await Promise.all(await this.toChoices(e)),this.choices.forEach(n=>n.enabled=!1),typeof a!="function"&&this.selectable.length===0)throw new Error("At least one choice must be selectable");The(r)&&(r=Object.keys(r)),Array.isArray(r)?(o!=null&&(this.index=this.findIndex(o)),r.forEach(n=>this.enable(this.find(n))),await this.render()):(o!=null&&(r=o),typeof r=="string"&&(r=this.findIndex(r)),typeof r=="number"&&r>-1&&(this.index=Math.max(0,Math.min(r,this.choices.length)),this.enable(this.find(this.index)))),this.isDisabled(this.focused)&&await this.down()}async toChoices(e,r){this.state.loadingChoices=!0;let o=[],a=0,n=async(u,A)=>{typeof u=="function"&&(u=await u.call(this)),u instanceof Promise&&(u=await u);for(let p=0;p<u.length;p++){let h=u[p]=await this.toChoice(u[p],a++,A);o.push(h),h.choices&&await n(h.choices,h)}return o};return n(e,r).then(u=>(this.state.loadingChoices=!1,u))}async toChoice(e,r,o){if(typeof e=="function"&&(e=await e.call(this,this)),e instanceof Promise&&(e=await e),typeof e=="string"&&(e={name:e}),e.normalized)return e;e.normalized=!0;let a=e.value;if(e=pft(e.role,this.options)(this,e),typeof e.disabled=="string"&&!e.hint&&(e.hint=e.disabled,e.disabled=!0),e.disabled===!0&&e.hint==null&&(e.hint="(disabled)"),e.index!=null)return e;e.name=e.name||e.key||e.title||e.value||e.message,e.message=e.message||e.name||"",e.value=[e.value,e.name].find(this.isValue.bind(this)),e.input="",e.index=r,e.cursor=0,lk.define(e,"parent",o),e.level=o?o.level+1:1,e.indent==null&&(e.indent=o?o.indent+" ":e.indent||""),e.path=o?o.path+"."+e.name:e.name,e.enabled=!!(this.multiple&&!this.isDisabled(e)&&(e.enabled||this.isSelected(e))),this.isDisabled(e)||(this.longest=Math.max(this.longest,Aft.unstyle(e.message).length));let u={...e};return e.reset=(A=u.input,p=u.value)=>{for(let h of Object.keys(u))e[h]=u[h];e.input=A,e.value=p},a==null&&typeof e.initial=="function"&&(e.input=await e.initial.call(this,this.state,e,r)),e}async onChoice(e,r){this.emit("choice",e,r,this),typeof e.onChoice=="function"&&await e.onChoice.call(this,this.state,e,r)}async addChoice(e,r,o){let a=await this.toChoice(e,r,o);return this.choices.push(a),this.index=this.choices.length-1,this.limit=this.choices.length,a}async newItem(e,r,o){let a={name:"New choice name?",editable:!0,newChoice:!0,...e},n=await this.addChoice(a,r,o);return n.updateChoice=()=>{delete n.newChoice,n.name=n.message=n.input,n.input="",n.cursor=0},this.render()}indent(e){return e.indent==null?e.level>1?" ".repeat(e.level-1):"":e.indent}dispatch(e,r){if(this.multiple&&this[r.name])return this[r.name]();this.alert()}focus(e,r){return typeof r!="boolean"&&(r=e.enabled),r&&!e.enabled&&this.selected.length>=this.maxSelected?this.alert():(this.index=e.index,e.enabled=r&&!this.isDisabled(e),e)}space(){return this.multiple?(this.toggle(this.focused),this.render()):this.alert()}a(){if(this.maxSelected<this.choices.length)return this.alert();let e=this.selectable.every(r=>r.enabled);return this.choices.forEach(r=>r.enabled=!e),this.render()}i(){return this.choices.length-this.selected.length>this.maxSelected?this.alert():(this.choices.forEach(e=>e.enabled=!e.enabled),this.render())}g(e=this.focused){return this.choices.some(r=>!!r.parent)?(this.toggle(e.parent&&!e.choices?e.parent:e),this.render()):this.a()}toggle(e,r){if(!e.enabled&&this.selected.length>=this.maxSelected)return this.alert();typeof r!="boolean"&&(r=!e.enabled),e.enabled=r,e.choices&&e.choices.forEach(a=>this.toggle(a,r));let o=e.parent;for(;o;){let a=o.choices.filter(n=>this.isDisabled(n));o.enabled=a.every(n=>n.enabled===!0),o=o.parent}return Rhe(this,this.choices),this.emit("toggle",e,this),e}enable(e){return this.selected.length>=this.maxSelected?this.alert():(e.enabled=!this.isDisabled(e),e.choices&&e.choices.forEach(this.enable.bind(this)),e)}disable(e){return e.enabled=!1,e.choices&&e.choices.forEach(this.disable.bind(this)),e}number(e){this.num+=e;let r=o=>{let a=Number(o);if(a>this.choices.length-1)return this.alert();let n=this.focused,u=this.choices.find(A=>a===A.index);if(!u.enabled&&this.selected.length>=this.maxSelected)return this.alert();if(this.visible.indexOf(u)===-1){let A=W_(this.choices),p=A.indexOf(u);if(n.index>p){let h=A.slice(p,p+this.limit),E=A.filter(I=>!h.includes(I));this.choices=h.concat(E)}else{let h=p-this.limit+1;this.choices=A.slice(h).concat(A.slice(0,h))}}return this.index=this.choices.indexOf(u),this.toggle(this.focused),this.render()};return clearTimeout(this.numberTimeout),new Promise(o=>{let a=this.choices.length,n=this.num,u=(A=!1,p)=>{clearTimeout(this.numberTimeout),A&&(p=r(n)),this.num="",o(p)};if(n==="0"||n.length===1&&Number(n+"0")>a)return u(!0);if(Number(n)>a)return u(!1,this.alert());this.numberTimeout=setTimeout(()=>u(!0),this.delay)})}home(){return this.choices=W_(this.choices),this.index=0,this.render()}end(){let e=this.choices.length-this.limit,r=W_(this.choices);return this.choices=r.slice(e).concat(r.slice(0,e)),this.index=this.limit-1,this.render()}first(){return this.index=0,this.render()}last(){return this.index=this.visible.length-1,this.render()}prev(){return this.visible.length<=1?this.alert():this.up()}next(){return this.visible.length<=1?this.alert():this.down()}right(){return this.cursor>=this.input.length?this.alert():(this.cursor++,this.render())}left(){return this.cursor<=0?this.alert():(this.cursor--,this.render())}up(){let e=this.choices.length,r=this.visible.length,o=this.index;return this.options.scroll===!1&&o===0?this.alert():e>r&&o===0?this.scrollUp():(this.index=(o-1%e+e)%e,this.isDisabled()?this.up():this.render())}down(){let e=this.choices.length,r=this.visible.length,o=this.index;return this.options.scroll===!1&&o===r-1?this.alert():e>r&&o===r-1?this.scrollDown():(this.index=(o+1)%e,this.isDisabled()?this.down():this.render())}scrollUp(e=0){return this.choices=hft(this.choices),this.index=e,this.isDisabled()?this.up():this.render()}scrollDown(e=this.visible.length-1){return this.choices=gft(this.choices),this.index=e,this.isDisabled()?this.down():this.render()}async shiftUp(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index-1),await this.up(),this.sorting=!1;return}return this.scrollUp(this.index)}async shiftDown(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index+1),await this.down(),this.sorting=!1;return}return this.scrollDown(this.index)}pageUp(){return this.visible.length<=1?this.alert():(this.limit=Math.max(this.limit-1,0),this.index=Math.min(this.limit-1,this.index),this._limit=this.limit,this.isDisabled()?this.up():this.render())}pageDown(){return this.visible.length>=this.choices.length?this.alert():(this.index=Math.max(0,this.index),this.limit=Math.min(this.limit+1,this.choices.length),this._limit=this.limit,this.isDisabled()?this.down():this.render())}swap(e){dft(this.choices,this.index,e)}isDisabled(e=this.focused){return e&&["disabled","collapsed","hidden","completing","readonly"].some(o=>e[o]===!0)?!0:e&&e.role==="heading"}isEnabled(e=this.focused){if(Array.isArray(e))return e.every(r=>this.isEnabled(r));if(e.choices){let r=e.choices.filter(o=>!this.isDisabled(o));return e.enabled&&r.every(o=>this.isEnabled(o))}return e.enabled&&!this.isDisabled(e)}isChoice(e,r){return e.name===r||e.index===Number(r)}isSelected(e){return Array.isArray(this.initial)?this.initial.some(r=>this.isChoice(e,r)):this.isChoice(e,this.initial)}map(e=[],r="value"){return[].concat(e||[]).reduce((o,a)=>(o[a]=this.find(a,r),o),{})}filter(e,r){let a=typeof e=="function"?e:(A,p)=>[A.name,p].includes(e),u=(this.options.multiple?this.state._choices:this.choices).filter(a);return r?u.map(A=>A[r]):u}find(e,r){if(The(e))return r?e[r]:e;let a=typeof e=="function"?e:(u,A)=>[u.name,A].includes(e),n=this.choices.find(a);if(n)return r?n[r]:n}findIndex(e){return this.choices.indexOf(this.find(e))}async submit(){let e=this.focused;if(!e)return this.alert();if(e.newChoice)return e.input?(e.updateChoice(),this.render()):this.alert();if(this.choices.some(u=>u.newChoice))return this.alert();let{reorder:r,sort:o}=this.options,a=this.multiple===!0,n=this.selected;return n===void 0?this.alert():(Array.isArray(n)&&r!==!1&&o!==!0&&(n=lk.reorder(n)),this.value=a?n.map(u=>u.name):n.name,super.submit())}set choices(e=[]){this.state._choices=this.state._choices||[],this.state.choices=e;for(let r of e)this.state._choices.some(o=>o.name===r.name)||this.state._choices.push(r);if(!this._initial&&this.options.initial){this._initial=!0;let r=this.initial;if(typeof r=="string"||typeof r=="number"){let o=this.find(r);o&&(this.initial=o.index,this.focus(o,!0))}}}get choices(){return Rhe(this,this.state.choices||[])}set visible(e){this.state.visible=e}get visible(){return(this.state.visible||this.choices).slice(0,this.limit)}set limit(e){this.state.limit=e}get limit(){let{state:e,options:r,choices:o}=this,a=e.limit||this._limit||r.limit||o.length;return Math.min(a,this.height)}set value(e){super.value=e}get value(){return typeof super.value!="string"&&super.value===this.initial?this.input:super.value}set index(e){this.state.index=e}get index(){return Math.max(0,this.state?this.state.index:0)}get enabled(){return this.filter(this.isEnabled.bind(this))}get focused(){let e=this.choices[this.index];return e&&this.state.submitted&&this.multiple!==!0&&(e.enabled=!0),e}get selectable(){return this.choices.filter(e=>!this.isDisabled(e))}get selected(){return this.multiple?this.enabled:this.focused}};function Rhe(t,e){if(e instanceof Promise)return e;if(typeof e=="function"){if(lk.isAsyncFn(e))return e;e=e.call(t,t)}for(let r of e){if(Array.isArray(r.choices)){let o=r.choices.filter(a=>!t.isDisabled(a));r.enabled=o.every(a=>a.enabled===!0)}t.isDisabled(r)===!0&&delete r.enabled}return e}Nhe.exports=V_});var Sh=_((a8t,Lhe)=>{"use strict";var mft=c2(),K_=No(),J_=class extends mft{constructor(e){super(e),this.emptyError=this.options.emptyError||"No items were selected"}async dispatch(e,r){if(this.multiple)return this[r.name]?await this[r.name](e,r):await super.dispatch(e,r);this.alert()}separator(){if(this.options.separator)return super.separator();let e=this.styles.muted(this.symbols.ellipsis);return this.state.submitted?super.separator():e}pointer(e,r){return!this.multiple||this.options.pointer?super.pointer(e,r):""}indicator(e,r){return this.multiple?super.indicator(e,r):""}choiceMessage(e,r){let o=this.resolve(e.message,this.state,e,r);return e.role==="heading"&&!K_.hasColor(o)&&(o=this.styles.strong(o)),this.resolve(o,this.state,e,r)}choiceSeparator(){return":"}async renderChoice(e,r){await this.onChoice(e,r);let o=this.index===r,a=await this.pointer(e,r),n=await this.indicator(e,r)+(e.pad||""),u=await this.resolve(e.hint,this.state,e,r);u&&!K_.hasColor(u)&&(u=this.styles.muted(u));let A=this.indent(e),p=await this.choiceMessage(e,r),h=()=>[this.margin[3],A+a+n,p,this.margin[1],u].filter(Boolean).join(" ");return e.role==="heading"?h():e.disabled?(K_.hasColor(p)||(p=this.styles.disabled(p)),h()):(o&&(p=this.styles.em(p)),h())}async renderChoices(){if(this.state.loading==="choices")return this.styles.warning("Loading choices");if(this.state.submitted)return"";let e=this.visible.map(async(n,u)=>await this.renderChoice(n,u)),r=await Promise.all(e);r.length||r.push(this.styles.danger("No matching choices"));let o=this.margin[0]+r.join(` +`),a;return this.options.choicesHeader&&(a=await this.resolve(this.options.choicesHeader,this.state)),[a,o].filter(Boolean).join(` +`)}format(){return!this.state.submitted||this.state.cancelled?"":Array.isArray(this.selected)?this.selected.map(e=>this.styles.primary(e.name)).join(", "):this.styles.primary(this.selected.name)}async render(){let{submitted:e,size:r}=this.state,o="",a=await this.header(),n=await this.prefix(),u=await this.separator(),A=await this.message();this.options.promptLine!==!1&&(o=[n,A,u,""].join(" "),this.state.prompt=o);let p=await this.format(),h=await this.error()||await this.hint(),E=await this.renderChoices(),I=await this.footer();p&&(o+=p),h&&!o.includes(h)&&(o+=" "+h),e&&!p&&!E.trim()&&this.multiple&&this.emptyError!=null&&(o+=this.styles.danger(this.emptyError)),this.clear(r),this.write([a,o,E,I].filter(Boolean).join(` +`)),this.write(this.margin[2]),this.restore()}};Lhe.exports=J_});var Ohe=_((l8t,Mhe)=>{"use strict";var yft=Sh(),Eft=(t,e)=>{let r=t.toLowerCase();return o=>{let n=o.toLowerCase().indexOf(r),u=e(o.slice(n,n+r.length));return n>=0?o.slice(0,n)+u+o.slice(n+r.length):o}},z_=class extends yft{constructor(e){super(e),this.cursorShow()}moveCursor(e){this.state.cursor+=e}dispatch(e){return this.append(e)}space(e){return this.options.multiple?super.space(e):this.append(e)}append(e){let{cursor:r,input:o}=this.state;return this.input=o.slice(0,r)+e+o.slice(r),this.moveCursor(1),this.complete()}delete(){let{cursor:e,input:r}=this.state;return r?(this.input=r.slice(0,e-1)+r.slice(e),this.moveCursor(-1),this.complete()):this.alert()}deleteForward(){let{cursor:e,input:r}=this.state;return r[e]===void 0?this.alert():(this.input=`${r}`.slice(0,e)+`${r}`.slice(e+1),this.complete())}number(e){return this.append(e)}async complete(){this.completing=!0,this.choices=await this.suggest(this.input,this.state._choices),this.state.limit=void 0,this.index=Math.min(Math.max(this.visible.length-1,0),this.index),await this.render(),this.completing=!1}suggest(e=this.input,r=this.state._choices){if(typeof this.options.suggest=="function")return this.options.suggest.call(this,e,r);let o=e.toLowerCase();return r.filter(a=>a.message.toLowerCase().includes(o))}pointer(){return""}format(){if(!this.focused)return this.input;if(this.options.multiple&&this.state.submitted)return this.selected.map(e=>this.styles.primary(e.message)).join(", ");if(this.state.submitted){let e=this.value=this.input=this.focused.value;return this.styles.primary(e)}return this.input}async render(){if(this.state.status!=="pending")return super.render();let e=this.options.highlight?this.options.highlight.bind(this):this.styles.placeholder,r=Eft(this.input,e),o=this.choices;this.choices=o.map(a=>({...a,message:r(a.message)})),await super.render(),this.choices=o}submit(){return this.options.multiple&&(this.value=this.selected.map(e=>e.name)),super.submit()}};Mhe.exports=z_});var Z_=_((c8t,Uhe)=>{"use strict";var X_=No();Uhe.exports=(t,e={})=>{t.cursorHide();let{input:r="",initial:o="",pos:a,showCursor:n=!0,color:u}=e,A=u||t.styles.placeholder,p=X_.inverse(t.styles.primary),h=T=>p(t.styles.black(T)),E=r,I=" ",v=h(I);if(t.blink&&t.blink.off===!0&&(h=T=>T,v=""),n&&a===0&&o===""&&r==="")return h(I);if(n&&a===0&&(r===o||r===""))return h(o[0])+A(o.slice(1));o=X_.isPrimitive(o)?`${o}`:"",r=X_.isPrimitive(r)?`${r}`:"";let b=o&&o.startsWith(r)&&o!==r,C=b?h(o[r.length]):v;if(a!==r.length&&n===!0&&(E=r.slice(0,a)+h(r[a])+r.slice(a+1),C=""),n===!1&&(C=""),b){let T=t.styles.unstyle(E+C);return E+C+A(o.slice(T.length))}return E+C}});var ck=_((u8t,_he)=>{"use strict";var Cft=Vc(),wft=Sh(),Ift=Z_(),$_=class extends wft{constructor(e){super({...e,multiple:!0}),this.type="form",this.initial=this.options.initial,this.align=[this.options.align,"right"].find(r=>r!=null),this.emptyError="",this.values={}}async reset(e){return await super.reset(),e===!0&&(this._index=this.index),this.index=this._index,this.values={},this.choices.forEach(r=>r.reset&&r.reset()),this.render()}dispatch(e){return!!e&&this.append(e)}append(e){let r=this.focused;if(!r)return this.alert();let{cursor:o,input:a}=r;return r.value=r.input=a.slice(0,o)+e+a.slice(o),r.cursor++,this.render()}delete(){let e=this.focused;if(!e||e.cursor<=0)return this.alert();let{cursor:r,input:o}=e;return e.value=e.input=o.slice(0,r-1)+o.slice(r),e.cursor--,this.render()}deleteForward(){let e=this.focused;if(!e)return this.alert();let{cursor:r,input:o}=e;if(o[r]===void 0)return this.alert();let a=`${o}`.slice(0,r)+`${o}`.slice(r+1);return e.value=e.input=a,this.render()}right(){let e=this.focused;return e?e.cursor>=e.input.length?this.alert():(e.cursor++,this.render()):this.alert()}left(){let e=this.focused;return e?e.cursor<=0?this.alert():(e.cursor--,this.render()):this.alert()}space(e,r){return this.dispatch(e,r)}number(e,r){return this.dispatch(e,r)}next(){let e=this.focused;if(!e)return this.alert();let{initial:r,input:o}=e;return r&&r.startsWith(o)&&o!==r?(e.value=e.input=r,e.cursor=e.value.length,this.render()):super.next()}prev(){let e=this.focused;return e?e.cursor===0?super.prev():(e.value=e.input="",e.cursor=0,this.render()):this.alert()}separator(){return""}format(e){return this.state.submitted?"":super.format(e)}pointer(){return""}indicator(e){return e.input?"\u29BF":"\u2299"}async choiceSeparator(e,r){let o=await this.resolve(e.separator,this.state,e,r)||":";return o?" "+this.styles.disabled(o):""}async renderChoice(e,r){await this.onChoice(e,r);let{state:o,styles:a}=this,{cursor:n,initial:u="",name:A,hint:p,input:h=""}=e,{muted:E,submitted:I,primary:v,danger:b}=a,C=p,T=this.index===r,L=e.validate||(()=>!0),U=await this.choiceSeparator(e,r),J=e.message;this.align==="right"&&(J=J.padStart(this.longest+1," ")),this.align==="left"&&(J=J.padEnd(this.longest+1," "));let te=this.values[A]=h||u,le=h?"success":"dark";await L.call(e,te,this.state)!==!0&&(le="danger");let pe=a[le],Ae=pe(await this.indicator(e,r))+(e.pad||""),ye=this.indent(e),ae=()=>[ye,Ae,J+U,h,C].filter(Boolean).join(" ");if(o.submitted)return J=Cft.unstyle(J),h=I(h),C="",ae();if(e.format)h=await e.format.call(this,h,e,r);else{let we=this.styles.muted;h=Ift(this,{input:h,initial:u,pos:n,showCursor:T,color:we})}return this.isValue(h)||(h=this.styles.muted(this.symbols.ellipsis)),e.result&&(this.values[A]=await e.result.call(this,te,e,r)),T&&(J=v(J)),e.error?h+=(h?" ":"")+b(e.error.trim()):e.hint&&(h+=(h?" ":"")+E(e.hint.trim())),ae()}async submit(){return this.value=this.values,super.base.submit.call(this)}};_he.exports=$_});var e8=_((A8t,jhe)=>{"use strict";var Bft=ck(),vft=()=>{throw new Error("expected prompt to have a custom authenticate method")},Hhe=(t=vft)=>{class e extends Bft{constructor(o){super(o)}async submit(){this.value=await t.call(this,this.values,this.state),super.base.submit.call(this)}static create(o){return Hhe(o)}}return e};jhe.exports=Hhe()});var Yhe=_((f8t,Ghe)=>{"use strict";var Dft=e8();function Pft(t,e){return t.username===this.options.username&&t.password===this.options.password}var qhe=(t=Pft)=>{let e=[{name:"username",message:"username"},{name:"password",message:"password",format(o){return this.options.showPassword?o:(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(o.length))}}];class r extends Dft.create(t){constructor(a){super({...a,choices:e})}static create(a){return qhe(a)}}return r};Ghe.exports=qhe()});var uk=_((p8t,Whe)=>{"use strict";var Sft=hC(),{isPrimitive:xft,hasColor:bft}=No(),t8=class extends Sft{constructor(e){super(e),this.cursorHide()}async initialize(){let e=await this.resolve(this.initial,this.state);this.input=await this.cast(e),await super.initialize()}dispatch(e){return this.isValue(e)?(this.input=e,this.submit()):this.alert()}format(e){let{styles:r,state:o}=this;return o.submitted?r.success(e):r.primary(e)}cast(e){return this.isTrue(e)}isTrue(e){return/^[ty1]/i.test(e)}isFalse(e){return/^[fn0]/i.test(e)}isValue(e){return xft(e)&&(this.isTrue(e)||this.isFalse(e))}async hint(){if(this.state.status==="pending"){let e=await this.element("hint");return bft(e)?e:this.styles.muted(e)}}async render(){let{input:e,size:r}=this.state,o=await this.prefix(),a=await this.separator(),n=await this.message(),u=this.styles.muted(this.default),A=[o,n,u,a].filter(Boolean).join(" ");this.state.prompt=A;let p=await this.header(),h=this.value=this.cast(e),E=await this.format(h),I=await this.error()||await this.hint(),v=await this.footer();I&&!A.includes(I)&&(E+=" "+I),A+=" "+E,this.clear(r),this.write([p,A,v].filter(Boolean).join(` +`)),this.restore()}set value(e){super.value=e}get value(){return this.cast(super.value)}};Whe.exports=t8});var Khe=_((h8t,Vhe)=>{"use strict";var kft=uk(),r8=class extends kft{constructor(e){super(e),this.default=this.options.default||(this.initial?"(Y/n)":"(y/N)")}};Vhe.exports=r8});var zhe=_((g8t,Jhe)=>{"use strict";var Qft=Sh(),Fft=ck(),gC=Fft.prototype,n8=class extends Qft{constructor(e){super({...e,multiple:!0}),this.align=[this.options.align,"left"].find(r=>r!=null),this.emptyError="",this.values={}}dispatch(e,r){let o=this.focused,a=o.parent||{};return!o.editable&&!a.editable&&(e==="a"||e==="i")?super[e]():gC.dispatch.call(this,e,r)}append(e,r){return gC.append.call(this,e,r)}delete(e,r){return gC.delete.call(this,e,r)}space(e){return this.focused.editable?this.append(e):super.space()}number(e){return this.focused.editable?this.append(e):super.number(e)}next(){return this.focused.editable?gC.next.call(this):super.next()}prev(){return this.focused.editable?gC.prev.call(this):super.prev()}async indicator(e,r){let o=e.indicator||"",a=e.editable?o:super.indicator(e,r);return await this.resolve(a,this.state,e,r)||""}indent(e){return e.role==="heading"?"":e.editable?" ":" "}async renderChoice(e,r){return e.indent="",e.editable?gC.renderChoice.call(this,e,r):super.renderChoice(e,r)}error(){return""}footer(){return this.state.error}async validate(){let e=!0;for(let r of this.choices){if(typeof r.validate!="function"||r.role==="heading")continue;let o=r.parent?this.value[r.parent.name]:this.value;if(r.editable?o=r.value===r.name?r.initial||"":r.value:this.isDisabled(r)||(o=r.enabled===!0),e=await r.validate(o,this.state),e!==!0)break}return e!==!0&&(this.state.error=typeof e=="string"?e:"Invalid Input"),e}submit(){if(this.focused.newChoice===!0)return super.submit();if(this.choices.some(e=>e.newChoice))return this.alert();this.value={};for(let e of this.choices){let r=e.parent?this.value[e.parent.name]:this.value;if(e.role==="heading"){this.value[e.name]={};continue}e.editable?r[e.name]=e.value===e.name?e.initial||"":e.value:this.isDisabled(e)||(r[e.name]=e.enabled===!0)}return this.base.submit.call(this)}};Jhe.exports=n8});var Yd=_((d8t,Xhe)=>{"use strict";var Tft=hC(),Rft=Z_(),{isPrimitive:Nft}=No(),i8=class extends Tft{constructor(e){super(e),this.initial=Nft(this.initial)?String(this.initial):"",this.initial&&this.cursorHide(),this.state.prevCursor=0,this.state.clipboard=[]}async keypress(e,r={}){let o=this.state.prevKeypress;return this.state.prevKeypress=r,this.options.multiline===!0&&r.name==="return"&&(!o||o.name!=="return")?this.append(` +`,r):super.keypress(e,r)}moveCursor(e){this.cursor+=e}reset(){return this.input=this.value="",this.cursor=0,this.render()}dispatch(e,r){if(!e||r.ctrl||r.code)return this.alert();this.append(e)}append(e){let{cursor:r,input:o}=this.state;this.input=`${o}`.slice(0,r)+e+`${o}`.slice(r),this.moveCursor(String(e).length),this.render()}insert(e){this.append(e)}delete(){let{cursor:e,input:r}=this.state;if(e<=0)return this.alert();this.input=`${r}`.slice(0,e-1)+`${r}`.slice(e),this.moveCursor(-1),this.render()}deleteForward(){let{cursor:e,input:r}=this.state;if(r[e]===void 0)return this.alert();this.input=`${r}`.slice(0,e)+`${r}`.slice(e+1),this.render()}cutForward(){let e=this.cursor;if(this.input.length<=e)return this.alert();this.state.clipboard.push(this.input.slice(e)),this.input=this.input.slice(0,e),this.render()}cutLeft(){let e=this.cursor;if(e===0)return this.alert();let r=this.input.slice(0,e),o=this.input.slice(e),a=r.split(" ");this.state.clipboard.push(a.pop()),this.input=a.join(" "),this.cursor=this.input.length,this.input+=o,this.render()}paste(){if(!this.state.clipboard.length)return this.alert();this.insert(this.state.clipboard.pop()),this.render()}toggleCursor(){this.state.prevCursor?(this.cursor=this.state.prevCursor,this.state.prevCursor=0):(this.state.prevCursor=this.cursor,this.cursor=0),this.render()}first(){this.cursor=0,this.render()}last(){this.cursor=this.input.length-1,this.render()}next(){let e=this.initial!=null?String(this.initial):"";if(!e||!e.startsWith(this.input))return this.alert();this.input=this.initial,this.cursor=this.initial.length,this.render()}prev(){if(!this.input)return this.alert();this.reset()}backward(){return this.left()}forward(){return this.right()}right(){return this.cursor>=this.input.length?this.alert():(this.moveCursor(1),this.render())}left(){return this.cursor<=0?this.alert():(this.moveCursor(-1),this.render())}isValue(e){return!!e}async format(e=this.value){let r=await this.resolve(this.initial,this.state);return this.state.submitted?this.styles.submitted(e||r):Rft(this,{input:e,initial:r,pos:this.cursor})}async render(){let e=this.state.size,r=await this.prefix(),o=await this.separator(),a=await this.message(),n=[r,a,o].filter(Boolean).join(" ");this.state.prompt=n;let u=await this.header(),A=await this.format(),p=await this.error()||await this.hint(),h=await this.footer();p&&!A.includes(p)&&(A+=" "+p),n+=" "+A,this.clear(e),this.write([u,n,h].filter(Boolean).join(` +`)),this.restore()}};Xhe.exports=i8});var $he=_((m8t,Zhe)=>{"use strict";var Lft=t=>t.filter((e,r)=>t.lastIndexOf(e)===r),Ak=t=>Lft(t).filter(Boolean);Zhe.exports=(t,e={},r="")=>{let{past:o=[],present:a=""}=e,n,u;switch(t){case"prev":case"undo":return n=o.slice(0,o.length-1),u=o[o.length-1]||"",{past:Ak([r,...n]),present:u};case"next":case"redo":return n=o.slice(1),u=o[0]||"",{past:Ak([...n,r]),present:u};case"save":return{past:Ak([...o,r]),present:""};case"remove":return u=Ak(o.filter(A=>A!==r)),a="",u.length&&(a=u.pop()),{past:u,present:a};default:throw new Error(`Invalid action: "${t}"`)}}});var o8=_((y8t,t0e)=>{"use strict";var Mft=Yd(),e0e=$he(),s8=class extends Mft{constructor(e){super(e);let r=this.options.history;if(r&&r.store){let o=r.values||this.initial;this.autosave=!!r.autosave,this.store=r.store,this.data=this.store.get("values")||{past:[],present:o},this.initial=this.data.present||this.data.past[this.data.past.length-1]}}completion(e){return this.store?(this.data=e0e(e,this.data,this.input),this.data.present?(this.input=this.data.present,this.cursor=this.input.length,this.render()):this.alert()):this.alert()}altUp(){return this.completion("prev")}altDown(){return this.completion("next")}prev(){return this.save(),super.prev()}save(){!this.store||(this.data=e0e("save",this.data,this.input),this.store.set("values",this.data))}submit(){return this.store&&this.autosave===!0&&this.save(),super.submit()}};t0e.exports=s8});var n0e=_((E8t,r0e)=>{"use strict";var Oft=Yd(),a8=class extends Oft{format(){return""}};r0e.exports=a8});var s0e=_((C8t,i0e)=>{"use strict";var Uft=Yd(),l8=class extends Uft{constructor(e={}){super(e),this.sep=this.options.separator||/, */,this.initial=e.initial||""}split(e=this.value){return e?String(e).split(this.sep):[]}format(){let e=this.state.submitted?this.styles.primary:r=>r;return this.list.map(e).join(", ")}async submit(e){let r=this.state.error||await this.validate(this.list,this.state);return r!==!0?(this.state.error=r,super.submit()):(this.value=this.list,super.submit())}get list(){return this.split()}};i0e.exports=l8});var a0e=_((w8t,o0e)=>{"use strict";var _ft=Sh(),c8=class extends _ft{constructor(e){super({...e,multiple:!0})}};o0e.exports=c8});var A8=_((I8t,l0e)=>{"use strict";var Hft=Yd(),u8=class extends Hft{constructor(e={}){super({style:"number",...e}),this.min=this.isValue(e.min)?this.toNumber(e.min):-1/0,this.max=this.isValue(e.max)?this.toNumber(e.max):1/0,this.delay=e.delay!=null?e.delay:1e3,this.float=e.float!==!1,this.round=e.round===!0||e.float===!1,this.major=e.major||10,this.minor=e.minor||1,this.initial=e.initial!=null?e.initial:"",this.input=String(this.initial),this.cursor=this.input.length,this.cursorShow()}append(e){return!/[-+.]/.test(e)||e==="."&&this.input.includes(".")?this.alert("invalid number"):super.append(e)}number(e){return super.append(e)}next(){return this.input&&this.input!==this.initial?this.alert():this.isValue(this.initial)?(this.input=this.initial,this.cursor=String(this.initial).length,this.render()):this.alert()}up(e){let r=e||this.minor,o=this.toNumber(this.input);return o>this.max+r?this.alert():(this.input=`${o+r}`,this.render())}down(e){let r=e||this.minor,o=this.toNumber(this.input);return o<this.min-r?this.alert():(this.input=`${o-r}`,this.render())}shiftDown(){return this.down(this.major)}shiftUp(){return this.up(this.major)}format(e=this.input){return typeof this.options.format=="function"?this.options.format.call(this,e):this.styles.info(e)}toNumber(e=""){return this.float?+e:Math.round(+e)}isValue(e){return/^[-+]?[0-9]+((\.)|(\.[0-9]+))?$/.test(e)}submit(){let e=[this.input,this.initial].find(r=>this.isValue(r));return this.value=this.toNumber(e||0),super.submit()}};l0e.exports=u8});var u0e=_((B8t,c0e)=>{c0e.exports=A8()});var f0e=_((v8t,A0e)=>{"use strict";var jft=Yd(),f8=class extends jft{constructor(e){super(e),this.cursorShow()}format(e=this.input){return this.keypressed?(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(e.length)):""}};A0e.exports=f8});var g0e=_((D8t,h0e)=>{"use strict";var qft=Vc(),Gft=c2(),p0e=No(),p8=class extends Gft{constructor(e={}){super(e),this.widths=[].concat(e.messageWidth||50),this.align=[].concat(e.align||"left"),this.linebreak=e.linebreak||!1,this.edgeLength=e.edgeLength||3,this.newline=e.newline||` + `;let r=e.startNumber||1;typeof this.scale=="number"&&(this.scaleKey=!1,this.scale=Array(this.scale).fill(0).map((o,a)=>({name:a+r})))}async reset(){return this.tableized=!1,await super.reset(),this.render()}tableize(){if(this.tableized===!0)return;this.tableized=!0;let e=0;for(let r of this.choices){e=Math.max(e,r.message.length),r.scaleIndex=r.initial||2,r.scale=[];for(let o=0;o<this.scale.length;o++)r.scale.push({index:o})}this.widths[0]=Math.min(this.widths[0],e+3)}async dispatch(e,r){if(this.multiple)return this[r.name]?await this[r.name](e,r):await super.dispatch(e,r);this.alert()}heading(e,r,o){return this.styles.strong(e)}separator(){return this.styles.muted(this.symbols.ellipsis)}right(){let e=this.focused;return e.scaleIndex>=this.scale.length-1?this.alert():(e.scaleIndex++,this.render())}left(){let e=this.focused;return e.scaleIndex<=0?this.alert():(e.scaleIndex--,this.render())}indent(){return""}format(){return this.state.submitted?this.choices.map(r=>this.styles.info(r.index)).join(", "):""}pointer(){return""}renderScaleKey(){return this.scaleKey===!1||this.state.submitted?"":["",...this.scale.map(o=>` ${o.name} - ${o.message}`)].map(o=>this.styles.muted(o)).join(` +`)}renderScaleHeading(e){let r=this.scale.map(p=>p.name);typeof this.options.renderScaleHeading=="function"&&(r=this.options.renderScaleHeading.call(this,e));let o=this.scaleLength-r.join("").length,a=Math.round(o/(r.length-1)),u=r.map(p=>this.styles.strong(p)).join(" ".repeat(a)),A=" ".repeat(this.widths[0]);return this.margin[3]+A+this.margin[1]+u}scaleIndicator(e,r,o){if(typeof this.options.scaleIndicator=="function")return this.options.scaleIndicator.call(this,e,r,o);let a=e.scaleIndex===r.index;return r.disabled?this.styles.hint(this.symbols.radio.disabled):a?this.styles.success(this.symbols.radio.on):this.symbols.radio.off}renderScale(e,r){let o=e.scale.map(n=>this.scaleIndicator(e,n,r)),a=this.term==="Hyper"?"":" ";return o.join(a+this.symbols.line.repeat(this.edgeLength))}async renderChoice(e,r){await this.onChoice(e,r);let o=this.index===r,a=await this.pointer(e,r),n=await e.hint;n&&!p0e.hasColor(n)&&(n=this.styles.muted(n));let u=C=>this.margin[3]+C.replace(/\s+$/,"").padEnd(this.widths[0]," "),A=this.newline,p=this.indent(e),h=await this.resolve(e.message,this.state,e,r),E=await this.renderScale(e,r),I=this.margin[1]+this.margin[3];this.scaleLength=qft.unstyle(E).length,this.widths[0]=Math.min(this.widths[0],this.width-this.scaleLength-I.length);let b=p0e.wordWrap(h,{width:this.widths[0],newline:A}).split(` +`).map(C=>u(C)+this.margin[1]);return o&&(E=this.styles.info(E),b=b.map(C=>this.styles.info(C))),b[0]+=E,this.linebreak&&b.push(""),[p+a,b.join(` +`)].filter(Boolean)}async renderChoices(){if(this.state.submitted)return"";this.tableize();let e=this.visible.map(async(a,n)=>await this.renderChoice(a,n)),r=await Promise.all(e),o=await this.renderScaleHeading();return this.margin[0]+[o,...r.map(a=>a.join(" "))].join(` +`)}async render(){let{submitted:e,size:r}=this.state,o=await this.prefix(),a=await this.separator(),n=await this.message(),u="";this.options.promptLine!==!1&&(u=[o,n,a,""].join(" "),this.state.prompt=u);let A=await this.header(),p=await this.format(),h=await this.renderScaleKey(),E=await this.error()||await this.hint(),I=await this.renderChoices(),v=await this.footer(),b=this.emptyError;p&&(u+=p),E&&!u.includes(E)&&(u+=" "+E),e&&!p&&!I.trim()&&this.multiple&&b!=null&&(u+=this.styles.danger(b)),this.clear(r),this.write([A,u,h,I,v].filter(Boolean).join(` +`)),this.state.submitted||this.write(this.margin[2]),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIndex;return this.base.submit.call(this)}};h0e.exports=p8});var y0e=_((P8t,m0e)=>{"use strict";var d0e=Vc(),Yft=(t="")=>typeof t=="string"?t.replace(/^['"]|['"]$/g,""):"",g8=class{constructor(e){this.name=e.key,this.field=e.field||{},this.value=Yft(e.initial||this.field.initial||""),this.message=e.message||this.name,this.cursor=0,this.input="",this.lines=[]}},Wft=async(t={},e={},r=o=>o)=>{let o=new Set,a=t.fields||[],n=t.template,u=[],A=[],p=[],h=1;typeof n=="function"&&(n=await n());let E=-1,I=()=>n[++E],v=()=>n[E+1],b=C=>{C.line=h,u.push(C)};for(b({type:"bos",value:""});E<n.length-1;){let C=I();if(/^[^\S\n ]$/.test(C)){b({type:"text",value:C});continue}if(C===` +`){b({type:"newline",value:C}),h++;continue}if(C==="\\"){C+=I(),b({type:"text",value:C});continue}if((C==="$"||C==="#"||C==="{")&&v()==="{"){let L=I();C+=L;let U={type:"template",open:C,inner:"",close:"",value:C},J;for(;J=I();){if(J==="}"){v()==="}"&&(J+=I()),U.value+=J,U.close=J;break}J===":"?(U.initial="",U.key=U.inner):U.initial!==void 0&&(U.initial+=J),U.value+=J,U.inner+=J}U.template=U.open+(U.initial||U.inner)+U.close,U.key=U.key||U.inner,e.hasOwnProperty(U.key)&&(U.initial=e[U.key]),U=r(U),b(U),p.push(U.key),o.add(U.key);let te=A.find(le=>le.name===U.key);U.field=a.find(le=>le.name===U.key),te||(te=new g8(U),A.push(te)),te.lines.push(U.line-1);continue}let T=u[u.length-1];T.type==="text"&&T.line===h?T.value+=C:b({type:"text",value:C})}return b({type:"eos",value:""}),{input:n,tabstops:u,unique:o,keys:p,items:A}};m0e.exports=async t=>{let e=t.options,r=new Set(e.required===!0?[]:e.required||[]),o={...e.values,...e.initial},{tabstops:a,items:n,keys:u}=await Wft(e,o),A=h8("result",t,e),p=h8("format",t,e),h=h8("validate",t,e,!0),E=t.isValue.bind(t);return async(I={},v=!1)=>{let b=0;I.required=r,I.items=n,I.keys=u,I.output="";let C=async(J,te,le,pe)=>{let Ae=await h(J,te,le,pe);return Ae===!1?"Invalid field "+le.name:Ae};for(let J of a){let te=J.value,le=J.key;if(J.type!=="template"){te&&(I.output+=te);continue}if(J.type==="template"){let pe=n.find(Pe=>Pe.name===le);e.required===!0&&I.required.add(pe.name);let Ae=[pe.input,I.values[pe.value],pe.value,te].find(E),ae=(pe.field||{}).message||J.inner;if(v){let Pe=await C(I.values[le],I,pe,b);if(Pe&&typeof Pe=="string"||Pe===!1){I.invalid.set(le,Pe);continue}I.invalid.delete(le);let g=await A(I.values[le],I,pe,b);I.output+=d0e.unstyle(g);continue}pe.placeholder=!1;let we=te;te=await p(te,I,pe,b),Ae!==te?(I.values[le]=Ae,te=t.styles.typing(Ae),I.missing.delete(ae)):(I.values[le]=void 0,Ae=`<${ae}>`,te=t.styles.primary(Ae),pe.placeholder=!0,I.required.has(le)&&I.missing.add(ae)),I.missing.has(ae)&&I.validating&&(te=t.styles.warning(Ae)),I.invalid.has(le)&&I.validating&&(te=t.styles.danger(Ae)),b===I.index&&(we!==te?te=t.styles.underline(te):te=t.styles.heading(d0e.unstyle(te))),b++}te&&(I.output+=te)}let T=I.output.split(` +`).map(J=>" "+J),L=n.length,U=0;for(let J of n)I.invalid.has(J.name)&&J.lines.forEach(te=>{T[te][0]===" "&&(T[te]=I.styles.danger(I.symbols.bullet)+T[te].slice(1))}),t.isValue(I.values[J.name])&&U++;return I.completed=(U/L*100).toFixed(0),I.output=T.join(` +`),I.output}};function h8(t,e,r,o){return(a,n,u,A)=>typeof u.field[t]=="function"?u.field[t].call(e,a,n,u,A):[o,a].find(p=>e.isValue(p))}});var C0e=_((S8t,E0e)=>{"use strict";var Vft=Vc(),Kft=y0e(),Jft=hC(),d8=class extends Jft{constructor(e){super(e),this.cursorHide(),this.reset(!0)}async initialize(){this.interpolate=await Kft(this),await super.initialize()}async reset(e){this.state.keys=[],this.state.invalid=new Map,this.state.missing=new Set,this.state.completed=0,this.state.values={},e!==!0&&(await this.initialize(),await this.render())}moveCursor(e){let r=this.getItem();this.cursor+=e,r.cursor+=e}dispatch(e,r){if(!r.code&&!r.ctrl&&e!=null&&this.getItem()){this.append(e,r);return}this.alert()}append(e,r){let o=this.getItem(),a=o.input.slice(0,this.cursor),n=o.input.slice(this.cursor);this.input=o.input=`${a}${e}${n}`,this.moveCursor(1),this.render()}delete(){let e=this.getItem();if(this.cursor<=0||!e.input)return this.alert();let r=e.input.slice(this.cursor),o=e.input.slice(0,this.cursor-1);this.input=e.input=`${o}${r}`,this.moveCursor(-1),this.render()}increment(e){return e>=this.state.keys.length-1?0:e+1}decrement(e){return e<=0?this.state.keys.length-1:e-1}first(){this.state.index=0,this.render()}last(){this.state.index=this.state.keys.length-1,this.render()}right(){if(this.cursor>=this.input.length)return this.alert();this.moveCursor(1),this.render()}left(){if(this.cursor<=0)return this.alert();this.moveCursor(-1),this.render()}prev(){this.state.index=this.decrement(this.state.index),this.getItem(),this.render()}next(){this.state.index=this.increment(this.state.index),this.getItem(),this.render()}up(){this.prev()}down(){this.next()}format(e){let r=this.state.completed<100?this.styles.warning:this.styles.success;return this.state.submitted===!0&&this.state.completed!==100&&(r=this.styles.danger),r(`${this.state.completed}% completed`)}async render(){let{index:e,keys:r=[],submitted:o,size:a}=this.state,n=[this.options.newline,` +`].find(J=>J!=null),u=await this.prefix(),A=await this.separator(),p=await this.message(),h=[u,p,A].filter(Boolean).join(" ");this.state.prompt=h;let E=await this.header(),I=await this.error()||"",v=await this.hint()||"",b=o?"":await this.interpolate(this.state),C=this.state.key=r[e]||"",T=await this.format(C),L=await this.footer();T&&(h+=" "+T),v&&!T&&this.state.completed===0&&(h+=" "+v),this.clear(a);let U=[E,h,b,L,I.trim()];this.write(U.filter(Boolean).join(n)),this.restore()}getItem(e){let{items:r,keys:o,index:a}=this.state,n=r.find(u=>u.name===o[a]);return n&&n.input!=null&&(this.input=n.input,this.cursor=n.cursor),n}async submit(){typeof this.interpolate!="function"&&await this.initialize(),await this.interpolate(this.state,!0);let{invalid:e,missing:r,output:o,values:a}=this.state;if(e.size){let A="";for(let[p,h]of e)A+=`Invalid ${p}: ${h} +`;return this.state.error=A,super.submit()}if(r.size)return this.state.error="Required: "+[...r.keys()].join(", "),super.submit();let u=Vft.unstyle(o).split(` +`).map(A=>A.slice(1)).join(` +`);return this.value={values:a,result:u},super.submit()}};E0e.exports=d8});var I0e=_((x8t,w0e)=>{"use strict";var zft="(Use <shift>+<up/down> to sort)",Xft=Sh(),m8=class extends Xft{constructor(e){super({...e,reorder:!1,sort:!0,multiple:!0}),this.state.hint=[this.options.hint,zft].find(this.isValue.bind(this))}indicator(){return""}async renderChoice(e,r){let o=await super.renderChoice(e,r),a=this.symbols.identicalTo+" ",n=this.index===r&&this.sorting?this.styles.muted(a):" ";return this.options.drag===!1&&(n=""),this.options.numbered===!0?n+`${r+1} - `+o:n+o}get selected(){return this.choices}submit(){return this.value=this.choices.map(e=>e.value),super.submit()}};w0e.exports=m8});var v0e=_((b8t,B0e)=>{"use strict";var Zft=c2(),y8=class extends Zft{constructor(e={}){if(super(e),this.emptyError=e.emptyError||"No items were selected",this.term=process.env.TERM_PROGRAM,!this.options.header){let r=["","4 - Strongly Agree","3 - Agree","2 - Neutral","1 - Disagree","0 - Strongly Disagree",""];r=r.map(o=>this.styles.muted(o)),this.state.header=r.join(` + `)}}async toChoices(...e){if(this.createdScales)return!1;this.createdScales=!0;let r=await super.toChoices(...e);for(let o of r)o.scale=$ft(5,this.options),o.scaleIdx=2;return r}dispatch(){this.alert()}space(){let e=this.focused,r=e.scale[e.scaleIdx],o=r.selected;return e.scale.forEach(a=>a.selected=!1),r.selected=!o,this.render()}indicator(){return""}pointer(){return""}separator(){return this.styles.muted(this.symbols.ellipsis)}right(){let e=this.focused;return e.scaleIdx>=e.scale.length-1?this.alert():(e.scaleIdx++,this.render())}left(){let e=this.focused;return e.scaleIdx<=0?this.alert():(e.scaleIdx--,this.render())}indent(){return" "}async renderChoice(e,r){await this.onChoice(e,r);let o=this.index===r,a=this.term==="Hyper",n=a?9:8,u=a?"":" ",A=this.symbols.line.repeat(n),p=" ".repeat(n+(a?0:1)),h=te=>(te?this.styles.success("\u25C9"):"\u25EF")+u,E=r+1+".",I=o?this.styles.heading:this.styles.noop,v=await this.resolve(e.message,this.state,e,r),b=this.indent(e),C=b+e.scale.map((te,le)=>h(le===e.scaleIdx)).join(A),T=te=>te===e.scaleIdx?I(te):te,L=b+e.scale.map((te,le)=>T(le)).join(p),U=()=>[E,v].filter(Boolean).join(" "),J=()=>[U(),C,L," "].filter(Boolean).join(` +`);return o&&(C=this.styles.cyan(C),L=this.styles.cyan(L)),J()}async renderChoices(){if(this.state.submitted)return"";let e=this.visible.map(async(o,a)=>await this.renderChoice(o,a)),r=await Promise.all(e);return r.length||r.push(this.styles.danger("No matching choices")),r.join(` +`)}format(){return this.state.submitted?this.choices.map(r=>this.styles.info(r.scaleIdx)).join(", "):""}async render(){let{submitted:e,size:r}=this.state,o=await this.prefix(),a=await this.separator(),n=await this.message(),u=[o,n,a].filter(Boolean).join(" ");this.state.prompt=u;let A=await this.header(),p=await this.format(),h=await this.error()||await this.hint(),E=await this.renderChoices(),I=await this.footer();(p||!h)&&(u+=" "+p),h&&!u.includes(h)&&(u+=" "+h),e&&!p&&!E&&this.multiple&&this.type!=="form"&&(u+=this.styles.danger(this.emptyError)),this.clear(r),this.write([u,A,E,I].filter(Boolean).join(` +`)),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIdx;return this.base.submit.call(this)}};function $ft(t,e={}){if(Array.isArray(e.scale))return e.scale.map(o=>({...o}));let r=[];for(let o=1;o<t+1;o++)r.push({i:o,selected:!1});return r}B0e.exports=y8});var P0e=_((k8t,D0e)=>{D0e.exports=o8()});var x0e=_((Q8t,S0e)=>{"use strict";var ept=uk(),E8=class extends ept{async initialize(){await super.initialize(),this.value=this.initial=!!this.options.initial,this.disabled=this.options.disabled||"no",this.enabled=this.options.enabled||"yes",await this.render()}reset(){this.value=this.initial,this.render()}delete(){this.alert()}toggle(){this.value=!this.value,this.render()}enable(){if(this.value===!0)return this.alert();this.value=!0,this.render()}disable(){if(this.value===!1)return this.alert();this.value=!1,this.render()}up(){this.toggle()}down(){this.toggle()}right(){this.toggle()}left(){this.toggle()}next(){this.toggle()}prev(){this.toggle()}dispatch(e="",r){switch(e.toLowerCase()){case" ":return this.toggle();case"1":case"y":case"t":return this.enable();case"0":case"n":case"f":return this.disable();default:return this.alert()}}format(){let e=o=>this.styles.primary.underline(o);return[this.value?this.disabled:e(this.disabled),this.value?e(this.enabled):this.enabled].join(this.styles.muted(" / "))}async render(){let{size:e}=this.state,r=await this.header(),o=await this.prefix(),a=await this.separator(),n=await this.message(),u=await this.format(),A=await this.error()||await this.hint(),p=await this.footer(),h=[o,n,a,u].join(" ");this.state.prompt=h,A&&!h.includes(A)&&(h+=" "+A),this.clear(e),this.write([r,h,p].filter(Boolean).join(` +`)),this.write(this.margin[2]),this.restore()}};S0e.exports=E8});var k0e=_((F8t,b0e)=>{"use strict";var tpt=Sh(),C8=class extends tpt{constructor(e){if(super(e),typeof this.options.correctChoice!="number"||this.options.correctChoice<0)throw new Error("Please specify the index of the correct answer from the list of choices")}async toChoices(e,r){let o=await super.toChoices(e,r);if(o.length<2)throw new Error("Please give at least two choices to the user");if(this.options.correctChoice>o.length)throw new Error("Please specify the index of the correct answer from the list of choices");return o}check(e){return e.index===this.options.correctChoice}async result(e){return{selectedAnswer:e,correctAnswer:this.options.choices[this.options.correctChoice].value,correct:await this.check(this.state)}}};b0e.exports=C8});var F0e=_(w8=>{"use strict";var Q0e=No(),As=(t,e)=>{Q0e.defineExport(w8,t,e),Q0e.defineExport(w8,t.toLowerCase(),e)};As("AutoComplete",()=>Ohe());As("BasicAuth",()=>Yhe());As("Confirm",()=>Khe());As("Editable",()=>zhe());As("Form",()=>ck());As("Input",()=>o8());As("Invisible",()=>n0e());As("List",()=>s0e());As("MultiSelect",()=>a0e());As("Numeral",()=>u0e());As("Password",()=>f0e());As("Scale",()=>g0e());As("Select",()=>Sh());As("Snippet",()=>C0e());As("Sort",()=>I0e());As("Survey",()=>v0e());As("Text",()=>P0e());As("Toggle",()=>x0e());As("Quiz",()=>k0e())});var R0e=_((R8t,T0e)=>{T0e.exports={ArrayPrompt:c2(),AuthPrompt:e8(),BooleanPrompt:uk(),NumberPrompt:A8(),StringPrompt:Yd()}});var A2=_((N8t,L0e)=>{"use strict";var N0e=Be("assert"),B8=Be("events"),xh=No(),Jc=class extends B8{constructor(e,r){super(),this.options=xh.merge({},e),this.answers={...r}}register(e,r){if(xh.isObject(e)){for(let a of Object.keys(e))this.register(a,e[a]);return this}N0e.equal(typeof r,"function","expected a function");let o=e.toLowerCase();return r.prototype instanceof this.Prompt?this.prompts[o]=r:this.prompts[o]=r(this.Prompt,this),this}async prompt(e=[]){for(let r of[].concat(e))try{typeof r=="function"&&(r=await r.call(this)),await this.ask(xh.merge({},this.options,r))}catch(o){return Promise.reject(o)}return this.answers}async ask(e){typeof e=="function"&&(e=await e.call(this));let r=xh.merge({},this.options,e),{type:o,name:a}=e,{set:n,get:u}=xh;if(typeof o=="function"&&(o=await o.call(this,e,this.answers)),!o)return this.answers[a];N0e(this.prompts[o],`Prompt "${o}" is not registered`);let A=new this.prompts[o](r),p=u(this.answers,a);A.state.answers=this.answers,A.enquirer=this,a&&A.on("submit",E=>{this.emit("answer",a,E,A),n(this.answers,a,E)});let h=A.emit.bind(A);return A.emit=(...E)=>(this.emit.call(this,...E),h(...E)),this.emit("prompt",A,this),r.autofill&&p!=null?(A.value=A.input=p,r.autofill==="show"&&await A.submit()):p=A.value=await A.run(),p}use(e){return e.call(this,this),this}set Prompt(e){this._Prompt=e}get Prompt(){return this._Prompt||this.constructor.Prompt}get prompts(){return this.constructor.prompts}static set Prompt(e){this._Prompt=e}static get Prompt(){return this._Prompt||hC()}static get prompts(){return F0e()}static get types(){return R0e()}static get prompt(){let e=(r,...o)=>{let a=new this(...o),n=a.emit.bind(a);return a.emit=(...u)=>(e.emit(...u),n(...u)),a.prompt(r)};return xh.mixinEmitter(e,new B8),e}};xh.mixinEmitter(Jc,new B8);var I8=Jc.prompts;for(let t of Object.keys(I8)){let e=t.toLowerCase(),r=o=>new I8[t](o).run();Jc.prompt[e]=r,Jc[e]=r,Jc[t]||Reflect.defineProperty(Jc,t,{get:()=>I8[t]})}var u2=t=>{xh.defineExport(Jc,t,()=>Jc.types[t])};u2("ArrayPrompt");u2("AuthPrompt");u2("BooleanPrompt");u2("NumberPrompt");u2("StringPrompt");L0e.exports=Jc});var g2=_((mHt,q0e)=>{var apt=Zb();function lpt(t,e,r){var o=t==null?void 0:apt(t,e);return o===void 0?r:o}q0e.exports=lpt});var W0e=_((BHt,Y0e)=>{function cpt(t,e){for(var r=-1,o=t==null?0:t.length;++r<o&&e(t[r],r,t)!==!1;);return t}Y0e.exports=cpt});var K0e=_((vHt,V0e)=>{var upt=gd(),Apt=zP();function fpt(t,e){return t&&upt(e,Apt(e),t)}V0e.exports=fpt});var z0e=_((DHt,J0e)=>{var ppt=gd(),hpt=qy();function gpt(t,e){return t&&ppt(e,hpt(e),t)}J0e.exports=gpt});var Z0e=_((PHt,X0e)=>{var dpt=gd(),mpt=GP();function ypt(t,e){return dpt(t,mpt(t),e)}X0e.exports=ypt});var b8=_((SHt,$0e)=>{var Ept=qP(),Cpt=tS(),wpt=GP(),Ipt=KN(),Bpt=Object.getOwnPropertySymbols,vpt=Bpt?function(t){for(var e=[];t;)Ept(e,wpt(t)),t=Cpt(t);return e}:Ipt;$0e.exports=vpt});var tge=_((xHt,ege)=>{var Dpt=gd(),Ppt=b8();function Spt(t,e){return Dpt(t,Ppt(t),e)}ege.exports=Spt});var k8=_((bHt,rge)=>{var xpt=VN(),bpt=b8(),kpt=qy();function Qpt(t){return xpt(t,kpt,bpt)}rge.exports=Qpt});var ige=_((kHt,nge)=>{var Fpt=Object.prototype,Tpt=Fpt.hasOwnProperty;function Rpt(t){var e=t.length,r=new t.constructor(e);return e&&typeof t[0]=="string"&&Tpt.call(t,"index")&&(r.index=t.index,r.input=t.input),r}nge.exports=Rpt});var oge=_((QHt,sge)=>{var Npt=$P();function Lpt(t,e){var r=e?Npt(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.byteLength)}sge.exports=Lpt});var lge=_((FHt,age)=>{var Mpt=/\w*$/;function Opt(t){var e=new t.constructor(t.source,Mpt.exec(t));return e.lastIndex=t.lastIndex,e}age.exports=Opt});var pge=_((THt,fge)=>{var cge=fd(),uge=cge?cge.prototype:void 0,Age=uge?uge.valueOf:void 0;function Upt(t){return Age?Object(Age.call(t)):{}}fge.exports=Upt});var gge=_((RHt,hge)=>{var _pt=$P(),Hpt=oge(),jpt=lge(),qpt=pge(),Gpt=lL(),Ypt="[object Boolean]",Wpt="[object Date]",Vpt="[object Map]",Kpt="[object Number]",Jpt="[object RegExp]",zpt="[object Set]",Xpt="[object String]",Zpt="[object Symbol]",$pt="[object ArrayBuffer]",eht="[object DataView]",tht="[object Float32Array]",rht="[object Float64Array]",nht="[object Int8Array]",iht="[object Int16Array]",sht="[object Int32Array]",oht="[object Uint8Array]",aht="[object Uint8ClampedArray]",lht="[object Uint16Array]",cht="[object Uint32Array]";function uht(t,e,r){var o=t.constructor;switch(e){case $pt:return _pt(t);case Ypt:case Wpt:return new o(+t);case eht:return Hpt(t,r);case tht:case rht:case nht:case iht:case sht:case oht:case aht:case lht:case cht:return Gpt(t,r);case Vpt:return new o;case Kpt:case Xpt:return new o(t);case Jpt:return jpt(t);case zpt:return new o;case Zpt:return qpt(t)}}hge.exports=uht});var mge=_((NHt,dge)=>{var Aht=qI(),fht=Ju(),pht="[object Map]";function hht(t){return fht(t)&&Aht(t)==pht}dge.exports=hht});var wge=_((LHt,Cge)=>{var ght=mge(),dht=WP(),yge=VP(),Ege=yge&&yge.isMap,mht=Ege?dht(Ege):ght;Cge.exports=mht});var Bge=_((MHt,Ige)=>{var yht=qI(),Eht=Ju(),Cht="[object Set]";function wht(t){return Eht(t)&&yht(t)==Cht}Ige.exports=wht});var Sge=_((OHt,Pge)=>{var Iht=Bge(),Bht=WP(),vge=VP(),Dge=vge&&vge.isSet,vht=Dge?Bht(Dge):Iht;Pge.exports=vht});var Q8=_((UHt,Qge)=>{var Dht=HP(),Pht=W0e(),Sht=rS(),xht=K0e(),bht=z0e(),kht=aL(),Qht=eS(),Fht=Z0e(),Tht=tge(),Rht=ZN(),Nht=k8(),Lht=qI(),Mht=ige(),Oht=gge(),Uht=cL(),_ht=Hl(),Hht=OI(),jht=wge(),qht=il(),Ght=Sge(),Yht=zP(),Wht=qy(),Vht=1,Kht=2,Jht=4,xge="[object Arguments]",zht="[object Array]",Xht="[object Boolean]",Zht="[object Date]",$ht="[object Error]",bge="[object Function]",e0t="[object GeneratorFunction]",t0t="[object Map]",r0t="[object Number]",kge="[object Object]",n0t="[object RegExp]",i0t="[object Set]",s0t="[object String]",o0t="[object Symbol]",a0t="[object WeakMap]",l0t="[object ArrayBuffer]",c0t="[object DataView]",u0t="[object Float32Array]",A0t="[object Float64Array]",f0t="[object Int8Array]",p0t="[object Int16Array]",h0t="[object Int32Array]",g0t="[object Uint8Array]",d0t="[object Uint8ClampedArray]",m0t="[object Uint16Array]",y0t="[object Uint32Array]",ri={};ri[xge]=ri[zht]=ri[l0t]=ri[c0t]=ri[Xht]=ri[Zht]=ri[u0t]=ri[A0t]=ri[f0t]=ri[p0t]=ri[h0t]=ri[t0t]=ri[r0t]=ri[kge]=ri[n0t]=ri[i0t]=ri[s0t]=ri[o0t]=ri[g0t]=ri[d0t]=ri[m0t]=ri[y0t]=!0;ri[$ht]=ri[bge]=ri[a0t]=!1;function pk(t,e,r,o,a,n){var u,A=e&Vht,p=e&Kht,h=e&Jht;if(r&&(u=a?r(t,o,a,n):r(t)),u!==void 0)return u;if(!qht(t))return t;var E=_ht(t);if(E){if(u=Mht(t),!A)return Qht(t,u)}else{var I=Lht(t),v=I==bge||I==e0t;if(Hht(t))return kht(t,A);if(I==kge||I==xge||v&&!a){if(u=p||v?{}:Uht(t),!A)return p?Tht(t,bht(u,t)):Fht(t,xht(u,t))}else{if(!ri[I])return a?t:{};u=Oht(t,I,A)}}n||(n=new Dht);var b=n.get(t);if(b)return b;n.set(t,u),Ght(t)?t.forEach(function(L){u.add(pk(L,e,r,L,t,n))}):jht(t)&&t.forEach(function(L,U){u.set(U,pk(L,e,r,U,t,n))});var C=h?p?Nht:Rht:p?Wht:Yht,T=E?void 0:C(t);return Pht(T||t,function(L,U){T&&(U=L,L=t[U]),Sht(u,U,pk(L,e,r,U,t,n))}),u}Qge.exports=pk});var F8=_((_Ht,Fge)=>{var E0t=Q8(),C0t=1,w0t=4;function I0t(t){return E0t(t,C0t|w0t)}Fge.exports=I0t});var T8=_((HHt,Tge)=>{var B0t=v_();function v0t(t,e,r){return t==null?t:B0t(t,e,r)}Tge.exports=v0t});var Oge=_((VHt,Mge)=>{var D0t=Object.prototype,P0t=D0t.hasOwnProperty;function S0t(t,e){return t!=null&&P0t.call(t,e)}Mge.exports=S0t});var _ge=_((KHt,Uge)=>{var x0t=Oge(),b0t=D_();function k0t(t,e){return t!=null&&b0t(t,e,x0t)}Uge.exports=k0t});var jge=_((JHt,Hge)=>{function Q0t(t){var e=t==null?0:t.length;return e?t[e-1]:void 0}Hge.exports=Q0t});var Gge=_((zHt,qge)=>{var F0t=Zb(),T0t=gU();function R0t(t,e){return e.length<2?t:F0t(t,T0t(e,0,-1))}qge.exports=R0t});var N8=_((XHt,Yge)=>{var N0t=jd(),L0t=jge(),M0t=Gge(),O0t=aC();function U0t(t,e){return e=N0t(e,t),t=M0t(t,e),t==null||delete t[O0t(L0t(e))]}Yge.exports=U0t});var L8=_((ZHt,Wge)=>{var _0t=N8();function H0t(t,e){return t==null?!0:_0t(t,e)}Wge.exports=H0t});var Xge=_((S6t,G0t)=>{G0t.exports={name:"@yarnpkg/cli",version:"4.0.2",license:"BSD-2-Clause",main:"./sources/index.ts",exports:{".":"./sources/index.ts","./polyfills":"./sources/polyfills.ts","./package.json":"./package.json"},dependencies:{"@yarnpkg/core":"workspace:^","@yarnpkg/fslib":"workspace:^","@yarnpkg/libzip":"workspace:^","@yarnpkg/parsers":"workspace:^","@yarnpkg/plugin-compat":"workspace:^","@yarnpkg/plugin-constraints":"workspace:^","@yarnpkg/plugin-dlx":"workspace:^","@yarnpkg/plugin-essentials":"workspace:^","@yarnpkg/plugin-exec":"workspace:^","@yarnpkg/plugin-file":"workspace:^","@yarnpkg/plugin-git":"workspace:^","@yarnpkg/plugin-github":"workspace:^","@yarnpkg/plugin-http":"workspace:^","@yarnpkg/plugin-init":"workspace:^","@yarnpkg/plugin-interactive-tools":"workspace:^","@yarnpkg/plugin-link":"workspace:^","@yarnpkg/plugin-nm":"workspace:^","@yarnpkg/plugin-npm":"workspace:^","@yarnpkg/plugin-npm-cli":"workspace:^","@yarnpkg/plugin-pack":"workspace:^","@yarnpkg/plugin-patch":"workspace:^","@yarnpkg/plugin-pnp":"workspace:^","@yarnpkg/plugin-pnpm":"workspace:^","@yarnpkg/plugin-stage":"workspace:^","@yarnpkg/plugin-typescript":"workspace:^","@yarnpkg/plugin-version":"workspace:^","@yarnpkg/plugin-workspace-tools":"workspace:^","@yarnpkg/shell":"workspace:^","ci-info":"^3.2.0",clipanion:"^4.0.0-rc.2",semver:"^7.1.2",tslib:"^2.4.0",typanion:"^3.14.0"},devDependencies:{"@types/semver":"^7.1.0","@yarnpkg/builder":"workspace:^","@yarnpkg/monorepo":"workspace:^","@yarnpkg/pnpify":"workspace:^"},peerDependencies:{"@yarnpkg/core":"workspace:^"},scripts:{postpack:"rm -rf lib",prepack:'run build:compile "$(pwd)"',"build:cli+hook":"run build:pnp:hook && builder build bundle","build:cli":"builder build bundle","run:cli":"builder run","update-local":"run build:cli --no-git-hash && rsync -a --delete bundles/ bin/"},publishConfig:{main:"./lib/index.js",bin:null,exports:{".":"./lib/index.js","./package.json":"./package.json"}},files:["/lib/**/*","!/lib/pluginConfiguration.*","!/lib/cli.*"],"@yarnpkg/builder":{bundles:{standard:["@yarnpkg/plugin-essentials","@yarnpkg/plugin-compat","@yarnpkg/plugin-constraints","@yarnpkg/plugin-dlx","@yarnpkg/plugin-exec","@yarnpkg/plugin-file","@yarnpkg/plugin-git","@yarnpkg/plugin-github","@yarnpkg/plugin-http","@yarnpkg/plugin-init","@yarnpkg/plugin-interactive-tools","@yarnpkg/plugin-link","@yarnpkg/plugin-nm","@yarnpkg/plugin-npm","@yarnpkg/plugin-npm-cli","@yarnpkg/plugin-pack","@yarnpkg/plugin-patch","@yarnpkg/plugin-pnp","@yarnpkg/plugin-pnpm","@yarnpkg/plugin-stage","@yarnpkg/plugin-typescript","@yarnpkg/plugin-version","@yarnpkg/plugin-workspace-tools"]}},repository:{type:"git",url:"ssh://git@github.com/yarnpkg/berry.git",directory:"packages/yarnpkg-cli"},engines:{node:">=18.12.0"}}});var Y8=_((n5t,ude)=>{"use strict";ude.exports=function(e,r){r===!0&&(r=0);var o="";if(typeof e=="string")try{o=new URL(e).protocol}catch{}else e&&e.constructor===URL&&(o=e.protocol);var a=o.split(/\:|\+/).filter(Boolean);return typeof r=="number"?a[r]:a}});var fde=_((i5t,Ade)=>{"use strict";var cgt=Y8();function ugt(t){var e={protocols:[],protocol:null,port:null,resource:"",host:"",user:"",password:"",pathname:"",hash:"",search:"",href:t,query:{},parse_failed:!1};try{var r=new URL(t);e.protocols=cgt(r),e.protocol=e.protocols[0],e.port=r.port,e.resource=r.hostname,e.host=r.host,e.user=r.username||"",e.password=r.password||"",e.pathname=r.pathname,e.hash=r.hash.slice(1),e.search=r.search.slice(1),e.href=r.href,e.query=Object.fromEntries(r.searchParams)}catch{e.protocols=["file"],e.protocol=e.protocols[0],e.port="",e.resource="",e.user="",e.pathname="",e.hash="",e.search="",e.href=t,e.query={},e.parse_failed=!0}return e}Ade.exports=ugt});var gde=_((s5t,hde)=>{"use strict";var Agt=fde();function fgt(t){return t&&typeof t=="object"&&"default"in t?t:{default:t}}var pgt=fgt(Agt),hgt="text/plain",ggt="us-ascii",pde=(t,e)=>e.some(r=>r instanceof RegExp?r.test(t):r===t),dgt=(t,{stripHash:e})=>{let r=/^data:(?<type>[^,]*?),(?<data>[^#]*?)(?:#(?<hash>.*))?$/.exec(t);if(!r)throw new Error(`Invalid URL: ${t}`);let{type:o,data:a,hash:n}=r.groups,u=o.split(";");n=e?"":n;let A=!1;u[u.length-1]==="base64"&&(u.pop(),A=!0);let p=(u.shift()||"").toLowerCase(),E=[...u.map(I=>{let[v,b=""]=I.split("=").map(C=>C.trim());return v==="charset"&&(b=b.toLowerCase(),b===ggt)?"":`${v}${b?`=${b}`:""}`}).filter(Boolean)];return A&&E.push("base64"),(E.length>0||p&&p!==hgt)&&E.unshift(p),`data:${E.join(";")},${A?a.trim():a}${n?`#${n}`:""}`};function mgt(t,e){if(e={defaultProtocol:"http:",normalizeProtocol:!0,forceHttp:!1,forceHttps:!1,stripAuthentication:!0,stripHash:!1,stripTextFragment:!0,stripWWW:!0,removeQueryParameters:[/^utm_\w+/i],removeTrailingSlash:!0,removeSingleSlash:!0,removeDirectoryIndex:!1,sortQueryParameters:!0,...e},t=t.trim(),/^data:/i.test(t))return dgt(t,e);if(/^view-source:/i.test(t))throw new Error("`view-source:` is not supported as it is a non-standard protocol");let r=t.startsWith("//");!r&&/^\.*\//.test(t)||(t=t.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,e.defaultProtocol));let a=new URL(t);if(e.forceHttp&&e.forceHttps)throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");if(e.forceHttp&&a.protocol==="https:"&&(a.protocol="http:"),e.forceHttps&&a.protocol==="http:"&&(a.protocol="https:"),e.stripAuthentication&&(a.username="",a.password=""),e.stripHash?a.hash="":e.stripTextFragment&&(a.hash=a.hash.replace(/#?:~:text.*?$/i,"")),a.pathname){let u=/\b[a-z][a-z\d+\-.]{1,50}:\/\//g,A=0,p="";for(;;){let E=u.exec(a.pathname);if(!E)break;let I=E[0],v=E.index,b=a.pathname.slice(A,v);p+=b.replace(/\/{2,}/g,"/"),p+=I,A=v+I.length}let h=a.pathname.slice(A,a.pathname.length);p+=h.replace(/\/{2,}/g,"/"),a.pathname=p}if(a.pathname)try{a.pathname=decodeURI(a.pathname)}catch{}if(e.removeDirectoryIndex===!0&&(e.removeDirectoryIndex=[/^index\.[a-z]+$/]),Array.isArray(e.removeDirectoryIndex)&&e.removeDirectoryIndex.length>0){let u=a.pathname.split("/"),A=u[u.length-1];pde(A,e.removeDirectoryIndex)&&(u=u.slice(0,-1),a.pathname=u.slice(1).join("/")+"/")}if(a.hostname&&(a.hostname=a.hostname.replace(/\.$/,""),e.stripWWW&&/^www\.(?!www\.)[a-z\-\d]{1,63}\.[a-z.\-\d]{2,63}$/.test(a.hostname)&&(a.hostname=a.hostname.replace(/^www\./,""))),Array.isArray(e.removeQueryParameters))for(let u of[...a.searchParams.keys()])pde(u,e.removeQueryParameters)&&a.searchParams.delete(u);if(e.removeQueryParameters===!0&&(a.search=""),e.sortQueryParameters){a.searchParams.sort();try{a.search=decodeURIComponent(a.search)}catch{}}e.removeTrailingSlash&&(a.pathname=a.pathname.replace(/\/$/,""));let n=t;return t=a.toString(),!e.removeSingleSlash&&a.pathname==="/"&&!n.endsWith("/")&&a.hash===""&&(t=t.replace(/\/$/,"")),(e.removeTrailingSlash||a.pathname==="/")&&a.hash===""&&e.removeSingleSlash&&(t=t.replace(/\/$/,"")),r&&!e.normalizeProtocol&&(t=t.replace(/^http:\/\//,"//")),e.stripProtocol&&(t=t.replace(/^(?:https?:)?\/\//,"")),t}var W8=(t,e=!1)=>{let r=/^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:]([\~,\.\w,\-,\_,\/]+?(?:\.git|\/)?)$/,o=n=>{let u=new Error(n);throw u.subject_url=t,u};(typeof t!="string"||!t.trim())&&o("Invalid url."),t.length>W8.MAX_INPUT_LENGTH&&o("Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH."),e&&(typeof e!="object"&&(e={stripHash:!1}),t=mgt(t,e));let a=pgt.default(t);if(a.parse_failed){let n=a.href.match(r);n?(a.protocols=["ssh"],a.protocol="ssh",a.resource=n[2],a.host=n[2],a.user=n[1],a.pathname=`/${n[3]}`,a.parse_failed=!1):o("URL parsing failed.")}return a};W8.MAX_INPUT_LENGTH=2048;hde.exports=W8});var yde=_((o5t,mde)=>{"use strict";var ygt=Y8();function dde(t){if(Array.isArray(t))return t.indexOf("ssh")!==-1||t.indexOf("rsync")!==-1;if(typeof t!="string")return!1;var e=ygt(t);if(t=t.substring(t.indexOf("://")+3),dde(e))return!0;var r=new RegExp(".([a-zA-Z\\d]+):(\\d+)/");return!t.match(r)&&t.indexOf("@")<t.indexOf(":")}mde.exports=dde});var wde=_((a5t,Cde)=>{"use strict";var Egt=gde(),Ede=yde();function Cgt(t){var e=Egt(t);return e.token="",e.password==="x-oauth-basic"?e.token=e.user:e.user==="x-token-auth"&&(e.token=e.password),Ede(e.protocols)||e.protocols.length===0&&Ede(t)?e.protocol="ssh":e.protocols.length?e.protocol=e.protocols[0]:(e.protocol="file",e.protocols=["file"]),e.href=e.href.replace(/\/$/,""),e}Cde.exports=Cgt});var Bde=_((l5t,Ide)=>{"use strict";var wgt=wde();function V8(t){if(typeof t!="string")throw new Error("The url must be a string.");var e=/^([a-z\d-]{1,39})\/([-\.\w]{1,100})$/i;e.test(t)&&(t="https://github.com/"+t);var r=wgt(t),o=r.resource.split("."),a=null;switch(r.toString=function(L){return V8.stringify(this,L)},r.source=o.length>2?o.slice(1-o.length).join("."):r.source=r.resource,r.git_suffix=/\.git$/.test(r.pathname),r.name=decodeURIComponent((r.pathname||r.href).replace(/(^\/)|(\/$)/g,"").replace(/\.git$/,"")),r.owner=decodeURIComponent(r.user),r.source){case"git.cloudforge.com":r.owner=r.user,r.organization=o[0],r.source="cloudforge.com";break;case"visualstudio.com":if(r.resource==="vs-ssh.visualstudio.com"){a=r.name.split("/"),a.length===4&&(r.organization=a[1],r.owner=a[2],r.name=a[3],r.full_name=a[2]+"/"+a[3]);break}else{a=r.name.split("/"),a.length===2?(r.owner=a[1],r.name=a[1],r.full_name="_git/"+r.name):a.length===3?(r.name=a[2],a[0]==="DefaultCollection"?(r.owner=a[2],r.organization=a[0],r.full_name=r.organization+"/_git/"+r.name):(r.owner=a[0],r.full_name=r.owner+"/_git/"+r.name)):a.length===4&&(r.organization=a[0],r.owner=a[1],r.name=a[3],r.full_name=r.organization+"/"+r.owner+"/_git/"+r.name);break}case"dev.azure.com":case"azure.com":if(r.resource==="ssh.dev.azure.com"){a=r.name.split("/"),a.length===4&&(r.organization=a[1],r.owner=a[2],r.name=a[3]);break}else{a=r.name.split("/"),a.length===5?(r.organization=a[0],r.owner=a[1],r.name=a[4],r.full_name="_git/"+r.name):a.length===3?(r.name=a[2],a[0]==="DefaultCollection"?(r.owner=a[2],r.organization=a[0],r.full_name=r.organization+"/_git/"+r.name):(r.owner=a[0],r.full_name=r.owner+"/_git/"+r.name)):a.length===4&&(r.organization=a[0],r.owner=a[1],r.name=a[3],r.full_name=r.organization+"/"+r.owner+"/_git/"+r.name),r.query&&r.query.path&&(r.filepath=r.query.path.replace(/^\/+/g,"")),r.query&&r.query.version&&(r.ref=r.query.version.replace(/^GB/,""));break}default:a=r.name.split("/");var n=a.length-1;if(a.length>=2){var u=a.indexOf("-",2),A=a.indexOf("blob",2),p=a.indexOf("tree",2),h=a.indexOf("commit",2),E=a.indexOf("src",2),I=a.indexOf("raw",2),v=a.indexOf("edit",2);n=u>0?u-1:A>0?A-1:p>0?p-1:h>0?h-1:E>0?E-1:I>0?I-1:v>0?v-1:n,r.owner=a.slice(0,n).join("/"),r.name=a[n],h&&(r.commit=a[n+2])}r.ref="",r.filepathtype="",r.filepath="";var b=a.length>n&&a[n+1]==="-"?n+1:n;a.length>b+2&&["raw","src","blob","tree","edit"].indexOf(a[b+1])>=0&&(r.filepathtype=a[b+1],r.ref=a[b+2],a.length>b+3&&(r.filepath=a.slice(b+3).join("/"))),r.organization=r.owner;break}r.full_name||(r.full_name=r.owner,r.name&&(r.full_name&&(r.full_name+="/"),r.full_name+=r.name)),r.owner.startsWith("scm/")&&(r.source="bitbucket-server",r.owner=r.owner.replace("scm/",""),r.organization=r.owner,r.full_name=r.owner+"/"+r.name);var C=/(projects|users)\/(.*?)\/repos\/(.*?)((\/.*$)|$)/,T=C.exec(r.pathname);return T!=null&&(r.source="bitbucket-server",T[1]==="users"?r.owner="~"+T[2]:r.owner=T[2],r.organization=r.owner,r.name=T[3],a=T[4].split("/"),a.length>1&&(["raw","browse"].indexOf(a[1])>=0?(r.filepathtype=a[1],a.length>2&&(r.filepath=a.slice(2).join("/"))):a[1]==="commits"&&a.length>2&&(r.commit=a[2])),r.full_name=r.owner+"/"+r.name,r.query.at?r.ref=r.query.at:r.ref=""),r}V8.stringify=function(t,e){e=e||(t.protocols&&t.protocols.length?t.protocols.join("+"):t.protocol);var r=t.port?":"+t.port:"",o=t.user||"git",a=t.git_suffix?".git":"";switch(e){case"ssh":return r?"ssh://"+o+"@"+t.resource+r+"/"+t.full_name+a:o+"@"+t.resource+":"+t.full_name+a;case"git+ssh":case"ssh+git":case"ftp":case"ftps":return e+"://"+o+"@"+t.resource+r+"/"+t.full_name+a;case"http":case"https":var n=t.token?Igt(t):t.user&&(t.protocols.includes("http")||t.protocols.includes("https"))?t.user+"@":"";return e+"://"+n+t.resource+r+"/"+Bgt(t)+a;default:return t.href}};function Igt(t){switch(t.source){case"bitbucket.org":return"x-token-auth:"+t.token+"@";default:return t.token+"@"}}function Bgt(t){switch(t.source){case"bitbucket-server":return"scm/"+t.full_name;default:return""+t.full_name}}Ide.exports=V8});var Ude=_((H9t,Ode)=>{var Rgt=jx(),Ngt=eS(),Lgt=Hl(),Mgt=fE(),Ogt=B_(),Ugt=aC(),_gt=R1();function Hgt(t){return Lgt(t)?Rgt(t,Ugt):Mgt(t)?[t]:Ngt(Ogt(_gt(t)))}Ode.exports=Hgt});function Ygt(t,e){return e===1&&Ggt.has(t[0])}function I2(t){let e=Array.isArray(t)?t:(0,jde.default)(t);return e.map((o,a)=>jgt.test(o)?`[${o}]`:qgt.test(o)&&!Ygt(e,a)?`.${o}`:`[${JSON.stringify(o)}]`).join("").replace(/^\./,"")}function Wgt(t,e){let r=[];if(e.methodName!==null&&r.push(de.pretty(t,e.methodName,de.Type.CODE)),e.file!==null){let o=[];o.push(de.pretty(t,e.file,de.Type.PATH)),e.line!==null&&(o.push(de.pretty(t,e.line,de.Type.NUMBER)),e.column!==null&&o.push(de.pretty(t,e.column,de.Type.NUMBER))),r.push(`(${o.join(de.pretty(t,":","grey"))})`)}return r.join(" ")}function mk(t,{manifestUpdates:e,reportedErrors:r},{fix:o}={}){let a=new Map,n=new Map,u=[...r.keys()].map(A=>[A,new Map]);for(let[A,p]of[...u,...e]){let h=r.get(A)?.map(b=>({text:b,fixable:!1}))??[],E=!1,I=t.getWorkspaceByCwd(A),v=I.manifest.exportTo({});for(let[b,C]of p){if(C.size>1){let T=[...C].map(([L,U])=>{let J=de.pretty(t.configuration,L,de.Type.INSPECT),te=U.size>0?Wgt(t.configuration,U.values().next().value):null;return te!==null?` +${J} at ${te}`:` +${J}`}).join("");h.push({text:`Conflict detected in constraint targeting ${de.pretty(t.configuration,b,de.Type.CODE)}; conflicting values are:${T}`,fixable:!1})}else{let[[T]]=C,L=(0,_de.default)(v,b);if(JSON.stringify(L)===JSON.stringify(T))continue;if(!o){let U=typeof L>"u"?`Missing field ${de.pretty(t.configuration,b,de.Type.CODE)}; expected ${de.pretty(t.configuration,T,de.Type.INSPECT)}`:typeof T>"u"?`Extraneous field ${de.pretty(t.configuration,b,de.Type.CODE)} currently set to ${de.pretty(t.configuration,L,de.Type.INSPECT)}`:`Invalid field ${de.pretty(t.configuration,b,de.Type.CODE)}; expected ${de.pretty(t.configuration,T,de.Type.INSPECT)}, found ${de.pretty(t.configuration,L,de.Type.INSPECT)}`;h.push({text:U,fixable:!0});continue}typeof T>"u"?(0,qde.default)(v,b):(0,Hde.default)(v,b,T),E=!0}E&&a.set(I,v)}h.length>0&&n.set(I,h)}return{changedWorkspaces:a,remainingErrors:n}}function Gde(t,{configuration:e}){let r={children:[]};for(let[o,a]of t){let n=[];for(let A of a){let p=A.text.split(/\n/);A.fixable&&(p[0]=`${de.pretty(e,"\u2699","gray")} ${p[0]}`),n.push({value:de.tuple(de.Type.NO_HINT,p[0]),children:p.slice(1).map(h=>({value:de.tuple(de.Type.NO_HINT,h)}))})}let u={value:de.tuple(de.Type.LOCATOR,o.anchoredLocator),children:je.sortMap(n,A=>A.value[1])};r.children.push(u)}return r.children=je.sortMap(r.children,o=>o.value[1]),r}var _de,Hde,jde,qde,CC,jgt,qgt,Ggt,B2=Et(()=>{Ye();_de=$e(g2()),Hde=$e(T8()),jde=$e(Ude()),qde=$e(L8()),CC=class{constructor(e){this.indexedFields=e;this.items=[];this.indexes={};this.clear()}clear(){this.items=[];for(let e of this.indexedFields)this.indexes[e]=new Map}insert(e){this.items.push(e);for(let r of this.indexedFields){let o=Object.hasOwn(e,r)?e[r]:void 0;if(typeof o>"u")continue;je.getArrayWithDefault(this.indexes[r],o).push(e)}return e}find(e){if(typeof e>"u")return this.items;let r=Object.entries(e);if(r.length===0)return this.items;let o=[],a;for(let[u,A]of r){let p=u,h=Object.hasOwn(this.indexes,p)?this.indexes[p]:void 0;if(typeof h>"u"){o.push([p,A]);continue}let E=new Set(h.get(A)??[]);if(E.size===0)return[];if(typeof a>"u")a=E;else for(let I of a)E.has(I)||a.delete(I);if(a.size===0)break}let n=[...a??[]];return o.length>0&&(n=n.filter(u=>{for(let[A,p]of o)if(!(typeof p<"u"?Object.hasOwn(u,A)&&u[A]===p:Object.hasOwn(u,A)===!1))return!1;return!0})),n}},jgt=/^[0-9]+$/,qgt=/^[a-zA-Z0-9_]+$/,Ggt=new Set(["scripts",...Mt.allDependencies])});var Yde=_(($9t,aH)=>{var Vgt;(function(t){var e=function(){return{"append/2":[new t.type.Rule(new t.type.Term("append",[new t.type.Var("X"),new t.type.Var("L")]),new t.type.Term("foldl",[new t.type.Term("append",[]),new t.type.Var("X"),new t.type.Term("[]",[]),new t.type.Var("L")]))],"append/3":[new t.type.Rule(new t.type.Term("append",[new t.type.Term("[]",[]),new t.type.Var("X"),new t.type.Var("X")]),null),new t.type.Rule(new t.type.Term("append",[new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("T")]),new t.type.Var("X"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("S")])]),new t.type.Term("append",[new t.type.Var("T"),new t.type.Var("X"),new t.type.Var("S")]))],"member/2":[new t.type.Rule(new t.type.Term("member",[new t.type.Var("X"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("_")])]),null),new t.type.Rule(new t.type.Term("member",[new t.type.Var("X"),new t.type.Term(".",[new t.type.Var("_"),new t.type.Var("Xs")])]),new t.type.Term("member",[new t.type.Var("X"),new t.type.Var("Xs")]))],"permutation/2":[new t.type.Rule(new t.type.Term("permutation",[new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("permutation",[new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("T")]),new t.type.Var("S")]),new t.type.Term(",",[new t.type.Term("permutation",[new t.type.Var("T"),new t.type.Var("P")]),new t.type.Term(",",[new t.type.Term("append",[new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("P")]),new t.type.Term("append",[new t.type.Var("X"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("Y")]),new t.type.Var("S")])])]))],"maplist/2":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("X")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("Xs")])]))],"maplist/3":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("A"),new t.type.Var("As")]),new t.type.Term(".",[new t.type.Var("B"),new t.type.Var("Bs")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("A"),new t.type.Var("B")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("As"),new t.type.Var("Bs")])]))],"maplist/4":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("A"),new t.type.Var("As")]),new t.type.Term(".",[new t.type.Var("B"),new t.type.Var("Bs")]),new t.type.Term(".",[new t.type.Var("C"),new t.type.Var("Cs")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("A"),new t.type.Var("B"),new t.type.Var("C")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("As"),new t.type.Var("Bs"),new t.type.Var("Cs")])]))],"maplist/5":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("A"),new t.type.Var("As")]),new t.type.Term(".",[new t.type.Var("B"),new t.type.Var("Bs")]),new t.type.Term(".",[new t.type.Var("C"),new t.type.Var("Cs")]),new t.type.Term(".",[new t.type.Var("D"),new t.type.Var("Ds")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("A"),new t.type.Var("B"),new t.type.Var("C"),new t.type.Var("D")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("As"),new t.type.Var("Bs"),new t.type.Var("Cs"),new t.type.Var("Ds")])]))],"maplist/6":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("A"),new t.type.Var("As")]),new t.type.Term(".",[new t.type.Var("B"),new t.type.Var("Bs")]),new t.type.Term(".",[new t.type.Var("C"),new t.type.Var("Cs")]),new t.type.Term(".",[new t.type.Var("D"),new t.type.Var("Ds")]),new t.type.Term(".",[new t.type.Var("E"),new t.type.Var("Es")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("A"),new t.type.Var("B"),new t.type.Var("C"),new t.type.Var("D"),new t.type.Var("E")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("As"),new t.type.Var("Bs"),new t.type.Var("Cs"),new t.type.Var("Ds"),new t.type.Var("Es")])]))],"maplist/7":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("A"),new t.type.Var("As")]),new t.type.Term(".",[new t.type.Var("B"),new t.type.Var("Bs")]),new t.type.Term(".",[new t.type.Var("C"),new t.type.Var("Cs")]),new t.type.Term(".",[new t.type.Var("D"),new t.type.Var("Ds")]),new t.type.Term(".",[new t.type.Var("E"),new t.type.Var("Es")]),new t.type.Term(".",[new t.type.Var("F"),new t.type.Var("Fs")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("A"),new t.type.Var("B"),new t.type.Var("C"),new t.type.Var("D"),new t.type.Var("E"),new t.type.Var("F")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("As"),new t.type.Var("Bs"),new t.type.Var("Cs"),new t.type.Var("Ds"),new t.type.Var("Es"),new t.type.Var("Fs")])]))],"maplist/8":[new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("A"),new t.type.Var("As")]),new t.type.Term(".",[new t.type.Var("B"),new t.type.Var("Bs")]),new t.type.Term(".",[new t.type.Var("C"),new t.type.Var("Cs")]),new t.type.Term(".",[new t.type.Var("D"),new t.type.Var("Ds")]),new t.type.Term(".",[new t.type.Var("E"),new t.type.Var("Es")]),new t.type.Term(".",[new t.type.Var("F"),new t.type.Var("Fs")]),new t.type.Term(".",[new t.type.Var("G"),new t.type.Var("Gs")])]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P"),new t.type.Var("A"),new t.type.Var("B"),new t.type.Var("C"),new t.type.Var("D"),new t.type.Var("E"),new t.type.Var("F"),new t.type.Var("G")]),new t.type.Term("maplist",[new t.type.Var("P"),new t.type.Var("As"),new t.type.Var("Bs"),new t.type.Var("Cs"),new t.type.Var("Ds"),new t.type.Var("Es"),new t.type.Var("Fs"),new t.type.Var("Gs")])]))],"include/3":[new t.type.Rule(new t.type.Term("include",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("include",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("T")]),new t.type.Var("L")]),new t.type.Term(",",[new t.type.Term("=..",[new t.type.Var("P"),new t.type.Var("A")]),new t.type.Term(",",[new t.type.Term("append",[new t.type.Var("A"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Term("[]",[])]),new t.type.Var("B")]),new t.type.Term(",",[new t.type.Term("=..",[new t.type.Var("F"),new t.type.Var("B")]),new t.type.Term(",",[new t.type.Term(";",[new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("F")]),new t.type.Term(",",[new t.type.Term("=",[new t.type.Var("L"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("S")])]),new t.type.Term("!",[])])]),new t.type.Term("=",[new t.type.Var("L"),new t.type.Var("S")])]),new t.type.Term("include",[new t.type.Var("P"),new t.type.Var("T"),new t.type.Var("S")])])])])]))],"exclude/3":[new t.type.Rule(new t.type.Term("exclude",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Term("[]",[])]),null),new t.type.Rule(new t.type.Term("exclude",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("T")]),new t.type.Var("S")]),new t.type.Term(",",[new t.type.Term("exclude",[new t.type.Var("P"),new t.type.Var("T"),new t.type.Var("E")]),new t.type.Term(",",[new t.type.Term("=..",[new t.type.Var("P"),new t.type.Var("L")]),new t.type.Term(",",[new t.type.Term("append",[new t.type.Var("L"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Term("[]",[])]),new t.type.Var("Q")]),new t.type.Term(",",[new t.type.Term("=..",[new t.type.Var("R"),new t.type.Var("Q")]),new t.type.Term(";",[new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("R")]),new t.type.Term(",",[new t.type.Term("!",[]),new t.type.Term("=",[new t.type.Var("S"),new t.type.Var("E")])])]),new t.type.Term("=",[new t.type.Var("S"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("E")])])])])])])]))],"foldl/4":[new t.type.Rule(new t.type.Term("foldl",[new t.type.Var("_"),new t.type.Term("[]",[]),new t.type.Var("I"),new t.type.Var("I")]),null),new t.type.Rule(new t.type.Term("foldl",[new t.type.Var("P"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Var("T")]),new t.type.Var("I"),new t.type.Var("R")]),new t.type.Term(",",[new t.type.Term("=..",[new t.type.Var("P"),new t.type.Var("L")]),new t.type.Term(",",[new t.type.Term("append",[new t.type.Var("L"),new t.type.Term(".",[new t.type.Var("I"),new t.type.Term(".",[new t.type.Var("H"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Term("[]",[])])])]),new t.type.Var("L2")]),new t.type.Term(",",[new t.type.Term("=..",[new t.type.Var("P2"),new t.type.Var("L2")]),new t.type.Term(",",[new t.type.Term("call",[new t.type.Var("P2")]),new t.type.Term("foldl",[new t.type.Var("P"),new t.type.Var("T"),new t.type.Var("X"),new t.type.Var("R")])])])])]))],"select/3":[new t.type.Rule(new t.type.Term("select",[new t.type.Var("E"),new t.type.Term(".",[new t.type.Var("E"),new t.type.Var("Xs")]),new t.type.Var("Xs")]),null),new t.type.Rule(new t.type.Term("select",[new t.type.Var("E"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Ys")])]),new t.type.Term("select",[new t.type.Var("E"),new t.type.Var("Xs"),new t.type.Var("Ys")]))],"sum_list/2":[new t.type.Rule(new t.type.Term("sum_list",[new t.type.Term("[]",[]),new t.type.Num(0,!1)]),null),new t.type.Rule(new t.type.Term("sum_list",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Var("S")]),new t.type.Term(",",[new t.type.Term("sum_list",[new t.type.Var("Xs"),new t.type.Var("Y")]),new t.type.Term("is",[new t.type.Var("S"),new t.type.Term("+",[new t.type.Var("X"),new t.type.Var("Y")])])]))],"max_list/2":[new t.type.Rule(new t.type.Term("max_list",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Term("[]",[])]),new t.type.Var("X")]),null),new t.type.Rule(new t.type.Term("max_list",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Var("S")]),new t.type.Term(",",[new t.type.Term("max_list",[new t.type.Var("Xs"),new t.type.Var("Y")]),new t.type.Term(";",[new t.type.Term(",",[new t.type.Term(">=",[new t.type.Var("X"),new t.type.Var("Y")]),new t.type.Term(",",[new t.type.Term("=",[new t.type.Var("S"),new t.type.Var("X")]),new t.type.Term("!",[])])]),new t.type.Term("=",[new t.type.Var("S"),new t.type.Var("Y")])])]))],"min_list/2":[new t.type.Rule(new t.type.Term("min_list",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Term("[]",[])]),new t.type.Var("X")]),null),new t.type.Rule(new t.type.Term("min_list",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Var("S")]),new t.type.Term(",",[new t.type.Term("min_list",[new t.type.Var("Xs"),new t.type.Var("Y")]),new t.type.Term(";",[new t.type.Term(",",[new t.type.Term("=<",[new t.type.Var("X"),new t.type.Var("Y")]),new t.type.Term(",",[new t.type.Term("=",[new t.type.Var("S"),new t.type.Var("X")]),new t.type.Term("!",[])])]),new t.type.Term("=",[new t.type.Var("S"),new t.type.Var("Y")])])]))],"prod_list/2":[new t.type.Rule(new t.type.Term("prod_list",[new t.type.Term("[]",[]),new t.type.Num(1,!1)]),null),new t.type.Rule(new t.type.Term("prod_list",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Var("S")]),new t.type.Term(",",[new t.type.Term("prod_list",[new t.type.Var("Xs"),new t.type.Var("Y")]),new t.type.Term("is",[new t.type.Var("S"),new t.type.Term("*",[new t.type.Var("X"),new t.type.Var("Y")])])]))],"last/2":[new t.type.Rule(new t.type.Term("last",[new t.type.Term(".",[new t.type.Var("X"),new t.type.Term("[]",[])]),new t.type.Var("X")]),null),new t.type.Rule(new t.type.Term("last",[new t.type.Term(".",[new t.type.Var("_"),new t.type.Var("Xs")]),new t.type.Var("X")]),new t.type.Term("last",[new t.type.Var("Xs"),new t.type.Var("X")]))],"prefix/2":[new t.type.Rule(new t.type.Term("prefix",[new t.type.Var("Part"),new t.type.Var("Whole")]),new t.type.Term("append",[new t.type.Var("Part"),new t.type.Var("_"),new t.type.Var("Whole")]))],"nth0/3":[new t.type.Rule(new t.type.Term("nth0",[new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z")]),new t.type.Term(";",[new t.type.Term("->",[new t.type.Term("var",[new t.type.Var("X")]),new t.type.Term("nth",[new t.type.Num(0,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("_")])]),new t.type.Term(",",[new t.type.Term(">=",[new t.type.Var("X"),new t.type.Num(0,!1)]),new t.type.Term(",",[new t.type.Term("nth",[new t.type.Num(0,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("_")]),new t.type.Term("!",[])])])]))],"nth1/3":[new t.type.Rule(new t.type.Term("nth1",[new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z")]),new t.type.Term(";",[new t.type.Term("->",[new t.type.Term("var",[new t.type.Var("X")]),new t.type.Term("nth",[new t.type.Num(1,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("_")])]),new t.type.Term(",",[new t.type.Term(">",[new t.type.Var("X"),new t.type.Num(0,!1)]),new t.type.Term(",",[new t.type.Term("nth",[new t.type.Num(1,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("_")]),new t.type.Term("!",[])])])]))],"nth0/4":[new t.type.Rule(new t.type.Term("nth0",[new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("W")]),new t.type.Term(";",[new t.type.Term("->",[new t.type.Term("var",[new t.type.Var("X")]),new t.type.Term("nth",[new t.type.Num(0,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("W")])]),new t.type.Term(",",[new t.type.Term(">=",[new t.type.Var("X"),new t.type.Num(0,!1)]),new t.type.Term(",",[new t.type.Term("nth",[new t.type.Num(0,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("W")]),new t.type.Term("!",[])])])]))],"nth1/4":[new t.type.Rule(new t.type.Term("nth1",[new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("W")]),new t.type.Term(";",[new t.type.Term("->",[new t.type.Term("var",[new t.type.Var("X")]),new t.type.Term("nth",[new t.type.Num(1,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("W")])]),new t.type.Term(",",[new t.type.Term(">",[new t.type.Var("X"),new t.type.Num(0,!1)]),new t.type.Term(",",[new t.type.Term("nth",[new t.type.Num(1,!1),new t.type.Var("X"),new t.type.Var("Y"),new t.type.Var("Z"),new t.type.Var("W")]),new t.type.Term("!",[])])])]))],"nth/5":[new t.type.Rule(new t.type.Term("nth",[new t.type.Var("N"),new t.type.Var("N"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Var("X"),new t.type.Var("Xs")]),null),new t.type.Rule(new t.type.Term("nth",[new t.type.Var("N"),new t.type.Var("O"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Xs")]),new t.type.Var("Y"),new t.type.Term(".",[new t.type.Var("X"),new t.type.Var("Ys")])]),new t.type.Term(",",[new t.type.Term("is",[new t.type.Var("M"),new t.type.Term("+",[new t.type.Var("N"),new t.type.Num(1,!1)])]),new t.type.Term("nth",[new t.type.Var("M"),new t.type.Var("O"),new t.type.Var("Xs"),new t.type.Var("Y"),new t.type.Var("Ys")])]))],"length/2":function(o,a,n){var u=n.args[0],A=n.args[1];if(!t.type.is_variable(A)&&!t.type.is_integer(A))o.throw_error(t.error.type("integer",A,n.indicator));else if(t.type.is_integer(A)&&A.value<0)o.throw_error(t.error.domain("not_less_than_zero",A,n.indicator));else{var p=new t.type.Term("length",[u,new t.type.Num(0,!1),A]);t.type.is_integer(A)&&(p=new t.type.Term(",",[p,new t.type.Term("!",[])])),o.prepend([new t.type.State(a.goal.replace(p),a.substitution,a)])}},"length/3":[new t.type.Rule(new t.type.Term("length",[new t.type.Term("[]",[]),new t.type.Var("N"),new t.type.Var("N")]),null),new t.type.Rule(new t.type.Term("length",[new t.type.Term(".",[new t.type.Var("_"),new t.type.Var("X")]),new t.type.Var("A"),new t.type.Var("N")]),new t.type.Term(",",[new t.type.Term("succ",[new t.type.Var("A"),new t.type.Var("B")]),new t.type.Term("length",[new t.type.Var("X"),new t.type.Var("B"),new t.type.Var("N")])]))],"replicate/3":function(o,a,n){var u=n.args[0],A=n.args[1],p=n.args[2];if(t.type.is_variable(A))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_integer(A))o.throw_error(t.error.type("integer",A,n.indicator));else if(A.value<0)o.throw_error(t.error.domain("not_less_than_zero",A,n.indicator));else if(!t.type.is_variable(p)&&!t.type.is_list(p))o.throw_error(t.error.type("list",p,n.indicator));else{for(var h=new t.type.Term("[]"),E=0;E<A.value;E++)h=new t.type.Term(".",[u,h]);o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[h,p])),a.substitution,a)])}},"sort/2":function(o,a,n){var u=n.args[0],A=n.args[1];if(t.type.is_variable(u))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_variable(A)&&!t.type.is_fully_list(A))o.throw_error(t.error.type("list",A,n.indicator));else{for(var p=[],h=u;h.indicator==="./2";)p.push(h.args[0]),h=h.args[1];if(t.type.is_variable(h))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_empty_list(h))o.throw_error(t.error.type("list",u,n.indicator));else{for(var E=p.sort(t.compare),I=E.length-1;I>0;I--)E[I].equals(E[I-1])&&E.splice(I,1);for(var v=new t.type.Term("[]"),I=E.length-1;I>=0;I--)v=new t.type.Term(".",[E[I],v]);o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[v,A])),a.substitution,a)])}}},"msort/2":function(o,a,n){var u=n.args[0],A=n.args[1];if(t.type.is_variable(u))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_variable(A)&&!t.type.is_fully_list(A))o.throw_error(t.error.type("list",A,n.indicator));else{for(var p=[],h=u;h.indicator==="./2";)p.push(h.args[0]),h=h.args[1];if(t.type.is_variable(h))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_empty_list(h))o.throw_error(t.error.type("list",u,n.indicator));else{for(var E=p.sort(t.compare),I=new t.type.Term("[]"),v=E.length-1;v>=0;v--)I=new t.type.Term(".",[E[v],I]);o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[I,A])),a.substitution,a)])}}},"keysort/2":function(o,a,n){var u=n.args[0],A=n.args[1];if(t.type.is_variable(u))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_variable(A)&&!t.type.is_fully_list(A))o.throw_error(t.error.type("list",A,n.indicator));else{for(var p=[],h,E=u;E.indicator==="./2";){if(h=E.args[0],t.type.is_variable(h)){o.throw_error(t.error.instantiation(n.indicator));return}else if(!t.type.is_term(h)||h.indicator!=="-/2"){o.throw_error(t.error.type("pair",h,n.indicator));return}h.args[0].pair=h.args[1],p.push(h.args[0]),E=E.args[1]}if(t.type.is_variable(E))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_empty_list(E))o.throw_error(t.error.type("list",u,n.indicator));else{for(var I=p.sort(t.compare),v=new t.type.Term("[]"),b=I.length-1;b>=0;b--)v=new t.type.Term(".",[new t.type.Term("-",[I[b],I[b].pair]),v]),delete I[b].pair;o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[v,A])),a.substitution,a)])}}},"take/3":function(o,a,n){var u=n.args[0],A=n.args[1],p=n.args[2];if(t.type.is_variable(A)||t.type.is_variable(u))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_list(A))o.throw_error(t.error.type("list",A,n.indicator));else if(!t.type.is_integer(u))o.throw_error(t.error.type("integer",u,n.indicator));else if(!t.type.is_variable(p)&&!t.type.is_list(p))o.throw_error(t.error.type("list",p,n.indicator));else{for(var h=u.value,E=[],I=A;h>0&&I.indicator==="./2";)E.push(I.args[0]),I=I.args[1],h--;if(h===0){for(var v=new t.type.Term("[]"),h=E.length-1;h>=0;h--)v=new t.type.Term(".",[E[h],v]);o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[v,p])),a.substitution,a)])}}},"drop/3":function(o,a,n){var u=n.args[0],A=n.args[1],p=n.args[2];if(t.type.is_variable(A)||t.type.is_variable(u))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_list(A))o.throw_error(t.error.type("list",A,n.indicator));else if(!t.type.is_integer(u))o.throw_error(t.error.type("integer",u,n.indicator));else if(!t.type.is_variable(p)&&!t.type.is_list(p))o.throw_error(t.error.type("list",p,n.indicator));else{for(var h=u.value,E=[],I=A;h>0&&I.indicator==="./2";)E.push(I.args[0]),I=I.args[1],h--;h===0&&o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[I,p])),a.substitution,a)])}},"reverse/2":function(o,a,n){var u=n.args[0],A=n.args[1],p=t.type.is_instantiated_list(u),h=t.type.is_instantiated_list(A);if(t.type.is_variable(u)&&t.type.is_variable(A))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_variable(u)&&!t.type.is_fully_list(u))o.throw_error(t.error.type("list",u,n.indicator));else if(!t.type.is_variable(A)&&!t.type.is_fully_list(A))o.throw_error(t.error.type("list",A,n.indicator));else if(!p&&!h)o.throw_error(t.error.instantiation(n.indicator));else{for(var E=p?u:A,I=new t.type.Term("[]",[]);E.indicator==="./2";)I=new t.type.Term(".",[E.args[0],I]),E=E.args[1];o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[I,p?A:u])),a.substitution,a)])}},"list_to_set/2":function(o,a,n){var u=n.args[0],A=n.args[1];if(t.type.is_variable(u))o.throw_error(t.error.instantiation(n.indicator));else{for(var p=u,h=[];p.indicator==="./2";)h.push(p.args[0]),p=p.args[1];if(t.type.is_variable(p))o.throw_error(t.error.instantiation(n.indicator));else if(!t.type.is_term(p)||p.indicator!=="[]/0")o.throw_error(t.error.type("list",u,n.indicator));else{for(var E=[],I=new t.type.Term("[]",[]),v,b=0;b<h.length;b++){v=!1;for(var C=0;C<E.length&&!v;C++)v=t.compare(h[b],E[C])===0;v||E.push(h[b])}for(b=E.length-1;b>=0;b--)I=new t.type.Term(".",[E[b],I]);o.prepend([new t.type.State(a.goal.replace(new t.type.Term("=",[A,I])),a.substitution,a)])}}}}},r=["append/2","append/3","member/2","permutation/2","maplist/2","maplist/3","maplist/4","maplist/5","maplist/6","maplist/7","maplist/8","include/3","exclude/3","foldl/4","sum_list/2","max_list/2","min_list/2","prod_list/2","last/2","prefix/2","nth0/3","nth1/3","nth0/4","nth1/4","length/2","replicate/3","select/3","sort/2","msort/2","keysort/2","take/3","drop/3","reverse/2","list_to_set/2"];typeof aH<"u"?aH.exports=function(o){t=o,new t.type.Module("lists",e(),r)}:new t.type.Module("lists",e(),r)})(Vgt)});var ome=_(Yr=>{"use strict";var Zd=process.platform==="win32",lH="aes-256-cbc",Kgt="sha256",Kde="The current environment doesn't support interactive reading from TTY.",Yn=Be("fs"),Wde=process.binding("tty_wrap").TTY,uH=Be("child_process"),l0=Be("path"),AH={prompt:"> ",hideEchoBack:!1,mask:"*",limit:[],limitMessage:"Input another, please.$<( [)limit(])>",defaultInput:"",trueValue:[],falseValue:[],caseSensitive:!1,keepWhitespace:!1,encoding:"utf8",bufferSize:1024,print:void 0,history:!0,cd:!1,phContent:void 0,preCheck:void 0},Jf="none",Xc,IC,Vde=!1,a0,Ek,cH,Jgt=0,dH="",Xd=[],Ck,Jde=!1,fH=!1,v2=!1;function zde(t){function e(r){return r.replace(/[^\w\u0080-\uFFFF]/g,function(o){return"#"+o.charCodeAt(0)+";"})}return Ek.concat(function(r){var o=[];return Object.keys(r).forEach(function(a){r[a]==="boolean"?t[a]&&o.push("--"+a):r[a]==="string"&&t[a]&&o.push("--"+a,e(t[a]))}),o}({display:"string",displayOnly:"boolean",keyIn:"boolean",hideEchoBack:"boolean",mask:"string",limit:"string",caseSensitive:"boolean"}))}function zgt(t,e){function r(U){var J,te="",le;for(cH=cH||Be("os").tmpdir();;){J=l0.join(cH,U+te);try{le=Yn.openSync(J,"wx")}catch(pe){if(pe.code==="EEXIST"){te++;continue}else throw pe}Yn.closeSync(le);break}return J}var o,a,n,u={},A,p,h=r("readline-sync.stdout"),E=r("readline-sync.stderr"),I=r("readline-sync.exit"),v=r("readline-sync.done"),b=Be("crypto"),C,T,L;C=b.createHash(Kgt),C.update(""+process.pid+Jgt+++Math.random()),L=C.digest("hex"),T=b.createDecipher(lH,L),o=zde(t),Zd?(a=process.env.ComSpec||"cmd.exe",process.env.Q='"',n=["/V:ON","/S","/C","(%Q%"+a+"%Q% /V:ON /S /C %Q%%Q%"+a0+"%Q%"+o.map(function(U){return" %Q%"+U+"%Q%"}).join("")+" & (echo !ERRORLEVEL!)>%Q%"+I+"%Q%%Q%) 2>%Q%"+E+"%Q% |%Q%"+process.execPath+"%Q% %Q%"+__dirname+"\\encrypt.js%Q% %Q%"+lH+"%Q% %Q%"+L+"%Q% >%Q%"+h+"%Q% & (echo 1)>%Q%"+v+"%Q%"]):(a="/bin/sh",n=["-c",'("'+a0+'"'+o.map(function(U){return" '"+U.replace(/'/g,"'\\''")+"'"}).join("")+'; echo $?>"'+I+'") 2>"'+E+'" |"'+process.execPath+'" "'+__dirname+'/encrypt.js" "'+lH+'" "'+L+'" >"'+h+'"; echo 1 >"'+v+'"']),v2&&v2("_execFileSync",o);try{uH.spawn(a,n,e)}catch(U){u.error=new Error(U.message),u.error.method="_execFileSync - spawn",u.error.program=a,u.error.args=n}for(;Yn.readFileSync(v,{encoding:t.encoding}).trim()!=="1";);return(A=Yn.readFileSync(I,{encoding:t.encoding}).trim())==="0"?u.input=T.update(Yn.readFileSync(h,{encoding:"binary"}),"hex",t.encoding)+T.final(t.encoding):(p=Yn.readFileSync(E,{encoding:t.encoding}).trim(),u.error=new Error(Kde+(p?` +`+p:"")),u.error.method="_execFileSync",u.error.program=a,u.error.args=n,u.error.extMessage=p,u.error.exitCode=+A),Yn.unlinkSync(h),Yn.unlinkSync(E),Yn.unlinkSync(I),Yn.unlinkSync(v),u}function Xgt(t){var e,r={},o,a={env:process.env,encoding:t.encoding};if(a0||(Zd?process.env.PSModulePath?(a0="powershell.exe",Ek=["-ExecutionPolicy","Bypass","-File",__dirname+"\\read.ps1"]):(a0="cscript.exe",Ek=["//nologo",__dirname+"\\read.cs.js"]):(a0="/bin/sh",Ek=[__dirname+"/read.sh"])),Zd&&!process.env.PSModulePath&&(a.stdio=[process.stdin]),uH.execFileSync){e=zde(t),v2&&v2("execFileSync",e);try{r.input=uH.execFileSync(a0,e,a)}catch(n){o=n.stderr?(n.stderr+"").trim():"",r.error=new Error(Kde+(o?` +`+o:"")),r.error.method="execFileSync",r.error.program=a0,r.error.args=e,r.error.extMessage=o,r.error.exitCode=n.status,r.error.code=n.code,r.error.signal=n.signal}}else r=zgt(t,a);return r.error||(r.input=r.input.replace(/^\s*'|'\s*$/g,""),t.display=""),r}function pH(t){var e="",r=t.display,o=!t.display&&t.keyIn&&t.hideEchoBack&&!t.mask;function a(){var n=Xgt(t);if(n.error)throw n.error;return n.input}return fH&&fH(t),function(){var n,u,A;function p(){return n||(n=process.binding("fs"),u=process.binding("constants")),n}if(typeof Jf=="string")if(Jf=null,Zd){if(A=function(h){var E=h.replace(/^\D+/,"").split("."),I=0;return(E[0]=+E[0])&&(I+=E[0]*1e4),(E[1]=+E[1])&&(I+=E[1]*100),(E[2]=+E[2])&&(I+=E[2]),I}(process.version),!(A>=20302&&A<40204||A>=5e4&&A<50100||A>=50600&&A<60200)&&process.stdin.isTTY)process.stdin.pause(),Jf=process.stdin.fd,IC=process.stdin._handle;else try{Jf=p().open("CONIN$",u.O_RDWR,parseInt("0666",8)),IC=new Wde(Jf,!0)}catch{}if(process.stdout.isTTY)Xc=process.stdout.fd;else{try{Xc=Yn.openSync("\\\\.\\CON","w")}catch{}if(typeof Xc!="number")try{Xc=p().open("CONOUT$",u.O_RDWR,parseInt("0666",8))}catch{}}}else{if(process.stdin.isTTY){process.stdin.pause();try{Jf=Yn.openSync("/dev/tty","r"),IC=process.stdin._handle}catch{}}else try{Jf=Yn.openSync("/dev/tty","r"),IC=new Wde(Jf,!1)}catch{}if(process.stdout.isTTY)Xc=process.stdout.fd;else try{Xc=Yn.openSync("/dev/tty","w")}catch{}}}(),function(){var n,u,A=!t.hideEchoBack&&!t.keyIn,p,h,E,I,v;Ck="";function b(C){return C===Vde?!0:IC.setRawMode(C)!==0?!1:(Vde=C,!0)}if(Jde||!IC||typeof Xc!="number"&&(t.display||!A)){e=a();return}if(t.display&&(Yn.writeSync(Xc,t.display),t.display=""),!t.displayOnly){if(!b(!A)){e=a();return}for(h=t.keyIn?1:t.bufferSize,p=Buffer.allocUnsafe&&Buffer.alloc?Buffer.alloc(h):new Buffer(h),t.keyIn&&t.limit&&(u=new RegExp("[^"+t.limit+"]","g"+(t.caseSensitive?"":"i")));;){E=0;try{E=Yn.readSync(Jf,p,0,h)}catch(C){if(C.code!=="EOF"){b(!1),e+=a();return}}if(E>0?(I=p.toString(t.encoding,0,E),Ck+=I):(I=` +`,Ck+=String.fromCharCode(0)),I&&typeof(v=(I.match(/^(.*?)[\r\n]/)||[])[1])=="string"&&(I=v,n=!0),I&&(I=I.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g,"")),I&&u&&(I=I.replace(u,"")),I&&(A||(t.hideEchoBack?t.mask&&Yn.writeSync(Xc,new Array(I.length+1).join(t.mask)):Yn.writeSync(Xc,I)),e+=I),!t.keyIn&&n||t.keyIn&&e.length>=h)break}!A&&!o&&Yn.writeSync(Xc,` +`),b(!1)}}(),t.print&&!o&&t.print(r+(t.displayOnly?"":(t.hideEchoBack?new Array(e.length+1).join(t.mask):e)+` +`),t.encoding),t.displayOnly?"":dH=t.keepWhitespace||t.keyIn?e:e.trim()}function Zgt(t,e){var r=[];function o(a){a!=null&&(Array.isArray(a)?a.forEach(o):(!e||e(a))&&r.push(a))}return o(t),r}function mH(t){return t.replace(/[\x00-\x7f]/g,function(e){return"\\x"+("00"+e.charCodeAt().toString(16)).substr(-2)})}function Ts(){var t=Array.prototype.slice.call(arguments),e,r;return t.length&&typeof t[0]=="boolean"&&(r=t.shift(),r&&(e=Object.keys(AH),t.unshift(AH))),t.reduce(function(o,a){return a==null||(a.hasOwnProperty("noEchoBack")&&!a.hasOwnProperty("hideEchoBack")&&(a.hideEchoBack=a.noEchoBack,delete a.noEchoBack),a.hasOwnProperty("noTrim")&&!a.hasOwnProperty("keepWhitespace")&&(a.keepWhitespace=a.noTrim,delete a.noTrim),r||(e=Object.keys(a)),e.forEach(function(n){var u;if(!!a.hasOwnProperty(n))switch(u=a[n],n){case"mask":case"limitMessage":case"defaultInput":case"encoding":u=u!=null?u+"":"",u&&n!=="limitMessage"&&(u=u.replace(/[\r\n]/g,"")),o[n]=u;break;case"bufferSize":!isNaN(u=parseInt(u,10))&&typeof u=="number"&&(o[n]=u);break;case"displayOnly":case"keyIn":case"hideEchoBack":case"caseSensitive":case"keepWhitespace":case"history":case"cd":o[n]=!!u;break;case"limit":case"trueValue":case"falseValue":o[n]=Zgt(u,function(A){var p=typeof A;return p==="string"||p==="number"||p==="function"||A instanceof RegExp}).map(function(A){return typeof A=="string"?A.replace(/[\r\n]/g,""):A});break;case"print":case"phContent":case"preCheck":o[n]=typeof u=="function"?u:void 0;break;case"prompt":case"display":o[n]=u??"";break}})),o},{})}function hH(t,e,r){return e.some(function(o){var a=typeof o;return a==="string"?r?t===o:t.toLowerCase()===o.toLowerCase():a==="number"?parseFloat(t)===o:a==="function"?o(t):o instanceof RegExp?o.test(t):!1})}function yH(t,e){var r=l0.normalize(Zd?(process.env.HOMEDRIVE||"")+(process.env.HOMEPATH||""):process.env.HOME||"").replace(/[\/\\]+$/,"");return t=l0.normalize(t),e?t.replace(/^~(?=\/|\\|$)/,r):t.replace(new RegExp("^"+mH(r)+"(?=\\/|\\\\|$)",Zd?"i":""),"~")}function BC(t,e){var r="(?:\\(([\\s\\S]*?)\\))?(\\w+|.-.)(?:\\(([\\s\\S]*?)\\))?",o=new RegExp("(\\$)?(\\$<"+r+">)","g"),a=new RegExp("(\\$)?(\\$\\{"+r+"\\})","g");function n(u,A,p,h,E,I){var v;return A||typeof(v=e(E))!="string"?p:v?(h||"")+v+(I||""):""}return t.replace(o,n).replace(a,n)}function Xde(t,e,r){var o,a=[],n=-1,u=0,A="",p;function h(E,I){return I.length>3?(E.push(I[0]+"..."+I[I.length-1]),p=!0):I.length&&(E=E.concat(I)),E}return o=t.reduce(function(E,I){return E.concat((I+"").split(""))},[]).reduce(function(E,I){var v,b;return e||(I=I.toLowerCase()),v=/^\d$/.test(I)?1:/^[A-Z]$/.test(I)?2:/^[a-z]$/.test(I)?3:0,r&&v===0?A+=I:(b=I.charCodeAt(0),v&&v===n&&b===u+1?a.push(I):(E=h(E,a),a=[I],n=v),u=b),E},[]),o=h(o,a),A&&(o.push(A),p=!0),{values:o,suppressed:p}}function Zde(t,e){return t.join(t.length>2?", ":e?" / ":"/")}function $de(t,e){var r,o,a={},n;if(e.phContent&&(r=e.phContent(t,e)),typeof r!="string")switch(t){case"hideEchoBack":case"mask":case"defaultInput":case"caseSensitive":case"keepWhitespace":case"encoding":case"bufferSize":case"history":case"cd":r=e.hasOwnProperty(t)?typeof e[t]=="boolean"?e[t]?"on":"off":e[t]+"":"";break;case"limit":case"trueValue":case"falseValue":o=e[e.hasOwnProperty(t+"Src")?t+"Src":t],e.keyIn?(a=Xde(o,e.caseSensitive),o=a.values):o=o.filter(function(u){var A=typeof u;return A==="string"||A==="number"}),r=Zde(o,a.suppressed);break;case"limitCount":case"limitCountNotZero":r=e[e.hasOwnProperty("limitSrc")?"limitSrc":"limit"].length,r=r||t!=="limitCountNotZero"?r+"":"";break;case"lastInput":r=dH;break;case"cwd":case"CWD":case"cwdHome":r=process.cwd(),t==="CWD"?r=l0.basename(r):t==="cwdHome"&&(r=yH(r));break;case"date":case"time":case"localeDate":case"localeTime":r=new Date()["to"+t.replace(/^./,function(u){return u.toUpperCase()})+"String"]();break;default:typeof(n=(t.match(/^history_m(\d+)$/)||[])[1])=="string"&&(r=Xd[Xd.length-n]||"")}return r}function eme(t){var e=/^(.)-(.)$/.exec(t),r="",o,a,n,u;if(!e)return null;for(o=e[1].charCodeAt(0),a=e[2].charCodeAt(0),u=o<a?1:-1,n=o;n!==a+u;n+=u)r+=String.fromCharCode(n);return r}function gH(t){var e=new RegExp(/(\s*)(?:("|')(.*?)(?:\2|$)|(\S+))/g),r,o="",a=[],n;for(t=t.trim();r=e.exec(t);)n=r[3]||r[4]||"",r[1]&&(a.push(o),o=""),o+=n;return o&&a.push(o),a}function tme(t,e){return e.trueValue.length&&hH(t,e.trueValue,e.caseSensitive)?!0:e.falseValue.length&&hH(t,e.falseValue,e.caseSensitive)?!1:t}function rme(t){var e,r,o,a,n,u,A;function p(E){return $de(E,t)}function h(E){t.display+=(/[^\r\n]$/.test(t.display)?` +`:"")+E}for(t.limitSrc=t.limit,t.displaySrc=t.display,t.limit="",t.display=BC(t.display+"",p);;){if(e=pH(t),r=!1,o="",t.defaultInput&&!e&&(e=t.defaultInput),t.history&&((a=/^\s*\!(?:\!|-1)(:p)?\s*$/.exec(e))?(n=Xd[0]||"",a[1]?r=!0:e=n,h(n+` +`),r||(t.displayOnly=!0,pH(t),t.displayOnly=!1)):e&&e!==Xd[Xd.length-1]&&(Xd=[e])),!r&&t.cd&&e)switch(u=gH(e),u[0].toLowerCase()){case"cd":if(u[1])try{process.chdir(yH(u[1],!0))}catch(E){h(E+"")}r=!0;break;case"pwd":h(process.cwd()),r=!0;break}if(!r&&t.preCheck&&(A=t.preCheck(e,t),e=A.res,A.forceNext&&(r=!0)),!r){if(!t.limitSrc.length||hH(e,t.limitSrc,t.caseSensitive))break;t.limitMessage&&(o=BC(t.limitMessage,p))}h((o?o+` +`:"")+BC(t.displaySrc+"",p))}return tme(e,t)}Yr._DBG_set_useExt=function(t){Jde=t};Yr._DBG_set_checkOptions=function(t){fH=t};Yr._DBG_set_checkMethod=function(t){v2=t};Yr._DBG_clearHistory=function(){dH="",Xd=[]};Yr.setDefaultOptions=function(t){return AH=Ts(!0,t),Ts(!0)};Yr.question=function(t,e){return rme(Ts(Ts(!0,e),{display:t}))};Yr.prompt=function(t){var e=Ts(!0,t);return e.display=e.prompt,rme(e)};Yr.keyIn=function(t,e){var r=Ts(Ts(!0,e),{display:t,keyIn:!0,keepWhitespace:!0});return r.limitSrc=r.limit.filter(function(o){var a=typeof o;return a==="string"||a==="number"}).map(function(o){return BC(o+"",eme)}),r.limit=mH(r.limitSrc.join("")),["trueValue","falseValue"].forEach(function(o){r[o]=r[o].reduce(function(a,n){var u=typeof n;return u==="string"||u==="number"?a=a.concat((n+"").split("")):a.push(n),a},[])}),r.display=BC(r.display+"",function(o){return $de(o,r)}),tme(pH(r),r)};Yr.questionEMail=function(t,e){return t==null&&(t="Input e-mail address: "),Yr.question(t,Ts({hideEchoBack:!1,limit:/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,limitMessage:"Input valid e-mail address, please.",trueValue:null,falseValue:null},e,{keepWhitespace:!1,cd:!1}))};Yr.questionNewPassword=function(t,e){var r,o,a,n=Ts({hideEchoBack:!0,mask:"*",limitMessage:`It can include: $<charlist> +And the length must be: $<length>`,trueValue:null,falseValue:null,caseSensitive:!0},e,{history:!1,cd:!1,phContent:function(b){return b==="charlist"?r.text:b==="length"?o+"..."+a:null}}),u,A,p,h,E,I,v;for(e=e||{},u=BC(e.charlist?e.charlist+"":"$<!-~>",eme),(isNaN(o=parseInt(e.min,10))||typeof o!="number")&&(o=12),(isNaN(a=parseInt(e.max,10))||typeof a!="number")&&(a=24),h=new RegExp("^["+mH(u)+"]{"+o+","+a+"}$"),r=Xde([u],n.caseSensitive,!0),r.text=Zde(r.values,r.suppressed),A=e.confirmMessage!=null?e.confirmMessage:"Reinput a same one to confirm it: ",p=e.unmatchMessage!=null?e.unmatchMessage:"It differs from first one. Hit only the Enter key if you want to retry from first one.",t==null&&(t="Input new password: "),E=n.limitMessage;!v;)n.limit=h,n.limitMessage=E,I=Yr.question(t,n),n.limit=[I,""],n.limitMessage=p,v=Yr.question(A,n);return I};function nme(t,e,r){var o;function a(n){return o=r(n),!isNaN(o)&&typeof o=="number"}return Yr.question(t,Ts({limitMessage:"Input valid number, please."},e,{limit:a,cd:!1})),o}Yr.questionInt=function(t,e){return nme(t,e,function(r){return parseInt(r,10)})};Yr.questionFloat=function(t,e){return nme(t,e,parseFloat)};Yr.questionPath=function(t,e){var r,o="",a=Ts({hideEchoBack:!1,limitMessage:`$<error( +)>Input valid path, please.$<( Min:)min>$<( Max:)max>`,history:!0,cd:!0},e,{keepWhitespace:!1,limit:function(n){var u,A,p;n=yH(n,!0),o="";function h(E){E.split(/\/|\\/).reduce(function(I,v){var b=l0.resolve(I+=v+l0.sep);if(!Yn.existsSync(b))Yn.mkdirSync(b);else if(!Yn.statSync(b).isDirectory())throw new Error("Non directory already exists: "+b);return I},"")}try{if(u=Yn.existsSync(n),r=u?Yn.realpathSync(n):l0.resolve(n),!e.hasOwnProperty("exists")&&!u||typeof e.exists=="boolean"&&e.exists!==u)return o=(u?"Already exists":"No such file or directory")+": "+r,!1;if(!u&&e.create&&(e.isDirectory?h(r):(h(l0.dirname(r)),Yn.closeSync(Yn.openSync(r,"w"))),r=Yn.realpathSync(r)),u&&(e.min||e.max||e.isFile||e.isDirectory)){if(A=Yn.statSync(r),e.isFile&&!A.isFile())return o="Not file: "+r,!1;if(e.isDirectory&&!A.isDirectory())return o="Not directory: "+r,!1;if(e.min&&A.size<+e.min||e.max&&A.size>+e.max)return o="Size "+A.size+" is out of range: "+r,!1}if(typeof e.validate=="function"&&(p=e.validate(r))!==!0)return typeof p=="string"&&(o=p),!1}catch(E){return o=E+"",!1}return!0},phContent:function(n){return n==="error"?o:n!=="min"&&n!=="max"?null:e.hasOwnProperty(n)?e[n]+"":""}});return e=e||{},t==null&&(t='Input path (you can "cd" and "pwd"): '),Yr.question(t,a),r};function ime(t,e){var r={},o={};return typeof t=="object"?(Object.keys(t).forEach(function(a){typeof t[a]=="function"&&(o[e.caseSensitive?a:a.toLowerCase()]=t[a])}),r.preCheck=function(a){var n;return r.args=gH(a),n=r.args[0]||"",e.caseSensitive||(n=n.toLowerCase()),r.hRes=n!=="_"&&o.hasOwnProperty(n)?o[n].apply(a,r.args.slice(1)):o.hasOwnProperty("_")?o._.apply(a,r.args):null,{res:a,forceNext:!1}},o.hasOwnProperty("_")||(r.limit=function(){var a=r.args[0]||"";return e.caseSensitive||(a=a.toLowerCase()),o.hasOwnProperty(a)})):r.preCheck=function(a){return r.args=gH(a),r.hRes=typeof t=="function"?t.apply(a,r.args):!0,{res:a,forceNext:!1}},r}Yr.promptCL=function(t,e){var r=Ts({hideEchoBack:!1,limitMessage:"Requested command is not available.",caseSensitive:!1,history:!0},e),o=ime(t,r);return r.limit=o.limit,r.preCheck=o.preCheck,Yr.prompt(r),o.args};Yr.promptLoop=function(t,e){for(var r=Ts({hideEchoBack:!1,trueValue:null,falseValue:null,caseSensitive:!1,history:!0},e);!t(Yr.prompt(r)););};Yr.promptCLLoop=function(t,e){var r=Ts({hideEchoBack:!1,limitMessage:"Requested command is not available.",caseSensitive:!1,history:!0},e),o=ime(t,r);for(r.limit=o.limit,r.preCheck=o.preCheck;Yr.prompt(r),!o.hRes;);};Yr.promptSimShell=function(t){return Yr.prompt(Ts({hideEchoBack:!1,history:!0},t,{prompt:function(){return Zd?"$<cwd>>":(process.env.USER||"")+(process.env.HOSTNAME?"@"+process.env.HOSTNAME.replace(/\..*$/,""):"")+":$<cwdHome>$ "}()}))};function sme(t,e,r){var o;return t==null&&(t="Are you sure? "),(!e||e.guide!==!1)&&(t+="")&&(t=t.replace(/\s*:?\s*$/,"")+" [y/n]: "),o=Yr.keyIn(t,Ts(e,{hideEchoBack:!1,limit:r,trueValue:"y",falseValue:"n",caseSensitive:!1})),typeof o=="boolean"?o:""}Yr.keyInYN=function(t,e){return sme(t,e)};Yr.keyInYNStrict=function(t,e){return sme(t,e,"yn")};Yr.keyInPause=function(t,e){t==null&&(t="Continue..."),(!e||e.guide!==!1)&&(t+="")&&(t=t.replace(/\s+$/,"")+" (Hit any key)"),Yr.keyIn(t,Ts({limit:null},e,{hideEchoBack:!0,mask:""}))};Yr.keyInSelect=function(t,e,r){var o=Ts({hideEchoBack:!1},r,{trueValue:null,falseValue:null,caseSensitive:!1,phContent:function(p){return p==="itemsCount"?t.length+"":p==="firstItem"?(t[0]+"").trim():p==="lastItem"?(t[t.length-1]+"").trim():null}}),a="",n={},u=49,A=` +`;if(!Array.isArray(t)||!t.length||t.length>35)throw"`items` must be Array (max length: 35).";return t.forEach(function(p,h){var E=String.fromCharCode(u);a+=E,n[E]=h,A+="["+E+"] "+(p+"").trim()+` +`,u=u===57?97:u+1}),(!r||r.cancel!==!1)&&(a+="0",n[0]=-1,A+="[0] "+(r&&r.cancel!=null&&typeof r.cancel!="boolean"?(r.cancel+"").trim():"CANCEL")+` +`),o.limit=a,A+=` +`,e==null&&(e="Choose one from list: "),(e+="")&&((!r||r.guide!==!1)&&(e=e.replace(/\s*:?\s*$/,"")+" [$<limit>]: "),A+=e),n[Yr.keyIn(A,o).toLowerCase()]};Yr.getRawInput=function(){return Ck};function D2(t,e){var r;return e.length&&(r={},r[t]=e[0]),Yr.setDefaultOptions(r)[t]}Yr.setPrint=function(){return D2("print",arguments)};Yr.setPrompt=function(){return D2("prompt",arguments)};Yr.setEncoding=function(){return D2("encoding",arguments)};Yr.setMask=function(){return D2("mask",arguments)};Yr.setBufferSize=function(){return D2("bufferSize",arguments)}});var EH=_((t7t,hl)=>{(function(){var t={major:0,minor:2,patch:66,status:"beta"};tau_file_system={files:{},open:function(w,S,y){var F=tau_file_system.files[w];if(!F){if(y==="read")return null;F={path:w,text:"",type:S,get:function(z,X){return X===this.text.length||X>this.text.length?"end_of_file":this.text.substring(X,X+z)},put:function(z,X){return X==="end_of_file"?(this.text+=z,!0):X==="past_end_of_file"?null:(this.text=this.text.substring(0,X)+z+this.text.substring(X+z.length),!0)},get_byte:function(z){if(z==="end_of_stream")return-1;var X=Math.floor(z/2);if(this.text.length<=X)return-1;var Z=n(this.text[Math.floor(z/2)],0);return z%2===0?Z&255:Z/256>>>0},put_byte:function(z,X){var Z=X==="end_of_stream"?this.text.length:Math.floor(X/2);if(this.text.length<Z)return null;var ie=this.text.length===Z?-1:n(this.text[Math.floor(X/2)],0);return X%2===0?(ie=ie/256>>>0,ie=(ie&255)<<8|z&255):(ie=ie&255,ie=(z&255)<<8|ie&255),this.text.length===Z?this.text+=u(ie):this.text=this.text.substring(0,Z)+u(ie)+this.text.substring(Z+1),!0},flush:function(){return!0},close:function(){var z=tau_file_system.files[this.path];return z?!0:null}},tau_file_system.files[w]=F}return y==="write"&&(F.text=""),F}},tau_user_input={buffer:"",get:function(w,S){for(var y;tau_user_input.buffer.length<w;)y=window.prompt(),y&&(tau_user_input.buffer+=y);return y=tau_user_input.buffer.substr(0,w),tau_user_input.buffer=tau_user_input.buffer.substr(w),y}},tau_user_output={put:function(w,S){return console.log(w),!0},flush:function(){return!0}},nodejs_file_system={open:function(w,S,y){var F=Be("fs"),z=F.openSync(w,y[0]);return y==="read"&&!F.existsSync(w)?null:{get:function(X,Z){var ie=new Buffer(X);return F.readSync(z,ie,0,X,Z),ie.toString()},put:function(X,Z){var ie=Buffer.from(X);if(Z==="end_of_file")F.writeSync(z,ie);else{if(Z==="past_end_of_file")return null;F.writeSync(z,ie,0,ie.length,Z)}return!0},get_byte:function(X){return null},put_byte:function(X,Z){return null},flush:function(){return!0},close:function(){return F.closeSync(z),!0}}}},nodejs_user_input={buffer:"",get:function(w,S){for(var y,F=ome();nodejs_user_input.buffer.length<w;)nodejs_user_input.buffer+=F.question();return y=nodejs_user_input.buffer.substr(0,w),nodejs_user_input.buffer=nodejs_user_input.buffer.substr(w),y}},nodejs_user_output={put:function(w,S){return process.stdout.write(w),!0},flush:function(){return!0}};var e;Array.prototype.indexOf?e=function(w,S){return w.indexOf(S)}:e=function(w,S){for(var y=w.length,F=0;F<y;F++)if(S===w[F])return F;return-1};var r=function(w,S){if(w.length!==0){for(var y=w[0],F=w.length,z=1;z<F;z++)y=S(y,w[z]);return y}},o;Array.prototype.map?o=function(w,S){return w.map(S)}:o=function(w,S){for(var y=[],F=w.length,z=0;z<F;z++)y.push(S(w[z]));return y};var a;Array.prototype.filter?a=function(w,S){return w.filter(S)}:a=function(w,S){for(var y=[],F=w.length,z=0;z<F;z++)S(w[z])&&y.push(w[z]);return y};var n;String.prototype.codePointAt?n=function(w,S){return w.codePointAt(S)}:n=function(w,S){return w.charCodeAt(S)};var u;String.fromCodePoint?u=function(){return String.fromCodePoint.apply(null,arguments)}:u=function(){return String.fromCharCode.apply(null,arguments)};var A=0,p=1,h=/(\\a)|(\\b)|(\\f)|(\\n)|(\\r)|(\\t)|(\\v)|\\x([0-9a-fA-F]+)\\|\\([0-7]+)\\|(\\\\)|(\\')|('')|(\\")|(\\`)|(\\.)|(.)/g,E={"\\a":7,"\\b":8,"\\f":12,"\\n":10,"\\r":13,"\\t":9,"\\v":11};function I(w){var S=[],y=!1;return w.replace(h,function(F,z,X,Z,ie,Se,Ne,ot,dt,jt,$t,xt,an,Qr,mr,xr,Wr){switch(!0){case dt!==void 0:return S.push(parseInt(dt,16)),"";case jt!==void 0:return S.push(parseInt(jt,8)),"";case $t!==void 0:case xt!==void 0:case an!==void 0:case Qr!==void 0:case mr!==void 0:return S.push(n(F.substr(1),0)),"";case Wr!==void 0:return S.push(n(Wr,0)),"";case xr!==void 0:y=!0;default:return S.push(E[F]),""}}),y?null:S}function v(w,S){var y="";if(w.length<2)return w;try{w=w.replace(/\\([0-7]+)\\/g,function(Z,ie){return u(parseInt(ie,8))}),w=w.replace(/\\x([0-9a-fA-F]+)\\/g,function(Z,ie){return u(parseInt(ie,16))})}catch{return null}for(var F=0;F<w.length;F++){var z=w.charAt(F),X=w.charAt(F+1);if(z===S&&X===S)F++,y+=S;else if(z==="\\")if(["a","b","f","n","r","t","v","'",'"',"\\","a","\b","\f",` +`,"\r"," ","\v"].indexOf(X)!==-1)switch(F+=1,X){case"a":y+="a";break;case"b":y+="\b";break;case"f":y+="\f";break;case"n":y+=` +`;break;case"r":y+="\r";break;case"t":y+=" ";break;case"v":y+="\v";break;case"'":y+="'";break;case'"':y+='"';break;case"\\":y+="\\";break}else return null;else y+=z}return y}function b(w){for(var S="",y=0;y<w.length;y++)switch(w.charAt(y)){case"'":S+="\\'";break;case"\\":S+="\\\\";break;case"\b":S+="\\b";break;case"\f":S+="\\f";break;case` +`:S+="\\n";break;case"\r":S+="\\r";break;case" ":S+="\\t";break;case"\v":S+="\\v";break;default:S+=w.charAt(y);break}return S}function C(w){var S=w.substr(2);switch(w.substr(0,2).toLowerCase()){case"0x":return parseInt(S,16);case"0b":return parseInt(S,2);case"0o":return parseInt(S,8);case"0'":return I(S)[0];default:return parseFloat(w)}}var T={whitespace:/^\s*(?:(?:%.*)|(?:\/\*(?:\n|\r|.)*?\*\/)|(?:\s+))\s*/,variable:/^(?:[A-Z_][a-zA-Z0-9_]*)/,atom:/^(\!|,|;|[a-z][0-9a-zA-Z_]*|[#\$\&\*\+\-\.\/\:\<\=\>\?\@\^\~\\]+|'(?:[^']*?(?:\\(?:x?\d+)?\\)*(?:'')*(?:\\')*)*')/,number:/^(?:0o[0-7]+|0x[0-9a-fA-F]+|0b[01]+|0'(?:''|\\[abfnrtv\\'"`]|\\x?\d+\\|[^\\])|\d+(?:\.\d+(?:[eE][+-]?\d+)?)?)/,string:/^(?:"([^"]|""|\\")*"|`([^`]|``|\\`)*`)/,l_brace:/^(?:\[)/,r_brace:/^(?:\])/,l_bracket:/^(?:\{)/,r_bracket:/^(?:\})/,bar:/^(?:\|)/,l_paren:/^(?:\()/,r_paren:/^(?:\))/};function L(w,S){return w.get_flag("char_conversion").id==="on"?S.replace(/./g,function(y){return w.get_char_conversion(y)}):S}function U(w){this.thread=w,this.text="",this.tokens=[]}U.prototype.set_last_tokens=function(w){return this.tokens=w},U.prototype.new_text=function(w){this.text=w,this.tokens=[]},U.prototype.get_tokens=function(w){var S,y=0,F=0,z=0,X=[],Z=!1;if(w){var ie=this.tokens[w-1];y=ie.len,S=L(this.thread,this.text.substr(ie.len)),F=ie.line,z=ie.start}else S=this.text;if(/^\s*$/.test(S))return null;for(;S!=="";){var Se=[],Ne=!1;if(/^\n/.exec(S)!==null){F++,z=0,y++,S=S.replace(/\n/,""),Z=!0;continue}for(var ot in T)if(T.hasOwnProperty(ot)){var dt=T[ot].exec(S);dt&&Se.push({value:dt[0],name:ot,matches:dt})}if(!Se.length)return this.set_last_tokens([{value:S,matches:[],name:"lexical",line:F,start:z}]);var ie=r(Se,function(Qr,mr){return Qr.value.length>=mr.value.length?Qr:mr});switch(ie.start=z,ie.line=F,S=S.replace(ie.value,""),z+=ie.value.length,y+=ie.value.length,ie.name){case"atom":ie.raw=ie.value,ie.value.charAt(0)==="'"&&(ie.value=v(ie.value.substr(1,ie.value.length-2),"'"),ie.value===null&&(ie.name="lexical",ie.value="unknown escape sequence"));break;case"number":ie.float=ie.value.substring(0,2)!=="0x"&&ie.value.match(/[.eE]/)!==null&&ie.value!=="0'.",ie.value=C(ie.value),ie.blank=Ne;break;case"string":var jt=ie.value.charAt(0);ie.value=v(ie.value.substr(1,ie.value.length-2),jt),ie.value===null&&(ie.name="lexical",ie.value="unknown escape sequence");break;case"whitespace":var $t=X[X.length-1];$t&&($t.space=!0),Ne=!0;continue;case"r_bracket":X.length>0&&X[X.length-1].name==="l_bracket"&&(ie=X.pop(),ie.name="atom",ie.value="{}",ie.raw="{}",ie.space=!1);break;case"r_brace":X.length>0&&X[X.length-1].name==="l_brace"&&(ie=X.pop(),ie.name="atom",ie.value="[]",ie.raw="[]",ie.space=!1);break}ie.len=y,X.push(ie),Ne=!1}var xt=this.set_last_tokens(X);return xt.length===0?null:xt};function J(w,S,y,F,z){if(!S[y])return{type:A,value:x.error.syntax(S[y-1],"expression expected",!0)};var X;if(F==="0"){var Z=S[y];switch(Z.name){case"number":return{type:p,len:y+1,value:new x.type.Num(Z.value,Z.float)};case"variable":return{type:p,len:y+1,value:new x.type.Var(Z.value)};case"string":var ie;switch(w.get_flag("double_quotes").id){case"atom":ie=new H(Z.value,[]);break;case"codes":ie=new H("[]",[]);for(var Se=Z.value.length-1;Se>=0;Se--)ie=new H(".",[new x.type.Num(n(Z.value,Se),!1),ie]);break;case"chars":ie=new H("[]",[]);for(var Se=Z.value.length-1;Se>=0;Se--)ie=new H(".",[new x.type.Term(Z.value.charAt(Se),[]),ie]);break}return{type:p,len:y+1,value:ie};case"l_paren":var xt=J(w,S,y+1,w.__get_max_priority(),!0);return xt.type!==p?xt:S[xt.len]&&S[xt.len].name==="r_paren"?(xt.len++,xt):{type:A,derived:!0,value:x.error.syntax(S[xt.len]?S[xt.len]:S[xt.len-1],") or operator expected",!S[xt.len])};case"l_bracket":var xt=J(w,S,y+1,w.__get_max_priority(),!0);return xt.type!==p?xt:S[xt.len]&&S[xt.len].name==="r_bracket"?(xt.len++,xt.value=new H("{}",[xt.value]),xt):{type:A,derived:!0,value:x.error.syntax(S[xt.len]?S[xt.len]:S[xt.len-1],"} or operator expected",!S[xt.len])}}var Ne=te(w,S,y,z);return Ne.type===p||Ne.derived||(Ne=le(w,S,y),Ne.type===p||Ne.derived)?Ne:{type:A,derived:!1,value:x.error.syntax(S[y],"unexpected token")}}var ot=w.__get_max_priority(),dt=w.__get_next_priority(F),jt=y;if(S[y].name==="atom"&&S[y+1]&&(S[y].space||S[y+1].name!=="l_paren")){var Z=S[y++],$t=w.__lookup_operator_classes(F,Z.value);if($t&&$t.indexOf("fy")>-1){var xt=J(w,S,y,F,z);if(xt.type!==A)return Z.value==="-"&&!Z.space&&x.type.is_number(xt.value)?{value:new x.type.Num(-xt.value.value,xt.value.is_float),len:xt.len,type:p}:{value:new x.type.Term(Z.value,[xt.value]),len:xt.len,type:p};X=xt}else if($t&&$t.indexOf("fx")>-1){var xt=J(w,S,y,dt,z);if(xt.type!==A)return{value:new x.type.Term(Z.value,[xt.value]),len:xt.len,type:p};X=xt}}y=jt;var xt=J(w,S,y,dt,z);if(xt.type===p){y=xt.len;var Z=S[y];if(S[y]&&(S[y].name==="atom"&&w.__lookup_operator_classes(F,Z.value)||S[y].name==="bar"&&w.__lookup_operator_classes(F,"|"))){var an=dt,Qr=F,$t=w.__lookup_operator_classes(F,Z.value);if($t.indexOf("xf")>-1)return{value:new x.type.Term(Z.value,[xt.value]),len:++xt.len,type:p};if($t.indexOf("xfx")>-1){var mr=J(w,S,y+1,an,z);return mr.type===p?{value:new x.type.Term(Z.value,[xt.value,mr.value]),len:mr.len,type:p}:(mr.derived=!0,mr)}else if($t.indexOf("xfy")>-1){var mr=J(w,S,y+1,Qr,z);return mr.type===p?{value:new x.type.Term(Z.value,[xt.value,mr.value]),len:mr.len,type:p}:(mr.derived=!0,mr)}else if(xt.type!==A)for(;;){y=xt.len;var Z=S[y];if(Z&&Z.name==="atom"&&w.__lookup_operator_classes(F,Z.value)){var $t=w.__lookup_operator_classes(F,Z.value);if($t.indexOf("yf")>-1)xt={value:new x.type.Term(Z.value,[xt.value]),len:++y,type:p};else if($t.indexOf("yfx")>-1){var mr=J(w,S,++y,an,z);if(mr.type===A)return mr.derived=!0,mr;y=mr.len,xt={value:new x.type.Term(Z.value,[xt.value,mr.value]),len:y,type:p}}else break}else break}}else X={type:A,value:x.error.syntax(S[xt.len-1],"operator expected")};return xt}return xt}function te(w,S,y,F){if(!S[y]||S[y].name==="atom"&&S[y].raw==="."&&!F&&(S[y].space||!S[y+1]||S[y+1].name!=="l_paren"))return{type:A,derived:!1,value:x.error.syntax(S[y-1],"unfounded token")};var z=S[y],X=[];if(S[y].name==="atom"&&S[y].raw!==","){if(y++,S[y-1].space)return{type:p,len:y,value:new x.type.Term(z.value,X)};if(S[y]&&S[y].name==="l_paren"){if(S[y+1]&&S[y+1].name==="r_paren")return{type:A,derived:!0,value:x.error.syntax(S[y+1],"argument expected")};var Z=J(w,S,++y,"999",!0);if(Z.type===A)return Z.derived?Z:{type:A,derived:!0,value:x.error.syntax(S[y]?S[y]:S[y-1],"argument expected",!S[y])};for(X.push(Z.value),y=Z.len;S[y]&&S[y].name==="atom"&&S[y].value===",";){if(Z=J(w,S,y+1,"999",!0),Z.type===A)return Z.derived?Z:{type:A,derived:!0,value:x.error.syntax(S[y+1]?S[y+1]:S[y],"argument expected",!S[y+1])};X.push(Z.value),y=Z.len}if(S[y]&&S[y].name==="r_paren")y++;else return{type:A,derived:!0,value:x.error.syntax(S[y]?S[y]:S[y-1],", or ) expected",!S[y])}}return{type:p,len:y,value:new x.type.Term(z.value,X)}}return{type:A,derived:!1,value:x.error.syntax(S[y],"term expected")}}function le(w,S,y){if(!S[y])return{type:A,derived:!1,value:x.error.syntax(S[y-1],"[ expected")};if(S[y]&&S[y].name==="l_brace"){var F=J(w,S,++y,"999",!0),z=[F.value],X=void 0;if(F.type===A)return S[y]&&S[y].name==="r_brace"?{type:p,len:y+1,value:new x.type.Term("[]",[])}:{type:A,derived:!0,value:x.error.syntax(S[y],"] expected")};for(y=F.len;S[y]&&S[y].name==="atom"&&S[y].value===",";){if(F=J(w,S,y+1,"999",!0),F.type===A)return F.derived?F:{type:A,derived:!0,value:x.error.syntax(S[y+1]?S[y+1]:S[y],"argument expected",!S[y+1])};z.push(F.value),y=F.len}var Z=!1;if(S[y]&&S[y].name==="bar"){if(Z=!0,F=J(w,S,y+1,"999",!0),F.type===A)return F.derived?F:{type:A,derived:!0,value:x.error.syntax(S[y+1]?S[y+1]:S[y],"argument expected",!S[y+1])};X=F.value,y=F.len}return S[y]&&S[y].name==="r_brace"?{type:p,len:y+1,value:g(z,X)}:{type:A,derived:!0,value:x.error.syntax(S[y]?S[y]:S[y-1],Z?"] expected":", or | or ] expected",!S[y])}}return{type:A,derived:!1,value:x.error.syntax(S[y],"list expected")}}function pe(w,S,y){var F=S[y].line,z=J(w,S,y,w.__get_max_priority(),!1),X=null,Z;if(z.type!==A)if(y=z.len,S[y]&&S[y].name==="atom"&&S[y].raw===".")if(y++,x.type.is_term(z.value)){if(z.value.indicator===":-/2"?(X=new x.type.Rule(z.value.args[0],Pe(z.value.args[1])),Z={value:X,len:y,type:p}):z.value.indicator==="-->/2"?(X=ae(new x.type.Rule(z.value.args[0],z.value.args[1]),w),X.body=Pe(X.body),Z={value:X,len:y,type:x.type.is_rule(X)?p:A}):(X=new x.type.Rule(z.value,null),Z={value:X,len:y,type:p}),X){var ie=X.singleton_variables();ie.length>0&&w.throw_warning(x.warning.singleton(ie,X.head.indicator,F))}return Z}else return{type:A,value:x.error.syntax(S[y],"callable expected")};else return{type:A,value:x.error.syntax(S[y]?S[y]:S[y-1],". or operator expected")};return z}function Ae(w,S,y){y=y||{},y.from=y.from?y.from:"$tau-js",y.reconsult=y.reconsult!==void 0?y.reconsult:!0;var F=new U(w),z={},X;F.new_text(S);var Z=0,ie=F.get_tokens(Z);do{if(ie===null||!ie[Z])break;var Se=pe(w,ie,Z);if(Se.type===A)return new H("throw",[Se.value]);if(Se.value.body===null&&Se.value.head.indicator==="?-/1"){var Ne=new Je(w.session);Ne.add_goal(Se.value.head.args[0]),Ne.answer(function(dt){x.type.is_error(dt)?w.throw_warning(dt.args[0]):(dt===!1||dt===null)&&w.throw_warning(x.warning.failed_goal(Se.value.head.args[0],Se.len))}),Z=Se.len;var ot=!0}else if(Se.value.body===null&&Se.value.head.indicator===":-/1"){var ot=w.run_directive(Se.value.head.args[0]);Z=Se.len,Se.value.head.args[0].indicator==="char_conversion/2"&&(ie=F.get_tokens(Z),Z=0)}else{X=Se.value.head.indicator,y.reconsult!==!1&&z[X]!==!0&&!w.is_multifile_predicate(X)&&(w.session.rules[X]=a(w.session.rules[X]||[],function(jt){return jt.dynamic}),z[X]=!0);var ot=w.add_rule(Se.value,y);Z=Se.len}if(!ot)return ot}while(!0);return!0}function ye(w,S){var y=new U(w);y.new_text(S);var F=0;do{var z=y.get_tokens(F);if(z===null)break;var X=J(w,z,0,w.__get_max_priority(),!1);if(X.type!==A){var Z=X.len,ie=Z;if(z[Z]&&z[Z].name==="atom"&&z[Z].raw===".")w.add_goal(Pe(X.value));else{var Se=z[Z];return new H("throw",[x.error.syntax(Se||z[Z-1],". or operator expected",!Se)])}F=X.len+1}else return new H("throw",[X.value])}while(!0);return!0}function ae(w,S){w=w.rename(S);var y=S.next_free_variable(),F=we(w.body,y,S);return F.error?F.value:(w.body=F.value,w.head.args=w.head.args.concat([y,F.variable]),w.head=new H(w.head.id,w.head.args),w)}function we(w,S,y){var F;if(x.type.is_term(w)&&w.indicator==="!/0")return{value:w,variable:S,error:!1};if(x.type.is_term(w)&&w.indicator===",/2"){var z=we(w.args[0],S,y);if(z.error)return z;var X=we(w.args[1],z.variable,y);return X.error?X:{value:new H(",",[z.value,X.value]),variable:X.variable,error:!1}}else{if(x.type.is_term(w)&&w.indicator==="{}/1")return{value:w.args[0],variable:S,error:!1};if(x.type.is_empty_list(w))return{value:new H("true",[]),variable:S,error:!1};if(x.type.is_list(w)){F=y.next_free_variable();for(var Z=w,ie;Z.indicator==="./2";)ie=Z,Z=Z.args[1];return x.type.is_variable(Z)?{value:x.error.instantiation("DCG"),variable:S,error:!0}:x.type.is_empty_list(Z)?(ie.args[1]=F,{value:new H("=",[S,w]),variable:F,error:!1}):{value:x.error.type("list",w,"DCG"),variable:S,error:!0}}else return x.type.is_callable(w)?(F=y.next_free_variable(),w.args=w.args.concat([S,F]),w=new H(w.id,w.args),{value:w,variable:F,error:!1}):{value:x.error.type("callable",w,"DCG"),variable:S,error:!0}}}function Pe(w){return x.type.is_variable(w)?new H("call",[w]):x.type.is_term(w)&&[",/2",";/2","->/2"].indexOf(w.indicator)!==-1?new H(w.id,[Pe(w.args[0]),Pe(w.args[1])]):w}function g(w,S){for(var y=S||new x.type.Term("[]",[]),F=w.length-1;F>=0;F--)y=new x.type.Term(".",[w[F],y]);return y}function Ee(w,S){for(var y=w.length-1;y>=0;y--)w[y]===S&&w.splice(y,1)}function De(w){for(var S={},y=[],F=0;F<w.length;F++)w[F]in S||(y.push(w[F]),S[w[F]]=!0);return y}function ce(w,S,y,F){if(w.session.rules[y]!==null){for(var z=0;z<w.session.rules[y].length;z++)if(w.session.rules[y][z]===F){w.session.rules[y].splice(z,1),w.success(S);break}}}function ne(w){return function(S,y,F){var z=F.args[0],X=F.args.slice(1,w);if(x.type.is_variable(z))S.throw_error(x.error.instantiation(S.level));else if(!x.type.is_callable(z))S.throw_error(x.error.type("callable",z,S.level));else{var Z=new H(z.id,z.args.concat(X));S.prepend([new be(y.goal.replace(Z),y.substitution,y)])}}}function ee(w){for(var S=w.length-1;S>=0;S--)if(w.charAt(S)==="/")return new H("/",[new H(w.substring(0,S)),new ke(parseInt(w.substring(S+1)),!1)])}function Ie(w){this.id=w}function ke(w,S){this.is_float=S!==void 0?S:parseInt(w)!==w,this.value=this.is_float?w:parseInt(w)}var ht=0;function H(w,S,y){this.ref=y||++ht,this.id=w,this.args=S||[],this.indicator=w+"/"+this.args.length}var lt=0;function Re(w,S,y,F,z,X){this.id=lt++,this.stream=w,this.mode=S,this.alias=y,this.type=F!==void 0?F:"text",this.reposition=z!==void 0?z:!0,this.eof_action=X!==void 0?X:"eof_code",this.position=this.mode==="append"?"end_of_stream":0,this.output=this.mode==="write"||this.mode==="append",this.input=this.mode==="read"}function Qe(w){w=w||{},this.links=w}function be(w,S,y){S=S||new Qe,y=y||null,this.goal=w,this.substitution=S,this.parent=y}function _e(w,S,y){this.head=w,this.body=S,this.dynamic=y||!1}function Te(w){w=w===void 0||w<=0?1e3:w,this.rules={},this.src_predicates={},this.rename=0,this.modules=[],this.thread=new Je(this),this.total_threads=1,this.renamed_variables={},this.public_predicates={},this.multifile_predicates={},this.limit=w,this.streams={user_input:new Re(typeof hl<"u"&&hl.exports?nodejs_user_input:tau_user_input,"read","user_input","text",!1,"reset"),user_output:new Re(typeof hl<"u"&&hl.exports?nodejs_user_output:tau_user_output,"write","user_output","text",!1,"eof_code")},this.file_system=typeof hl<"u"&&hl.exports?nodejs_file_system:tau_file_system,this.standard_input=this.streams.user_input,this.standard_output=this.streams.user_output,this.current_input=this.streams.user_input,this.current_output=this.streams.user_output,this.format_success=function(S){return S.substitution},this.format_error=function(S){return S.goal},this.flag={bounded:x.flag.bounded.value,max_integer:x.flag.max_integer.value,min_integer:x.flag.min_integer.value,integer_rounding_function:x.flag.integer_rounding_function.value,char_conversion:x.flag.char_conversion.value,debug:x.flag.debug.value,max_arity:x.flag.max_arity.value,unknown:x.flag.unknown.value,double_quotes:x.flag.double_quotes.value,occurs_check:x.flag.occurs_check.value,dialect:x.flag.dialect.value,version_data:x.flag.version_data.value,nodejs:x.flag.nodejs.value},this.__loaded_modules=[],this.__char_conversion={},this.__operators={1200:{":-":["fx","xfx"],"-->":["xfx"],"?-":["fx"]},1100:{";":["xfy"]},1050:{"->":["xfy"]},1e3:{",":["xfy"]},900:{"\\+":["fy"]},700:{"=":["xfx"],"\\=":["xfx"],"==":["xfx"],"\\==":["xfx"],"@<":["xfx"],"@=<":["xfx"],"@>":["xfx"],"@>=":["xfx"],"=..":["xfx"],is:["xfx"],"=:=":["xfx"],"=\\=":["xfx"],"<":["xfx"],"=<":["xfx"],">":["xfx"],">=":["xfx"]},600:{":":["xfy"]},500:{"+":["yfx"],"-":["yfx"],"/\\":["yfx"],"\\/":["yfx"]},400:{"*":["yfx"],"/":["yfx"],"//":["yfx"],rem:["yfx"],mod:["yfx"],"<<":["yfx"],">>":["yfx"]},200:{"**":["xfx"],"^":["xfy"],"-":["fy"],"+":["fy"],"\\":["fy"]}}}function Je(w){this.epoch=Date.now(),this.session=w,this.session.total_threads++,this.total_steps=0,this.cpu_time=0,this.cpu_time_last=0,this.points=[],this.debugger=!1,this.debugger_states=[],this.level="top_level/0",this.__calls=[],this.current_limit=this.session.limit,this.warnings=[]}function He(w,S,y){this.id=w,this.rules=S,this.exports=y,x.module[w]=this}He.prototype.exports_predicate=function(w){return this.exports.indexOf(w)!==-1},Ie.prototype.unify=function(w,S){if(S&&e(w.variables(),this.id)!==-1&&!x.type.is_variable(w))return null;var y={};return y[this.id]=w,new Qe(y)},ke.prototype.unify=function(w,S){return x.type.is_number(w)&&this.value===w.value&&this.is_float===w.is_float?new Qe:null},H.prototype.unify=function(w,S){if(x.type.is_term(w)&&this.indicator===w.indicator){for(var y=new Qe,F=0;F<this.args.length;F++){var z=x.unify(this.args[F].apply(y),w.args[F].apply(y),S);if(z===null)return null;for(var X in z.links)y.links[X]=z.links[X];y=y.apply(z)}return y}return null},Re.prototype.unify=function(w,S){return x.type.is_stream(w)&&this.id===w.id?new Qe:null},Ie.prototype.toString=function(w){return this.id},ke.prototype.toString=function(w){return this.is_float&&e(this.value.toString(),".")===-1?this.value+".0":this.value.toString()},H.prototype.toString=function(w,S,y){if(w=w||{},w.quoted=w.quoted===void 0?!0:w.quoted,w.ignore_ops=w.ignore_ops===void 0?!1:w.ignore_ops,w.numbervars=w.numbervars===void 0?!1:w.numbervars,S=S===void 0?1200:S,y=y===void 0?"":y,w.numbervars&&this.indicator==="$VAR/1"&&x.type.is_integer(this.args[0])&&this.args[0].value>=0){var F=this.args[0].value,z=Math.floor(F/26),X=F%26;return"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[X]+(z!==0?z:"")}switch(this.indicator){case"[]/0":case"{}/0":case"!/0":return this.id;case"{}/1":return"{"+this.args[0].toString(w)+"}";case"./2":for(var Z="["+this.args[0].toString(w),ie=this.args[1];ie.indicator==="./2";)Z+=", "+ie.args[0].toString(w),ie=ie.args[1];return ie.indicator!=="[]/0"&&(Z+="|"+ie.toString(w)),Z+="]",Z;case",/2":return"("+this.args[0].toString(w)+", "+this.args[1].toString(w)+")";default:var Se=this.id,Ne=w.session?w.session.lookup_operator(this.id,this.args.length):null;if(w.session===void 0||w.ignore_ops||Ne===null)return w.quoted&&!/^(!|,|;|[a-z][0-9a-zA-Z_]*)$/.test(Se)&&Se!=="{}"&&Se!=="[]"&&(Se="'"+b(Se)+"'"),Se+(this.args.length?"("+o(this.args,function($t){return $t.toString(w)}).join(", ")+")":"");var ot=Ne.priority>S.priority||Ne.priority===S.priority&&(Ne.class==="xfy"&&this.indicator!==S.indicator||Ne.class==="yfx"&&this.indicator!==S.indicator||this.indicator===S.indicator&&Ne.class==="yfx"&&y==="right"||this.indicator===S.indicator&&Ne.class==="xfy"&&y==="left");Ne.indicator=this.indicator;var dt=ot?"(":"",jt=ot?")":"";return this.args.length===0?"("+this.id+")":["fy","fx"].indexOf(Ne.class)!==-1?dt+Se+" "+this.args[0].toString(w,Ne)+jt:["yf","xf"].indexOf(Ne.class)!==-1?dt+this.args[0].toString(w,Ne)+" "+Se+jt:dt+this.args[0].toString(w,Ne,"left")+" "+this.id+" "+this.args[1].toString(w,Ne,"right")+jt}},Re.prototype.toString=function(w){return"<stream>("+this.id+")"},Qe.prototype.toString=function(w){var S="{";for(var y in this.links)!this.links.hasOwnProperty(y)||(S!=="{"&&(S+=", "),S+=y+"/"+this.links[y].toString(w));return S+="}",S},be.prototype.toString=function(w){return this.goal===null?"<"+this.substitution.toString(w)+">":"<"+this.goal.toString(w)+", "+this.substitution.toString(w)+">"},_e.prototype.toString=function(w){return this.body?this.head.toString(w)+" :- "+this.body.toString(w)+".":this.head.toString(w)+"."},Te.prototype.toString=function(w){for(var S="",y=0;y<this.modules.length;y++)S+=":- use_module(library("+this.modules[y]+`)). +`;S+=` +`;for(key in this.rules)for(y=0;y<this.rules[key].length;y++)S+=this.rules[key][y].toString(w),S+=` +`;return S},Ie.prototype.clone=function(){return new Ie(this.id)},ke.prototype.clone=function(){return new ke(this.value,this.is_float)},H.prototype.clone=function(){return new H(this.id,o(this.args,function(w){return w.clone()}))},Re.prototype.clone=function(){return new Stram(this.stream,this.mode,this.alias,this.type,this.reposition,this.eof_action)},Qe.prototype.clone=function(){var w={};for(var S in this.links)!this.links.hasOwnProperty(S)||(w[S]=this.links[S].clone());return new Qe(w)},be.prototype.clone=function(){return new be(this.goal.clone(),this.substitution.clone(),this.parent)},_e.prototype.clone=function(){return new _e(this.head.clone(),this.body!==null?this.body.clone():null)},Ie.prototype.equals=function(w){return x.type.is_variable(w)&&this.id===w.id},ke.prototype.equals=function(w){return x.type.is_number(w)&&this.value===w.value&&this.is_float===w.is_float},H.prototype.equals=function(w){if(!x.type.is_term(w)||this.indicator!==w.indicator)return!1;for(var S=0;S<this.args.length;S++)if(!this.args[S].equals(w.args[S]))return!1;return!0},Re.prototype.equals=function(w){return x.type.is_stream(w)&&this.id===w.id},Qe.prototype.equals=function(w){var S;if(!x.type.is_substitution(w))return!1;for(S in this.links)if(!!this.links.hasOwnProperty(S)&&(!w.links[S]||!this.links[S].equals(w.links[S])))return!1;for(S in w.links)if(!!w.links.hasOwnProperty(S)&&!this.links[S])return!1;return!0},be.prototype.equals=function(w){return x.type.is_state(w)&&this.goal.equals(w.goal)&&this.substitution.equals(w.substitution)&&this.parent===w.parent},_e.prototype.equals=function(w){return x.type.is_rule(w)&&this.head.equals(w.head)&&(this.body===null&&w.body===null||this.body!==null&&this.body.equals(w.body))},Ie.prototype.rename=function(w){return w.get_free_variable(this)},ke.prototype.rename=function(w){return this},H.prototype.rename=function(w){return new H(this.id,o(this.args,function(S){return S.rename(w)}))},Re.prototype.rename=function(w){return this},_e.prototype.rename=function(w){return new _e(this.head.rename(w),this.body!==null?this.body.rename(w):null)},Ie.prototype.variables=function(){return[this.id]},ke.prototype.variables=function(){return[]},H.prototype.variables=function(){return[].concat.apply([],o(this.args,function(w){return w.variables()}))},Re.prototype.variables=function(){return[]},_e.prototype.variables=function(){return this.body===null?this.head.variables():this.head.variables().concat(this.body.variables())},Ie.prototype.apply=function(w){return w.lookup(this.id)?w.lookup(this.id):this},ke.prototype.apply=function(w){return this},H.prototype.apply=function(w){if(this.indicator==="./2"){for(var S=[],y=this;y.indicator==="./2";)S.push(y.args[0].apply(w)),y=y.args[1];for(var F=y.apply(w),z=S.length-1;z>=0;z--)F=new H(".",[S[z],F]);return F}return new H(this.id,o(this.args,function(X){return X.apply(w)}),this.ref)},Re.prototype.apply=function(w){return this},_e.prototype.apply=function(w){return new _e(this.head.apply(w),this.body!==null?this.body.apply(w):null)},Qe.prototype.apply=function(w){var S,y={};for(S in this.links)!this.links.hasOwnProperty(S)||(y[S]=this.links[S].apply(w));return new Qe(y)},H.prototype.select=function(){for(var w=this;w.indicator===",/2";)w=w.args[0];return w},H.prototype.replace=function(w){return this.indicator===",/2"?this.args[0].indicator===",/2"?new H(",",[this.args[0].replace(w),this.args[1]]):w===null?this.args[1]:new H(",",[w,this.args[1]]):w},H.prototype.search=function(w){if(x.type.is_term(w)&&w.ref!==void 0&&this.ref===w.ref)return!0;for(var S=0;S<this.args.length;S++)if(x.type.is_term(this.args[S])&&this.args[S].search(w))return!0;return!1},Te.prototype.get_current_input=function(){return this.current_input},Je.prototype.get_current_input=function(){return this.session.get_current_input()},Te.prototype.get_current_output=function(){return this.current_output},Je.prototype.get_current_output=function(){return this.session.get_current_output()},Te.prototype.set_current_input=function(w){this.current_input=w},Je.prototype.set_current_input=function(w){return this.session.set_current_input(w)},Te.prototype.set_current_output=function(w){this.current_input=w},Je.prototype.set_current_output=function(w){return this.session.set_current_output(w)},Te.prototype.get_stream_by_alias=function(w){return this.streams[w]},Je.prototype.get_stream_by_alias=function(w){return this.session.get_stream_by_alias(w)},Te.prototype.file_system_open=function(w,S,y){return this.file_system.open(w,S,y)},Je.prototype.file_system_open=function(w,S,y){return this.session.file_system_open(w,S,y)},Te.prototype.get_char_conversion=function(w){return this.__char_conversion[w]||w},Je.prototype.get_char_conversion=function(w){return this.session.get_char_conversion(w)},Te.prototype.parse=function(w){return this.thread.parse(w)},Je.prototype.parse=function(w){var S=new U(this);S.new_text(w);var y=S.get_tokens();if(y===null)return!1;var F=J(this,y,0,this.__get_max_priority(),!1);return F.len!==y.length?!1:{value:F.value,expr:F,tokens:y}},Te.prototype.get_flag=function(w){return this.flag[w]},Je.prototype.get_flag=function(w){return this.session.get_flag(w)},Te.prototype.add_rule=function(w,S){return S=S||{},S.from=S.from?S.from:"$tau-js",this.src_predicates[w.head.indicator]=S.from,this.rules[w.head.indicator]||(this.rules[w.head.indicator]=[]),this.rules[w.head.indicator].push(w),this.public_predicates.hasOwnProperty(w.head.indicator)||(this.public_predicates[w.head.indicator]=!1),!0},Je.prototype.add_rule=function(w,S){return this.session.add_rule(w,S)},Te.prototype.run_directive=function(w){this.thread.run_directive(w)},Je.prototype.run_directive=function(w){return x.type.is_directive(w)?(x.directive[w.indicator](this,w),!0):!1},Te.prototype.__get_max_priority=function(){return"1200"},Je.prototype.__get_max_priority=function(){return this.session.__get_max_priority()},Te.prototype.__get_next_priority=function(w){var S=0;w=parseInt(w);for(var y in this.__operators)if(!!this.__operators.hasOwnProperty(y)){var F=parseInt(y);F>S&&F<w&&(S=F)}return S.toString()},Je.prototype.__get_next_priority=function(w){return this.session.__get_next_priority(w)},Te.prototype.__lookup_operator_classes=function(w,S){return this.__operators.hasOwnProperty(w)&&this.__operators[w][S]instanceof Array&&this.__operators[w][S]||!1},Je.prototype.__lookup_operator_classes=function(w,S){return this.session.__lookup_operator_classes(w,S)},Te.prototype.lookup_operator=function(w,S){for(var y in this.__operators)if(this.__operators[y][w]){for(var F=0;F<this.__operators[y][w].length;F++)if(S===0||this.__operators[y][w][F].length===S+1)return{priority:y,class:this.__operators[y][w][F]}}return null},Je.prototype.lookup_operator=function(w,S){return this.session.lookup_operator(w,S)},Te.prototype.throw_warning=function(w){this.thread.throw_warning(w)},Je.prototype.throw_warning=function(w){this.warnings.push(w)},Te.prototype.get_warnings=function(){return this.thread.get_warnings()},Je.prototype.get_warnings=function(){return this.warnings},Te.prototype.add_goal=function(w,S){this.thread.add_goal(w,S)},Je.prototype.add_goal=function(w,S,y){y=y||null,S===!0&&(this.points=[]);for(var F=w.variables(),z={},X=0;X<F.length;X++)z[F[X]]=new Ie(F[X]);this.points.push(new be(w,new Qe(z),y))},Te.prototype.consult=function(w,S){return this.thread.consult(w,S)},Je.prototype.consult=function(w,S){var y="";if(typeof w=="string"){y=w;var F=y.length;if(y.substring(F-3,F)===".pl"&&document.getElementById(y)){var z=document.getElementById(y),X=z.getAttribute("type");X!==null&&X.replace(/ /g,"").toLowerCase()==="text/prolog"&&(y=z.text)}}else if(w.nodeName)switch(w.nodeName.toLowerCase()){case"input":case"textarea":y=w.value;break;default:y=w.innerHTML;break}else return!1;return this.warnings=[],Ae(this,y,S)},Te.prototype.query=function(w){return this.thread.query(w)},Je.prototype.query=function(w){return this.points=[],this.debugger_points=[],ye(this,w)},Te.prototype.head_point=function(){return this.thread.head_point()},Je.prototype.head_point=function(){return this.points[this.points.length-1]},Te.prototype.get_free_variable=function(w){return this.thread.get_free_variable(w)},Je.prototype.get_free_variable=function(w){var S=[];if(w.id==="_"||this.session.renamed_variables[w.id]===void 0){for(this.session.rename++,this.points.length>0&&(S=this.head_point().substitution.domain());e(S,x.format_variable(this.session.rename))!==-1;)this.session.rename++;if(w.id==="_")return new Ie(x.format_variable(this.session.rename));this.session.renamed_variables[w.id]=x.format_variable(this.session.rename)}return new Ie(this.session.renamed_variables[w.id])},Te.prototype.next_free_variable=function(){return this.thread.next_free_variable()},Je.prototype.next_free_variable=function(){this.session.rename++;var w=[];for(this.points.length>0&&(w=this.head_point().substitution.domain());e(w,x.format_variable(this.session.rename))!==-1;)this.session.rename++;return new Ie(x.format_variable(this.session.rename))},Te.prototype.is_public_predicate=function(w){return!this.public_predicates.hasOwnProperty(w)||this.public_predicates[w]===!0},Je.prototype.is_public_predicate=function(w){return this.session.is_public_predicate(w)},Te.prototype.is_multifile_predicate=function(w){return this.multifile_predicates.hasOwnProperty(w)&&this.multifile_predicates[w]===!0},Je.prototype.is_multifile_predicate=function(w){return this.session.is_multifile_predicate(w)},Te.prototype.prepend=function(w){return this.thread.prepend(w)},Je.prototype.prepend=function(w){for(var S=w.length-1;S>=0;S--)this.points.push(w[S])},Te.prototype.success=function(w,S){return this.thread.success(w,S)},Je.prototype.success=function(w,y){var y=typeof y>"u"?w:y;this.prepend([new be(w.goal.replace(null),w.substitution,y)])},Te.prototype.throw_error=function(w){return this.thread.throw_error(w)},Je.prototype.throw_error=function(w){this.prepend([new be(new H("throw",[w]),new Qe,null,null)])},Te.prototype.step_rule=function(w,S){return this.thread.step_rule(w,S)},Je.prototype.step_rule=function(w,S){var y=S.indicator;if(w==="user"&&(w=null),w===null&&this.session.rules.hasOwnProperty(y))return this.session.rules[y];for(var F=w===null?this.session.modules:e(this.session.modules,w)===-1?[]:[w],z=0;z<F.length;z++){var X=x.module[F[z]];if(X.rules.hasOwnProperty(y)&&(X.rules.hasOwnProperty(this.level)||X.exports_predicate(y)))return x.module[F[z]].rules[y]}return null},Te.prototype.step=function(){return this.thread.step()},Je.prototype.step=function(){if(this.points.length!==0){var w=!1,S=this.points.pop();if(this.debugger&&this.debugger_states.push(S),x.type.is_term(S.goal)){var y=S.goal.select(),F=null,z=[];if(y!==null){this.total_steps++;for(var X=S;X.parent!==null&&X.parent.goal.search(y);)X=X.parent;if(this.level=X.parent===null?"top_level/0":X.parent.goal.select().indicator,x.type.is_term(y)&&y.indicator===":/2"&&(F=y.args[0].id,y=y.args[1]),F===null&&x.type.is_builtin(y))this.__call_indicator=y.indicator,w=x.predicate[y.indicator](this,S,y);else{var Z=this.step_rule(F,y);if(Z===null)this.session.rules.hasOwnProperty(y.indicator)||(this.get_flag("unknown").id==="error"?this.throw_error(x.error.existence("procedure",y.indicator,this.level)):this.get_flag("unknown").id==="warning"&&this.throw_warning("unknown procedure "+y.indicator+" (from "+this.level+")"));else if(Z instanceof Function)w=Z(this,S,y);else{for(var ie in Z)if(!!Z.hasOwnProperty(ie)){var Se=Z[ie];this.session.renamed_variables={},Se=Se.rename(this);var Ne=this.get_flag("occurs_check").indicator==="true/0",ot=new be,dt=x.unify(y,Se.head,Ne);dt!==null&&(ot.goal=S.goal.replace(Se.body),ot.goal!==null&&(ot.goal=ot.goal.apply(dt)),ot.substitution=S.substitution.apply(dt),ot.parent=S,z.push(ot))}this.prepend(z)}}}}else x.type.is_variable(S.goal)?this.throw_error(x.error.instantiation(this.level)):this.throw_error(x.error.type("callable",S.goal,this.level));return w}},Te.prototype.answer=function(w){return this.thread.answer(w)},Je.prototype.answer=function(w){w=w||function(S){},this.__calls.push(w),!(this.__calls.length>1)&&this.again()},Te.prototype.answers=function(w,S,y){return this.thread.answers(w,S,y)},Je.prototype.answers=function(w,S,y){var F=S||1e3,z=this;if(S<=0){y&&y();return}this.answer(function(X){w(X),X!==!1?setTimeout(function(){z.answers(w,S-1,y)},1):y&&y()})},Te.prototype.again=function(w){return this.thread.again(w)},Je.prototype.again=function(w){for(var S,y=Date.now();this.__calls.length>0;){for(this.warnings=[],w!==!1&&(this.current_limit=this.session.limit);this.current_limit>0&&this.points.length>0&&this.head_point().goal!==null&&!x.type.is_error(this.head_point().goal);)if(this.current_limit--,this.step()===!0)return;var F=Date.now();this.cpu_time_last=F-y,this.cpu_time+=this.cpu_time_last;var z=this.__calls.shift();this.current_limit<=0?z(null):this.points.length===0?z(!1):x.type.is_error(this.head_point().goal)?(S=this.session.format_error(this.points.pop()),this.points=[],z(S)):(this.debugger&&this.debugger_states.push(this.head_point()),S=this.session.format_success(this.points.pop()),z(S))}},Te.prototype.unfold=function(w){if(w.body===null)return!1;var S=w.head,y=w.body,F=y.select(),z=new Je(this),X=[];z.add_goal(F),z.step();for(var Z=z.points.length-1;Z>=0;Z--){var ie=z.points[Z],Se=S.apply(ie.substitution),Ne=y.replace(ie.goal);Ne!==null&&(Ne=Ne.apply(ie.substitution)),X.push(new _e(Se,Ne))}var ot=this.rules[S.indicator],dt=e(ot,w);return X.length>0&&dt!==-1?(ot.splice.apply(ot,[dt,1].concat(X)),!0):!1},Je.prototype.unfold=function(w){return this.session.unfold(w)},Ie.prototype.interpret=function(w){return x.error.instantiation(w.level)},ke.prototype.interpret=function(w){return this},H.prototype.interpret=function(w){return x.type.is_unitary_list(this)?this.args[0].interpret(w):x.operate(w,this)},Ie.prototype.compare=function(w){return this.id<w.id?-1:this.id>w.id?1:0},ke.prototype.compare=function(w){if(this.value===w.value&&this.is_float===w.is_float)return 0;if(this.value<w.value||this.value===w.value&&this.is_float&&!w.is_float)return-1;if(this.value>w.value)return 1},H.prototype.compare=function(w){if(this.args.length<w.args.length||this.args.length===w.args.length&&this.id<w.id)return-1;if(this.args.length>w.args.length||this.args.length===w.args.length&&this.id>w.id)return 1;for(var S=0;S<this.args.length;S++){var y=x.compare(this.args[S],w.args[S]);if(y!==0)return y}return 0},Qe.prototype.lookup=function(w){return this.links[w]?this.links[w]:null},Qe.prototype.filter=function(w){var S={};for(var y in this.links)if(!!this.links.hasOwnProperty(y)){var F=this.links[y];w(y,F)&&(S[y]=F)}return new Qe(S)},Qe.prototype.exclude=function(w){var S={};for(var y in this.links)!this.links.hasOwnProperty(y)||e(w,y)===-1&&(S[y]=this.links[y]);return new Qe(S)},Qe.prototype.add=function(w,S){this.links[w]=S},Qe.prototype.domain=function(w){var S=w===!0?function(z){return z}:function(z){return new Ie(z)},y=[];for(var F in this.links)y.push(S(F));return y},Ie.prototype.compile=function(){return'new pl.type.Var("'+this.id.toString()+'")'},ke.prototype.compile=function(){return"new pl.type.Num("+this.value.toString()+", "+this.is_float.toString()+")"},H.prototype.compile=function(){return'new pl.type.Term("'+this.id.replace(/"/g,'\\"')+'", ['+o(this.args,function(w){return w.compile()})+"])"},_e.prototype.compile=function(){return"new pl.type.Rule("+this.head.compile()+", "+(this.body===null?"null":this.body.compile())+")"},Te.prototype.compile=function(){var w,S=[],y;for(var F in this.rules)if(!!this.rules.hasOwnProperty(F)){var z=this.rules[F];y=[],w='"'+F+'": [';for(var X=0;X<z.length;X++)y.push(z[X].compile());w+=y.join(),w+="]",S.push(w)}return"{"+S.join()+"};"},Ie.prototype.toJavaScript=function(){},ke.prototype.toJavaScript=function(){return this.value},H.prototype.toJavaScript=function(){if(this.args.length===0&&this.indicator!=="[]/0")return this.id;if(x.type.is_list(this)){for(var w=[],S=this,y;S.indicator==="./2";){if(y=S.args[0].toJavaScript(),y===void 0)return;w.push(y),S=S.args[1]}if(S.indicator==="[]/0")return w}},_e.prototype.singleton_variables=function(){var w=this.head.variables(),S={},y=[];this.body!==null&&(w=w.concat(this.body.variables()));for(var F=0;F<w.length;F++)S[w[F]]===void 0&&(S[w[F]]=0),S[w[F]]++;for(var z in S)z!=="_"&&S[z]===1&&y.push(z);return y};var x={__env:typeof hl<"u"&&hl.exports?global:window,module:{},version:t,parser:{tokenizer:U,expression:J},utils:{str_indicator:ee,codePointAt:n,fromCodePoint:u},statistics:{getCountTerms:function(){return ht}},fromJavaScript:{test:{boolean:function(w){return w===!0||w===!1},number:function(w){return typeof w=="number"},string:function(w){return typeof w=="string"},list:function(w){return w instanceof Array},variable:function(w){return w===void 0},any:function(w){return!0}},conversion:{boolean:function(w){return new H(w?"true":"false",[])},number:function(w){return new ke(w,w%1!==0)},string:function(w){return new H(w,[])},list:function(w){for(var S=[],y,F=0;F<w.length;F++){if(y=x.fromJavaScript.apply(w[F]),y===void 0)return;S.push(y)}return g(S)},variable:function(w){return new Ie("_")},any:function(w){}},apply:function(w){for(var S in x.fromJavaScript.test)if(S!=="any"&&x.fromJavaScript.test[S](w))return x.fromJavaScript.conversion[S](w);return x.fromJavaScript.conversion.any(w)}},type:{Var:Ie,Num:ke,Term:H,Rule:_e,State:be,Stream:Re,Module:He,Thread:Je,Session:Te,Substitution:Qe,order:[Ie,ke,H,Re],compare:function(w,S){var y=e(x.type.order,w.constructor),F=e(x.type.order,S.constructor);if(y<F)return-1;if(y>F)return 1;if(w.constructor===ke){if(w.is_float&&S.is_float)return 0;if(w.is_float)return-1;if(S.is_float)return 1}return 0},is_substitution:function(w){return w instanceof Qe},is_state:function(w){return w instanceof be},is_rule:function(w){return w instanceof _e},is_variable:function(w){return w instanceof Ie},is_stream:function(w){return w instanceof Re},is_anonymous_var:function(w){return w instanceof Ie&&w.id==="_"},is_callable:function(w){return w instanceof H},is_number:function(w){return w instanceof ke},is_integer:function(w){return w instanceof ke&&!w.is_float},is_float:function(w){return w instanceof ke&&w.is_float},is_term:function(w){return w instanceof H},is_atom:function(w){return w instanceof H&&w.args.length===0},is_ground:function(w){if(w instanceof Ie)return!1;if(w instanceof H){for(var S=0;S<w.args.length;S++)if(!x.type.is_ground(w.args[S]))return!1}return!0},is_atomic:function(w){return w instanceof H&&w.args.length===0||w instanceof ke},is_compound:function(w){return w instanceof H&&w.args.length>0},is_list:function(w){return w instanceof H&&(w.indicator==="[]/0"||w.indicator==="./2")},is_empty_list:function(w){return w instanceof H&&w.indicator==="[]/0"},is_non_empty_list:function(w){return w instanceof H&&w.indicator==="./2"},is_fully_list:function(w){for(;w instanceof H&&w.indicator==="./2";)w=w.args[1];return w instanceof Ie||w instanceof H&&w.indicator==="[]/0"},is_instantiated_list:function(w){for(;w instanceof H&&w.indicator==="./2";)w=w.args[1];return w instanceof H&&w.indicator==="[]/0"},is_unitary_list:function(w){return w instanceof H&&w.indicator==="./2"&&w.args[1]instanceof H&&w.args[1].indicator==="[]/0"},is_character:function(w){return w instanceof H&&(w.id.length===1||w.id.length>0&&w.id.length<=2&&n(w.id,0)>=65536)},is_character_code:function(w){return w instanceof ke&&!w.is_float&&w.value>=0&&w.value<=1114111},is_byte:function(w){return w instanceof ke&&!w.is_float&&w.value>=0&&w.value<=255},is_operator:function(w){return w instanceof H&&x.arithmetic.evaluation[w.indicator]},is_directive:function(w){return w instanceof H&&x.directive[w.indicator]!==void 0},is_builtin:function(w){return w instanceof H&&x.predicate[w.indicator]!==void 0},is_error:function(w){return w instanceof H&&w.indicator==="throw/1"},is_predicate_indicator:function(w){return w instanceof H&&w.indicator==="//2"&&w.args[0]instanceof H&&w.args[0].args.length===0&&w.args[1]instanceof ke&&w.args[1].is_float===!1},is_flag:function(w){return w instanceof H&&w.args.length===0&&x.flag[w.id]!==void 0},is_value_flag:function(w,S){if(!x.type.is_flag(w))return!1;for(var y in x.flag[w.id].allowed)if(!!x.flag[w.id].allowed.hasOwnProperty(y)&&x.flag[w.id].allowed[y].equals(S))return!0;return!1},is_io_mode:function(w){return x.type.is_atom(w)&&["read","write","append"].indexOf(w.id)!==-1},is_stream_option:function(w){return x.type.is_term(w)&&(w.indicator==="alias/1"&&x.type.is_atom(w.args[0])||w.indicator==="reposition/1"&&x.type.is_atom(w.args[0])&&(w.args[0].id==="true"||w.args[0].id==="false")||w.indicator==="type/1"&&x.type.is_atom(w.args[0])&&(w.args[0].id==="text"||w.args[0].id==="binary")||w.indicator==="eof_action/1"&&x.type.is_atom(w.args[0])&&(w.args[0].id==="error"||w.args[0].id==="eof_code"||w.args[0].id==="reset"))},is_stream_position:function(w){return x.type.is_integer(w)&&w.value>=0||x.type.is_atom(w)&&(w.id==="end_of_stream"||w.id==="past_end_of_stream")},is_stream_property:function(w){return x.type.is_term(w)&&(w.indicator==="input/0"||w.indicator==="output/0"||w.indicator==="alias/1"&&(x.type.is_variable(w.args[0])||x.type.is_atom(w.args[0]))||w.indicator==="file_name/1"&&(x.type.is_variable(w.args[0])||x.type.is_atom(w.args[0]))||w.indicator==="position/1"&&(x.type.is_variable(w.args[0])||x.type.is_stream_position(w.args[0]))||w.indicator==="reposition/1"&&(x.type.is_variable(w.args[0])||x.type.is_atom(w.args[0])&&(w.args[0].id==="true"||w.args[0].id==="false"))||w.indicator==="type/1"&&(x.type.is_variable(w.args[0])||x.type.is_atom(w.args[0])&&(w.args[0].id==="text"||w.args[0].id==="binary"))||w.indicator==="mode/1"&&(x.type.is_variable(w.args[0])||x.type.is_atom(w.args[0])&&(w.args[0].id==="read"||w.args[0].id==="write"||w.args[0].id==="append"))||w.indicator==="eof_action/1"&&(x.type.is_variable(w.args[0])||x.type.is_atom(w.args[0])&&(w.args[0].id==="error"||w.args[0].id==="eof_code"||w.args[0].id==="reset"))||w.indicator==="end_of_stream/1"&&(x.type.is_variable(w.args[0])||x.type.is_atom(w.args[0])&&(w.args[0].id==="at"||w.args[0].id==="past"||w.args[0].id==="not")))},is_streamable:function(w){return w.__proto__.stream!==void 0},is_read_option:function(w){return x.type.is_term(w)&&["variables/1","variable_names/1","singletons/1"].indexOf(w.indicator)!==-1},is_write_option:function(w){return x.type.is_term(w)&&(w.indicator==="quoted/1"&&x.type.is_atom(w.args[0])&&(w.args[0].id==="true"||w.args[0].id==="false")||w.indicator==="ignore_ops/1"&&x.type.is_atom(w.args[0])&&(w.args[0].id==="true"||w.args[0].id==="false")||w.indicator==="numbervars/1"&&x.type.is_atom(w.args[0])&&(w.args[0].id==="true"||w.args[0].id==="false"))},is_close_option:function(w){return x.type.is_term(w)&&w.indicator==="force/1"&&x.type.is_atom(w.args[0])&&(w.args[0].id==="true"||w.args[0].id==="false")},is_modifiable_flag:function(w){return x.type.is_flag(w)&&x.flag[w.id].changeable},is_module:function(w){return w instanceof H&&w.indicator==="library/1"&&w.args[0]instanceof H&&w.args[0].args.length===0&&x.module[w.args[0].id]!==void 0}},arithmetic:{evaluation:{"e/0":{type_args:null,type_result:!0,fn:function(w){return Math.E}},"pi/0":{type_args:null,type_result:!0,fn:function(w){return Math.PI}},"tau/0":{type_args:null,type_result:!0,fn:function(w){return 2*Math.PI}},"epsilon/0":{type_args:null,type_result:!0,fn:function(w){return Number.EPSILON}},"+/1":{type_args:null,type_result:null,fn:function(w,S){return w}},"-/1":{type_args:null,type_result:null,fn:function(w,S){return-w}},"\\/1":{type_args:!1,type_result:!1,fn:function(w,S){return~w}},"abs/1":{type_args:null,type_result:null,fn:function(w,S){return Math.abs(w)}},"sign/1":{type_args:null,type_result:null,fn:function(w,S){return Math.sign(w)}},"float_integer_part/1":{type_args:!0,type_result:!1,fn:function(w,S){return parseInt(w)}},"float_fractional_part/1":{type_args:!0,type_result:!0,fn:function(w,S){return w-parseInt(w)}},"float/1":{type_args:null,type_result:!0,fn:function(w,S){return parseFloat(w)}},"floor/1":{type_args:!0,type_result:!1,fn:function(w,S){return Math.floor(w)}},"truncate/1":{type_args:!0,type_result:!1,fn:function(w,S){return parseInt(w)}},"round/1":{type_args:!0,type_result:!1,fn:function(w,S){return Math.round(w)}},"ceiling/1":{type_args:!0,type_result:!1,fn:function(w,S){return Math.ceil(w)}},"sin/1":{type_args:null,type_result:!0,fn:function(w,S){return Math.sin(w)}},"cos/1":{type_args:null,type_result:!0,fn:function(w,S){return Math.cos(w)}},"tan/1":{type_args:null,type_result:!0,fn:function(w,S){return Math.tan(w)}},"asin/1":{type_args:null,type_result:!0,fn:function(w,S){return Math.asin(w)}},"acos/1":{type_args:null,type_result:!0,fn:function(w,S){return Math.acos(w)}},"atan/1":{type_args:null,type_result:!0,fn:function(w,S){return Math.atan(w)}},"atan2/2":{type_args:null,type_result:!0,fn:function(w,S,y){return Math.atan2(w,S)}},"exp/1":{type_args:null,type_result:!0,fn:function(w,S){return Math.exp(w)}},"sqrt/1":{type_args:null,type_result:!0,fn:function(w,S){return Math.sqrt(w)}},"log/1":{type_args:null,type_result:!0,fn:function(w,S){return w>0?Math.log(w):x.error.evaluation("undefined",S.__call_indicator)}},"+/2":{type_args:null,type_result:null,fn:function(w,S,y){return w+S}},"-/2":{type_args:null,type_result:null,fn:function(w,S,y){return w-S}},"*/2":{type_args:null,type_result:null,fn:function(w,S,y){return w*S}},"//2":{type_args:null,type_result:!0,fn:function(w,S,y){return S?w/S:x.error.evaluation("zero_division",y.__call_indicator)}},"///2":{type_args:!1,type_result:!1,fn:function(w,S,y){return S?parseInt(w/S):x.error.evaluation("zero_division",y.__call_indicator)}},"**/2":{type_args:null,type_result:!0,fn:function(w,S,y){return Math.pow(w,S)}},"^/2":{type_args:null,type_result:null,fn:function(w,S,y){return Math.pow(w,S)}},"<</2":{type_args:!1,type_result:!1,fn:function(w,S,y){return w<<S}},">>/2":{type_args:!1,type_result:!1,fn:function(w,S,y){return w>>S}},"/\\/2":{type_args:!1,type_result:!1,fn:function(w,S,y){return w&S}},"\\//2":{type_args:!1,type_result:!1,fn:function(w,S,y){return w|S}},"xor/2":{type_args:!1,type_result:!1,fn:function(w,S,y){return w^S}},"rem/2":{type_args:!1,type_result:!1,fn:function(w,S,y){return S?w%S:x.error.evaluation("zero_division",y.__call_indicator)}},"mod/2":{type_args:!1,type_result:!1,fn:function(w,S,y){return S?w-parseInt(w/S)*S:x.error.evaluation("zero_division",y.__call_indicator)}},"max/2":{type_args:null,type_result:null,fn:function(w,S,y){return Math.max(w,S)}},"min/2":{type_args:null,type_result:null,fn:function(w,S,y){return Math.min(w,S)}}}},directive:{"dynamic/1":function(w,S){var y=S.args[0];if(x.type.is_variable(y))w.throw_error(x.error.instantiation(S.indicator));else if(!x.type.is_compound(y)||y.indicator!=="//2")w.throw_error(x.error.type("predicate_indicator",y,S.indicator));else if(x.type.is_variable(y.args[0])||x.type.is_variable(y.args[1]))w.throw_error(x.error.instantiation(S.indicator));else if(!x.type.is_atom(y.args[0]))w.throw_error(x.error.type("atom",y.args[0],S.indicator));else if(!x.type.is_integer(y.args[1]))w.throw_error(x.error.type("integer",y.args[1],S.indicator));else{var F=S.args[0].args[0].id+"/"+S.args[0].args[1].value;w.session.public_predicates[F]=!0,w.session.rules[F]||(w.session.rules[F]=[])}},"multifile/1":function(w,S){var y=S.args[0];x.type.is_variable(y)?w.throw_error(x.error.instantiation(S.indicator)):!x.type.is_compound(y)||y.indicator!=="//2"?w.throw_error(x.error.type("predicate_indicator",y,S.indicator)):x.type.is_variable(y.args[0])||x.type.is_variable(y.args[1])?w.throw_error(x.error.instantiation(S.indicator)):x.type.is_atom(y.args[0])?x.type.is_integer(y.args[1])?w.session.multifile_predicates[S.args[0].args[0].id+"/"+S.args[0].args[1].value]=!0:w.throw_error(x.error.type("integer",y.args[1],S.indicator)):w.throw_error(x.error.type("atom",y.args[0],S.indicator))},"set_prolog_flag/2":function(w,S){var y=S.args[0],F=S.args[1];x.type.is_variable(y)||x.type.is_variable(F)?w.throw_error(x.error.instantiation(S.indicator)):x.type.is_atom(y)?x.type.is_flag(y)?x.type.is_value_flag(y,F)?x.type.is_modifiable_flag(y)?w.session.flag[y.id]=F:w.throw_error(x.error.permission("modify","flag",y)):w.throw_error(x.error.domain("flag_value",new H("+",[y,F]),S.indicator)):w.throw_error(x.error.domain("prolog_flag",y,S.indicator)):w.throw_error(x.error.type("atom",y,S.indicator))},"use_module/1":function(w,S){var y=S.args[0];if(x.type.is_variable(y))w.throw_error(x.error.instantiation(S.indicator));else if(!x.type.is_term(y))w.throw_error(x.error.type("term",y,S.indicator));else if(x.type.is_module(y)){var F=y.args[0].id;e(w.session.modules,F)===-1&&w.session.modules.push(F)}},"char_conversion/2":function(w,S){var y=S.args[0],F=S.args[1];x.type.is_variable(y)||x.type.is_variable(F)?w.throw_error(x.error.instantiation(S.indicator)):x.type.is_character(y)?x.type.is_character(F)?y.id===F.id?delete w.session.__char_conversion[y.id]:w.session.__char_conversion[y.id]=F.id:w.throw_error(x.error.type("character",F,S.indicator)):w.throw_error(x.error.type("character",y,S.indicator))},"op/3":function(w,S){var y=S.args[0],F=S.args[1],z=S.args[2];if(x.type.is_variable(y)||x.type.is_variable(F)||x.type.is_variable(z))w.throw_error(x.error.instantiation(S.indicator));else if(!x.type.is_integer(y))w.throw_error(x.error.type("integer",y,S.indicator));else if(!x.type.is_atom(F))w.throw_error(x.error.type("atom",F,S.indicator));else if(!x.type.is_atom(z))w.throw_error(x.error.type("atom",z,S.indicator));else if(y.value<0||y.value>1200)w.throw_error(x.error.domain("operator_priority",y,S.indicator));else if(z.id===",")w.throw_error(x.error.permission("modify","operator",z,S.indicator));else if(z.id==="|"&&(y.value<1001||F.id.length!==3))w.throw_error(x.error.permission("modify","operator",z,S.indicator));else if(["fy","fx","yf","xf","xfx","yfx","xfy"].indexOf(F.id)===-1)w.throw_error(x.error.domain("operator_specifier",F,S.indicator));else{var X={prefix:null,infix:null,postfix:null};for(var Z in w.session.__operators)if(!!w.session.__operators.hasOwnProperty(Z)){var ie=w.session.__operators[Z][z.id];ie&&(e(ie,"fx")!==-1&&(X.prefix={priority:Z,type:"fx"}),e(ie,"fy")!==-1&&(X.prefix={priority:Z,type:"fy"}),e(ie,"xf")!==-1&&(X.postfix={priority:Z,type:"xf"}),e(ie,"yf")!==-1&&(X.postfix={priority:Z,type:"yf"}),e(ie,"xfx")!==-1&&(X.infix={priority:Z,type:"xfx"}),e(ie,"xfy")!==-1&&(X.infix={priority:Z,type:"xfy"}),e(ie,"yfx")!==-1&&(X.infix={priority:Z,type:"yfx"}))}var Se;switch(F.id){case"fy":case"fx":Se="prefix";break;case"yf":case"xf":Se="postfix";break;default:Se="infix";break}if(((X.prefix&&Se==="prefix"||X.postfix&&Se==="postfix"||X.infix&&Se==="infix")&&X[Se].type!==F.id||X.infix&&Se==="postfix"||X.postfix&&Se==="infix")&&y.value!==0)w.throw_error(x.error.permission("create","operator",z,S.indicator));else return X[Se]&&(Ee(w.session.__operators[X[Se].priority][z.id],F.id),w.session.__operators[X[Se].priority][z.id].length===0&&delete w.session.__operators[X[Se].priority][z.id]),y.value>0&&(w.session.__operators[y.value]||(w.session.__operators[y.value.toString()]={}),w.session.__operators[y.value][z.id]||(w.session.__operators[y.value][z.id]=[]),w.session.__operators[y.value][z.id].push(F.id)),!0}}},predicate:{"op/3":function(w,S,y){x.directive["op/3"](w,y)&&w.success(S)},"current_op/3":function(w,S,y){var F=y.args[0],z=y.args[1],X=y.args[2],Z=[];for(var ie in w.session.__operators)for(var Se in w.session.__operators[ie])for(var Ne=0;Ne<w.session.__operators[ie][Se].length;Ne++)Z.push(new be(S.goal.replace(new H(",",[new H("=",[new ke(ie,!1),F]),new H(",",[new H("=",[new H(w.session.__operators[ie][Se][Ne],[]),z]),new H("=",[new H(Se,[]),X])])])),S.substitution,S));w.prepend(Z)},";/2":function(w,S,y){if(x.type.is_term(y.args[0])&&y.args[0].indicator==="->/2"){var F=w.points,z=w.session.format_success,X=w.session.format_error;w.session.format_success=function(Ne){return Ne.substitution},w.session.format_error=function(Ne){return Ne.goal},w.points=[new be(y.args[0].args[0],S.substitution,S)];var Z=function(Ne){w.points=F,w.session.format_success=z,w.session.format_error=X,Ne===!1?w.prepend([new be(S.goal.replace(y.args[1]),S.substitution,S)]):x.type.is_error(Ne)?w.throw_error(Ne.args[0]):Ne===null?(w.prepend([S]),w.__calls.shift()(null)):w.prepend([new be(S.goal.replace(y.args[0].args[1]).apply(Ne),S.substitution.apply(Ne),S)])};w.__calls.unshift(Z)}else{var ie=new be(S.goal.replace(y.args[0]),S.substitution,S),Se=new be(S.goal.replace(y.args[1]),S.substitution,S);w.prepend([ie,Se])}},"!/0":function(w,S,y){var F,z,X=[];for(F=S,z=null;F.parent!==null&&F.parent.goal.search(y);)if(z=F,F=F.parent,F.goal!==null){var Z=F.goal.select();if(Z&&Z.id==="call"&&Z.search(y)){F=z;break}}for(var ie=w.points.length-1;ie>=0;ie--){for(var Se=w.points[ie],Ne=Se.parent;Ne!==null&&Ne!==F.parent;)Ne=Ne.parent;Ne===null&&Ne!==F.parent&&X.push(Se)}w.points=X.reverse(),w.success(S)},"\\+/1":function(w,S,y){var F=y.args[0];x.type.is_variable(F)?w.throw_error(x.error.instantiation(w.level)):x.type.is_callable(F)?w.prepend([new be(S.goal.replace(new H(",",[new H(",",[new H("call",[F]),new H("!",[])]),new H("fail",[])])),S.substitution,S),new be(S.goal.replace(null),S.substitution,S)]):w.throw_error(x.error.type("callable",F,w.level))},"->/2":function(w,S,y){var F=S.goal.replace(new H(",",[y.args[0],new H(",",[new H("!"),y.args[1]])]));w.prepend([new be(F,S.substitution,S)])},"fail/0":function(w,S,y){},"false/0":function(w,S,y){},"true/0":function(w,S,y){w.success(S)},"call/1":ne(1),"call/2":ne(2),"call/3":ne(3),"call/4":ne(4),"call/5":ne(5),"call/6":ne(6),"call/7":ne(7),"call/8":ne(8),"once/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("call",[F]),new H("!",[])])),S.substitution,S)])},"forall/2":function(w,S,y){var F=y.args[0],z=y.args[1];w.prepend([new be(S.goal.replace(new H("\\+",[new H(",",[new H("call",[F]),new H("\\+",[new H("call",[z])])])])),S.substitution,S)])},"repeat/0":function(w,S,y){w.prepend([new be(S.goal.replace(null),S.substitution,S),S])},"throw/1":function(w,S,y){x.type.is_variable(y.args[0])?w.throw_error(x.error.instantiation(w.level)):w.throw_error(y.args[0])},"catch/3":function(w,S,y){var F=w.points;w.points=[],w.prepend([new be(y.args[0],S.substitution,S)]);var z=w.session.format_success,X=w.session.format_error;w.session.format_success=function(ie){return ie.substitution},w.session.format_error=function(ie){return ie.goal};var Z=function(ie){var Se=w.points;if(w.points=F,w.session.format_success=z,w.session.format_error=X,x.type.is_error(ie)){for(var Ne=[],ot=w.points.length-1;ot>=0;ot--){for(var $t=w.points[ot],dt=$t.parent;dt!==null&&dt!==S.parent;)dt=dt.parent;dt===null&&dt!==S.parent&&Ne.push($t)}w.points=Ne;var jt=w.get_flag("occurs_check").indicator==="true/0",$t=new be,xt=x.unify(ie.args[0],y.args[1],jt);xt!==null?($t.substitution=S.substitution.apply(xt),$t.goal=S.goal.replace(y.args[2]).apply(xt),$t.parent=S,w.prepend([$t])):w.throw_error(ie.args[0])}else if(ie!==!1){for(var an=ie===null?[]:[new be(S.goal.apply(ie).replace(null),S.substitution.apply(ie),S)],Qr=[],ot=Se.length-1;ot>=0;ot--){Qr.push(Se[ot]);var mr=Se[ot].goal!==null?Se[ot].goal.select():null;if(x.type.is_term(mr)&&mr.indicator==="!/0")break}var xr=o(Qr,function(Wr){return Wr.goal===null&&(Wr.goal=new H("true",[])),Wr=new be(S.goal.replace(new H("catch",[Wr.goal,y.args[1],y.args[2]])),S.substitution.apply(Wr.substitution),Wr.parent),Wr.exclude=y.args[0].variables(),Wr}).reverse();w.prepend(xr),w.prepend(an),ie===null&&(this.current_limit=0,w.__calls.shift()(null))}};w.__calls.unshift(Z)},"=/2":function(w,S,y){var F=w.get_flag("occurs_check").indicator==="true/0",z=new be,X=x.unify(y.args[0],y.args[1],F);X!==null&&(z.goal=S.goal.apply(X).replace(null),z.substitution=S.substitution.apply(X),z.parent=S,w.prepend([z]))},"unify_with_occurs_check/2":function(w,S,y){var F=new be,z=x.unify(y.args[0],y.args[1],!0);z!==null&&(F.goal=S.goal.apply(z).replace(null),F.substitution=S.substitution.apply(z),F.parent=S,w.prepend([F]))},"\\=/2":function(w,S,y){var F=w.get_flag("occurs_check").indicator==="true/0",z=x.unify(y.args[0],y.args[1],F);z===null&&w.success(S)},"subsumes_term/2":function(w,S,y){var F=w.get_flag("occurs_check").indicator==="true/0",z=x.unify(y.args[1],y.args[0],F);z!==null&&y.args[1].apply(z).equals(y.args[1])&&w.success(S)},"findall/3":function(w,S,y){var F=y.args[0],z=y.args[1],X=y.args[2];if(x.type.is_variable(z))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_callable(z))w.throw_error(x.error.type("callable",z,y.indicator));else if(!x.type.is_variable(X)&&!x.type.is_list(X))w.throw_error(x.error.type("list",X,y.indicator));else{var Z=w.next_free_variable(),ie=new H(",",[z,new H("=",[Z,F])]),Se=w.points,Ne=w.session.limit,ot=w.session.format_success;w.session.format_success=function($t){return $t.substitution},w.add_goal(ie,!0,S);var dt=[],jt=function($t){if($t!==!1&&$t!==null&&!x.type.is_error($t))w.__calls.unshift(jt),dt.push($t.links[Z.id]),w.session.limit=w.current_limit;else if(w.points=Se,w.session.limit=Ne,w.session.format_success=ot,x.type.is_error($t))w.throw_error($t.args[0]);else if(w.current_limit>0){for(var xt=new H("[]"),an=dt.length-1;an>=0;an--)xt=new H(".",[dt[an],xt]);w.prepend([new be(S.goal.replace(new H("=",[X,xt])),S.substitution,S)])}};w.__calls.unshift(jt)}},"bagof/3":function(w,S,y){var F,z=y.args[0],X=y.args[1],Z=y.args[2];if(x.type.is_variable(X))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_callable(X))w.throw_error(x.error.type("callable",X,y.indicator));else if(!x.type.is_variable(Z)&&!x.type.is_list(Z))w.throw_error(x.error.type("list",Z,y.indicator));else{var ie=w.next_free_variable(),Se;X.indicator==="^/2"?(Se=X.args[0].variables(),X=X.args[1]):Se=[],Se=Se.concat(z.variables());for(var Ne=X.variables().filter(function(xr){return e(Se,xr)===-1}),ot=new H("[]"),dt=Ne.length-1;dt>=0;dt--)ot=new H(".",[new Ie(Ne[dt]),ot]);var jt=new H(",",[X,new H("=",[ie,new H(",",[ot,z])])]),$t=w.points,xt=w.session.limit,an=w.session.format_success;w.session.format_success=function(xr){return xr.substitution},w.add_goal(jt,!0,S);var Qr=[],mr=function(xr){if(xr!==!1&&xr!==null&&!x.type.is_error(xr)){w.__calls.unshift(mr);var Wr=!1,Vn=xr.links[ie.id].args[0],Ns=xr.links[ie.id].args[1];for(var Ri in Qr)if(!!Qr.hasOwnProperty(Ri)){var ps=Qr[Ri];if(ps.variables.equals(Vn)){ps.answers.push(Ns),Wr=!0;break}}Wr||Qr.push({variables:Vn,answers:[Ns]}),w.session.limit=w.current_limit}else if(w.points=$t,w.session.limit=xt,w.session.format_success=an,x.type.is_error(xr))w.throw_error(xr.args[0]);else if(w.current_limit>0){for(var io=[],Si=0;Si<Qr.length;Si++){xr=Qr[Si].answers;for(var Ls=new H("[]"),so=xr.length-1;so>=0;so--)Ls=new H(".",[xr[so],Ls]);io.push(new be(S.goal.replace(new H(",",[new H("=",[ot,Qr[Si].variables]),new H("=",[Z,Ls])])),S.substitution,S))}w.prepend(io)}};w.__calls.unshift(mr)}},"setof/3":function(w,S,y){var F,z=y.args[0],X=y.args[1],Z=y.args[2];if(x.type.is_variable(X))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_callable(X))w.throw_error(x.error.type("callable",X,y.indicator));else if(!x.type.is_variable(Z)&&!x.type.is_list(Z))w.throw_error(x.error.type("list",Z,y.indicator));else{var ie=w.next_free_variable(),Se;X.indicator==="^/2"?(Se=X.args[0].variables(),X=X.args[1]):Se=[],Se=Se.concat(z.variables());for(var Ne=X.variables().filter(function(xr){return e(Se,xr)===-1}),ot=new H("[]"),dt=Ne.length-1;dt>=0;dt--)ot=new H(".",[new Ie(Ne[dt]),ot]);var jt=new H(",",[X,new H("=",[ie,new H(",",[ot,z])])]),$t=w.points,xt=w.session.limit,an=w.session.format_success;w.session.format_success=function(xr){return xr.substitution},w.add_goal(jt,!0,S);var Qr=[],mr=function(xr){if(xr!==!1&&xr!==null&&!x.type.is_error(xr)){w.__calls.unshift(mr);var Wr=!1,Vn=xr.links[ie.id].args[0],Ns=xr.links[ie.id].args[1];for(var Ri in Qr)if(!!Qr.hasOwnProperty(Ri)){var ps=Qr[Ri];if(ps.variables.equals(Vn)){ps.answers.push(Ns),Wr=!0;break}}Wr||Qr.push({variables:Vn,answers:[Ns]}),w.session.limit=w.current_limit}else if(w.points=$t,w.session.limit=xt,w.session.format_success=an,x.type.is_error(xr))w.throw_error(xr.args[0]);else if(w.current_limit>0){for(var io=[],Si=0;Si<Qr.length;Si++){xr=Qr[Si].answers.sort(x.compare);for(var Ls=new H("[]"),so=xr.length-1;so>=0;so--)Ls=new H(".",[xr[so],Ls]);io.push(new be(S.goal.replace(new H(",",[new H("=",[ot,Qr[Si].variables]),new H("=",[Z,Ls])])),S.substitution,S))}w.prepend(io)}};w.__calls.unshift(mr)}},"functor/3":function(w,S,y){var F,z=y.args[0],X=y.args[1],Z=y.args[2];if(x.type.is_variable(z)&&(x.type.is_variable(X)||x.type.is_variable(Z)))w.throw_error(x.error.instantiation("functor/3"));else if(!x.type.is_variable(Z)&&!x.type.is_integer(Z))w.throw_error(x.error.type("integer",y.args[2],"functor/3"));else if(!x.type.is_variable(X)&&!x.type.is_atomic(X))w.throw_error(x.error.type("atomic",y.args[1],"functor/3"));else if(x.type.is_integer(X)&&x.type.is_integer(Z)&&Z.value!==0)w.throw_error(x.error.type("atom",y.args[1],"functor/3"));else if(x.type.is_variable(z)){if(y.args[2].value>=0){for(var ie=[],Se=0;Se<Z.value;Se++)ie.push(w.next_free_variable());var Ne=x.type.is_integer(X)?X:new H(X.id,ie);w.prepend([new be(S.goal.replace(new H("=",[z,Ne])),S.substitution,S)])}}else{var ot=x.type.is_integer(z)?z:new H(z.id,[]),dt=x.type.is_integer(z)?new ke(0,!1):new ke(z.args.length,!1),jt=new H(",",[new H("=",[ot,X]),new H("=",[dt,Z])]);w.prepend([new be(S.goal.replace(jt),S.substitution,S)])}},"arg/3":function(w,S,y){if(x.type.is_variable(y.args[0])||x.type.is_variable(y.args[1]))w.throw_error(x.error.instantiation(y.indicator));else if(y.args[0].value<0)w.throw_error(x.error.domain("not_less_than_zero",y.args[0],y.indicator));else if(!x.type.is_compound(y.args[1]))w.throw_error(x.error.type("compound",y.args[1],y.indicator));else{var F=y.args[0].value;if(F>0&&F<=y.args[1].args.length){var z=new H("=",[y.args[1].args[F-1],y.args[2]]);w.prepend([new be(S.goal.replace(z),S.substitution,S)])}}},"=../2":function(w,S,y){var F;if(x.type.is_variable(y.args[0])&&(x.type.is_variable(y.args[1])||x.type.is_non_empty_list(y.args[1])&&x.type.is_variable(y.args[1].args[0])))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_fully_list(y.args[1]))w.throw_error(x.error.type("list",y.args[1],y.indicator));else if(x.type.is_variable(y.args[0])){if(!x.type.is_variable(y.args[1])){var X=[];for(F=y.args[1].args[1];F.indicator==="./2";)X.push(F.args[0]),F=F.args[1];x.type.is_variable(y.args[0])&&x.type.is_variable(F)?w.throw_error(x.error.instantiation(y.indicator)):X.length===0&&x.type.is_compound(y.args[1].args[0])?w.throw_error(x.error.type("atomic",y.args[1].args[0],y.indicator)):X.length>0&&(x.type.is_compound(y.args[1].args[0])||x.type.is_number(y.args[1].args[0]))?w.throw_error(x.error.type("atom",y.args[1].args[0],y.indicator)):X.length===0?w.prepend([new be(S.goal.replace(new H("=",[y.args[1].args[0],y.args[0]],S)),S.substitution,S)]):w.prepend([new be(S.goal.replace(new H("=",[new H(y.args[1].args[0].id,X),y.args[0]])),S.substitution,S)])}}else{if(x.type.is_atomic(y.args[0]))F=new H(".",[y.args[0],new H("[]")]);else{F=new H("[]");for(var z=y.args[0].args.length-1;z>=0;z--)F=new H(".",[y.args[0].args[z],F]);F=new H(".",[new H(y.args[0].id),F])}w.prepend([new be(S.goal.replace(new H("=",[F,y.args[1]])),S.substitution,S)])}},"copy_term/2":function(w,S,y){var F=y.args[0].rename(w);w.prepend([new be(S.goal.replace(new H("=",[F,y.args[1]])),S.substitution,S.parent)])},"term_variables/2":function(w,S,y){var F=y.args[0],z=y.args[1];if(!x.type.is_fully_list(z))w.throw_error(x.error.type("list",z,y.indicator));else{var X=g(o(De(F.variables()),function(Z){return new Ie(Z)}));w.prepend([new be(S.goal.replace(new H("=",[z,X])),S.substitution,S)])}},"clause/2":function(w,S,y){if(x.type.is_variable(y.args[0]))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_callable(y.args[0]))w.throw_error(x.error.type("callable",y.args[0],y.indicator));else if(!x.type.is_variable(y.args[1])&&!x.type.is_callable(y.args[1]))w.throw_error(x.error.type("callable",y.args[1],y.indicator));else if(w.session.rules[y.args[0].indicator]!==void 0)if(w.is_public_predicate(y.args[0].indicator)){var F=[];for(var z in w.session.rules[y.args[0].indicator])if(!!w.session.rules[y.args[0].indicator].hasOwnProperty(z)){var X=w.session.rules[y.args[0].indicator][z];w.session.renamed_variables={},X=X.rename(w),X.body===null&&(X.body=new H("true"));var Z=new H(",",[new H("=",[X.head,y.args[0]]),new H("=",[X.body,y.args[1]])]);F.push(new be(S.goal.replace(Z),S.substitution,S))}w.prepend(F)}else w.throw_error(x.error.permission("access","private_procedure",y.args[0].indicator,y.indicator))},"current_predicate/1":function(w,S,y){var F=y.args[0];if(!x.type.is_variable(F)&&(!x.type.is_compound(F)||F.indicator!=="//2"))w.throw_error(x.error.type("predicate_indicator",F,y.indicator));else if(!x.type.is_variable(F)&&!x.type.is_variable(F.args[0])&&!x.type.is_atom(F.args[0]))w.throw_error(x.error.type("atom",F.args[0],y.indicator));else if(!x.type.is_variable(F)&&!x.type.is_variable(F.args[1])&&!x.type.is_integer(F.args[1]))w.throw_error(x.error.type("integer",F.args[1],y.indicator));else{var z=[];for(var X in w.session.rules)if(!!w.session.rules.hasOwnProperty(X)){var Z=X.lastIndexOf("/"),ie=X.substr(0,Z),Se=parseInt(X.substr(Z+1,X.length-(Z+1))),Ne=new H("/",[new H(ie),new ke(Se,!1)]),ot=new H("=",[Ne,F]);z.push(new be(S.goal.replace(ot),S.substitution,S))}w.prepend(z)}},"asserta/1":function(w,S,y){if(x.type.is_variable(y.args[0]))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_callable(y.args[0]))w.throw_error(x.error.type("callable",y.args[0],y.indicator));else{var F,z;y.args[0].indicator===":-/2"?(F=y.args[0].args[0],z=Pe(y.args[0].args[1])):(F=y.args[0],z=null),x.type.is_callable(F)?z!==null&&!x.type.is_callable(z)?w.throw_error(x.error.type("callable",z,y.indicator)):w.is_public_predicate(F.indicator)?(w.session.rules[F.indicator]===void 0&&(w.session.rules[F.indicator]=[]),w.session.public_predicates[F.indicator]=!0,w.session.rules[F.indicator]=[new _e(F,z,!0)].concat(w.session.rules[F.indicator]),w.success(S)):w.throw_error(x.error.permission("modify","static_procedure",F.indicator,y.indicator)):w.throw_error(x.error.type("callable",F,y.indicator))}},"assertz/1":function(w,S,y){if(x.type.is_variable(y.args[0]))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_callable(y.args[0]))w.throw_error(x.error.type("callable",y.args[0],y.indicator));else{var F,z;y.args[0].indicator===":-/2"?(F=y.args[0].args[0],z=Pe(y.args[0].args[1])):(F=y.args[0],z=null),x.type.is_callable(F)?z!==null&&!x.type.is_callable(z)?w.throw_error(x.error.type("callable",z,y.indicator)):w.is_public_predicate(F.indicator)?(w.session.rules[F.indicator]===void 0&&(w.session.rules[F.indicator]=[]),w.session.public_predicates[F.indicator]=!0,w.session.rules[F.indicator].push(new _e(F,z,!0)),w.success(S)):w.throw_error(x.error.permission("modify","static_procedure",F.indicator,y.indicator)):w.throw_error(x.error.type("callable",F,y.indicator))}},"retract/1":function(w,S,y){if(x.type.is_variable(y.args[0]))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_callable(y.args[0]))w.throw_error(x.error.type("callable",y.args[0],y.indicator));else{var F,z;if(y.args[0].indicator===":-/2"?(F=y.args[0].args[0],z=y.args[0].args[1]):(F=y.args[0],z=new H("true")),typeof S.retract>"u")if(w.is_public_predicate(F.indicator)){if(w.session.rules[F.indicator]!==void 0){for(var X=[],Z=0;Z<w.session.rules[F.indicator].length;Z++){w.session.renamed_variables={};var ie=w.session.rules[F.indicator][Z],Se=ie.rename(w);Se.body===null&&(Se.body=new H("true",[]));var Ne=w.get_flag("occurs_check").indicator==="true/0",ot=x.unify(new H(",",[F,z]),new H(",",[Se.head,Se.body]),Ne);if(ot!==null){var dt=new be(S.goal.replace(new H(",",[new H("retract",[new H(":-",[F,z])]),new H(",",[new H("=",[F,Se.head]),new H("=",[z,Se.body])])])),S.substitution,S);dt.retract=ie,X.push(dt)}}w.prepend(X)}}else w.throw_error(x.error.permission("modify","static_procedure",F.indicator,y.indicator));else ce(w,S,F.indicator,S.retract)}},"retractall/1":function(w,S,y){var F=y.args[0];x.type.is_variable(F)?w.throw_error(x.error.instantiation(y.indicator)):x.type.is_callable(F)?w.prepend([new be(S.goal.replace(new H(",",[new H("retract",[new x.type.Term(":-",[F,new Ie("_")])]),new H("fail",[])])),S.substitution,S),new be(S.goal.replace(null),S.substitution,S)]):w.throw_error(x.error.type("callable",F,y.indicator))},"abolish/1":function(w,S,y){if(x.type.is_variable(y.args[0])||x.type.is_term(y.args[0])&&y.args[0].indicator==="//2"&&(x.type.is_variable(y.args[0].args[0])||x.type.is_variable(y.args[0].args[1])))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_term(y.args[0])||y.args[0].indicator!=="//2")w.throw_error(x.error.type("predicate_indicator",y.args[0],y.indicator));else if(!x.type.is_atom(y.args[0].args[0]))w.throw_error(x.error.type("atom",y.args[0].args[0],y.indicator));else if(!x.type.is_integer(y.args[0].args[1]))w.throw_error(x.error.type("integer",y.args[0].args[1],y.indicator));else if(y.args[0].args[1].value<0)w.throw_error(x.error.domain("not_less_than_zero",y.args[0].args[1],y.indicator));else if(x.type.is_number(w.get_flag("max_arity"))&&y.args[0].args[1].value>w.get_flag("max_arity").value)w.throw_error(x.error.representation("max_arity",y.indicator));else{var F=y.args[0].args[0].id+"/"+y.args[0].args[1].value;w.is_public_predicate(F)?(delete w.session.rules[F],w.success(S)):w.throw_error(x.error.permission("modify","static_procedure",F,y.indicator))}},"atom_length/2":function(w,S,y){if(x.type.is_variable(y.args[0]))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_atom(y.args[0]))w.throw_error(x.error.type("atom",y.args[0],y.indicator));else if(!x.type.is_variable(y.args[1])&&!x.type.is_integer(y.args[1]))w.throw_error(x.error.type("integer",y.args[1],y.indicator));else if(x.type.is_integer(y.args[1])&&y.args[1].value<0)w.throw_error(x.error.domain("not_less_than_zero",y.args[1],y.indicator));else{var F=new ke(y.args[0].id.length,!1);w.prepend([new be(S.goal.replace(new H("=",[F,y.args[1]])),S.substitution,S)])}},"atom_concat/3":function(w,S,y){var F,z,X=y.args[0],Z=y.args[1],ie=y.args[2];if(x.type.is_variable(ie)&&(x.type.is_variable(X)||x.type.is_variable(Z)))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(X)&&!x.type.is_atom(X))w.throw_error(x.error.type("atom",X,y.indicator));else if(!x.type.is_variable(Z)&&!x.type.is_atom(Z))w.throw_error(x.error.type("atom",Z,y.indicator));else if(!x.type.is_variable(ie)&&!x.type.is_atom(ie))w.throw_error(x.error.type("atom",ie,y.indicator));else{var Se=x.type.is_variable(X),Ne=x.type.is_variable(Z);if(!Se&&!Ne)z=new H("=",[ie,new H(X.id+Z.id)]),w.prepend([new be(S.goal.replace(z),S.substitution,S)]);else if(Se&&!Ne)F=ie.id.substr(0,ie.id.length-Z.id.length),F+Z.id===ie.id&&(z=new H("=",[X,new H(F)]),w.prepend([new be(S.goal.replace(z),S.substitution,S)]));else if(Ne&&!Se)F=ie.id.substr(X.id.length),X.id+F===ie.id&&(z=new H("=",[Z,new H(F)]),w.prepend([new be(S.goal.replace(z),S.substitution,S)]));else{for(var ot=[],dt=0;dt<=ie.id.length;dt++){var jt=new H(ie.id.substr(0,dt)),$t=new H(ie.id.substr(dt));z=new H(",",[new H("=",[jt,X]),new H("=",[$t,Z])]),ot.push(new be(S.goal.replace(z),S.substitution,S))}w.prepend(ot)}}},"sub_atom/5":function(w,S,y){var F,z=y.args[0],X=y.args[1],Z=y.args[2],ie=y.args[3],Se=y.args[4];if(x.type.is_variable(z))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(X)&&!x.type.is_integer(X))w.throw_error(x.error.type("integer",X,y.indicator));else if(!x.type.is_variable(Z)&&!x.type.is_integer(Z))w.throw_error(x.error.type("integer",Z,y.indicator));else if(!x.type.is_variable(ie)&&!x.type.is_integer(ie))w.throw_error(x.error.type("integer",ie,y.indicator));else if(x.type.is_integer(X)&&X.value<0)w.throw_error(x.error.domain("not_less_than_zero",X,y.indicator));else if(x.type.is_integer(Z)&&Z.value<0)w.throw_error(x.error.domain("not_less_than_zero",Z,y.indicator));else if(x.type.is_integer(ie)&&ie.value<0)w.throw_error(x.error.domain("not_less_than_zero",ie,y.indicator));else{var Ne=[],ot=[],dt=[];if(x.type.is_variable(X))for(F=0;F<=z.id.length;F++)Ne.push(F);else Ne.push(X.value);if(x.type.is_variable(Z))for(F=0;F<=z.id.length;F++)ot.push(F);else ot.push(Z.value);if(x.type.is_variable(ie))for(F=0;F<=z.id.length;F++)dt.push(F);else dt.push(ie.value);var jt=[];for(var $t in Ne)if(!!Ne.hasOwnProperty($t)){F=Ne[$t];for(var xt in ot)if(!!ot.hasOwnProperty(xt)){var an=ot[xt],Qr=z.id.length-F-an;if(e(dt,Qr)!==-1&&F+an+Qr===z.id.length){var mr=z.id.substr(F,an);if(z.id===z.id.substr(0,F)+mr+z.id.substr(F+an,Qr)){var xr=new H("=",[new H(mr),Se]),Wr=new H("=",[X,new ke(F)]),Vn=new H("=",[Z,new ke(an)]),Ns=new H("=",[ie,new ke(Qr)]),Ri=new H(",",[new H(",",[new H(",",[Wr,Vn]),Ns]),xr]);jt.push(new be(S.goal.replace(Ri),S.substitution,S))}}}}w.prepend(jt)}},"atom_chars/2":function(w,S,y){var F=y.args[0],z=y.args[1];if(x.type.is_variable(F)&&x.type.is_variable(z))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(F)&&!x.type.is_atom(F))w.throw_error(x.error.type("atom",F,y.indicator));else if(x.type.is_variable(F)){for(var ie=z,Se=x.type.is_variable(F),Ne="";ie.indicator==="./2";){if(x.type.is_character(ie.args[0]))Ne+=ie.args[0].id;else if(x.type.is_variable(ie.args[0])&&Se){w.throw_error(x.error.instantiation(y.indicator));return}else if(!x.type.is_variable(ie.args[0])){w.throw_error(x.error.type("character",ie.args[0],y.indicator));return}ie=ie.args[1]}x.type.is_variable(ie)&&Se?w.throw_error(x.error.instantiation(y.indicator)):!x.type.is_empty_list(ie)&&!x.type.is_variable(ie)?w.throw_error(x.error.type("list",z,y.indicator)):w.prepend([new be(S.goal.replace(new H("=",[new H(Ne),F])),S.substitution,S)])}else{for(var X=new H("[]"),Z=F.id.length-1;Z>=0;Z--)X=new H(".",[new H(F.id.charAt(Z)),X]);w.prepend([new be(S.goal.replace(new H("=",[z,X])),S.substitution,S)])}},"atom_codes/2":function(w,S,y){var F=y.args[0],z=y.args[1];if(x.type.is_variable(F)&&x.type.is_variable(z))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(F)&&!x.type.is_atom(F))w.throw_error(x.error.type("atom",F,y.indicator));else if(x.type.is_variable(F)){for(var ie=z,Se=x.type.is_variable(F),Ne="";ie.indicator==="./2";){if(x.type.is_character_code(ie.args[0]))Ne+=u(ie.args[0].value);else if(x.type.is_variable(ie.args[0])&&Se){w.throw_error(x.error.instantiation(y.indicator));return}else if(!x.type.is_variable(ie.args[0])){w.throw_error(x.error.representation("character_code",y.indicator));return}ie=ie.args[1]}x.type.is_variable(ie)&&Se?w.throw_error(x.error.instantiation(y.indicator)):!x.type.is_empty_list(ie)&&!x.type.is_variable(ie)?w.throw_error(x.error.type("list",z,y.indicator)):w.prepend([new be(S.goal.replace(new H("=",[new H(Ne),F])),S.substitution,S)])}else{for(var X=new H("[]"),Z=F.id.length-1;Z>=0;Z--)X=new H(".",[new ke(n(F.id,Z),!1),X]);w.prepend([new be(S.goal.replace(new H("=",[z,X])),S.substitution,S)])}},"char_code/2":function(w,S,y){var F=y.args[0],z=y.args[1];if(x.type.is_variable(F)&&x.type.is_variable(z))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(F)&&!x.type.is_character(F))w.throw_error(x.error.type("character",F,y.indicator));else if(!x.type.is_variable(z)&&!x.type.is_integer(z))w.throw_error(x.error.type("integer",z,y.indicator));else if(!x.type.is_variable(z)&&!x.type.is_character_code(z))w.throw_error(x.error.representation("character_code",y.indicator));else if(x.type.is_variable(z)){var X=new ke(n(F.id,0),!1);w.prepend([new be(S.goal.replace(new H("=",[X,z])),S.substitution,S)])}else{var Z=new H(u(z.value));w.prepend([new be(S.goal.replace(new H("=",[Z,F])),S.substitution,S)])}},"number_chars/2":function(w,S,y){var F,z=y.args[0],X=y.args[1];if(x.type.is_variable(z)&&x.type.is_variable(X))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(z)&&!x.type.is_number(z))w.throw_error(x.error.type("number",z,y.indicator));else if(!x.type.is_variable(X)&&!x.type.is_list(X))w.throw_error(x.error.type("list",X,y.indicator));else{var Z=x.type.is_variable(z);if(!x.type.is_variable(X)){var ie=X,Se=!0;for(F="";ie.indicator==="./2";){if(x.type.is_character(ie.args[0]))F+=ie.args[0].id;else if(x.type.is_variable(ie.args[0]))Se=!1;else if(!x.type.is_variable(ie.args[0])){w.throw_error(x.error.type("character",ie.args[0],y.indicator));return}ie=ie.args[1]}if(Se=Se&&x.type.is_empty_list(ie),!x.type.is_empty_list(ie)&&!x.type.is_variable(ie)){w.throw_error(x.error.type("list",X,y.indicator));return}if(!Se&&Z){w.throw_error(x.error.instantiation(y.indicator));return}else if(Se)if(x.type.is_variable(ie)&&Z){w.throw_error(x.error.instantiation(y.indicator));return}else{var Ne=w.parse(F),ot=Ne.value;!x.type.is_number(ot)||Ne.tokens[Ne.tokens.length-1].space?w.throw_error(x.error.syntax_by_predicate("parseable_number",y.indicator)):w.prepend([new be(S.goal.replace(new H("=",[z,ot])),S.substitution,S)]);return}}if(!Z){F=z.toString();for(var dt=new H("[]"),jt=F.length-1;jt>=0;jt--)dt=new H(".",[new H(F.charAt(jt)),dt]);w.prepend([new be(S.goal.replace(new H("=",[X,dt])),S.substitution,S)])}}},"number_codes/2":function(w,S,y){var F,z=y.args[0],X=y.args[1];if(x.type.is_variable(z)&&x.type.is_variable(X))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(z)&&!x.type.is_number(z))w.throw_error(x.error.type("number",z,y.indicator));else if(!x.type.is_variable(X)&&!x.type.is_list(X))w.throw_error(x.error.type("list",X,y.indicator));else{var Z=x.type.is_variable(z);if(!x.type.is_variable(X)){var ie=X,Se=!0;for(F="";ie.indicator==="./2";){if(x.type.is_character_code(ie.args[0]))F+=u(ie.args[0].value);else if(x.type.is_variable(ie.args[0]))Se=!1;else if(!x.type.is_variable(ie.args[0])){w.throw_error(x.error.type("character_code",ie.args[0],y.indicator));return}ie=ie.args[1]}if(Se=Se&&x.type.is_empty_list(ie),!x.type.is_empty_list(ie)&&!x.type.is_variable(ie)){w.throw_error(x.error.type("list",X,y.indicator));return}if(!Se&&Z){w.throw_error(x.error.instantiation(y.indicator));return}else if(Se)if(x.type.is_variable(ie)&&Z){w.throw_error(x.error.instantiation(y.indicator));return}else{var Ne=w.parse(F),ot=Ne.value;!x.type.is_number(ot)||Ne.tokens[Ne.tokens.length-1].space?w.throw_error(x.error.syntax_by_predicate("parseable_number",y.indicator)):w.prepend([new be(S.goal.replace(new H("=",[z,ot])),S.substitution,S)]);return}}if(!Z){F=z.toString();for(var dt=new H("[]"),jt=F.length-1;jt>=0;jt--)dt=new H(".",[new ke(n(F,jt),!1),dt]);w.prepend([new be(S.goal.replace(new H("=",[X,dt])),S.substitution,S)])}}},"upcase_atom/2":function(w,S,y){var F=y.args[0],z=y.args[1];x.type.is_variable(F)?w.throw_error(x.error.instantiation(y.indicator)):x.type.is_atom(F)?!x.type.is_variable(z)&&!x.type.is_atom(z)?w.throw_error(x.error.type("atom",z,y.indicator)):w.prepend([new be(S.goal.replace(new H("=",[z,new H(F.id.toUpperCase(),[])])),S.substitution,S)]):w.throw_error(x.error.type("atom",F,y.indicator))},"downcase_atom/2":function(w,S,y){var F=y.args[0],z=y.args[1];x.type.is_variable(F)?w.throw_error(x.error.instantiation(y.indicator)):x.type.is_atom(F)?!x.type.is_variable(z)&&!x.type.is_atom(z)?w.throw_error(x.error.type("atom",z,y.indicator)):w.prepend([new be(S.goal.replace(new H("=",[z,new H(F.id.toLowerCase(),[])])),S.substitution,S)]):w.throw_error(x.error.type("atom",F,y.indicator))},"atomic_list_concat/2":function(w,S,y){var F=y.args[0],z=y.args[1];w.prepend([new be(S.goal.replace(new H("atomic_list_concat",[F,new H("",[]),z])),S.substitution,S)])},"atomic_list_concat/3":function(w,S,y){var F=y.args[0],z=y.args[1],X=y.args[2];if(x.type.is_variable(z)||x.type.is_variable(F)&&x.type.is_variable(X))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(F)&&!x.type.is_list(F))w.throw_error(x.error.type("list",F,y.indicator));else if(!x.type.is_variable(X)&&!x.type.is_atom(X))w.throw_error(x.error.type("atom",X,y.indicator));else if(x.type.is_variable(X)){for(var ie="",Se=F;x.type.is_term(Se)&&Se.indicator==="./2";){if(!x.type.is_atom(Se.args[0])&&!x.type.is_number(Se.args[0])){w.throw_error(x.error.type("atomic",Se.args[0],y.indicator));return}ie!==""&&(ie+=z.id),x.type.is_atom(Se.args[0])?ie+=Se.args[0].id:ie+=""+Se.args[0].value,Se=Se.args[1]}ie=new H(ie,[]),x.type.is_variable(Se)?w.throw_error(x.error.instantiation(y.indicator)):!x.type.is_term(Se)||Se.indicator!=="[]/0"?w.throw_error(x.error.type("list",F,y.indicator)):w.prepend([new be(S.goal.replace(new H("=",[ie,X])),S.substitution,S)])}else{var Z=g(o(X.id.split(z.id),function(Ne){return new H(Ne,[])}));w.prepend([new be(S.goal.replace(new H("=",[Z,F])),S.substitution,S)])}},"@=</2":function(w,S,y){x.compare(y.args[0],y.args[1])<=0&&w.success(S)},"==/2":function(w,S,y){x.compare(y.args[0],y.args[1])===0&&w.success(S)},"\\==/2":function(w,S,y){x.compare(y.args[0],y.args[1])!==0&&w.success(S)},"@</2":function(w,S,y){x.compare(y.args[0],y.args[1])<0&&w.success(S)},"@>/2":function(w,S,y){x.compare(y.args[0],y.args[1])>0&&w.success(S)},"@>=/2":function(w,S,y){x.compare(y.args[0],y.args[1])>=0&&w.success(S)},"compare/3":function(w,S,y){var F=y.args[0],z=y.args[1],X=y.args[2];if(!x.type.is_variable(F)&&!x.type.is_atom(F))w.throw_error(x.error.type("atom",F,y.indicator));else if(x.type.is_atom(F)&&["<",">","="].indexOf(F.id)===-1)w.throw_error(x.type.domain("order",F,y.indicator));else{var Z=x.compare(z,X);Z=Z===0?"=":Z===-1?"<":">",w.prepend([new be(S.goal.replace(new H("=",[F,new H(Z,[])])),S.substitution,S)])}},"is/2":function(w,S,y){var F=y.args[1].interpret(w);x.type.is_number(F)?w.prepend([new be(S.goal.replace(new H("=",[y.args[0],F],w.level)),S.substitution,S)]):w.throw_error(F)},"between/3":function(w,S,y){var F=y.args[0],z=y.args[1],X=y.args[2];if(x.type.is_variable(F)||x.type.is_variable(z))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_integer(F))w.throw_error(x.error.type("integer",F,y.indicator));else if(!x.type.is_integer(z))w.throw_error(x.error.type("integer",z,y.indicator));else if(!x.type.is_variable(X)&&!x.type.is_integer(X))w.throw_error(x.error.type("integer",X,y.indicator));else if(x.type.is_variable(X)){var Z=[new be(S.goal.replace(new H("=",[X,F])),S.substitution,S)];F.value<z.value&&Z.push(new be(S.goal.replace(new H("between",[new ke(F.value+1,!1),z,X])),S.substitution,S)),w.prepend(Z)}else F.value<=X.value&&z.value>=X.value&&w.success(S)},"succ/2":function(w,S,y){var F=y.args[0],z=y.args[1];x.type.is_variable(F)&&x.type.is_variable(z)?w.throw_error(x.error.instantiation(y.indicator)):!x.type.is_variable(F)&&!x.type.is_integer(F)?w.throw_error(x.error.type("integer",F,y.indicator)):!x.type.is_variable(z)&&!x.type.is_integer(z)?w.throw_error(x.error.type("integer",z,y.indicator)):!x.type.is_variable(F)&&F.value<0?w.throw_error(x.error.domain("not_less_than_zero",F,y.indicator)):!x.type.is_variable(z)&&z.value<0?w.throw_error(x.error.domain("not_less_than_zero",z,y.indicator)):(x.type.is_variable(z)||z.value>0)&&(x.type.is_variable(F)?w.prepend([new be(S.goal.replace(new H("=",[F,new ke(z.value-1,!1)])),S.substitution,S)]):w.prepend([new be(S.goal.replace(new H("=",[z,new ke(F.value+1,!1)])),S.substitution,S)]))},"=:=/2":function(w,S,y){var F=x.arithmetic_compare(w,y.args[0],y.args[1]);x.type.is_term(F)?w.throw_error(F):F===0&&w.success(S)},"=\\=/2":function(w,S,y){var F=x.arithmetic_compare(w,y.args[0],y.args[1]);x.type.is_term(F)?w.throw_error(F):F!==0&&w.success(S)},"</2":function(w,S,y){var F=x.arithmetic_compare(w,y.args[0],y.args[1]);x.type.is_term(F)?w.throw_error(F):F<0&&w.success(S)},"=</2":function(w,S,y){var F=x.arithmetic_compare(w,y.args[0],y.args[1]);x.type.is_term(F)?w.throw_error(F):F<=0&&w.success(S)},">/2":function(w,S,y){var F=x.arithmetic_compare(w,y.args[0],y.args[1]);x.type.is_term(F)?w.throw_error(F):F>0&&w.success(S)},">=/2":function(w,S,y){var F=x.arithmetic_compare(w,y.args[0],y.args[1]);x.type.is_term(F)?w.throw_error(F):F>=0&&w.success(S)},"var/1":function(w,S,y){x.type.is_variable(y.args[0])&&w.success(S)},"atom/1":function(w,S,y){x.type.is_atom(y.args[0])&&w.success(S)},"atomic/1":function(w,S,y){x.type.is_atomic(y.args[0])&&w.success(S)},"compound/1":function(w,S,y){x.type.is_compound(y.args[0])&&w.success(S)},"integer/1":function(w,S,y){x.type.is_integer(y.args[0])&&w.success(S)},"float/1":function(w,S,y){x.type.is_float(y.args[0])&&w.success(S)},"number/1":function(w,S,y){x.type.is_number(y.args[0])&&w.success(S)},"nonvar/1":function(w,S,y){x.type.is_variable(y.args[0])||w.success(S)},"ground/1":function(w,S,y){y.variables().length===0&&w.success(S)},"acyclic_term/1":function(w,S,y){for(var F=S.substitution.apply(S.substitution),z=y.args[0].variables(),X=0;X<z.length;X++)if(S.substitution.links[z[X]]!==void 0&&!S.substitution.links[z[X]].equals(F.links[z[X]]))return;w.success(S)},"callable/1":function(w,S,y){x.type.is_callable(y.args[0])&&w.success(S)},"is_list/1":function(w,S,y){for(var F=y.args[0];x.type.is_term(F)&&F.indicator==="./2";)F=F.args[1];x.type.is_term(F)&&F.indicator==="[]/0"&&w.success(S)},"current_input/1":function(w,S,y){var F=y.args[0];!x.type.is_variable(F)&&!x.type.is_stream(F)&&!x.type.is_atom(F)?w.throw_error(x.error.domain("stream",F,y.indicator)):(x.type.is_atom(F)&&w.get_stream_by_alias(F.id)&&(F=w.get_stream_by_alias(F.id)),w.prepend([new be(S.goal.replace(new H("=",[F,w.get_current_input()])),S.substitution,S)]))},"current_output/1":function(w,S,y){var F=y.args[0];!x.type.is_variable(F)&&!x.type.is_stream(F)&&!x.type.is_atom(F)?w.throw_error(x.error.domain("stream_or_alias",F,y.indicator)):(x.type.is_atom(F)&&w.get_stream_by_alias(F.id)&&(F=w.get_stream_by_alias(F.id)),w.prepend([new be(S.goal.replace(new H("=",[F,w.get_current_output()])),S.substitution,S)]))},"set_input/1":function(w,S,y){var F=y.args[0],z=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);x.type.is_variable(F)?w.throw_error(x.error.instantiation(y.indicator)):!x.type.is_variable(F)&&!x.type.is_stream(F)&&!x.type.is_atom(F)?w.throw_error(x.error.domain("stream_or_alias",F,y.indicator)):x.type.is_stream(z)?z.output===!0?w.throw_error(x.error.permission("input","stream",F,y.indicator)):(w.set_current_input(z),w.success(S)):w.throw_error(x.error.existence("stream",F,y.indicator))},"set_output/1":function(w,S,y){var F=y.args[0],z=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);x.type.is_variable(F)?w.throw_error(x.error.instantiation(y.indicator)):!x.type.is_variable(F)&&!x.type.is_stream(F)&&!x.type.is_atom(F)?w.throw_error(x.error.domain("stream_or_alias",F,y.indicator)):x.type.is_stream(z)?z.input===!0?w.throw_error(x.error.permission("output","stream",F,y.indicator)):(w.set_current_output(z),w.success(S)):w.throw_error(x.error.existence("stream",F,y.indicator))},"open/3":function(w,S,y){var F=y.args[0],z=y.args[1],X=y.args[2];w.prepend([new be(S.goal.replace(new H("open",[F,z,X,new H("[]",[])])),S.substitution,S)])},"open/4":function(w,S,y){var F=y.args[0],z=y.args[1],X=y.args[2],Z=y.args[3];if(x.type.is_variable(F)||x.type.is_variable(z))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(z)&&!x.type.is_atom(z))w.throw_error(x.error.type("atom",z,y.indicator));else if(!x.type.is_list(Z))w.throw_error(x.error.type("list",Z,y.indicator));else if(!x.type.is_variable(X))w.throw_error(x.error.type("variable",X,y.indicator));else if(!x.type.is_atom(F)&&!x.type.is_streamable(F))w.throw_error(x.error.domain("source_sink",F,y.indicator));else if(!x.type.is_io_mode(z))w.throw_error(x.error.domain("io_mode",z,y.indicator));else{for(var ie={},Se=Z,Ne;x.type.is_term(Se)&&Se.indicator==="./2";){if(Ne=Se.args[0],x.type.is_variable(Ne)){w.throw_error(x.error.instantiation(y.indicator));return}else if(!x.type.is_stream_option(Ne)){w.throw_error(x.error.domain("stream_option",Ne,y.indicator));return}ie[Ne.id]=Ne.args[0].id,Se=Se.args[1]}if(Se.indicator!=="[]/0"){x.type.is_variable(Se)?w.throw_error(x.error.instantiation(y.indicator)):w.throw_error(x.error.type("list",Z,y.indicator));return}else{var ot=ie.alias;if(ot&&w.get_stream_by_alias(ot)){w.throw_error(x.error.permission("open","source_sink",new H("alias",[new H(ot,[])]),y.indicator));return}ie.type||(ie.type="text");var dt;if(x.type.is_atom(F)?dt=w.file_system_open(F.id,ie.type,z.id):dt=F.stream(ie.type,z.id),dt===!1){w.throw_error(x.error.permission("open","source_sink",F,y.indicator));return}else if(dt===null){w.throw_error(x.error.existence("source_sink",F,y.indicator));return}var jt=new Re(dt,z.id,ie.alias,ie.type,ie.reposition==="true",ie.eof_action);ot?w.session.streams[ot]=jt:w.session.streams[jt.id]=jt,w.prepend([new be(S.goal.replace(new H("=",[X,jt])),S.substitution,S)])}}},"close/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H("close",[F,new H("[]",[])])),S.substitution,S)])},"close/2":function(w,S,y){var F=y.args[0],z=y.args[1],X=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);if(x.type.is_variable(F)||x.type.is_variable(z))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_list(z))w.throw_error(x.error.type("list",z,y.indicator));else if(!x.type.is_stream(F)&&!x.type.is_atom(F))w.throw_error(x.error.domain("stream_or_alias",F,y.indicator));else if(!x.type.is_stream(X)||X.stream===null)w.throw_error(x.error.existence("stream",F,y.indicator));else{for(var Z={},ie=z,Se;x.type.is_term(ie)&&ie.indicator==="./2";){if(Se=ie.args[0],x.type.is_variable(Se)){w.throw_error(x.error.instantiation(y.indicator));return}else if(!x.type.is_close_option(Se)){w.throw_error(x.error.domain("close_option",Se,y.indicator));return}Z[Se.id]=Se.args[0].id==="true",ie=ie.args[1]}if(ie.indicator!=="[]/0"){x.type.is_variable(ie)?w.throw_error(x.error.instantiation(y.indicator)):w.throw_error(x.error.type("list",z,y.indicator));return}else{if(X===w.session.standard_input||X===w.session.standard_output){w.success(S);return}else X===w.session.current_input?w.session.current_input=w.session.standard_input:X===w.session.current_output&&(w.session.current_output=w.session.current_output);X.alias!==null?delete w.session.streams[X.alias]:delete w.session.streams[X.id],X.output&&X.stream.flush();var Ne=X.stream.close();X.stream=null,(Z.force===!0||Ne===!0)&&w.success(S)}}},"flush_output/0":function(w,S,y){w.prepend([new be(S.goal.replace(new H(",",[new H("current_output",[new Ie("S")]),new H("flush_output",[new Ie("S")])])),S.substitution,S)])},"flush_output/1":function(w,S,y){var F=y.args[0],z=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);x.type.is_variable(F)?w.throw_error(x.error.instantiation(y.indicator)):!x.type.is_stream(F)&&!x.type.is_atom(F)?w.throw_error(x.error.domain("stream_or_alias",F,y.indicator)):!x.type.is_stream(z)||z.stream===null?w.throw_error(x.error.existence("stream",F,y.indicator)):F.input===!0?w.throw_error(x.error.permission("output","stream",output,y.indicator)):(z.stream.flush(),w.success(S))},"stream_property/2":function(w,S,y){var F=y.args[0],z=y.args[1],X=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);if(!x.type.is_variable(F)&&!x.type.is_stream(F)&&!x.type.is_atom(F))w.throw_error(x.error.domain("stream_or_alias",F,y.indicator));else if(!x.type.is_variable(F)&&(!x.type.is_stream(X)||X.stream===null))w.throw_error(x.error.existence("stream",F,y.indicator));else if(!x.type.is_variable(z)&&!x.type.is_stream_property(z))w.throw_error(x.error.domain("stream_property",z,y.indicator));else{var Z=[],ie=[];if(!x.type.is_variable(F))Z.push(X);else for(var Se in w.session.streams)Z.push(w.session.streams[Se]);for(var Ne=0;Ne<Z.length;Ne++){var ot=[];Z[Ne].filename&&ot.push(new H("file_name",[new H(Z[Ne].file_name,[])])),ot.push(new H("mode",[new H(Z[Ne].mode,[])])),ot.push(new H(Z[Ne].input?"input":"output",[])),Z[Ne].alias&&ot.push(new H("alias",[new H(Z[Ne].alias,[])])),ot.push(new H("position",[typeof Z[Ne].position=="number"?new ke(Z[Ne].position,!1):new H(Z[Ne].position,[])])),ot.push(new H("end_of_stream",[new H(Z[Ne].position==="end_of_stream"?"at":Z[Ne].position==="past_end_of_stream"?"past":"not",[])])),ot.push(new H("eof_action",[new H(Z[Ne].eof_action,[])])),ot.push(new H("reposition",[new H(Z[Ne].reposition?"true":"false",[])])),ot.push(new H("type",[new H(Z[Ne].type,[])]));for(var dt=0;dt<ot.length;dt++)ie.push(new be(S.goal.replace(new H(",",[new H("=",[x.type.is_variable(F)?F:X,Z[Ne]]),new H("=",[z,ot[dt]])])),S.substitution,S))}w.prepend(ie)}},"at_end_of_stream/0":function(w,S,y){w.prepend([new be(S.goal.replace(new H(",",[new H("current_input",[new Ie("S")]),new H(",",[new H("stream_property",[new Ie("S"),new H("end_of_stream",[new Ie("E")])]),new H(",",[new H("!",[]),new H(";",[new H("=",[new Ie("E"),new H("at",[])]),new H("=",[new Ie("E"),new H("past",[])])])])])])),S.substitution,S)])},"at_end_of_stream/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("stream_property",[F,new H("end_of_stream",[new Ie("E")])]),new H(",",[new H("!",[]),new H(";",[new H("=",[new Ie("E"),new H("at",[])]),new H("=",[new Ie("E"),new H("past",[])])])])])),S.substitution,S)])},"set_stream_position/2":function(w,S,y){var F=y.args[0],z=y.args[1],X=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);x.type.is_variable(F)||x.type.is_variable(z)?w.throw_error(x.error.instantiation(y.indicator)):!x.type.is_stream(F)&&!x.type.is_atom(F)?w.throw_error(x.error.domain("stream_or_alias",F,y.indicator)):!x.type.is_stream(X)||X.stream===null?w.throw_error(x.error.existence("stream",F,y.indicator)):x.type.is_stream_position(z)?X.reposition===!1?w.throw_error(x.error.permission("reposition","stream",F,y.indicator)):(x.type.is_integer(z)?X.position=z.value:X.position=z.id,w.success(S)):w.throw_error(x.error.domain("stream_position",z,y.indicator))},"get_char/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("current_input",[new Ie("S")]),new H("get_char",[new Ie("S"),F])])),S.substitution,S)])},"get_char/2":function(w,S,y){var F=y.args[0],z=y.args[1],X=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);if(x.type.is_variable(F))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(z)&&!x.type.is_character(z))w.throw_error(x.error.type("in_character",z,y.indicator));else if(!x.type.is_stream(F)&&!x.type.is_atom(F))w.throw_error(x.error.domain("stream_or_alias",F,y.indicator));else if(!x.type.is_stream(X)||X.stream===null)w.throw_error(x.error.existence("stream",F,y.indicator));else if(X.output)w.throw_error(x.error.permission("input","stream",F,y.indicator));else if(X.type==="binary")w.throw_error(x.error.permission("input","binary_stream",F,y.indicator));else if(X.position==="past_end_of_stream"&&X.eof_action==="error")w.throw_error(x.error.permission("input","past_end_of_stream",F,y.indicator));else{var Z;if(X.position==="end_of_stream")Z="end_of_file",X.position="past_end_of_stream";else{if(Z=X.stream.get(1,X.position),Z===null){w.throw_error(x.error.representation("character",y.indicator));return}X.position++}w.prepend([new be(S.goal.replace(new H("=",[new H(Z,[]),z])),S.substitution,S)])}},"get_code/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("current_input",[new Ie("S")]),new H("get_code",[new Ie("S"),F])])),S.substitution,S)])},"get_code/2":function(w,S,y){var F=y.args[0],z=y.args[1],X=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);if(x.type.is_variable(F))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(z)&&!x.type.is_integer(z))w.throw_error(x.error.type("integer",char,y.indicator));else if(!x.type.is_variable(F)&&!x.type.is_stream(F)&&!x.type.is_atom(F))w.throw_error(x.error.domain("stream_or_alias",F,y.indicator));else if(!x.type.is_stream(X)||X.stream===null)w.throw_error(x.error.existence("stream",F,y.indicator));else if(X.output)w.throw_error(x.error.permission("input","stream",F,y.indicator));else if(X.type==="binary")w.throw_error(x.error.permission("input","binary_stream",F,y.indicator));else if(X.position==="past_end_of_stream"&&X.eof_action==="error")w.throw_error(x.error.permission("input","past_end_of_stream",F,y.indicator));else{var Z;if(X.position==="end_of_stream")Z=-1,X.position="past_end_of_stream";else{if(Z=X.stream.get(1,X.position),Z===null){w.throw_error(x.error.representation("character",y.indicator));return}Z=n(Z,0),X.position++}w.prepend([new be(S.goal.replace(new H("=",[new ke(Z,!1),z])),S.substitution,S)])}},"peek_char/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("current_input",[new Ie("S")]),new H("peek_char",[new Ie("S"),F])])),S.substitution,S)])},"peek_char/2":function(w,S,y){var F=y.args[0],z=y.args[1],X=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);if(x.type.is_variable(F))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(z)&&!x.type.is_character(z))w.throw_error(x.error.type("in_character",z,y.indicator));else if(!x.type.is_stream(F)&&!x.type.is_atom(F))w.throw_error(x.error.domain("stream_or_alias",F,y.indicator));else if(!x.type.is_stream(X)||X.stream===null)w.throw_error(x.error.existence("stream",F,y.indicator));else if(X.output)w.throw_error(x.error.permission("input","stream",F,y.indicator));else if(X.type==="binary")w.throw_error(x.error.permission("input","binary_stream",F,y.indicator));else if(X.position==="past_end_of_stream"&&X.eof_action==="error")w.throw_error(x.error.permission("input","past_end_of_stream",F,y.indicator));else{var Z;if(X.position==="end_of_stream")Z="end_of_file",X.position="past_end_of_stream";else if(Z=X.stream.get(1,X.position),Z===null){w.throw_error(x.error.representation("character",y.indicator));return}w.prepend([new be(S.goal.replace(new H("=",[new H(Z,[]),z])),S.substitution,S)])}},"peek_code/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("current_input",[new Ie("S")]),new H("peek_code",[new Ie("S"),F])])),S.substitution,S)])},"peek_code/2":function(w,S,y){var F=y.args[0],z=y.args[1],X=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);if(x.type.is_variable(F))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(z)&&!x.type.is_integer(z))w.throw_error(x.error.type("integer",char,y.indicator));else if(!x.type.is_variable(F)&&!x.type.is_stream(F)&&!x.type.is_atom(F))w.throw_error(x.error.domain("stream_or_alias",F,y.indicator));else if(!x.type.is_stream(X)||X.stream===null)w.throw_error(x.error.existence("stream",F,y.indicator));else if(X.output)w.throw_error(x.error.permission("input","stream",F,y.indicator));else if(X.type==="binary")w.throw_error(x.error.permission("input","binary_stream",F,y.indicator));else if(X.position==="past_end_of_stream"&&X.eof_action==="error")w.throw_error(x.error.permission("input","past_end_of_stream",F,y.indicator));else{var Z;if(X.position==="end_of_stream")Z=-1,X.position="past_end_of_stream";else{if(Z=X.stream.get(1,X.position),Z===null){w.throw_error(x.error.representation("character",y.indicator));return}Z=n(Z,0)}w.prepend([new be(S.goal.replace(new H("=",[new ke(Z,!1),z])),S.substitution,S)])}},"put_char/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("current_output",[new Ie("S")]),new H("put_char",[new Ie("S"),F])])),S.substitution,S)])},"put_char/2":function(w,S,y){var F=y.args[0],z=y.args[1],X=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);x.type.is_variable(F)||x.type.is_variable(z)?w.throw_error(x.error.instantiation(y.indicator)):x.type.is_character(z)?!x.type.is_variable(F)&&!x.type.is_stream(F)&&!x.type.is_atom(F)?w.throw_error(x.error.domain("stream_or_alias",F,y.indicator)):!x.type.is_stream(X)||X.stream===null?w.throw_error(x.error.existence("stream",F,y.indicator)):X.input?w.throw_error(x.error.permission("output","stream",F,y.indicator)):X.type==="binary"?w.throw_error(x.error.permission("output","binary_stream",F,y.indicator)):X.stream.put(z.id,X.position)&&(typeof X.position=="number"&&X.position++,w.success(S)):w.throw_error(x.error.type("character",z,y.indicator))},"put_code/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("current_output",[new Ie("S")]),new H("put_code",[new Ie("S"),F])])),S.substitution,S)])},"put_code/2":function(w,S,y){var F=y.args[0],z=y.args[1],X=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);x.type.is_variable(F)||x.type.is_variable(z)?w.throw_error(x.error.instantiation(y.indicator)):x.type.is_integer(z)?x.type.is_character_code(z)?!x.type.is_variable(F)&&!x.type.is_stream(F)&&!x.type.is_atom(F)?w.throw_error(x.error.domain("stream_or_alias",F,y.indicator)):!x.type.is_stream(X)||X.stream===null?w.throw_error(x.error.existence("stream",F,y.indicator)):X.input?w.throw_error(x.error.permission("output","stream",F,y.indicator)):X.type==="binary"?w.throw_error(x.error.permission("output","binary_stream",F,y.indicator)):X.stream.put_char(u(z.value),X.position)&&(typeof X.position=="number"&&X.position++,w.success(S)):w.throw_error(x.error.representation("character_code",y.indicator)):w.throw_error(x.error.type("integer",z,y.indicator))},"nl/0":function(w,S,y){w.prepend([new be(S.goal.replace(new H(",",[new H("current_output",[new Ie("S")]),new H("put_char",[new Ie("S"),new H(` +`,[])])])),S.substitution,S)])},"nl/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H("put_char",[F,new H(` +`,[])])),S.substitution,S)])},"get_byte/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("current_input",[new Ie("S")]),new H("get_byte",[new Ie("S"),F])])),S.substitution,S)])},"get_byte/2":function(w,S,y){var F=y.args[0],z=y.args[1],X=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);if(x.type.is_variable(F))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(z)&&!x.type.is_byte(z))w.throw_error(x.error.type("in_byte",char,y.indicator));else if(!x.type.is_stream(F)&&!x.type.is_atom(F))w.throw_error(x.error.domain("stream_or_alias",F,y.indicator));else if(!x.type.is_stream(X)||X.stream===null)w.throw_error(x.error.existence("stream",F,y.indicator));else if(X.output)w.throw_error(x.error.permission("input","stream",F,y.indicator));else if(X.type==="text")w.throw_error(x.error.permission("input","text_stream",F,y.indicator));else if(X.position==="past_end_of_stream"&&X.eof_action==="error")w.throw_error(x.error.permission("input","past_end_of_stream",F,y.indicator));else{var Z;if(X.position==="end_of_stream")Z="end_of_file",X.position="past_end_of_stream";else{if(Z=X.stream.get_byte(X.position),Z===null){w.throw_error(x.error.representation("byte",y.indicator));return}X.position++}w.prepend([new be(S.goal.replace(new H("=",[new ke(Z,!1),z])),S.substitution,S)])}},"peek_byte/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("current_input",[new Ie("S")]),new H("peek_byte",[new Ie("S"),F])])),S.substitution,S)])},"peek_byte/2":function(w,S,y){var F=y.args[0],z=y.args[1],X=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);if(x.type.is_variable(F))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_variable(z)&&!x.type.is_byte(z))w.throw_error(x.error.type("in_byte",char,y.indicator));else if(!x.type.is_stream(F)&&!x.type.is_atom(F))w.throw_error(x.error.domain("stream_or_alias",F,y.indicator));else if(!x.type.is_stream(X)||X.stream===null)w.throw_error(x.error.existence("stream",F,y.indicator));else if(X.output)w.throw_error(x.error.permission("input","stream",F,y.indicator));else if(X.type==="text")w.throw_error(x.error.permission("input","text_stream",F,y.indicator));else if(X.position==="past_end_of_stream"&&X.eof_action==="error")w.throw_error(x.error.permission("input","past_end_of_stream",F,y.indicator));else{var Z;if(X.position==="end_of_stream")Z="end_of_file",X.position="past_end_of_stream";else if(Z=X.stream.get_byte(X.position),Z===null){w.throw_error(x.error.representation("byte",y.indicator));return}w.prepend([new be(S.goal.replace(new H("=",[new ke(Z,!1),z])),S.substitution,S)])}},"put_byte/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("current_output",[new Ie("S")]),new H("put_byte",[new Ie("S"),F])])),S.substitution,S)])},"put_byte/2":function(w,S,y){var F=y.args[0],z=y.args[1],X=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);x.type.is_variable(F)||x.type.is_variable(z)?w.throw_error(x.error.instantiation(y.indicator)):x.type.is_byte(z)?!x.type.is_variable(F)&&!x.type.is_stream(F)&&!x.type.is_atom(F)?w.throw_error(x.error.domain("stream_or_alias",F,y.indicator)):!x.type.is_stream(X)||X.stream===null?w.throw_error(x.error.existence("stream",F,y.indicator)):X.input?w.throw_error(x.error.permission("output","stream",F,y.indicator)):X.type==="text"?w.throw_error(x.error.permission("output","text_stream",F,y.indicator)):X.stream.put_byte(z.value,X.position)&&(typeof X.position=="number"&&X.position++,w.success(S)):w.throw_error(x.error.type("byte",z,y.indicator))},"read/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("current_input",[new Ie("S")]),new H("read_term",[new Ie("S"),F,new H("[]",[])])])),S.substitution,S)])},"read/2":function(w,S,y){var F=y.args[0],z=y.args[1];w.prepend([new be(S.goal.replace(new H("read_term",[F,z,new H("[]",[])])),S.substitution,S)])},"read_term/2":function(w,S,y){var F=y.args[0],z=y.args[1];w.prepend([new be(S.goal.replace(new H(",",[new H("current_input",[new Ie("S")]),new H("read_term",[new Ie("S"),F,z])])),S.substitution,S)])},"read_term/3":function(w,S,y){var F=y.args[0],z=y.args[1],X=y.args[2],Z=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);if(x.type.is_variable(F)||x.type.is_variable(X))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_list(X))w.throw_error(x.error.type("list",X,y.indicator));else if(!x.type.is_stream(F)&&!x.type.is_atom(F))w.throw_error(x.error.domain("stream_or_alias",F,y.indicator));else if(!x.type.is_stream(Z)||Z.stream===null)w.throw_error(x.error.existence("stream",F,y.indicator));else if(Z.output)w.throw_error(x.error.permission("input","stream",F,y.indicator));else if(Z.type==="binary")w.throw_error(x.error.permission("input","binary_stream",F,y.indicator));else if(Z.position==="past_end_of_stream"&&Z.eof_action==="error")w.throw_error(x.error.permission("input","past_end_of_stream",F,y.indicator));else{for(var ie={},Se=X,Ne;x.type.is_term(Se)&&Se.indicator==="./2";){if(Ne=Se.args[0],x.type.is_variable(Ne)){w.throw_error(x.error.instantiation(y.indicator));return}else if(!x.type.is_read_option(Ne)){w.throw_error(x.error.domain("read_option",Ne,y.indicator));return}ie[Ne.id]=Ne.args[0],Se=Se.args[1]}if(Se.indicator!=="[]/0"){x.type.is_variable(Se)?w.throw_error(x.error.instantiation(y.indicator)):w.throw_error(x.error.type("list",X,y.indicator));return}else{for(var ot,dt,jt,$t="",xt=[],an=null;an===null||an.name!=="atom"||an.value!=="."||jt.type===A&&x.flatten_error(new H("throw",[jt.value])).found==="token_not_found";){if(ot=Z.stream.get(1,Z.position),ot===null){w.throw_error(x.error.representation("character",y.indicator));return}if(ot==="end_of_file"||ot==="past_end_of_file"){jt?w.throw_error(x.error.syntax(xt[jt.len-1],". or expression expected",!1)):w.throw_error(x.error.syntax(null,"token not found",!0));return}Z.position++,$t+=ot,dt=new U(w),dt.new_text($t),xt=dt.get_tokens(),an=xt!==null&&xt.length>0?xt[xt.length-1]:null,xt!==null&&(jt=J(w,xt,0,w.__get_max_priority(),!1))}if(jt.type===p&&jt.len===xt.length-1&&an.value==="."){jt=jt.value.rename(w);var Qr=new H("=",[z,jt]);if(ie.variables){var mr=g(o(De(jt.variables()),function(xr){return new Ie(xr)}));Qr=new H(",",[Qr,new H("=",[ie.variables,mr])])}if(ie.variable_names){var mr=g(o(De(jt.variables()),function(Wr){var Vn;for(Vn in w.session.renamed_variables)if(w.session.renamed_variables.hasOwnProperty(Vn)&&w.session.renamed_variables[Vn]===Wr)break;return new H("=",[new H(Vn,[]),new Ie(Wr)])}));Qr=new H(",",[Qr,new H("=",[ie.variable_names,mr])])}if(ie.singletons){var mr=g(o(new _e(jt,null).singleton_variables(),function(Wr){var Vn;for(Vn in w.session.renamed_variables)if(w.session.renamed_variables.hasOwnProperty(Vn)&&w.session.renamed_variables[Vn]===Wr)break;return new H("=",[new H(Vn,[]),new Ie(Wr)])}));Qr=new H(",",[Qr,new H("=",[ie.singletons,mr])])}w.prepend([new be(S.goal.replace(Qr),S.substitution,S)])}else jt.type===p?w.throw_error(x.error.syntax(xt[jt.len],"unexpected token",!1)):w.throw_error(jt.value)}}},"write/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("current_output",[new Ie("S")]),new H("write",[new Ie("S"),F])])),S.substitution,S)])},"write/2":function(w,S,y){var F=y.args[0],z=y.args[1];w.prepend([new be(S.goal.replace(new H("write_term",[F,z,new H(".",[new H("quoted",[new H("false",[])]),new H(".",[new H("ignore_ops",[new H("false")]),new H(".",[new H("numbervars",[new H("true")]),new H("[]",[])])])])])),S.substitution,S)])},"writeq/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("current_output",[new Ie("S")]),new H("writeq",[new Ie("S"),F])])),S.substitution,S)])},"writeq/2":function(w,S,y){var F=y.args[0],z=y.args[1];w.prepend([new be(S.goal.replace(new H("write_term",[F,z,new H(".",[new H("quoted",[new H("true",[])]),new H(".",[new H("ignore_ops",[new H("false")]),new H(".",[new H("numbervars",[new H("true")]),new H("[]",[])])])])])),S.substitution,S)])},"write_canonical/1":function(w,S,y){var F=y.args[0];w.prepend([new be(S.goal.replace(new H(",",[new H("current_output",[new Ie("S")]),new H("write_canonical",[new Ie("S"),F])])),S.substitution,S)])},"write_canonical/2":function(w,S,y){var F=y.args[0],z=y.args[1];w.prepend([new be(S.goal.replace(new H("write_term",[F,z,new H(".",[new H("quoted",[new H("true",[])]),new H(".",[new H("ignore_ops",[new H("true")]),new H(".",[new H("numbervars",[new H("false")]),new H("[]",[])])])])])),S.substitution,S)])},"write_term/2":function(w,S,y){var F=y.args[0],z=y.args[1];w.prepend([new be(S.goal.replace(new H(",",[new H("current_output",[new Ie("S")]),new H("write_term",[new Ie("S"),F,z])])),S.substitution,S)])},"write_term/3":function(w,S,y){var F=y.args[0],z=y.args[1],X=y.args[2],Z=x.type.is_stream(F)?F:w.get_stream_by_alias(F.id);if(x.type.is_variable(F)||x.type.is_variable(X))w.throw_error(x.error.instantiation(y.indicator));else if(!x.type.is_list(X))w.throw_error(x.error.type("list",X,y.indicator));else if(!x.type.is_stream(F)&&!x.type.is_atom(F))w.throw_error(x.error.domain("stream_or_alias",F,y.indicator));else if(!x.type.is_stream(Z)||Z.stream===null)w.throw_error(x.error.existence("stream",F,y.indicator));else if(Z.input)w.throw_error(x.error.permission("output","stream",F,y.indicator));else if(Z.type==="binary")w.throw_error(x.error.permission("output","binary_stream",F,y.indicator));else if(Z.position==="past_end_of_stream"&&Z.eof_action==="error")w.throw_error(x.error.permission("output","past_end_of_stream",F,y.indicator));else{for(var ie={},Se=X,Ne;x.type.is_term(Se)&&Se.indicator==="./2";){if(Ne=Se.args[0],x.type.is_variable(Ne)){w.throw_error(x.error.instantiation(y.indicator));return}else if(!x.type.is_write_option(Ne)){w.throw_error(x.error.domain("write_option",Ne,y.indicator));return}ie[Ne.id]=Ne.args[0].id==="true",Se=Se.args[1]}if(Se.indicator!=="[]/0"){x.type.is_variable(Se)?w.throw_error(x.error.instantiation(y.indicator)):w.throw_error(x.error.type("list",X,y.indicator));return}else{ie.session=w.session;var ot=z.toString(ie);Z.stream.put(ot,Z.position),typeof Z.position=="number"&&(Z.position+=ot.length),w.success(S)}}},"halt/0":function(w,S,y){w.points=[]},"halt/1":function(w,S,y){var F=y.args[0];x.type.is_variable(F)?w.throw_error(x.error.instantiation(y.indicator)):x.type.is_integer(F)?w.points=[]:w.throw_error(x.error.type("integer",F,y.indicator))},"current_prolog_flag/2":function(w,S,y){var F=y.args[0],z=y.args[1];if(!x.type.is_variable(F)&&!x.type.is_atom(F))w.throw_error(x.error.type("atom",F,y.indicator));else if(!x.type.is_variable(F)&&!x.type.is_flag(F))w.throw_error(x.error.domain("prolog_flag",F,y.indicator));else{var X=[];for(var Z in x.flag)if(!!x.flag.hasOwnProperty(Z)){var ie=new H(",",[new H("=",[new H(Z),F]),new H("=",[w.get_flag(Z),z])]);X.push(new be(S.goal.replace(ie),S.substitution,S))}w.prepend(X)}},"set_prolog_flag/2":function(w,S,y){var F=y.args[0],z=y.args[1];x.type.is_variable(F)||x.type.is_variable(z)?w.throw_error(x.error.instantiation(y.indicator)):x.type.is_atom(F)?x.type.is_flag(F)?x.type.is_value_flag(F,z)?x.type.is_modifiable_flag(F)?(w.session.flag[F.id]=z,w.success(S)):w.throw_error(x.error.permission("modify","flag",F)):w.throw_error(x.error.domain("flag_value",new H("+",[F,z]),y.indicator)):w.throw_error(x.error.domain("prolog_flag",F,y.indicator)):w.throw_error(x.error.type("atom",F,y.indicator))}},flag:{bounded:{allowed:[new H("true"),new H("false")],value:new H("true"),changeable:!1},max_integer:{allowed:[new ke(Number.MAX_SAFE_INTEGER)],value:new ke(Number.MAX_SAFE_INTEGER),changeable:!1},min_integer:{allowed:[new ke(Number.MIN_SAFE_INTEGER)],value:new ke(Number.MIN_SAFE_INTEGER),changeable:!1},integer_rounding_function:{allowed:[new H("down"),new H("toward_zero")],value:new H("toward_zero"),changeable:!1},char_conversion:{allowed:[new H("on"),new H("off")],value:new H("on"),changeable:!0},debug:{allowed:[new H("on"),new H("off")],value:new H("off"),changeable:!0},max_arity:{allowed:[new H("unbounded")],value:new H("unbounded"),changeable:!1},unknown:{allowed:[new H("error"),new H("fail"),new H("warning")],value:new H("error"),changeable:!0},double_quotes:{allowed:[new H("chars"),new H("codes"),new H("atom")],value:new H("codes"),changeable:!0},occurs_check:{allowed:[new H("false"),new H("true")],value:new H("false"),changeable:!0},dialect:{allowed:[new H("tau")],value:new H("tau"),changeable:!1},version_data:{allowed:[new H("tau",[new ke(t.major,!1),new ke(t.minor,!1),new ke(t.patch,!1),new H(t.status)])],value:new H("tau",[new ke(t.major,!1),new ke(t.minor,!1),new ke(t.patch,!1),new H(t.status)]),changeable:!1},nodejs:{allowed:[new H("yes"),new H("no")],value:new H(typeof hl<"u"&&hl.exports?"yes":"no"),changeable:!1}},unify:function(w,S,y){y=y===void 0?!1:y;for(var F=[{left:w,right:S}],z={};F.length!==0;){var X=F.pop();if(w=X.left,S=X.right,x.type.is_term(w)&&x.type.is_term(S)){if(w.indicator!==S.indicator)return null;for(var Z=0;Z<w.args.length;Z++)F.push({left:w.args[Z],right:S.args[Z]})}else if(x.type.is_number(w)&&x.type.is_number(S)){if(w.value!==S.value||w.is_float!==S.is_float)return null}else if(x.type.is_variable(w)){if(x.type.is_variable(S)&&w.id===S.id)continue;if(y===!0&&S.variables().indexOf(w.id)!==-1)return null;if(w.id!=="_"){var ie=new Qe;ie.add(w.id,S);for(var Z=0;Z<F.length;Z++)F[Z].left=F[Z].left.apply(ie),F[Z].right=F[Z].right.apply(ie);for(var Z in z)z[Z]=z[Z].apply(ie);z[w.id]=S}}else if(x.type.is_variable(S))F.push({left:S,right:w});else if(w.unify!==void 0){if(!w.unify(S))return null}else return null}return new Qe(z)},compare:function(w,S){var y=x.type.compare(w,S);return y!==0?y:w.compare(S)},arithmetic_compare:function(w,S,y){var F=S.interpret(w);if(x.type.is_number(F)){var z=y.interpret(w);return x.type.is_number(z)?F.value<z.value?-1:F.value>z.value?1:0:z}else return F},operate:function(w,S){if(x.type.is_operator(S)){for(var y=x.type.is_operator(S),F=[],z,X=!1,Z=0;Z<S.args.length;Z++){if(z=S.args[Z].interpret(w),x.type.is_number(z)){if(y.type_args!==null&&z.is_float!==y.type_args)return x.error.type(y.type_args?"float":"integer",z,w.__call_indicator);F.push(z.value)}else return z;X=X||z.is_float}return F.push(w),z=x.arithmetic.evaluation[S.indicator].fn.apply(this,F),X=y.type_result===null?X:y.type_result,x.type.is_term(z)?z:z===Number.POSITIVE_INFINITY||z===Number.NEGATIVE_INFINITY?x.error.evaluation("overflow",w.__call_indicator):X===!1&&w.get_flag("bounded").id==="true"&&(z>w.get_flag("max_integer").value||z<w.get_flag("min_integer").value)?x.error.evaluation("int_overflow",w.__call_indicator):new ke(z,X)}else return x.error.type("evaluable",S.indicator,w.__call_indicator)},error:{existence:function(w,S,y){return typeof S=="string"&&(S=ee(S)),new H("error",[new H("existence_error",[new H(w),S]),ee(y)])},type:function(w,S,y){return new H("error",[new H("type_error",[new H(w),S]),ee(y)])},instantiation:function(w){return new H("error",[new H("instantiation_error"),ee(w)])},domain:function(w,S,y){return new H("error",[new H("domain_error",[new H(w),S]),ee(y)])},representation:function(w,S){return new H("error",[new H("representation_error",[new H(w)]),ee(S)])},permission:function(w,S,y,F){return new H("error",[new H("permission_error",[new H(w),new H(S),y]),ee(F)])},evaluation:function(w,S){return new H("error",[new H("evaluation_error",[new H(w)]),ee(S)])},syntax:function(w,S,y){w=w||{value:"",line:0,column:0,matches:[""],start:0};var F=y&&w.matches.length>0?w.start+w.matches[0].length:w.start,z=y?new H("token_not_found"):new H("found",[new H(w.value.toString())]),X=new H(".",[new H("line",[new ke(w.line+1)]),new H(".",[new H("column",[new ke(F+1)]),new H(".",[z,new H("[]",[])])])]);return new H("error",[new H("syntax_error",[new H(S)]),X])},syntax_by_predicate:function(w,S){return new H("error",[new H("syntax_error",[new H(w)]),ee(S)])}},warning:{singleton:function(w,S,y){for(var F=new H("[]"),z=w.length-1;z>=0;z--)F=new H(".",[new Ie(w[z]),F]);return new H("warning",[new H("singleton_variables",[F,ee(S)]),new H(".",[new H("line",[new ke(y,!1)]),new H("[]")])])},failed_goal:function(w,S){return new H("warning",[new H("failed_goal",[w]),new H(".",[new H("line",[new ke(S,!1)]),new H("[]")])])}},format_variable:function(w){return"_"+w},format_answer:function(w,S,F){S instanceof Te&&(S=S.thread);var F=F||{};if(F.session=S?S.session:void 0,x.type.is_error(w))return"uncaught exception: "+w.args[0].toString();if(w===!1)return"false.";if(w===null)return"limit exceeded ;";var z=0,X="";if(x.type.is_substitution(w)){var Z=w.domain(!0);w=w.filter(function(Ne,ot){return!x.type.is_variable(ot)||Z.indexOf(ot.id)!==-1&&Ne!==ot.id})}for(var ie in w.links)!w.links.hasOwnProperty(ie)||(z++,X!==""&&(X+=", "),X+=ie.toString(F)+" = "+w.links[ie].toString(F));var Se=typeof S>"u"||S.points.length>0?" ;":".";return z===0?"true"+Se:X+Se},flatten_error:function(w){if(!x.type.is_error(w))return null;w=w.args[0];var S={};return S.type=w.args[0].id,S.thrown=S.type==="syntax_error"?null:w.args[1].id,S.expected=null,S.found=null,S.representation=null,S.existence=null,S.existence_type=null,S.line=null,S.column=null,S.permission_operation=null,S.permission_type=null,S.evaluation_type=null,S.type==="type_error"||S.type==="domain_error"?(S.expected=w.args[0].args[0].id,S.found=w.args[0].args[1].toString()):S.type==="syntax_error"?w.args[1].indicator==="./2"?(S.expected=w.args[0].args[0].id,S.found=w.args[1].args[1].args[1].args[0],S.found=S.found.id==="token_not_found"?S.found.id:S.found.args[0].id,S.line=w.args[1].args[0].args[0].value,S.column=w.args[1].args[1].args[0].args[0].value):S.thrown=w.args[1].id:S.type==="permission_error"?(S.found=w.args[0].args[2].toString(),S.permission_operation=w.args[0].args[0].id,S.permission_type=w.args[0].args[1].id):S.type==="evaluation_error"?S.evaluation_type=w.args[0].args[0].id:S.type==="representation_error"?S.representation=w.args[0].args[0].id:S.type==="existence_error"&&(S.existence=w.args[0].args[1].toString(),S.existence_type=w.args[0].args[0].id),S},create:function(w){return new x.type.Session(w)}};typeof hl<"u"?hl.exports=x:window.pl=x})()});function ame(t,e,r){t.prepend(r.map(o=>new Ra.default.type.State(e.goal.replace(o),e.substitution,e)))}function CH(t){let e=cme.get(t.session);if(e==null)throw new Error("Assertion failed: A project should have been registered for the active session");return e}function ume(t,e){cme.set(t,e),t.consult(`:- use_module(library(${tdt.id})).`)}var wH,Ra,lme,c0,$gt,edt,cme,tdt,Ame=Et(()=>{Ye();wH=$e(g2()),Ra=$e(EH()),lme=$e(Be("vm")),{is_atom:c0,is_variable:$gt,is_instantiated_list:edt}=Ra.default.type;cme=new WeakMap;tdt=new Ra.default.type.Module("constraints",{["project_workspaces_by_descriptor/3"]:(t,e,r)=>{let[o,a,n]=r.args;if(!c0(o)||!c0(a)){t.throw_error(Ra.default.error.instantiation(r.indicator));return}let u=W.parseIdent(o.id),A=W.makeDescriptor(u,a.id),h=CH(t).tryWorkspaceByDescriptor(A);$gt(n)&&h!==null&&ame(t,e,[new Ra.default.type.Term("=",[n,new Ra.default.type.Term(String(h.relativeCwd))])]),c0(n)&&h!==null&&h.relativeCwd===n.id&&t.success(e)},["workspace_field/3"]:(t,e,r)=>{let[o,a,n]=r.args;if(!c0(o)||!c0(a)){t.throw_error(Ra.default.error.instantiation(r.indicator));return}let A=CH(t).tryWorkspaceByCwd(o.id);if(A==null)return;let p=(0,wH.default)(A.manifest.raw,a.id);typeof p>"u"||ame(t,e,[new Ra.default.type.Term("=",[n,new Ra.default.type.Term(typeof p=="object"?JSON.stringify(p):p)])])},["workspace_field_test/3"]:(t,e,r)=>{let[o,a,n]=r.args;t.prepend([new Ra.default.type.State(e.goal.replace(new Ra.default.type.Term("workspace_field_test",[o,a,n,new Ra.default.type.Term("[]",[])])),e.substitution,e)])},["workspace_field_test/4"]:(t,e,r)=>{let[o,a,n,u]=r.args;if(!c0(o)||!c0(a)||!c0(n)||!edt(u)){t.throw_error(Ra.default.error.instantiation(r.indicator));return}let p=CH(t).tryWorkspaceByCwd(o.id);if(p==null)return;let h=(0,wH.default)(p.manifest.raw,a.id);if(typeof h>"u")return;let E={$$:h};for(let[v,b]of u.toJavaScript().entries())E[`$${v}`]=b;lme.default.runInNewContext(n.id,E)&&t.success(e)}},["project_workspaces_by_descriptor/3","workspace_field/3","workspace_field_test/3","workspace_field_test/4"])});var S2={};Kt(S2,{Constraints:()=>P2,DependencyType:()=>gme});function to(t){if(t instanceof vC.default.type.Num)return t.value;if(t instanceof vC.default.type.Term)switch(t.indicator){case"throw/1":return to(t.args[0]);case"error/1":return to(t.args[0]);case"error/2":if(t.args[0]instanceof vC.default.type.Term&&t.args[0].indicator==="syntax_error/1")return Object.assign(to(t.args[0]),...to(t.args[1]));{let e=to(t.args[0]);return e.message+=` (in ${to(t.args[1])})`,e}case"syntax_error/1":return new zt(43,`Syntax error: ${to(t.args[0])}`);case"existence_error/2":return new zt(44,`Existence error: ${to(t.args[0])} ${to(t.args[1])} not found`);case"instantiation_error/0":return new zt(75,"Instantiation error: an argument is variable when an instantiated argument was expected");case"line/1":return{line:to(t.args[0])};case"column/1":return{column:to(t.args[0])};case"found/1":return{found:to(t.args[0])};case"./2":return[to(t.args[0])].concat(to(t.args[1]));case"//2":return`${to(t.args[0])}/${to(t.args[1])}`;default:return t.id}throw`couldn't pretty print because of unsupported node ${t}`}function pme(t){let e;try{e=to(t)}catch(r){throw typeof r=="string"?new zt(42,`Unknown error: ${t} (note: ${r})`):r}return typeof e.line<"u"&&typeof e.column<"u"&&(e.message+=` at line ${e.line}, column ${e.column}`),e}function $d(t){return t.id==="null"?null:`${t.toJavaScript()}`}function rdt(t){if(t.id==="null")return null;{let e=t.toJavaScript();if(typeof e!="string")return JSON.stringify(e);try{return JSON.stringify(JSON.parse(e))}catch{return JSON.stringify(e)}}}function u0(t){return typeof t=="string"?`'${t}'`:"[]"}var hme,vC,gme,fme,IH,P2,x2=Et(()=>{Ye();Ye();Pt();hme=$e(Yde()),vC=$e(EH());B2();Ame();(0,hme.default)(vC.default);gme=(o=>(o.Dependencies="dependencies",o.DevDependencies="devDependencies",o.PeerDependencies="peerDependencies",o))(gme||{}),fme=["dependencies","devDependencies","peerDependencies"];IH=class{constructor(e,r){let o=1e3*e.workspaces.length;this.session=vC.default.create(o),ume(this.session,e),this.session.consult(":- use_module(library(lists))."),this.session.consult(r)}fetchNextAnswer(){return new Promise(e=>{this.session.answer(r=>{e(r)})})}async*makeQuery(e){let r=this.session.query(e);if(r!==!0)throw pme(r);for(;;){let o=await this.fetchNextAnswer();if(o===null)throw new zt(79,"Resolution limit exceeded");if(!o)break;if(o.id==="throw")throw pme(o);yield o}}};P2=class{constructor(e){this.source="";this.project=e;let r=e.configuration.get("constraintsPath");oe.existsSync(r)&&(this.source=oe.readFileSync(r,"utf8"))}static async find(e){return new P2(e)}getProjectDatabase(){let e="";for(let r of fme)e+=`dependency_type(${r}). +`;for(let r of this.project.workspacesByCwd.values()){let o=r.relativeCwd;e+=`workspace(${u0(o)}). +`,e+=`workspace_ident(${u0(o)}, ${u0(W.stringifyIdent(r.anchoredLocator))}). +`,e+=`workspace_version(${u0(o)}, ${u0(r.manifest.version)}). +`;for(let a of fme)for(let n of r.manifest[a].values())e+=`workspace_has_dependency(${u0(o)}, ${u0(W.stringifyIdent(n))}, ${u0(n.range)}, ${a}). +`}return e+=`workspace(_) :- false. +`,e+=`workspace_ident(_, _) :- false. +`,e+=`workspace_version(_, _) :- false. +`,e+=`workspace_has_dependency(_, _, _, _) :- false. +`,e}getDeclarations(){let e="";return e+=`gen_enforced_dependency(_, _, _, _) :- false. +`,e+=`gen_enforced_field(_, _, _) :- false. +`,e}get fullSource(){return`${this.getProjectDatabase()} +${this.source} +${this.getDeclarations()}`}createSession(){return new IH(this.project,this.fullSource)}async processClassic(){let e=this.createSession();return{enforcedDependencies:await this.genEnforcedDependencies(e),enforcedFields:await this.genEnforcedFields(e)}}async process(){let{enforcedDependencies:e,enforcedFields:r}=await this.processClassic(),o=new Map;for(let{workspace:a,dependencyIdent:n,dependencyRange:u,dependencyType:A}of e){let p=I2([A,W.stringifyIdent(n)]),h=je.getMapWithDefault(o,a.cwd);je.getMapWithDefault(h,p).set(u??void 0,new Set)}for(let{workspace:a,fieldPath:n,fieldValue:u}of r){let A=I2(n),p=je.getMapWithDefault(o,a.cwd);je.getMapWithDefault(p,A).set(JSON.parse(u)??void 0,new Set)}return{manifestUpdates:o,reportedErrors:new Map}}async genEnforcedDependencies(e){let r=[];for await(let o of e.makeQuery("workspace(WorkspaceCwd), dependency_type(DependencyType), gen_enforced_dependency(WorkspaceCwd, DependencyIdent, DependencyRange, DependencyType).")){let a=K.resolve(this.project.cwd,$d(o.links.WorkspaceCwd)),n=$d(o.links.DependencyIdent),u=$d(o.links.DependencyRange),A=$d(o.links.DependencyType);if(a===null||n===null)throw new Error("Invalid rule");let p=this.project.getWorkspaceByCwd(a),h=W.parseIdent(n);r.push({workspace:p,dependencyIdent:h,dependencyRange:u,dependencyType:A})}return je.sortMap(r,[({dependencyRange:o})=>o!==null?"0":"1",({workspace:o})=>W.stringifyIdent(o.anchoredLocator),({dependencyIdent:o})=>W.stringifyIdent(o)])}async genEnforcedFields(e){let r=[];for await(let o of e.makeQuery("workspace(WorkspaceCwd), gen_enforced_field(WorkspaceCwd, FieldPath, FieldValue).")){let a=K.resolve(this.project.cwd,$d(o.links.WorkspaceCwd)),n=$d(o.links.FieldPath),u=rdt(o.links.FieldValue);if(a===null||n===null)throw new Error("Invalid rule");let A=this.project.getWorkspaceByCwd(a);r.push({workspace:A,fieldPath:n,fieldValue:u})}return je.sortMap(r,[({workspace:o})=>W.stringifyIdent(o.anchoredLocator),({fieldPath:o})=>o])}async*query(e){let r=this.createSession();for await(let o of r.makeQuery(e)){let a={};for(let[n,u]of Object.entries(o.links))n!=="_"&&(a[n]=$d(u));yield a}}}});var vme=_(vk=>{"use strict";Object.defineProperty(vk,"__esModule",{value:!0});function q2(t){let e=[...t.caches],r=e.shift();return r===void 0?Bme():{get(o,a,n={miss:()=>Promise.resolve()}){return r.get(o,a,n).catch(()=>q2({caches:e}).get(o,a,n))},set(o,a){return r.set(o,a).catch(()=>q2({caches:e}).set(o,a))},delete(o){return r.delete(o).catch(()=>q2({caches:e}).delete(o))},clear(){return r.clear().catch(()=>q2({caches:e}).clear())}}}function Bme(){return{get(t,e,r={miss:()=>Promise.resolve()}){return e().then(a=>Promise.all([a,r.miss(a)])).then(([a])=>a)},set(t,e){return Promise.resolve(e)},delete(t){return Promise.resolve()},clear(){return Promise.resolve()}}}vk.createFallbackableCache=q2;vk.createNullCache=Bme});var Pme=_((QWt,Dme)=>{Dme.exports=vme()});var Sme=_(LH=>{"use strict";Object.defineProperty(LH,"__esModule",{value:!0});function wdt(t={serializable:!0}){let e={};return{get(r,o,a={miss:()=>Promise.resolve()}){let n=JSON.stringify(r);if(n in e)return Promise.resolve(t.serializable?JSON.parse(e[n]):e[n]);let u=o(),A=a&&a.miss||(()=>Promise.resolve());return u.then(p=>A(p)).then(()=>u)},set(r,o){return e[JSON.stringify(r)]=t.serializable?JSON.stringify(o):o,Promise.resolve(o)},delete(r){return delete e[JSON.stringify(r)],Promise.resolve()},clear(){return e={},Promise.resolve()}}}LH.createInMemoryCache=wdt});var bme=_((TWt,xme)=>{xme.exports=Sme()});var Qme=_(Zc=>{"use strict";Object.defineProperty(Zc,"__esModule",{value:!0});function Idt(t,e,r){let o={"x-algolia-api-key":r,"x-algolia-application-id":e};return{headers(){return t===MH.WithinHeaders?o:{}},queryParameters(){return t===MH.WithinQueryParameters?o:{}}}}function Bdt(t){let e=0,r=()=>(e++,new Promise(o=>{setTimeout(()=>{o(t(r))},Math.min(100*e,1e3))}));return t(r)}function kme(t,e=(r,o)=>Promise.resolve()){return Object.assign(t,{wait(r){return kme(t.then(o=>Promise.all([e(o,r),o])).then(o=>o[1]))}})}function vdt(t){let e=t.length-1;for(e;e>0;e--){let r=Math.floor(Math.random()*(e+1)),o=t[e];t[e]=t[r],t[r]=o}return t}function Ddt(t,e){return e&&Object.keys(e).forEach(r=>{t[r]=e[r](t)}),t}function Pdt(t,...e){let r=0;return t.replace(/%s/g,()=>encodeURIComponent(e[r++]))}var Sdt="4.14.2",xdt=t=>()=>t.transporter.requester.destroy(),MH={WithinQueryParameters:0,WithinHeaders:1};Zc.AuthMode=MH;Zc.addMethods=Ddt;Zc.createAuth=Idt;Zc.createRetryablePromise=Bdt;Zc.createWaitablePromise=kme;Zc.destroy=xdt;Zc.encode=Pdt;Zc.shuffle=vdt;Zc.version=Sdt});var G2=_((NWt,Fme)=>{Fme.exports=Qme()});var Tme=_(OH=>{"use strict";Object.defineProperty(OH,"__esModule",{value:!0});var bdt={Delete:"DELETE",Get:"GET",Post:"POST",Put:"PUT"};OH.MethodEnum=bdt});var Y2=_((MWt,Rme)=>{Rme.exports=Tme()});var Jme=_(Fi=>{"use strict";Object.defineProperty(Fi,"__esModule",{value:!0});var Lme=Y2();function UH(t,e){let r=t||{},o=r.data||{};return Object.keys(r).forEach(a=>{["timeout","headers","queryParameters","data","cacheable"].indexOf(a)===-1&&(o[a]=r[a])}),{data:Object.entries(o).length>0?o:void 0,timeout:r.timeout||e,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}var W2={Read:1,Write:2,Any:3},xC={Up:1,Down:2,Timeouted:3},Mme=2*60*1e3;function HH(t,e=xC.Up){return{...t,status:e,lastUpdate:Date.now()}}function Ome(t){return t.status===xC.Up||Date.now()-t.lastUpdate>Mme}function Ume(t){return t.status===xC.Timeouted&&Date.now()-t.lastUpdate<=Mme}function jH(t){return typeof t=="string"?{protocol:"https",url:t,accept:W2.Any}:{protocol:t.protocol||"https",url:t.url,accept:t.accept||W2.Any}}function kdt(t,e){return Promise.all(e.map(r=>t.get(r,()=>Promise.resolve(HH(r))))).then(r=>{let o=r.filter(A=>Ome(A)),a=r.filter(A=>Ume(A)),n=[...o,...a],u=n.length>0?n.map(A=>jH(A)):e;return{getTimeout(A,p){return(a.length===0&&A===0?1:a.length+3+A)*p},statelessHosts:u}})}var Qdt=({isTimedOut:t,status:e})=>!t&&~~e===0,Fdt=t=>{let e=t.status;return t.isTimedOut||Qdt(t)||~~(e/100)!==2&&~~(e/100)!==4},Tdt=({status:t})=>~~(t/100)===2,Rdt=(t,e)=>Fdt(t)?e.onRetry(t):Tdt(t)?e.onSuccess(t):e.onFail(t);function Nme(t,e,r,o){let a=[],n=Gme(r,o),u=Yme(t,o),A=r.method,p=r.method!==Lme.MethodEnum.Get?{}:{...r.data,...o.data},h={"x-algolia-agent":t.userAgent.value,...t.queryParameters,...p,...o.queryParameters},E=0,I=(v,b)=>{let C=v.pop();if(C===void 0)throw Kme(_H(a));let T={data:n,headers:u,method:A,url:jme(C,r.path,h),connectTimeout:b(E,t.timeouts.connect),responseTimeout:b(E,o.timeout)},L=J=>{let te={request:T,response:J,host:C,triesLeft:v.length};return a.push(te),te},U={onSuccess:J=>_me(J),onRetry(J){let te=L(J);return J.isTimedOut&&E++,Promise.all([t.logger.info("Retryable failure",qH(te)),t.hostsCache.set(C,HH(C,J.isTimedOut?xC.Timeouted:xC.Down))]).then(()=>I(v,b))},onFail(J){throw L(J),Hme(J,_H(a))}};return t.requester.send(T).then(J=>Rdt(J,U))};return kdt(t.hostsCache,e).then(v=>I([...v.statelessHosts].reverse(),v.getTimeout))}function Ndt(t){let{hostsCache:e,logger:r,requester:o,requestsCache:a,responsesCache:n,timeouts:u,userAgent:A,hosts:p,queryParameters:h,headers:E}=t,I={hostsCache:e,logger:r,requester:o,requestsCache:a,responsesCache:n,timeouts:u,userAgent:A,headers:E,queryParameters:h,hosts:p.map(v=>jH(v)),read(v,b){let C=UH(b,I.timeouts.read),T=()=>Nme(I,I.hosts.filter(J=>(J.accept&W2.Read)!==0),v,C);if((C.cacheable!==void 0?C.cacheable:v.cacheable)!==!0)return T();let U={request:v,mappedRequestOptions:C,transporter:{queryParameters:I.queryParameters,headers:I.headers}};return I.responsesCache.get(U,()=>I.requestsCache.get(U,()=>I.requestsCache.set(U,T()).then(J=>Promise.all([I.requestsCache.delete(U),J]),J=>Promise.all([I.requestsCache.delete(U),Promise.reject(J)])).then(([J,te])=>te)),{miss:J=>I.responsesCache.set(U,J)})},write(v,b){return Nme(I,I.hosts.filter(C=>(C.accept&W2.Write)!==0),v,UH(b,I.timeouts.write))}};return I}function Ldt(t){let e={value:`Algolia for JavaScript (${t})`,add(r){let o=`; ${r.segment}${r.version!==void 0?` (${r.version})`:""}`;return e.value.indexOf(o)===-1&&(e.value=`${e.value}${o}`),e}};return e}function _me(t){try{return JSON.parse(t.content)}catch(e){throw Vme(e.message,t)}}function Hme({content:t,status:e},r){let o=t;try{o=JSON.parse(t).message}catch{}return Wme(o,e,r)}function Mdt(t,...e){let r=0;return t.replace(/%s/g,()=>encodeURIComponent(e[r++]))}function jme(t,e,r){let o=qme(r),a=`${t.protocol}://${t.url}/${e.charAt(0)==="/"?e.substr(1):e}`;return o.length&&(a+=`?${o}`),a}function qme(t){let e=r=>Object.prototype.toString.call(r)==="[object Object]"||Object.prototype.toString.call(r)==="[object Array]";return Object.keys(t).map(r=>Mdt("%s=%s",r,e(t[r])?JSON.stringify(t[r]):t[r])).join("&")}function Gme(t,e){if(t.method===Lme.MethodEnum.Get||t.data===void 0&&e.data===void 0)return;let r=Array.isArray(t.data)?t.data:{...t.data,...e.data};return JSON.stringify(r)}function Yme(t,e){let r={...t.headers,...e.headers},o={};return Object.keys(r).forEach(a=>{let n=r[a];o[a.toLowerCase()]=n}),o}function _H(t){return t.map(e=>qH(e))}function qH(t){let e=t.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return{...t,request:{...t.request,headers:{...t.request.headers,...e}}}}function Wme(t,e,r){return{name:"ApiError",message:t,status:e,transporterStackTrace:r}}function Vme(t,e){return{name:"DeserializationError",message:t,response:e}}function Kme(t){return{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:t}}Fi.CallEnum=W2;Fi.HostStatusEnum=xC;Fi.createApiError=Wme;Fi.createDeserializationError=Vme;Fi.createMappedRequestOptions=UH;Fi.createRetryError=Kme;Fi.createStatefulHost=HH;Fi.createStatelessHost=jH;Fi.createTransporter=Ndt;Fi.createUserAgent=Ldt;Fi.deserializeFailure=Hme;Fi.deserializeSuccess=_me;Fi.isStatefulHostTimeouted=Ume;Fi.isStatefulHostUp=Ome;Fi.serializeData=Gme;Fi.serializeHeaders=Yme;Fi.serializeQueryParameters=qme;Fi.serializeUrl=jme;Fi.stackFrameWithoutCredentials=qH;Fi.stackTraceWithoutCredentials=_H});var V2=_((UWt,zme)=>{zme.exports=Jme()});var Xme=_(d0=>{"use strict";Object.defineProperty(d0,"__esModule",{value:!0});var bC=G2(),Odt=V2(),K2=Y2(),Udt=t=>{let e=t.region||"us",r=bC.createAuth(bC.AuthMode.WithinHeaders,t.appId,t.apiKey),o=Odt.createTransporter({hosts:[{url:`analytics.${e}.algolia.com`}],...t,headers:{...r.headers(),"content-type":"application/json",...t.headers},queryParameters:{...r.queryParameters(),...t.queryParameters}}),a=t.appId;return bC.addMethods({appId:a,transporter:o},t.methods)},_dt=t=>(e,r)=>t.transporter.write({method:K2.MethodEnum.Post,path:"2/abtests",data:e},r),Hdt=t=>(e,r)=>t.transporter.write({method:K2.MethodEnum.Delete,path:bC.encode("2/abtests/%s",e)},r),jdt=t=>(e,r)=>t.transporter.read({method:K2.MethodEnum.Get,path:bC.encode("2/abtests/%s",e)},r),qdt=t=>e=>t.transporter.read({method:K2.MethodEnum.Get,path:"2/abtests"},e),Gdt=t=>(e,r)=>t.transporter.write({method:K2.MethodEnum.Post,path:bC.encode("2/abtests/%s/stop",e)},r);d0.addABTest=_dt;d0.createAnalyticsClient=Udt;d0.deleteABTest=Hdt;d0.getABTest=jdt;d0.getABTests=qdt;d0.stopABTest=Gdt});var $me=_((HWt,Zme)=>{Zme.exports=Xme()});var tye=_(J2=>{"use strict";Object.defineProperty(J2,"__esModule",{value:!0});var GH=G2(),Ydt=V2(),eye=Y2(),Wdt=t=>{let e=t.region||"us",r=GH.createAuth(GH.AuthMode.WithinHeaders,t.appId,t.apiKey),o=Ydt.createTransporter({hosts:[{url:`personalization.${e}.algolia.com`}],...t,headers:{...r.headers(),"content-type":"application/json",...t.headers},queryParameters:{...r.queryParameters(),...t.queryParameters}});return GH.addMethods({appId:t.appId,transporter:o},t.methods)},Vdt=t=>e=>t.transporter.read({method:eye.MethodEnum.Get,path:"1/strategies/personalization"},e),Kdt=t=>(e,r)=>t.transporter.write({method:eye.MethodEnum.Post,path:"1/strategies/personalization",data:e},r);J2.createPersonalizationClient=Wdt;J2.getPersonalizationStrategy=Vdt;J2.setPersonalizationStrategy=Kdt});var nye=_((qWt,rye)=>{rye.exports=tye()});var mye=_(Ft=>{"use strict";Object.defineProperty(Ft,"__esModule",{value:!0});var Gt=G2(),Na=V2(),Ir=Y2(),Jdt=Be("crypto");function Dk(t){let e=r=>t.request(r).then(o=>{if(t.batch!==void 0&&t.batch(o.hits),!t.shouldStop(o))return o.cursor?e({cursor:o.cursor}):e({page:(r.page||0)+1})});return e({})}var zdt=t=>{let e=t.appId,r=Gt.createAuth(t.authMode!==void 0?t.authMode:Gt.AuthMode.WithinHeaders,e,t.apiKey),o=Na.createTransporter({hosts:[{url:`${e}-dsn.algolia.net`,accept:Na.CallEnum.Read},{url:`${e}.algolia.net`,accept:Na.CallEnum.Write}].concat(Gt.shuffle([{url:`${e}-1.algolianet.com`},{url:`${e}-2.algolianet.com`},{url:`${e}-3.algolianet.com`}])),...t,headers:{...r.headers(),"content-type":"application/x-www-form-urlencoded",...t.headers},queryParameters:{...r.queryParameters(),...t.queryParameters}}),a={transporter:o,appId:e,addAlgoliaAgent(n,u){o.userAgent.add({segment:n,version:u})},clearCache(){return Promise.all([o.requestsCache.clear(),o.responsesCache.clear()]).then(()=>{})}};return Gt.addMethods(a,t.methods)};function iye(){return{name:"MissingObjectIDError",message:"All objects must have an unique objectID (like a primary key) to be valid. Algolia is also able to generate objectIDs automatically but *it's not recommended*. To do it, use the `{'autoGenerateObjectIDIfNotExist': true}` option."}}function sye(){return{name:"ObjectNotFoundError",message:"Object not found."}}function oye(){return{name:"ValidUntilNotFoundError",message:"ValidUntil not found in given secured api key."}}var Xdt=t=>(e,r)=>{let{queryParameters:o,...a}=r||{},n={acl:e,...o!==void 0?{queryParameters:o}:{}},u=(A,p)=>Gt.createRetryablePromise(h=>z2(t)(A.key,p).catch(E=>{if(E.status!==404)throw E;return h()}));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:"1/keys",data:n},a),u)},Zdt=t=>(e,r,o)=>{let a=Na.createMappedRequestOptions(o);return a.queryParameters["X-Algolia-User-ID"]=e,t.transporter.write({method:Ir.MethodEnum.Post,path:"1/clusters/mapping",data:{cluster:r}},a)},$dt=t=>(e,r,o)=>t.transporter.write({method:Ir.MethodEnum.Post,path:"1/clusters/mapping/batch",data:{users:e,cluster:r}},o),emt=t=>(e,r)=>Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("/1/dictionaries/%s/batch",e),data:{clearExistingDictionaryEntries:!0,requests:{action:"addEntry",body:[]}}},r),(o,a)=>kC(t)(o.taskID,a)),Pk=t=>(e,r,o)=>{let a=(n,u)=>X2(t)(e,{methods:{waitTask:Zi}}).waitTask(n.taskID,u);return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/operation",e),data:{operation:"copy",destination:r}},o),a)},tmt=t=>(e,r,o)=>Pk(t)(e,r,{...o,scope:[xk.Rules]}),rmt=t=>(e,r,o)=>Pk(t)(e,r,{...o,scope:[xk.Settings]}),nmt=t=>(e,r,o)=>Pk(t)(e,r,{...o,scope:[xk.Synonyms]}),imt=t=>(e,r)=>e.method===Ir.MethodEnum.Get?t.transporter.read(e,r):t.transporter.write(e,r),smt=t=>(e,r)=>{let o=(a,n)=>Gt.createRetryablePromise(u=>z2(t)(e,n).then(u).catch(A=>{if(A.status!==404)throw A}));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Delete,path:Gt.encode("1/keys/%s",e)},r),o)},omt=t=>(e,r,o)=>{let a=r.map(n=>({action:"deleteEntry",body:{objectID:n}}));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("/1/dictionaries/%s/batch",e),data:{clearExistingDictionaryEntries:!1,requests:a}},o),(n,u)=>kC(t)(n.taskID,u))},amt=()=>(t,e)=>{let r=Na.serializeQueryParameters(e),o=Jdt.createHmac("sha256",t).update(r).digest("hex");return Buffer.from(o+r).toString("base64")},z2=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/keys/%s",e)},r),aye=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/task/%s",e.toString())},r),lmt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"/1/dictionaries/*/settings"},e),cmt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"1/logs"},e),umt=()=>t=>{let e=Buffer.from(t,"base64").toString("ascii"),r=/validUntil=(\d+)/,o=e.match(r);if(o===null)throw oye();return parseInt(o[1],10)-Math.round(new Date().getTime()/1e3)},Amt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"1/clusters/mapping/top"},e),fmt=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/clusters/mapping/%s",e)},r),pmt=t=>e=>{let{retrieveMappings:r,...o}=e||{};return r===!0&&(o.getClusters=!0),t.transporter.read({method:Ir.MethodEnum.Get,path:"1/clusters/mapping/pending"},o)},X2=t=>(e,r={})=>{let o={transporter:t.transporter,appId:t.appId,indexName:e};return Gt.addMethods(o,r.methods)},hmt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"1/keys"},e),gmt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"1/clusters"},e),dmt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"1/indexes"},e),mmt=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:"1/clusters/mapping"},e),ymt=t=>(e,r,o)=>{let a=(n,u)=>X2(t)(e,{methods:{waitTask:Zi}}).waitTask(n.taskID,u);return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/operation",e),data:{operation:"move",destination:r}},o),a)},Emt=t=>(e,r)=>{let o=(a,n)=>Promise.all(Object.keys(a.taskID).map(u=>X2(t)(u,{methods:{waitTask:Zi}}).waitTask(a.taskID[u],n)));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:"1/indexes/*/batch",data:{requests:e}},r),o)},Cmt=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:e}},r),wmt=t=>(e,r)=>{let o=e.map(a=>({...a,params:Na.serializeQueryParameters(a.params||{})}));return t.transporter.read({method:Ir.MethodEnum.Post,path:"1/indexes/*/queries",data:{requests:o},cacheable:!0},r)},Imt=t=>(e,r)=>Promise.all(e.map(o=>{let{facetName:a,facetQuery:n,...u}=o.params;return X2(t)(o.indexName,{methods:{searchForFacetValues:hye}}).searchForFacetValues(a,n,{...r,...u})})),Bmt=t=>(e,r)=>{let o=Na.createMappedRequestOptions(r);return o.queryParameters["X-Algolia-User-ID"]=e,t.transporter.write({method:Ir.MethodEnum.Delete,path:"1/clusters/mapping"},o)},vmt=t=>(e,r,o)=>{let a=r.map(n=>({action:"addEntry",body:n}));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("/1/dictionaries/%s/batch",e),data:{clearExistingDictionaryEntries:!0,requests:a}},o),(n,u)=>kC(t)(n.taskID,u))},Dmt=t=>(e,r)=>{let o=(a,n)=>Gt.createRetryablePromise(u=>z2(t)(e,n).catch(A=>{if(A.status!==404)throw A;return u()}));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/keys/%s/restore",e)},r),o)},Pmt=t=>(e,r,o)=>{let a=r.map(n=>({action:"addEntry",body:n}));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("/1/dictionaries/%s/batch",e),data:{clearExistingDictionaryEntries:!1,requests:a}},o),(n,u)=>kC(t)(n.taskID,u))},Smt=t=>(e,r,o)=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("/1/dictionaries/%s/search",e),data:{query:r},cacheable:!0},o),xmt=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Post,path:"1/clusters/mapping/search",data:{query:e}},r),bmt=t=>(e,r)=>Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Put,path:"/1/dictionaries/*/settings",data:e},r),(o,a)=>kC(t)(o.taskID,a)),kmt=t=>(e,r)=>{let o=Object.assign({},r),{queryParameters:a,...n}=r||{},u=a?{queryParameters:a}:{},A=["acl","indexes","referers","restrictSources","queryParameters","description","maxQueriesPerIPPerHour","maxHitsPerQuery"],p=E=>Object.keys(o).filter(I=>A.indexOf(I)!==-1).every(I=>E[I]===o[I]),h=(E,I)=>Gt.createRetryablePromise(v=>z2(t)(e,I).then(b=>p(b)?Promise.resolve():v()));return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Put,path:Gt.encode("1/keys/%s",e),data:u},n),h)},kC=t=>(e,r)=>Gt.createRetryablePromise(o=>aye(t)(e,r).then(a=>a.status!=="published"?o():void 0)),lye=t=>(e,r)=>{let o=(a,n)=>Zi(t)(a.taskID,n);return Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/batch",t.indexName),data:{requests:e}},r),o)},Qmt=t=>e=>Dk({shouldStop:r=>r.cursor===void 0,...e,request:r=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/browse",t.indexName),data:r},e)}),Fmt=t=>e=>{let r={hitsPerPage:1e3,...e};return Dk({shouldStop:o=>o.hits.length<r.hitsPerPage,...r,request(o){return gye(t)("",{...r,...o}).then(a=>({...a,hits:a.hits.map(n=>(delete n._highlightResult,n))}))}})},Tmt=t=>e=>{let r={hitsPerPage:1e3,...e};return Dk({shouldStop:o=>o.hits.length<r.hitsPerPage,...r,request(o){return dye(t)("",{...r,...o}).then(a=>({...a,hits:a.hits.map(n=>(delete n._highlightResult,n))}))}})},Sk=t=>(e,r,o)=>{let{batchSize:a,...n}=o||{},u={taskIDs:[],objectIDs:[]},A=(p=0)=>{let h=[],E;for(E=p;E<e.length&&(h.push(e[E]),h.length!==(a||1e3));E++);return h.length===0?Promise.resolve(u):lye(t)(h.map(I=>({action:r,body:I})),n).then(I=>(u.objectIDs=u.objectIDs.concat(I.objectIDs),u.taskIDs.push(I.taskID),E++,A(E)))};return Gt.createWaitablePromise(A(),(p,h)=>Promise.all(p.taskIDs.map(E=>Zi(t)(E,h))))},Rmt=t=>e=>Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/clear",t.indexName)},e),(r,o)=>Zi(t)(r.taskID,o)),Nmt=t=>e=>{let{forwardToReplicas:r,...o}=e||{},a=Na.createMappedRequestOptions(o);return r&&(a.queryParameters.forwardToReplicas=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/rules/clear",t.indexName)},a),(n,u)=>Zi(t)(n.taskID,u))},Lmt=t=>e=>{let{forwardToReplicas:r,...o}=e||{},a=Na.createMappedRequestOptions(o);return r&&(a.queryParameters.forwardToReplicas=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/synonyms/clear",t.indexName)},a),(n,u)=>Zi(t)(n.taskID,u))},Mmt=t=>(e,r)=>Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/deleteByQuery",t.indexName),data:e},r),(o,a)=>Zi(t)(o.taskID,a)),Omt=t=>e=>Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Delete,path:Gt.encode("1/indexes/%s",t.indexName)},e),(r,o)=>Zi(t)(r.taskID,o)),Umt=t=>(e,r)=>Gt.createWaitablePromise(cye(t)([e],r).then(o=>({taskID:o.taskIDs[0]})),(o,a)=>Zi(t)(o.taskID,a)),cye=t=>(e,r)=>{let o=e.map(a=>({objectID:a}));return Sk(t)(o,rm.DeleteObject,r)},_mt=t=>(e,r)=>{let{forwardToReplicas:o,...a}=r||{},n=Na.createMappedRequestOptions(a);return o&&(n.queryParameters.forwardToReplicas=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Delete,path:Gt.encode("1/indexes/%s/rules/%s",t.indexName,e)},n),(u,A)=>Zi(t)(u.taskID,A))},Hmt=t=>(e,r)=>{let{forwardToReplicas:o,...a}=r||{},n=Na.createMappedRequestOptions(a);return o&&(n.queryParameters.forwardToReplicas=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Delete,path:Gt.encode("1/indexes/%s/synonyms/%s",t.indexName,e)},n),(u,A)=>Zi(t)(u.taskID,A))},jmt=t=>e=>uye(t)(e).then(()=>!0).catch(r=>{if(r.status!==404)throw r;return!1}),qmt=t=>(e,r,o)=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("1/answers/%s/prediction",t.indexName),data:{query:e,queryLanguages:r},cacheable:!0},o),Gmt=t=>(e,r)=>{let{query:o,paginate:a,...n}=r||{},u=0,A=()=>pye(t)(o||"",{...n,page:u}).then(p=>{for(let[h,E]of Object.entries(p.hits))if(e(E))return{object:E,position:parseInt(h,10),page:u};if(u++,a===!1||u>=p.nbPages)throw sye();return A()});return A()},Ymt=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/indexes/%s/%s",t.indexName,e)},r),Wmt=()=>(t,e)=>{for(let[r,o]of Object.entries(t.hits))if(o.objectID===e)return parseInt(r,10);return-1},Vmt=t=>(e,r)=>{let{attributesToRetrieve:o,...a}=r||{},n=e.map(u=>({indexName:t.indexName,objectID:u,...o?{attributesToRetrieve:o}:{}}));return t.transporter.read({method:Ir.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:n}},a)},Kmt=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/indexes/%s/rules/%s",t.indexName,e)},r),uye=t=>e=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/indexes/%s/settings",t.indexName),data:{getVersion:2}},e),Jmt=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/indexes/%s/synonyms/%s",t.indexName,e)},r),Aye=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Get,path:Gt.encode("1/indexes/%s/task/%s",t.indexName,e.toString())},r),zmt=t=>(e,r)=>Gt.createWaitablePromise(fye(t)([e],r).then(o=>({objectID:o.objectIDs[0],taskID:o.taskIDs[0]})),(o,a)=>Zi(t)(o.taskID,a)),fye=t=>(e,r)=>{let{createIfNotExists:o,...a}=r||{},n=o?rm.PartialUpdateObject:rm.PartialUpdateObjectNoCreate;return Sk(t)(e,n,a)},Xmt=t=>(e,r)=>{let{safe:o,autoGenerateObjectIDIfNotExist:a,batchSize:n,...u}=r||{},A=(C,T,L,U)=>Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/operation",C),data:{operation:L,destination:T}},U),(J,te)=>Zi(t)(J.taskID,te)),p=Math.random().toString(36).substring(7),h=`${t.indexName}_tmp_${p}`,E=YH({appId:t.appId,transporter:t.transporter,indexName:h}),I=[],v=A(t.indexName,h,"copy",{...u,scope:["settings","synonyms","rules"]});I.push(v);let b=(o?v.wait(u):v).then(()=>{let C=E(e,{...u,autoGenerateObjectIDIfNotExist:a,batchSize:n});return I.push(C),o?C.wait(u):C}).then(()=>{let C=A(h,t.indexName,"move",u);return I.push(C),o?C.wait(u):C}).then(()=>Promise.all(I)).then(([C,T,L])=>({objectIDs:T.objectIDs,taskIDs:[C.taskID,...T.taskIDs,L.taskID]}));return Gt.createWaitablePromise(b,(C,T)=>Promise.all(I.map(L=>L.wait(T))))},Zmt=t=>(e,r)=>WH(t)(e,{...r,clearExistingRules:!0}),$mt=t=>(e,r)=>VH(t)(e,{...r,clearExistingSynonyms:!0}),eyt=t=>(e,r)=>Gt.createWaitablePromise(YH(t)([e],r).then(o=>({objectID:o.objectIDs[0],taskID:o.taskIDs[0]})),(o,a)=>Zi(t)(o.taskID,a)),YH=t=>(e,r)=>{let{autoGenerateObjectIDIfNotExist:o,...a}=r||{},n=o?rm.AddObject:rm.UpdateObject;if(n===rm.UpdateObject){for(let u of e)if(u.objectID===void 0)return Gt.createWaitablePromise(Promise.reject(iye()))}return Sk(t)(e,n,a)},tyt=t=>(e,r)=>WH(t)([e],r),WH=t=>(e,r)=>{let{forwardToReplicas:o,clearExistingRules:a,...n}=r||{},u=Na.createMappedRequestOptions(n);return o&&(u.queryParameters.forwardToReplicas=1),a&&(u.queryParameters.clearExistingRules=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/rules/batch",t.indexName),data:e},u),(A,p)=>Zi(t)(A.taskID,p))},ryt=t=>(e,r)=>VH(t)([e],r),VH=t=>(e,r)=>{let{forwardToReplicas:o,clearExistingSynonyms:a,replaceExistingSynonyms:n,...u}=r||{},A=Na.createMappedRequestOptions(u);return o&&(A.queryParameters.forwardToReplicas=1),(n||a)&&(A.queryParameters.replaceExistingSynonyms=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/synonyms/batch",t.indexName),data:e},A),(p,h)=>Zi(t)(p.taskID,h))},pye=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/query",t.indexName),data:{query:e},cacheable:!0},r),hye=t=>(e,r,o)=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/facets/%s/query",t.indexName,e),data:{facetQuery:r},cacheable:!0},o),gye=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/rules/search",t.indexName),data:{query:e}},r),dye=t=>(e,r)=>t.transporter.read({method:Ir.MethodEnum.Post,path:Gt.encode("1/indexes/%s/synonyms/search",t.indexName),data:{query:e}},r),nyt=t=>(e,r)=>{let{forwardToReplicas:o,...a}=r||{},n=Na.createMappedRequestOptions(a);return o&&(n.queryParameters.forwardToReplicas=1),Gt.createWaitablePromise(t.transporter.write({method:Ir.MethodEnum.Put,path:Gt.encode("1/indexes/%s/settings",t.indexName),data:e},n),(u,A)=>Zi(t)(u.taskID,A))},Zi=t=>(e,r)=>Gt.createRetryablePromise(o=>Aye(t)(e,r).then(a=>a.status!=="published"?o():void 0)),iyt={AddObject:"addObject",Analytics:"analytics",Browser:"browse",DeleteIndex:"deleteIndex",DeleteObject:"deleteObject",EditSettings:"editSettings",ListIndexes:"listIndexes",Logs:"logs",Personalization:"personalization",Recommendation:"recommendation",Search:"search",SeeUnretrievableAttributes:"seeUnretrievableAttributes",Settings:"settings",Usage:"usage"},rm={AddObject:"addObject",UpdateObject:"updateObject",PartialUpdateObject:"partialUpdateObject",PartialUpdateObjectNoCreate:"partialUpdateObjectNoCreate",DeleteObject:"deleteObject",DeleteIndex:"delete",ClearIndex:"clear"},xk={Settings:"settings",Synonyms:"synonyms",Rules:"rules"},syt={None:"none",StopIfEnoughMatches:"stopIfEnoughMatches"},oyt={Synonym:"synonym",OneWaySynonym:"oneWaySynonym",AltCorrection1:"altCorrection1",AltCorrection2:"altCorrection2",Placeholder:"placeholder"};Ft.ApiKeyACLEnum=iyt;Ft.BatchActionEnum=rm;Ft.ScopeEnum=xk;Ft.StrategyEnum=syt;Ft.SynonymEnum=oyt;Ft.addApiKey=Xdt;Ft.assignUserID=Zdt;Ft.assignUserIDs=$dt;Ft.batch=lye;Ft.browseObjects=Qmt;Ft.browseRules=Fmt;Ft.browseSynonyms=Tmt;Ft.chunkedBatch=Sk;Ft.clearDictionaryEntries=emt;Ft.clearObjects=Rmt;Ft.clearRules=Nmt;Ft.clearSynonyms=Lmt;Ft.copyIndex=Pk;Ft.copyRules=tmt;Ft.copySettings=rmt;Ft.copySynonyms=nmt;Ft.createBrowsablePromise=Dk;Ft.createMissingObjectIDError=iye;Ft.createObjectNotFoundError=sye;Ft.createSearchClient=zdt;Ft.createValidUntilNotFoundError=oye;Ft.customRequest=imt;Ft.deleteApiKey=smt;Ft.deleteBy=Mmt;Ft.deleteDictionaryEntries=omt;Ft.deleteIndex=Omt;Ft.deleteObject=Umt;Ft.deleteObjects=cye;Ft.deleteRule=_mt;Ft.deleteSynonym=Hmt;Ft.exists=jmt;Ft.findAnswers=qmt;Ft.findObject=Gmt;Ft.generateSecuredApiKey=amt;Ft.getApiKey=z2;Ft.getAppTask=aye;Ft.getDictionarySettings=lmt;Ft.getLogs=cmt;Ft.getObject=Ymt;Ft.getObjectPosition=Wmt;Ft.getObjects=Vmt;Ft.getRule=Kmt;Ft.getSecuredApiKeyRemainingValidity=umt;Ft.getSettings=uye;Ft.getSynonym=Jmt;Ft.getTask=Aye;Ft.getTopUserIDs=Amt;Ft.getUserID=fmt;Ft.hasPendingMappings=pmt;Ft.initIndex=X2;Ft.listApiKeys=hmt;Ft.listClusters=gmt;Ft.listIndices=dmt;Ft.listUserIDs=mmt;Ft.moveIndex=ymt;Ft.multipleBatch=Emt;Ft.multipleGetObjects=Cmt;Ft.multipleQueries=wmt;Ft.multipleSearchForFacetValues=Imt;Ft.partialUpdateObject=zmt;Ft.partialUpdateObjects=fye;Ft.removeUserID=Bmt;Ft.replaceAllObjects=Xmt;Ft.replaceAllRules=Zmt;Ft.replaceAllSynonyms=$mt;Ft.replaceDictionaryEntries=vmt;Ft.restoreApiKey=Dmt;Ft.saveDictionaryEntries=Pmt;Ft.saveObject=eyt;Ft.saveObjects=YH;Ft.saveRule=tyt;Ft.saveRules=WH;Ft.saveSynonym=ryt;Ft.saveSynonyms=VH;Ft.search=pye;Ft.searchDictionaryEntries=Smt;Ft.searchForFacetValues=hye;Ft.searchRules=gye;Ft.searchSynonyms=dye;Ft.searchUserIDs=xmt;Ft.setDictionarySettings=bmt;Ft.setSettings=nyt;Ft.updateApiKey=kmt;Ft.waitAppTask=kC;Ft.waitTask=Zi});var Eye=_((YWt,yye)=>{yye.exports=mye()});var Cye=_(bk=>{"use strict";Object.defineProperty(bk,"__esModule",{value:!0});function ayt(){return{debug(t,e){return Promise.resolve()},info(t,e){return Promise.resolve()},error(t,e){return Promise.resolve()}}}var lyt={Debug:1,Info:2,Error:3};bk.LogLevelEnum=lyt;bk.createNullLogger=ayt});var Iye=_((VWt,wye)=>{wye.exports=Cye()});var Pye=_(KH=>{"use strict";Object.defineProperty(KH,"__esModule",{value:!0});var Bye=Be("http"),vye=Be("https"),cyt=Be("url"),Dye={keepAlive:!0},uyt=new Bye.Agent(Dye),Ayt=new vye.Agent(Dye);function fyt({agent:t,httpAgent:e,httpsAgent:r,requesterOptions:o={}}={}){let a=e||t||uyt,n=r||t||Ayt;return{send(u){return new Promise(A=>{let p=cyt.parse(u.url),h=p.query===null?p.pathname:`${p.pathname}?${p.query}`,E={...o,agent:p.protocol==="https:"?n:a,hostname:p.hostname,path:h,method:u.method,headers:{...o&&o.headers?o.headers:{},...u.headers},...p.port!==void 0?{port:p.port||""}:{}},I=(p.protocol==="https:"?vye:Bye).request(E,T=>{let L=[];T.on("data",U=>{L=L.concat(U)}),T.on("end",()=>{clearTimeout(b),clearTimeout(C),A({status:T.statusCode||0,content:Buffer.concat(L).toString(),isTimedOut:!1})})}),v=(T,L)=>setTimeout(()=>{I.abort(),A({status:0,content:L,isTimedOut:!0})},T*1e3),b=v(u.connectTimeout,"Connection timeout"),C;I.on("error",T=>{clearTimeout(b),clearTimeout(C),A({status:0,content:T.message,isTimedOut:!1})}),I.once("response",()=>{clearTimeout(b),C=v(u.responseTimeout,"Socket timeout")}),u.data!==void 0&&I.write(u.data),I.end()})},destroy(){return a.destroy(),n.destroy(),Promise.resolve()}}}KH.createNodeHttpRequester=fyt});var xye=_((JWt,Sye)=>{Sye.exports=Pye()});var Fye=_((zWt,Qye)=>{"use strict";var bye=Pme(),pyt=bme(),QC=$me(),zH=G2(),JH=nye(),Ut=Eye(),hyt=Iye(),gyt=xye(),dyt=V2();function kye(t,e,r){let o={appId:t,apiKey:e,timeouts:{connect:2,read:5,write:30},requester:gyt.createNodeHttpRequester(),logger:hyt.createNullLogger(),responsesCache:bye.createNullCache(),requestsCache:bye.createNullCache(),hostsCache:pyt.createInMemoryCache(),userAgent:dyt.createUserAgent(zH.version).add({segment:"Node.js",version:process.versions.node})},a={...o,...r},n=()=>u=>JH.createPersonalizationClient({...o,...u,methods:{getPersonalizationStrategy:JH.getPersonalizationStrategy,setPersonalizationStrategy:JH.setPersonalizationStrategy}});return Ut.createSearchClient({...a,methods:{search:Ut.multipleQueries,searchForFacetValues:Ut.multipleSearchForFacetValues,multipleBatch:Ut.multipleBatch,multipleGetObjects:Ut.multipleGetObjects,multipleQueries:Ut.multipleQueries,copyIndex:Ut.copyIndex,copySettings:Ut.copySettings,copyRules:Ut.copyRules,copySynonyms:Ut.copySynonyms,moveIndex:Ut.moveIndex,listIndices:Ut.listIndices,getLogs:Ut.getLogs,listClusters:Ut.listClusters,multipleSearchForFacetValues:Ut.multipleSearchForFacetValues,getApiKey:Ut.getApiKey,addApiKey:Ut.addApiKey,listApiKeys:Ut.listApiKeys,updateApiKey:Ut.updateApiKey,deleteApiKey:Ut.deleteApiKey,restoreApiKey:Ut.restoreApiKey,assignUserID:Ut.assignUserID,assignUserIDs:Ut.assignUserIDs,getUserID:Ut.getUserID,searchUserIDs:Ut.searchUserIDs,listUserIDs:Ut.listUserIDs,getTopUserIDs:Ut.getTopUserIDs,removeUserID:Ut.removeUserID,hasPendingMappings:Ut.hasPendingMappings,generateSecuredApiKey:Ut.generateSecuredApiKey,getSecuredApiKeyRemainingValidity:Ut.getSecuredApiKeyRemainingValidity,destroy:zH.destroy,clearDictionaryEntries:Ut.clearDictionaryEntries,deleteDictionaryEntries:Ut.deleteDictionaryEntries,getDictionarySettings:Ut.getDictionarySettings,getAppTask:Ut.getAppTask,replaceDictionaryEntries:Ut.replaceDictionaryEntries,saveDictionaryEntries:Ut.saveDictionaryEntries,searchDictionaryEntries:Ut.searchDictionaryEntries,setDictionarySettings:Ut.setDictionarySettings,waitAppTask:Ut.waitAppTask,customRequest:Ut.customRequest,initIndex:u=>A=>Ut.initIndex(u)(A,{methods:{batch:Ut.batch,delete:Ut.deleteIndex,findAnswers:Ut.findAnswers,getObject:Ut.getObject,getObjects:Ut.getObjects,saveObject:Ut.saveObject,saveObjects:Ut.saveObjects,search:Ut.search,searchForFacetValues:Ut.searchForFacetValues,waitTask:Ut.waitTask,setSettings:Ut.setSettings,getSettings:Ut.getSettings,partialUpdateObject:Ut.partialUpdateObject,partialUpdateObjects:Ut.partialUpdateObjects,deleteObject:Ut.deleteObject,deleteObjects:Ut.deleteObjects,deleteBy:Ut.deleteBy,clearObjects:Ut.clearObjects,browseObjects:Ut.browseObjects,getObjectPosition:Ut.getObjectPosition,findObject:Ut.findObject,exists:Ut.exists,saveSynonym:Ut.saveSynonym,saveSynonyms:Ut.saveSynonyms,getSynonym:Ut.getSynonym,searchSynonyms:Ut.searchSynonyms,browseSynonyms:Ut.browseSynonyms,deleteSynonym:Ut.deleteSynonym,clearSynonyms:Ut.clearSynonyms,replaceAllObjects:Ut.replaceAllObjects,replaceAllSynonyms:Ut.replaceAllSynonyms,searchRules:Ut.searchRules,getRule:Ut.getRule,deleteRule:Ut.deleteRule,saveRule:Ut.saveRule,saveRules:Ut.saveRules,replaceAllRules:Ut.replaceAllRules,browseRules:Ut.browseRules,clearRules:Ut.clearRules}}),initAnalytics:()=>u=>QC.createAnalyticsClient({...o,...u,methods:{addABTest:QC.addABTest,getABTest:QC.getABTest,getABTests:QC.getABTests,stopABTest:QC.stopABTest,deleteABTest:QC.deleteABTest}}),initPersonalization:n,initRecommendation:()=>u=>(a.logger.info("The `initRecommendation` method is deprecated. Use `initPersonalization` instead."),n()(u))}})}kye.version=zH.version;Qye.exports=kye});var ZH=_((XWt,XH)=>{var Tye=Fye();XH.exports=Tye;XH.exports.default=Tye});var t6=_(($Wt,Lye)=>{"use strict";var Nye=Object.getOwnPropertySymbols,yyt=Object.prototype.hasOwnProperty,Eyt=Object.prototype.propertyIsEnumerable;function Cyt(t){if(t==null)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(t)}function wyt(){try{if(!Object.assign)return!1;var t=new String("abc");if(t[5]="de",Object.getOwnPropertyNames(t)[0]==="5")return!1;for(var e={},r=0;r<10;r++)e["_"+String.fromCharCode(r)]=r;var o=Object.getOwnPropertyNames(e).map(function(n){return e[n]});if(o.join("")!=="0123456789")return!1;var a={};return"abcdefghijklmnopqrst".split("").forEach(function(n){a[n]=n}),Object.keys(Object.assign({},a)).join("")==="abcdefghijklmnopqrst"}catch{return!1}}Lye.exports=wyt()?Object.assign:function(t,e){for(var r,o=Cyt(t),a,n=1;n<arguments.length;n++){r=Object(arguments[n]);for(var u in r)yyt.call(r,u)&&(o[u]=r[u]);if(Nye){a=Nye(r);for(var A=0;A<a.length;A++)Eyt.call(r,a[A])&&(o[a[A]]=r[a[A]])}}return o}});var Kye=_(Nn=>{"use strict";var o6=t6(),$c=typeof Symbol=="function"&&Symbol.for,Z2=$c?Symbol.for("react.element"):60103,Iyt=$c?Symbol.for("react.portal"):60106,Byt=$c?Symbol.for("react.fragment"):60107,vyt=$c?Symbol.for("react.strict_mode"):60108,Dyt=$c?Symbol.for("react.profiler"):60114,Pyt=$c?Symbol.for("react.provider"):60109,Syt=$c?Symbol.for("react.context"):60110,xyt=$c?Symbol.for("react.forward_ref"):60112,byt=$c?Symbol.for("react.suspense"):60113,kyt=$c?Symbol.for("react.memo"):60115,Qyt=$c?Symbol.for("react.lazy"):60116,Mye=typeof Symbol=="function"&&Symbol.iterator;function $2(t){for(var e="https://reactjs.org/docs/error-decoder.html?invariant="+t,r=1;r<arguments.length;r++)e+="&args[]="+encodeURIComponent(arguments[r]);return"Minified React error #"+t+"; visit "+e+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var Oye={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Uye={};function FC(t,e,r){this.props=t,this.context=e,this.refs=Uye,this.updater=r||Oye}FC.prototype.isReactComponent={};FC.prototype.setState=function(t,e){if(typeof t!="object"&&typeof t!="function"&&t!=null)throw Error($2(85));this.updater.enqueueSetState(this,t,e,"setState")};FC.prototype.forceUpdate=function(t){this.updater.enqueueForceUpdate(this,t,"forceUpdate")};function _ye(){}_ye.prototype=FC.prototype;function a6(t,e,r){this.props=t,this.context=e,this.refs=Uye,this.updater=r||Oye}var l6=a6.prototype=new _ye;l6.constructor=a6;o6(l6,FC.prototype);l6.isPureReactComponent=!0;var c6={current:null},Hye=Object.prototype.hasOwnProperty,jye={key:!0,ref:!0,__self:!0,__source:!0};function qye(t,e,r){var o,a={},n=null,u=null;if(e!=null)for(o in e.ref!==void 0&&(u=e.ref),e.key!==void 0&&(n=""+e.key),e)Hye.call(e,o)&&!jye.hasOwnProperty(o)&&(a[o]=e[o]);var A=arguments.length-2;if(A===1)a.children=r;else if(1<A){for(var p=Array(A),h=0;h<A;h++)p[h]=arguments[h+2];a.children=p}if(t&&t.defaultProps)for(o in A=t.defaultProps,A)a[o]===void 0&&(a[o]=A[o]);return{$$typeof:Z2,type:t,key:n,ref:u,props:a,_owner:c6.current}}function Fyt(t,e){return{$$typeof:Z2,type:t.type,key:e,ref:t.ref,props:t.props,_owner:t._owner}}function u6(t){return typeof t=="object"&&t!==null&&t.$$typeof===Z2}function Tyt(t){var e={"=":"=0",":":"=2"};return"$"+(""+t).replace(/[=:]/g,function(r){return e[r]})}var Gye=/\/+/g,kk=[];function Yye(t,e,r,o){if(kk.length){var a=kk.pop();return a.result=t,a.keyPrefix=e,a.func=r,a.context=o,a.count=0,a}return{result:t,keyPrefix:e,func:r,context:o,count:0}}function Wye(t){t.result=null,t.keyPrefix=null,t.func=null,t.context=null,t.count=0,10>kk.length&&kk.push(t)}function n6(t,e,r,o){var a=typeof t;(a==="undefined"||a==="boolean")&&(t=null);var n=!1;if(t===null)n=!0;else switch(a){case"string":case"number":n=!0;break;case"object":switch(t.$$typeof){case Z2:case Iyt:n=!0}}if(n)return r(o,t,e===""?"."+r6(t,0):e),1;if(n=0,e=e===""?".":e+":",Array.isArray(t))for(var u=0;u<t.length;u++){a=t[u];var A=e+r6(a,u);n+=n6(a,A,r,o)}else if(t===null||typeof t!="object"?A=null:(A=Mye&&t[Mye]||t["@@iterator"],A=typeof A=="function"?A:null),typeof A=="function")for(t=A.call(t),u=0;!(a=t.next()).done;)a=a.value,A=e+r6(a,u++),n+=n6(a,A,r,o);else if(a==="object")throw r=""+t,Error($2(31,r==="[object Object]"?"object with keys {"+Object.keys(t).join(", ")+"}":r,""));return n}function i6(t,e,r){return t==null?0:n6(t,"",e,r)}function r6(t,e){return typeof t=="object"&&t!==null&&t.key!=null?Tyt(t.key):e.toString(36)}function Ryt(t,e){t.func.call(t.context,e,t.count++)}function Nyt(t,e,r){var o=t.result,a=t.keyPrefix;t=t.func.call(t.context,e,t.count++),Array.isArray(t)?s6(t,o,r,function(n){return n}):t!=null&&(u6(t)&&(t=Fyt(t,a+(!t.key||e&&e.key===t.key?"":(""+t.key).replace(Gye,"$&/")+"/")+r)),o.push(t))}function s6(t,e,r,o,a){var n="";r!=null&&(n=(""+r).replace(Gye,"$&/")+"/"),e=Yye(e,n,o,a),i6(t,Nyt,e),Wye(e)}var Vye={current:null};function zf(){var t=Vye.current;if(t===null)throw Error($2(321));return t}var Lyt={ReactCurrentDispatcher:Vye,ReactCurrentBatchConfig:{suspense:null},ReactCurrentOwner:c6,IsSomeRendererActing:{current:!1},assign:o6};Nn.Children={map:function(t,e,r){if(t==null)return t;var o=[];return s6(t,o,null,e,r),o},forEach:function(t,e,r){if(t==null)return t;e=Yye(null,null,e,r),i6(t,Ryt,e),Wye(e)},count:function(t){return i6(t,function(){return null},null)},toArray:function(t){var e=[];return s6(t,e,null,function(r){return r}),e},only:function(t){if(!u6(t))throw Error($2(143));return t}};Nn.Component=FC;Nn.Fragment=Byt;Nn.Profiler=Dyt;Nn.PureComponent=a6;Nn.StrictMode=vyt;Nn.Suspense=byt;Nn.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=Lyt;Nn.cloneElement=function(t,e,r){if(t==null)throw Error($2(267,t));var o=o6({},t.props),a=t.key,n=t.ref,u=t._owner;if(e!=null){if(e.ref!==void 0&&(n=e.ref,u=c6.current),e.key!==void 0&&(a=""+e.key),t.type&&t.type.defaultProps)var A=t.type.defaultProps;for(p in e)Hye.call(e,p)&&!jye.hasOwnProperty(p)&&(o[p]=e[p]===void 0&&A!==void 0?A[p]:e[p])}var p=arguments.length-2;if(p===1)o.children=r;else if(1<p){A=Array(p);for(var h=0;h<p;h++)A[h]=arguments[h+2];o.children=A}return{$$typeof:Z2,type:t.type,key:a,ref:n,props:o,_owner:u}};Nn.createContext=function(t,e){return e===void 0&&(e=null),t={$$typeof:Syt,_calculateChangedBits:e,_currentValue:t,_currentValue2:t,_threadCount:0,Provider:null,Consumer:null},t.Provider={$$typeof:Pyt,_context:t},t.Consumer=t};Nn.createElement=qye;Nn.createFactory=function(t){var e=qye.bind(null,t);return e.type=t,e};Nn.createRef=function(){return{current:null}};Nn.forwardRef=function(t){return{$$typeof:xyt,render:t}};Nn.isValidElement=u6;Nn.lazy=function(t){return{$$typeof:Qyt,_ctor:t,_status:-1,_result:null}};Nn.memo=function(t,e){return{$$typeof:kyt,type:t,compare:e===void 0?null:e}};Nn.useCallback=function(t,e){return zf().useCallback(t,e)};Nn.useContext=function(t,e){return zf().useContext(t,e)};Nn.useDebugValue=function(){};Nn.useEffect=function(t,e){return zf().useEffect(t,e)};Nn.useImperativeHandle=function(t,e,r){return zf().useImperativeHandle(t,e,r)};Nn.useLayoutEffect=function(t,e){return zf().useLayoutEffect(t,e)};Nn.useMemo=function(t,e){return zf().useMemo(t,e)};Nn.useReducer=function(t,e,r){return zf().useReducer(t,e,r)};Nn.useRef=function(t){return zf().useRef(t)};Nn.useState=function(t){return zf().useState(t)};Nn.version="16.13.1"});var sn=_((tVt,Jye)=>{"use strict";Jye.exports=Kye()});var f6=_((rVt,A6)=>{"use strict";var An=A6.exports;A6.exports.default=An;var Ln="\x1B[",eB="\x1B]",TC="\x07",Qk=";",zye=process.env.TERM_PROGRAM==="Apple_Terminal";An.cursorTo=(t,e)=>{if(typeof t!="number")throw new TypeError("The `x` argument is required");return typeof e!="number"?Ln+(t+1)+"G":Ln+(e+1)+";"+(t+1)+"H"};An.cursorMove=(t,e)=>{if(typeof t!="number")throw new TypeError("The `x` argument is required");let r="";return t<0?r+=Ln+-t+"D":t>0&&(r+=Ln+t+"C"),e<0?r+=Ln+-e+"A":e>0&&(r+=Ln+e+"B"),r};An.cursorUp=(t=1)=>Ln+t+"A";An.cursorDown=(t=1)=>Ln+t+"B";An.cursorForward=(t=1)=>Ln+t+"C";An.cursorBackward=(t=1)=>Ln+t+"D";An.cursorLeft=Ln+"G";An.cursorSavePosition=zye?"\x1B7":Ln+"s";An.cursorRestorePosition=zye?"\x1B8":Ln+"u";An.cursorGetPosition=Ln+"6n";An.cursorNextLine=Ln+"E";An.cursorPrevLine=Ln+"F";An.cursorHide=Ln+"?25l";An.cursorShow=Ln+"?25h";An.eraseLines=t=>{let e="";for(let r=0;r<t;r++)e+=An.eraseLine+(r<t-1?An.cursorUp():"");return t&&(e+=An.cursorLeft),e};An.eraseEndLine=Ln+"K";An.eraseStartLine=Ln+"1K";An.eraseLine=Ln+"2K";An.eraseDown=Ln+"J";An.eraseUp=Ln+"1J";An.eraseScreen=Ln+"2J";An.scrollUp=Ln+"S";An.scrollDown=Ln+"T";An.clearScreen="\x1Bc";An.clearTerminal=process.platform==="win32"?`${An.eraseScreen}${Ln}0f`:`${An.eraseScreen}${Ln}3J${Ln}H`;An.beep=TC;An.link=(t,e)=>[eB,"8",Qk,Qk,e,TC,t,eB,"8",Qk,Qk,TC].join("");An.image=(t,e={})=>{let r=`${eB}1337;File=inline=1`;return e.width&&(r+=`;width=${e.width}`),e.height&&(r+=`;height=${e.height}`),e.preserveAspectRatio===!1&&(r+=";preserveAspectRatio=0"),r+":"+t.toString("base64")+TC};An.iTerm={setCwd:(t=process.cwd())=>`${eB}50;CurrentDir=${t}${TC}`,annotation:(t,e={})=>{let r=`${eB}1337;`,o=typeof e.x<"u",a=typeof e.y<"u";if((o||a)&&!(o&&a&&typeof e.length<"u"))throw new Error("`x`, `y` and `length` must be defined when `x` or `y` is defined");return t=t.replace(/\|/g,""),r+=e.isHidden?"AddHiddenAnnotation=":"AddAnnotation=",e.length>0?r+=(o?[t,e.length,e.x,e.y]:[e.length,t]).join("|"):r+=t,r+TC}}});var Zye=_((nVt,p6)=>{"use strict";var Xye=(t,e)=>{for(let r of Reflect.ownKeys(e))Object.defineProperty(t,r,Object.getOwnPropertyDescriptor(e,r));return t};p6.exports=Xye;p6.exports.default=Xye});var eEe=_((iVt,Tk)=>{"use strict";var Myt=Zye(),Fk=new WeakMap,$ye=(t,e={})=>{if(typeof t!="function")throw new TypeError("Expected a function");let r,o=0,a=t.displayName||t.name||"<anonymous>",n=function(...u){if(Fk.set(n,++o),o===1)r=t.apply(this,u),t=null;else if(e.throw===!0)throw new Error(`Function \`${a}\` can only be called once`);return r};return Myt(n,t),Fk.set(n,o),n};Tk.exports=$ye;Tk.exports.default=$ye;Tk.exports.callCount=t=>{if(!Fk.has(t))throw new Error(`The given function \`${t.name}\` is not wrapped by the \`onetime\` package`);return Fk.get(t)}});var tEe=_((sVt,Rk)=>{Rk.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"];process.platform!=="win32"&&Rk.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT");process.platform==="linux"&&Rk.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")});var d6=_((oVt,LC)=>{var Ei=global.process,nm=function(t){return t&&typeof t=="object"&&typeof t.removeListener=="function"&&typeof t.emit=="function"&&typeof t.reallyExit=="function"&&typeof t.listeners=="function"&&typeof t.kill=="function"&&typeof t.pid=="number"&&typeof t.on=="function"};nm(Ei)?(rEe=Be("assert"),RC=tEe(),nEe=/^win/i.test(Ei.platform),tB=Be("events"),typeof tB!="function"&&(tB=tB.EventEmitter),Ei.__signal_exit_emitter__?Rs=Ei.__signal_exit_emitter__:(Rs=Ei.__signal_exit_emitter__=new tB,Rs.count=0,Rs.emitted={}),Rs.infinite||(Rs.setMaxListeners(1/0),Rs.infinite=!0),LC.exports=function(t,e){if(!nm(global.process))return function(){};rEe.equal(typeof t,"function","a callback must be provided for exit handler"),NC===!1&&h6();var r="exit";e&&e.alwaysLast&&(r="afterexit");var o=function(){Rs.removeListener(r,t),Rs.listeners("exit").length===0&&Rs.listeners("afterexit").length===0&&Nk()};return Rs.on(r,t),o},Nk=function(){!NC||!nm(global.process)||(NC=!1,RC.forEach(function(e){try{Ei.removeListener(e,Lk[e])}catch{}}),Ei.emit=Mk,Ei.reallyExit=g6,Rs.count-=1)},LC.exports.unload=Nk,im=function(e,r,o){Rs.emitted[e]||(Rs.emitted[e]=!0,Rs.emit(e,r,o))},Lk={},RC.forEach(function(t){Lk[t]=function(){if(!!nm(global.process)){var r=Ei.listeners(t);r.length===Rs.count&&(Nk(),im("exit",null,t),im("afterexit",null,t),nEe&&t==="SIGHUP"&&(t="SIGINT"),Ei.kill(Ei.pid,t))}}}),LC.exports.signals=function(){return RC},NC=!1,h6=function(){NC||!nm(global.process)||(NC=!0,Rs.count+=1,RC=RC.filter(function(e){try{return Ei.on(e,Lk[e]),!0}catch{return!1}}),Ei.emit=sEe,Ei.reallyExit=iEe)},LC.exports.load=h6,g6=Ei.reallyExit,iEe=function(e){!nm(global.process)||(Ei.exitCode=e||0,im("exit",Ei.exitCode,null),im("afterexit",Ei.exitCode,null),g6.call(Ei,Ei.exitCode))},Mk=Ei.emit,sEe=function(e,r){if(e==="exit"&&nm(global.process)){r!==void 0&&(Ei.exitCode=r);var o=Mk.apply(this,arguments);return im("exit",Ei.exitCode,null),im("afterexit",Ei.exitCode,null),o}else return Mk.apply(this,arguments)}):LC.exports=function(){return function(){}};var rEe,RC,nEe,tB,Rs,Nk,im,Lk,NC,h6,g6,iEe,Mk,sEe});var aEe=_((aVt,oEe)=>{"use strict";var Oyt=eEe(),Uyt=d6();oEe.exports=Oyt(()=>{Uyt(()=>{process.stderr.write("\x1B[?25h")},{alwaysLast:!0})})});var m6=_(MC=>{"use strict";var _yt=aEe(),Ok=!1;MC.show=(t=process.stderr)=>{!t.isTTY||(Ok=!1,t.write("\x1B[?25h"))};MC.hide=(t=process.stderr)=>{!t.isTTY||(_yt(),Ok=!0,t.write("\x1B[?25l"))};MC.toggle=(t,e)=>{t!==void 0&&(Ok=t),Ok?MC.show(e):MC.hide(e)}});var AEe=_(rB=>{"use strict";var uEe=rB&&rB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(rB,"__esModule",{value:!0});var lEe=uEe(f6()),cEe=uEe(m6()),Hyt=(t,{showCursor:e=!1}={})=>{let r=0,o="",a=!1,n=u=>{!e&&!a&&(cEe.default.hide(),a=!0);let A=u+` +`;A!==o&&(o=A,t.write(lEe.default.eraseLines(r)+A),r=A.split(` +`).length)};return n.clear=()=>{t.write(lEe.default.eraseLines(r)),o="",r=0},n.done=()=>{o="",r=0,e||(cEe.default.show(),a=!1)},n};rB.default={create:Hyt}});var fEe=_((uVt,jyt)=>{jyt.exports=[{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"SYSTEM_TEAMFOUNDATIONCOLLECTIONURI",pr:"SYSTEM_PULLREQUEST_PULLREQUESTID"},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN"},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY_BUILD_BASE",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Shippable",constant:"SHIPPABLE",env:"SHIPPABLE",pr:{IS_PULL_REQUEST:"true"}},{name:"Solano CI",constant:"SOLANO",env:"TDDIUM",pr:"TDDIUM_PR_ID"},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}}]});var gEe=_(gl=>{"use strict";var hEe=fEe(),pA=process.env;Object.defineProperty(gl,"_vendors",{value:hEe.map(function(t){return t.constant})});gl.name=null;gl.isPR=null;hEe.forEach(function(t){var e=Array.isArray(t.env)?t.env:[t.env],r=e.every(function(o){return pEe(o)});if(gl[t.constant]=r,r)switch(gl.name=t.name,typeof t.pr){case"string":gl.isPR=!!pA[t.pr];break;case"object":"env"in t.pr?gl.isPR=t.pr.env in pA&&pA[t.pr.env]!==t.pr.ne:"any"in t.pr?gl.isPR=t.pr.any.some(function(o){return!!pA[o]}):gl.isPR=pEe(t.pr);break;default:gl.isPR=null}});gl.isCI=!!(pA.CI||pA.CONTINUOUS_INTEGRATION||pA.BUILD_NUMBER||pA.RUN_ID||gl.name);function pEe(t){return typeof t=="string"?!!pA[t]:Object.keys(t).every(function(e){return pA[e]===t[e]})}});var mEe=_((fVt,dEe)=>{"use strict";dEe.exports=gEe().isCI});var EEe=_((pVt,yEe)=>{"use strict";var qyt=t=>{let e=new Set;do for(let r of Reflect.ownKeys(t))e.add([t,r]);while((t=Reflect.getPrototypeOf(t))&&t!==Object.prototype);return e};yEe.exports=(t,{include:e,exclude:r}={})=>{let o=a=>{let n=u=>typeof u=="string"?a===u:u.test(a);return e?e.some(n):r?!r.some(n):!0};for(let[a,n]of qyt(t.constructor.prototype)){if(n==="constructor"||!o(n))continue;let u=Reflect.getOwnPropertyDescriptor(a,n);u&&typeof u.value=="function"&&(t[n]=t[n].bind(t))}return t}});var PEe=_(kn=>{"use strict";Object.defineProperty(kn,"__esModule",{value:!0});var UC,sB,qk,Gk,v6;typeof window>"u"||typeof MessageChannel!="function"?(OC=null,y6=null,E6=function(){if(OC!==null)try{var t=kn.unstable_now();OC(!0,t),OC=null}catch(e){throw setTimeout(E6,0),e}},CEe=Date.now(),kn.unstable_now=function(){return Date.now()-CEe},UC=function(t){OC!==null?setTimeout(UC,0,t):(OC=t,setTimeout(E6,0))},sB=function(t,e){y6=setTimeout(t,e)},qk=function(){clearTimeout(y6)},Gk=function(){return!1},v6=kn.unstable_forceFrameRate=function(){}):(Uk=window.performance,C6=window.Date,wEe=window.setTimeout,IEe=window.clearTimeout,typeof console<"u"&&(BEe=window.cancelAnimationFrame,typeof window.requestAnimationFrame!="function"&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),typeof BEe!="function"&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")),typeof Uk=="object"&&typeof Uk.now=="function"?kn.unstable_now=function(){return Uk.now()}:(vEe=C6.now(),kn.unstable_now=function(){return C6.now()-vEe}),nB=!1,iB=null,_k=-1,w6=5,I6=0,Gk=function(){return kn.unstable_now()>=I6},v6=function(){},kn.unstable_forceFrameRate=function(t){0>t||125<t?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):w6=0<t?Math.floor(1e3/t):5},B6=new MessageChannel,Hk=B6.port2,B6.port1.onmessage=function(){if(iB!==null){var t=kn.unstable_now();I6=t+w6;try{iB(!0,t)?Hk.postMessage(null):(nB=!1,iB=null)}catch(e){throw Hk.postMessage(null),e}}else nB=!1},UC=function(t){iB=t,nB||(nB=!0,Hk.postMessage(null))},sB=function(t,e){_k=wEe(function(){t(kn.unstable_now())},e)},qk=function(){IEe(_k),_k=-1});var OC,y6,E6,CEe,Uk,C6,wEe,IEe,BEe,vEe,nB,iB,_k,w6,I6,B6,Hk;function D6(t,e){var r=t.length;t.push(e);e:for(;;){var o=Math.floor((r-1)/2),a=t[o];if(a!==void 0&&0<jk(a,e))t[o]=e,t[r]=a,r=o;else break e}}function nc(t){return t=t[0],t===void 0?null:t}function Yk(t){var e=t[0];if(e!==void 0){var r=t.pop();if(r!==e){t[0]=r;e:for(var o=0,a=t.length;o<a;){var n=2*(o+1)-1,u=t[n],A=n+1,p=t[A];if(u!==void 0&&0>jk(u,r))p!==void 0&&0>jk(p,u)?(t[o]=p,t[A]=r,o=A):(t[o]=u,t[n]=r,o=n);else if(p!==void 0&&0>jk(p,r))t[o]=p,t[A]=r,o=A;else break e}}return e}return null}function jk(t,e){var r=t.sortIndex-e.sortIndex;return r!==0?r:t.id-e.id}var eu=[],m0=[],Gyt=1,na=null,Lo=3,Wk=!1,sm=!1,oB=!1;function Vk(t){for(var e=nc(m0);e!==null;){if(e.callback===null)Yk(m0);else if(e.startTime<=t)Yk(m0),e.sortIndex=e.expirationTime,D6(eu,e);else break;e=nc(m0)}}function P6(t){if(oB=!1,Vk(t),!sm)if(nc(eu)!==null)sm=!0,UC(S6);else{var e=nc(m0);e!==null&&sB(P6,e.startTime-t)}}function S6(t,e){sm=!1,oB&&(oB=!1,qk()),Wk=!0;var r=Lo;try{for(Vk(e),na=nc(eu);na!==null&&(!(na.expirationTime>e)||t&&!Gk());){var o=na.callback;if(o!==null){na.callback=null,Lo=na.priorityLevel;var a=o(na.expirationTime<=e);e=kn.unstable_now(),typeof a=="function"?na.callback=a:na===nc(eu)&&Yk(eu),Vk(e)}else Yk(eu);na=nc(eu)}if(na!==null)var n=!0;else{var u=nc(m0);u!==null&&sB(P6,u.startTime-e),n=!1}return n}finally{na=null,Lo=r,Wk=!1}}function DEe(t){switch(t){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var Yyt=v6;kn.unstable_ImmediatePriority=1;kn.unstable_UserBlockingPriority=2;kn.unstable_NormalPriority=3;kn.unstable_IdlePriority=5;kn.unstable_LowPriority=4;kn.unstable_runWithPriority=function(t,e){switch(t){case 1:case 2:case 3:case 4:case 5:break;default:t=3}var r=Lo;Lo=t;try{return e()}finally{Lo=r}};kn.unstable_next=function(t){switch(Lo){case 1:case 2:case 3:var e=3;break;default:e=Lo}var r=Lo;Lo=e;try{return t()}finally{Lo=r}};kn.unstable_scheduleCallback=function(t,e,r){var o=kn.unstable_now();if(typeof r=="object"&&r!==null){var a=r.delay;a=typeof a=="number"&&0<a?o+a:o,r=typeof r.timeout=="number"?r.timeout:DEe(t)}else r=DEe(t),a=o;return r=a+r,t={id:Gyt++,callback:e,priorityLevel:t,startTime:a,expirationTime:r,sortIndex:-1},a>o?(t.sortIndex=a,D6(m0,t),nc(eu)===null&&t===nc(m0)&&(oB?qk():oB=!0,sB(P6,a-o))):(t.sortIndex=r,D6(eu,t),sm||Wk||(sm=!0,UC(S6))),t};kn.unstable_cancelCallback=function(t){t.callback=null};kn.unstable_wrapCallback=function(t){var e=Lo;return function(){var r=Lo;Lo=e;try{return t.apply(this,arguments)}finally{Lo=r}}};kn.unstable_getCurrentPriorityLevel=function(){return Lo};kn.unstable_shouldYield=function(){var t=kn.unstable_now();Vk(t);var e=nc(eu);return e!==na&&na!==null&&e!==null&&e.callback!==null&&e.startTime<=t&&e.expirationTime<na.expirationTime||Gk()};kn.unstable_requestPaint=Yyt;kn.unstable_continueExecution=function(){sm||Wk||(sm=!0,UC(S6))};kn.unstable_pauseExecution=function(){};kn.unstable_getFirstCallbackNode=function(){return nc(eu)};kn.unstable_Profiling=null});var x6=_((gVt,SEe)=>{"use strict";SEe.exports=PEe()});var xEe=_((dVt,aB)=>{aB.exports=function t(e){"use strict";var r=t6(),o=sn(),a=x6();function n(P){for(var D="https://reactjs.org/docs/error-decoder.html?invariant="+P,R=1;R<arguments.length;R++)D+="&args[]="+encodeURIComponent(arguments[R]);return"Minified React error #"+P+"; visit "+D+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var u=o.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;u.hasOwnProperty("ReactCurrentDispatcher")||(u.ReactCurrentDispatcher={current:null}),u.hasOwnProperty("ReactCurrentBatchConfig")||(u.ReactCurrentBatchConfig={suspense:null});var A=typeof Symbol=="function"&&Symbol.for,p=A?Symbol.for("react.element"):60103,h=A?Symbol.for("react.portal"):60106,E=A?Symbol.for("react.fragment"):60107,I=A?Symbol.for("react.strict_mode"):60108,v=A?Symbol.for("react.profiler"):60114,b=A?Symbol.for("react.provider"):60109,C=A?Symbol.for("react.context"):60110,T=A?Symbol.for("react.concurrent_mode"):60111,L=A?Symbol.for("react.forward_ref"):60112,U=A?Symbol.for("react.suspense"):60113,J=A?Symbol.for("react.suspense_list"):60120,te=A?Symbol.for("react.memo"):60115,le=A?Symbol.for("react.lazy"):60116;A&&Symbol.for("react.fundamental"),A&&Symbol.for("react.responder"),A&&Symbol.for("react.scope");var pe=typeof Symbol=="function"&&Symbol.iterator;function Ae(P){return P===null||typeof P!="object"?null:(P=pe&&P[pe]||P["@@iterator"],typeof P=="function"?P:null)}function ye(P){if(P._status===-1){P._status=0;var D=P._ctor;D=D(),P._result=D,D.then(function(R){P._status===0&&(R=R.default,P._status=1,P._result=R)},function(R){P._status===0&&(P._status=2,P._result=R)})}}function ae(P){if(P==null)return null;if(typeof P=="function")return P.displayName||P.name||null;if(typeof P=="string")return P;switch(P){case E:return"Fragment";case h:return"Portal";case v:return"Profiler";case I:return"StrictMode";case U:return"Suspense";case J:return"SuspenseList"}if(typeof P=="object")switch(P.$$typeof){case C:return"Context.Consumer";case b:return"Context.Provider";case L:var D=P.render;return D=D.displayName||D.name||"",P.displayName||(D!==""?"ForwardRef("+D+")":"ForwardRef");case te:return ae(P.type);case le:if(P=P._status===1?P._result:null)return ae(P)}return null}function we(P){var D=P,R=P;if(P.alternate)for(;D.return;)D=D.return;else{P=D;do D=P,(D.effectTag&1026)!==0&&(R=D.return),P=D.return;while(P)}return D.tag===3?R:null}function Pe(P){if(we(P)!==P)throw Error(n(188))}function g(P){var D=P.alternate;if(!D){if(D=we(P),D===null)throw Error(n(188));return D!==P?null:P}for(var R=P,j=D;;){var Y=R.return;if(Y===null)break;var fe=Y.alternate;if(fe===null){if(j=Y.return,j!==null){R=j;continue}break}if(Y.child===fe.child){for(fe=Y.child;fe;){if(fe===R)return Pe(Y),P;if(fe===j)return Pe(Y),D;fe=fe.sibling}throw Error(n(188))}if(R.return!==j.return)R=Y,j=fe;else{for(var ve=!1,vt=Y.child;vt;){if(vt===R){ve=!0,R=Y,j=fe;break}if(vt===j){ve=!0,j=Y,R=fe;break}vt=vt.sibling}if(!ve){for(vt=fe.child;vt;){if(vt===R){ve=!0,R=fe,j=Y;break}if(vt===j){ve=!0,j=fe,R=Y;break}vt=vt.sibling}if(!ve)throw Error(n(189))}}if(R.alternate!==j)throw Error(n(190))}if(R.tag!==3)throw Error(n(188));return R.stateNode.current===R?P:D}function Ee(P){if(P=g(P),!P)return null;for(var D=P;;){if(D.tag===5||D.tag===6)return D;if(D.child)D.child.return=D,D=D.child;else{if(D===P)break;for(;!D.sibling;){if(!D.return||D.return===P)return null;D=D.return}D.sibling.return=D.return,D=D.sibling}}return null}function De(P){if(P=g(P),!P)return null;for(var D=P;;){if(D.tag===5||D.tag===6)return D;if(D.child&&D.tag!==4)D.child.return=D,D=D.child;else{if(D===P)break;for(;!D.sibling;){if(!D.return||D.return===P)return null;D=D.return}D.sibling.return=D.return,D=D.sibling}}return null}var ce=e.getPublicInstance,ne=e.getRootHostContext,ee=e.getChildHostContext,Ie=e.prepareForCommit,ke=e.resetAfterCommit,ht=e.createInstance,H=e.appendInitialChild,lt=e.finalizeInitialChildren,Re=e.prepareUpdate,Qe=e.shouldSetTextContent,be=e.shouldDeprioritizeSubtree,_e=e.createTextInstance,Te=e.setTimeout,Je=e.clearTimeout,He=e.noTimeout,x=e.isPrimaryRenderer,w=e.supportsMutation,S=e.supportsPersistence,y=e.supportsHydration,F=e.appendChild,z=e.appendChildToContainer,X=e.commitTextUpdate,Z=e.commitMount,ie=e.commitUpdate,Se=e.insertBefore,Ne=e.insertInContainerBefore,ot=e.removeChild,dt=e.removeChildFromContainer,jt=e.resetTextContent,$t=e.hideInstance,xt=e.hideTextInstance,an=e.unhideInstance,Qr=e.unhideTextInstance,mr=e.cloneInstance,xr=e.createContainerChildSet,Wr=e.appendChildToContainerChildSet,Vn=e.finalizeContainerChildren,Ns=e.replaceContainerChildren,Ri=e.cloneHiddenInstance,ps=e.cloneHiddenTextInstance,io=e.canHydrateInstance,Si=e.canHydrateTextInstance,Ls=e.isSuspenseInstancePending,so=e.isSuspenseInstanceFallback,cc=e.getNextHydratableSibling,cu=e.getFirstHydratableChild,ap=e.hydrateInstance,lp=e.hydrateTextInstance,Ms=e.getNextHydratableInstanceAfterSuspenseInstance,Dn=e.commitHydratedContainer,oo=e.commitHydratedSuspenseInstance,Os=/^(.*)[\\\/]/;function ml(P){var D="";do{e:switch(P.tag){case 3:case 4:case 6:case 7:case 10:case 9:var R="";break e;default:var j=P._debugOwner,Y=P._debugSource,fe=ae(P.type);R=null,j&&(R=ae(j.type)),j=fe,fe="",Y?fe=" (at "+Y.fileName.replace(Os,"")+":"+Y.lineNumber+")":R&&(fe=" (created by "+R+")"),R=` + in `+(j||"Unknown")+fe}D+=R,P=P.return}while(P);return D}var yl=[],ao=-1;function Kn(P){0>ao||(P.current=yl[ao],yl[ao]=null,ao--)}function Mn(P,D){ao++,yl[ao]=P.current,P.current=D}var Ni={},On={current:Ni},_i={current:!1},tr=Ni;function Me(P,D){var R=P.type.contextTypes;if(!R)return Ni;var j=P.stateNode;if(j&&j.__reactInternalMemoizedUnmaskedChildContext===D)return j.__reactInternalMemoizedMaskedChildContext;var Y={},fe;for(fe in R)Y[fe]=D[fe];return j&&(P=P.stateNode,P.__reactInternalMemoizedUnmaskedChildContext=D,P.__reactInternalMemoizedMaskedChildContext=Y),Y}function ii(P){return P=P.childContextTypes,P!=null}function Oa(P){Kn(_i,P),Kn(On,P)}function hr(P){Kn(_i,P),Kn(On,P)}function uc(P,D,R){if(On.current!==Ni)throw Error(n(168));Mn(On,D,P),Mn(_i,R,P)}function uu(P,D,R){var j=P.stateNode;if(P=D.childContextTypes,typeof j.getChildContext!="function")return R;j=j.getChildContext();for(var Y in j)if(!(Y in P))throw Error(n(108,ae(D)||"Unknown",Y));return r({},R,{},j)}function Ac(P){var D=P.stateNode;return D=D&&D.__reactInternalMemoizedMergedChildContext||Ni,tr=On.current,Mn(On,D,P),Mn(_i,_i.current,P),!0}function El(P,D,R){var j=P.stateNode;if(!j)throw Error(n(169));R?(D=uu(P,D,tr),j.__reactInternalMemoizedMergedChildContext=D,Kn(_i,P),Kn(On,P),Mn(On,D,P)):Kn(_i,P),Mn(_i,R,P)}var vA=a.unstable_runWithPriority,Au=a.unstable_scheduleCallback,Ce=a.unstable_cancelCallback,Tt=a.unstable_shouldYield,fc=a.unstable_requestPaint,Hi=a.unstable_now,fu=a.unstable_getCurrentPriorityLevel,Yt=a.unstable_ImmediatePriority,Cl=a.unstable_UserBlockingPriority,DA=a.unstable_NormalPriority,cp=a.unstable_LowPriority,pc=a.unstable_IdlePriority,PA={},Qn=fc!==void 0?fc:function(){},hi=null,hc=null,SA=!1,sa=Hi(),Li=1e4>sa?Hi:function(){return Hi()-sa};function _o(){switch(fu()){case Yt:return 99;case Cl:return 98;case DA:return 97;case cp:return 96;case pc:return 95;default:throw Error(n(332))}}function Ze(P){switch(P){case 99:return Yt;case 98:return Cl;case 97:return DA;case 96:return cp;case 95:return pc;default:throw Error(n(332))}}function lo(P,D){return P=Ze(P),vA(P,D)}function gc(P,D,R){return P=Ze(P),Au(P,D,R)}function pu(P){return hi===null?(hi=[P],hc=Au(Yt,hu)):hi.push(P),PA}function ji(){if(hc!==null){var P=hc;hc=null,Ce(P)}hu()}function hu(){if(!SA&&hi!==null){SA=!0;var P=0;try{var D=hi;lo(99,function(){for(;P<D.length;P++){var R=D[P];do R=R(!0);while(R!==null)}}),hi=null}catch(R){throw hi!==null&&(hi=hi.slice(P+1)),Au(Yt,ji),R}finally{SA=!1}}}var xA=3;function Ua(P,D,R){return R/=10,1073741821-(((1073741821-P+D/10)/R|0)+1)*R}function dc(P,D){return P===D&&(P!==0||1/P===1/D)||P!==P&&D!==D}var hs=typeof Object.is=="function"?Object.is:dc,_t=Object.prototype.hasOwnProperty;function Fn(P,D){if(hs(P,D))return!0;if(typeof P!="object"||P===null||typeof D!="object"||D===null)return!1;var R=Object.keys(P),j=Object.keys(D);if(R.length!==j.length)return!1;for(j=0;j<R.length;j++)if(!_t.call(D,R[j])||!hs(P[R[j]],D[R[j]]))return!1;return!0}function Ci(P,D){if(P&&P.defaultProps){D=r({},D),P=P.defaultProps;for(var R in P)D[R]===void 0&&(D[R]=P[R])}return D}var oa={current:null},co=null,Us=null,aa=null;function la(){aa=Us=co=null}function Ho(P,D){var R=P.type._context;x?(Mn(oa,R._currentValue,P),R._currentValue=D):(Mn(oa,R._currentValue2,P),R._currentValue2=D)}function wi(P){var D=oa.current;Kn(oa,P),P=P.type._context,x?P._currentValue=D:P._currentValue2=D}function gs(P,D){for(;P!==null;){var R=P.alternate;if(P.childExpirationTime<D)P.childExpirationTime=D,R!==null&&R.childExpirationTime<D&&(R.childExpirationTime=D);else if(R!==null&&R.childExpirationTime<D)R.childExpirationTime=D;else break;P=P.return}}function ds(P,D){co=P,aa=Us=null,P=P.dependencies,P!==null&&P.firstContext!==null&&(P.expirationTime>=D&&(qo=!0),P.firstContext=null)}function ms(P,D){if(aa!==P&&D!==!1&&D!==0)if((typeof D!="number"||D===1073741823)&&(aa=P,D=1073741823),D={context:P,observedBits:D,next:null},Us===null){if(co===null)throw Error(n(308));Us=D,co.dependencies={expirationTime:0,firstContext:D,responders:null}}else Us=Us.next=D;return x?P._currentValue:P._currentValue2}var _s=!1;function Un(P){return{baseState:P,firstUpdate:null,lastUpdate:null,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function Pn(P){return{baseState:P.baseState,firstUpdate:P.firstUpdate,lastUpdate:P.lastUpdate,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function ys(P,D){return{expirationTime:P,suspenseConfig:D,tag:0,payload:null,callback:null,next:null,nextEffect:null}}function We(P,D){P.lastUpdate===null?P.firstUpdate=P.lastUpdate=D:(P.lastUpdate.next=D,P.lastUpdate=D)}function tt(P,D){var R=P.alternate;if(R===null){var j=P.updateQueue,Y=null;j===null&&(j=P.updateQueue=Un(P.memoizedState))}else j=P.updateQueue,Y=R.updateQueue,j===null?Y===null?(j=P.updateQueue=Un(P.memoizedState),Y=R.updateQueue=Un(R.memoizedState)):j=P.updateQueue=Pn(Y):Y===null&&(Y=R.updateQueue=Pn(j));Y===null||j===Y?We(j,D):j.lastUpdate===null||Y.lastUpdate===null?(We(j,D),We(Y,D)):(We(j,D),Y.lastUpdate=D)}function It(P,D){var R=P.updateQueue;R=R===null?P.updateQueue=Un(P.memoizedState):nr(P,R),R.lastCapturedUpdate===null?R.firstCapturedUpdate=R.lastCapturedUpdate=D:(R.lastCapturedUpdate.next=D,R.lastCapturedUpdate=D)}function nr(P,D){var R=P.alternate;return R!==null&&D===R.updateQueue&&(D=P.updateQueue=Pn(D)),D}function $(P,D,R,j,Y,fe){switch(R.tag){case 1:return P=R.payload,typeof P=="function"?P.call(fe,j,Y):P;case 3:P.effectTag=P.effectTag&-4097|64;case 0:if(P=R.payload,Y=typeof P=="function"?P.call(fe,j,Y):P,Y==null)break;return r({},j,Y);case 2:_s=!0}return j}function me(P,D,R,j,Y){_s=!1,D=nr(P,D);for(var fe=D.baseState,ve=null,vt=0,wt=D.firstUpdate,bt=fe;wt!==null;){var _r=wt.expirationTime;_r<Y?(ve===null&&(ve=wt,fe=bt),vt<_r&&(vt=_r)):(Pw(_r,wt.suspenseConfig),bt=$(P,D,wt,bt,R,j),wt.callback!==null&&(P.effectTag|=32,wt.nextEffect=null,D.lastEffect===null?D.firstEffect=D.lastEffect=wt:(D.lastEffect.nextEffect=wt,D.lastEffect=wt))),wt=wt.next}for(_r=null,wt=D.firstCapturedUpdate;wt!==null;){var is=wt.expirationTime;is<Y?(_r===null&&(_r=wt,ve===null&&(fe=bt)),vt<is&&(vt=is)):(bt=$(P,D,wt,bt,R,j),wt.callback!==null&&(P.effectTag|=32,wt.nextEffect=null,D.lastCapturedEffect===null?D.firstCapturedEffect=D.lastCapturedEffect=wt:(D.lastCapturedEffect.nextEffect=wt,D.lastCapturedEffect=wt))),wt=wt.next}ve===null&&(D.lastUpdate=null),_r===null?D.lastCapturedUpdate=null:P.effectTag|=32,ve===null&&_r===null&&(fe=bt),D.baseState=fe,D.firstUpdate=ve,D.firstCapturedUpdate=_r,_m(vt),P.expirationTime=vt,P.memoizedState=bt}function Le(P,D,R){D.firstCapturedUpdate!==null&&(D.lastUpdate!==null&&(D.lastUpdate.next=D.firstCapturedUpdate,D.lastUpdate=D.lastCapturedUpdate),D.firstCapturedUpdate=D.lastCapturedUpdate=null),ft(D.firstEffect,R),D.firstEffect=D.lastEffect=null,ft(D.firstCapturedEffect,R),D.firstCapturedEffect=D.lastCapturedEffect=null}function ft(P,D){for(;P!==null;){var R=P.callback;if(R!==null){P.callback=null;var j=D;if(typeof R!="function")throw Error(n(191,R));R.call(j)}P=P.nextEffect}}var pt=u.ReactCurrentBatchConfig,Rt=new o.Component().refs;function er(P,D,R,j){D=P.memoizedState,R=R(j,D),R=R==null?D:r({},D,R),P.memoizedState=R,j=P.updateQueue,j!==null&&P.expirationTime===0&&(j.baseState=R)}var Zr={isMounted:function(P){return(P=P._reactInternalFiber)?we(P)===P:!1},enqueueSetState:function(P,D,R){P=P._reactInternalFiber;var j=ga(),Y=pt.suspense;j=HA(j,P,Y),Y=ys(j,Y),Y.payload=D,R!=null&&(Y.callback=R),tt(P,Y),Sc(P,j)},enqueueReplaceState:function(P,D,R){P=P._reactInternalFiber;var j=ga(),Y=pt.suspense;j=HA(j,P,Y),Y=ys(j,Y),Y.tag=1,Y.payload=D,R!=null&&(Y.callback=R),tt(P,Y),Sc(P,j)},enqueueForceUpdate:function(P,D){P=P._reactInternalFiber;var R=ga(),j=pt.suspense;R=HA(R,P,j),j=ys(R,j),j.tag=2,D!=null&&(j.callback=D),tt(P,j),Sc(P,R)}};function qi(P,D,R,j,Y,fe,ve){return P=P.stateNode,typeof P.shouldComponentUpdate=="function"?P.shouldComponentUpdate(j,fe,ve):D.prototype&&D.prototype.isPureReactComponent?!Fn(R,j)||!Fn(Y,fe):!0}function es(P,D,R){var j=!1,Y=Ni,fe=D.contextType;return typeof fe=="object"&&fe!==null?fe=ms(fe):(Y=ii(D)?tr:On.current,j=D.contextTypes,fe=(j=j!=null)?Me(P,Y):Ni),D=new D(R,fe),P.memoizedState=D.state!==null&&D.state!==void 0?D.state:null,D.updater=Zr,P.stateNode=D,D._reactInternalFiber=P,j&&(P=P.stateNode,P.__reactInternalMemoizedUnmaskedChildContext=Y,P.__reactInternalMemoizedMaskedChildContext=fe),D}function xi(P,D,R,j){P=D.state,typeof D.componentWillReceiveProps=="function"&&D.componentWillReceiveProps(R,j),typeof D.UNSAFE_componentWillReceiveProps=="function"&&D.UNSAFE_componentWillReceiveProps(R,j),D.state!==P&&Zr.enqueueReplaceState(D,D.state,null)}function jo(P,D,R,j){var Y=P.stateNode;Y.props=R,Y.state=P.memoizedState,Y.refs=Rt;var fe=D.contextType;typeof fe=="object"&&fe!==null?Y.context=ms(fe):(fe=ii(D)?tr:On.current,Y.context=Me(P,fe)),fe=P.updateQueue,fe!==null&&(me(P,fe,R,Y,j),Y.state=P.memoizedState),fe=D.getDerivedStateFromProps,typeof fe=="function"&&(er(P,D,fe,R),Y.state=P.memoizedState),typeof D.getDerivedStateFromProps=="function"||typeof Y.getSnapshotBeforeUpdate=="function"||typeof Y.UNSAFE_componentWillMount!="function"&&typeof Y.componentWillMount!="function"||(D=Y.state,typeof Y.componentWillMount=="function"&&Y.componentWillMount(),typeof Y.UNSAFE_componentWillMount=="function"&&Y.UNSAFE_componentWillMount(),D!==Y.state&&Zr.enqueueReplaceState(Y,Y.state,null),fe=P.updateQueue,fe!==null&&(me(P,fe,R,Y,j),Y.state=P.memoizedState)),typeof Y.componentDidMount=="function"&&(P.effectTag|=4)}var bA=Array.isArray;function kA(P,D,R){if(P=R.ref,P!==null&&typeof P!="function"&&typeof P!="object"){if(R._owner){if(R=R._owner,R){if(R.tag!==1)throw Error(n(309));var j=R.stateNode}if(!j)throw Error(n(147,P));var Y=""+P;return D!==null&&D.ref!==null&&typeof D.ref=="function"&&D.ref._stringRef===Y?D.ref:(D=function(fe){var ve=j.refs;ve===Rt&&(ve=j.refs={}),fe===null?delete ve[Y]:ve[Y]=fe},D._stringRef=Y,D)}if(typeof P!="string")throw Error(n(284));if(!R._owner)throw Error(n(290,P))}return P}function up(P,D){if(P.type!=="textarea")throw Error(n(31,Object.prototype.toString.call(D)==="[object Object]"?"object with keys {"+Object.keys(D).join(", ")+"}":D,""))}function ng(P){function D(rt,Ke){if(P){var At=rt.lastEffect;At!==null?(At.nextEffect=Ke,rt.lastEffect=Ke):rt.firstEffect=rt.lastEffect=Ke,Ke.nextEffect=null,Ke.effectTag=8}}function R(rt,Ke){if(!P)return null;for(;Ke!==null;)D(rt,Ke),Ke=Ke.sibling;return null}function j(rt,Ke){for(rt=new Map;Ke!==null;)Ke.key!==null?rt.set(Ke.key,Ke):rt.set(Ke.index,Ke),Ke=Ke.sibling;return rt}function Y(rt,Ke,At){return rt=YA(rt,Ke,At),rt.index=0,rt.sibling=null,rt}function fe(rt,Ke,At){return rt.index=At,P?(At=rt.alternate,At!==null?(At=At.index,At<Ke?(rt.effectTag=2,Ke):At):(rt.effectTag=2,Ke)):Ke}function ve(rt){return P&&rt.alternate===null&&(rt.effectTag=2),rt}function vt(rt,Ke,At,Wt){return Ke===null||Ke.tag!==6?(Ke=Qw(At,rt.mode,Wt),Ke.return=rt,Ke):(Ke=Y(Ke,At,Wt),Ke.return=rt,Ke)}function wt(rt,Ke,At,Wt){return Ke!==null&&Ke.elementType===At.type?(Wt=Y(Ke,At.props,Wt),Wt.ref=kA(rt,Ke,At),Wt.return=rt,Wt):(Wt=Hm(At.type,At.key,At.props,null,rt.mode,Wt),Wt.ref=kA(rt,Ke,At),Wt.return=rt,Wt)}function bt(rt,Ke,At,Wt){return Ke===null||Ke.tag!==4||Ke.stateNode.containerInfo!==At.containerInfo||Ke.stateNode.implementation!==At.implementation?(Ke=Fw(At,rt.mode,Wt),Ke.return=rt,Ke):(Ke=Y(Ke,At.children||[],Wt),Ke.return=rt,Ke)}function _r(rt,Ke,At,Wt,vr){return Ke===null||Ke.tag!==7?(Ke=xu(At,rt.mode,Wt,vr),Ke.return=rt,Ke):(Ke=Y(Ke,At,Wt),Ke.return=rt,Ke)}function is(rt,Ke,At){if(typeof Ke=="string"||typeof Ke=="number")return Ke=Qw(""+Ke,rt.mode,At),Ke.return=rt,Ke;if(typeof Ke=="object"&&Ke!==null){switch(Ke.$$typeof){case p:return At=Hm(Ke.type,Ke.key,Ke.props,null,rt.mode,At),At.ref=kA(rt,null,Ke),At.return=rt,At;case h:return Ke=Fw(Ke,rt.mode,At),Ke.return=rt,Ke}if(bA(Ke)||Ae(Ke))return Ke=xu(Ke,rt.mode,At,null),Ke.return=rt,Ke;up(rt,Ke)}return null}function di(rt,Ke,At,Wt){var vr=Ke!==null?Ke.key:null;if(typeof At=="string"||typeof At=="number")return vr!==null?null:vt(rt,Ke,""+At,Wt);if(typeof At=="object"&&At!==null){switch(At.$$typeof){case p:return At.key===vr?At.type===E?_r(rt,Ke,At.props.children,Wt,vr):wt(rt,Ke,At,Wt):null;case h:return At.key===vr?bt(rt,Ke,At,Wt):null}if(bA(At)||Ae(At))return vr!==null?null:_r(rt,Ke,At,Wt,null);up(rt,At)}return null}function po(rt,Ke,At,Wt,vr){if(typeof Wt=="string"||typeof Wt=="number")return rt=rt.get(At)||null,vt(Ke,rt,""+Wt,vr);if(typeof Wt=="object"&&Wt!==null){switch(Wt.$$typeof){case p:return rt=rt.get(Wt.key===null?At:Wt.key)||null,Wt.type===E?_r(Ke,rt,Wt.props.children,vr,Wt.key):wt(Ke,rt,Wt,vr);case h:return rt=rt.get(Wt.key===null?At:Wt.key)||null,bt(Ke,rt,Wt,vr)}if(bA(Wt)||Ae(Wt))return rt=rt.get(At)||null,_r(Ke,rt,Wt,vr,null);up(Ke,Wt)}return null}function VA(rt,Ke,At,Wt){for(var vr=null,Sn=null,Fr=Ke,xn=Ke=0,ai=null;Fr!==null&&xn<At.length;xn++){Fr.index>xn?(ai=Fr,Fr=null):ai=Fr.sibling;var en=di(rt,Fr,At[xn],Wt);if(en===null){Fr===null&&(Fr=ai);break}P&&Fr&&en.alternate===null&&D(rt,Fr),Ke=fe(en,Ke,xn),Sn===null?vr=en:Sn.sibling=en,Sn=en,Fr=ai}if(xn===At.length)return R(rt,Fr),vr;if(Fr===null){for(;xn<At.length;xn++)Fr=is(rt,At[xn],Wt),Fr!==null&&(Ke=fe(Fr,Ke,xn),Sn===null?vr=Fr:Sn.sibling=Fr,Sn=Fr);return vr}for(Fr=j(rt,Fr);xn<At.length;xn++)ai=po(Fr,rt,xn,At[xn],Wt),ai!==null&&(P&&ai.alternate!==null&&Fr.delete(ai.key===null?xn:ai.key),Ke=fe(ai,Ke,xn),Sn===null?vr=ai:Sn.sibling=ai,Sn=ai);return P&&Fr.forEach(function(ho){return D(rt,ho)}),vr}function Yo(rt,Ke,At,Wt){var vr=Ae(At);if(typeof vr!="function")throw Error(n(150));if(At=vr.call(At),At==null)throw Error(n(151));for(var Sn=vr=null,Fr=Ke,xn=Ke=0,ai=null,en=At.next();Fr!==null&&!en.done;xn++,en=At.next()){Fr.index>xn?(ai=Fr,Fr=null):ai=Fr.sibling;var ho=di(rt,Fr,en.value,Wt);if(ho===null){Fr===null&&(Fr=ai);break}P&&Fr&&ho.alternate===null&&D(rt,Fr),Ke=fe(ho,Ke,xn),Sn===null?vr=ho:Sn.sibling=ho,Sn=ho,Fr=ai}if(en.done)return R(rt,Fr),vr;if(Fr===null){for(;!en.done;xn++,en=At.next())en=is(rt,en.value,Wt),en!==null&&(Ke=fe(en,Ke,xn),Sn===null?vr=en:Sn.sibling=en,Sn=en);return vr}for(Fr=j(rt,Fr);!en.done;xn++,en=At.next())en=po(Fr,rt,xn,en.value,Wt),en!==null&&(P&&en.alternate!==null&&Fr.delete(en.key===null?xn:en.key),Ke=fe(en,Ke,xn),Sn===null?vr=en:Sn.sibling=en,Sn=en);return P&&Fr.forEach(function(PF){return D(rt,PF)}),vr}return function(rt,Ke,At,Wt){var vr=typeof At=="object"&&At!==null&&At.type===E&&At.key===null;vr&&(At=At.props.children);var Sn=typeof At=="object"&&At!==null;if(Sn)switch(At.$$typeof){case p:e:{for(Sn=At.key,vr=Ke;vr!==null;){if(vr.key===Sn)if(vr.tag===7?At.type===E:vr.elementType===At.type){R(rt,vr.sibling),Ke=Y(vr,At.type===E?At.props.children:At.props,Wt),Ke.ref=kA(rt,vr,At),Ke.return=rt,rt=Ke;break e}else{R(rt,vr);break}else D(rt,vr);vr=vr.sibling}At.type===E?(Ke=xu(At.props.children,rt.mode,Wt,At.key),Ke.return=rt,rt=Ke):(Wt=Hm(At.type,At.key,At.props,null,rt.mode,Wt),Wt.ref=kA(rt,Ke,At),Wt.return=rt,rt=Wt)}return ve(rt);case h:e:{for(vr=At.key;Ke!==null;){if(Ke.key===vr)if(Ke.tag===4&&Ke.stateNode.containerInfo===At.containerInfo&&Ke.stateNode.implementation===At.implementation){R(rt,Ke.sibling),Ke=Y(Ke,At.children||[],Wt),Ke.return=rt,rt=Ke;break e}else{R(rt,Ke);break}else D(rt,Ke);Ke=Ke.sibling}Ke=Fw(At,rt.mode,Wt),Ke.return=rt,rt=Ke}return ve(rt)}if(typeof At=="string"||typeof At=="number")return At=""+At,Ke!==null&&Ke.tag===6?(R(rt,Ke.sibling),Ke=Y(Ke,At,Wt),Ke.return=rt,rt=Ke):(R(rt,Ke),Ke=Qw(At,rt.mode,Wt),Ke.return=rt,rt=Ke),ve(rt);if(bA(At))return VA(rt,Ke,At,Wt);if(Ae(At))return Yo(rt,Ke,At,Wt);if(Sn&&up(rt,At),typeof At>"u"&&!vr)switch(rt.tag){case 1:case 0:throw rt=rt.type,Error(n(152,rt.displayName||rt.name||"Component"))}return R(rt,Ke)}}var gu=ng(!0),ig=ng(!1),du={},uo={current:du},QA={current:du},mc={current:du};function ca(P){if(P===du)throw Error(n(174));return P}function sg(P,D){Mn(mc,D,P),Mn(QA,P,P),Mn(uo,du,P),D=ne(D),Kn(uo,P),Mn(uo,D,P)}function yc(P){Kn(uo,P),Kn(QA,P),Kn(mc,P)}function Pm(P){var D=ca(mc.current),R=ca(uo.current);D=ee(R,P.type,D),R!==D&&(Mn(QA,P,P),Mn(uo,D,P))}function og(P){QA.current===P&&(Kn(uo,P),Kn(QA,P))}var $n={current:0};function Ap(P){for(var D=P;D!==null;){if(D.tag===13){var R=D.memoizedState;if(R!==null&&(R=R.dehydrated,R===null||Ls(R)||so(R)))return D}else if(D.tag===19&&D.memoizedProps.revealOrder!==void 0){if((D.effectTag&64)!==0)return D}else if(D.child!==null){D.child.return=D,D=D.child;continue}if(D===P)break;for(;D.sibling===null;){if(D.return===null||D.return===P)return null;D=D.return}D.sibling.return=D.return,D=D.sibling}return null}function ag(P,D){return{responder:P,props:D}}var FA=u.ReactCurrentDispatcher,Hs=u.ReactCurrentBatchConfig,mu=0,Ha=null,Gi=null,ua=null,yu=null,Es=null,Ec=null,Cc=0,G=null,Dt=0,wl=!1,bi=null,wc=0;function ct(){throw Error(n(321))}function Eu(P,D){if(D===null)return!1;for(var R=0;R<D.length&&R<P.length;R++)if(!hs(P[R],D[R]))return!1;return!0}function lg(P,D,R,j,Y,fe){if(mu=fe,Ha=D,ua=P!==null?P.memoizedState:null,FA.current=ua===null?yw:bm,D=R(j,Y),wl){do wl=!1,wc+=1,ua=P!==null?P.memoizedState:null,Ec=yu,G=Es=Gi=null,FA.current=bm,D=R(j,Y);while(wl);bi=null,wc=0}if(FA.current=wu,P=Ha,P.memoizedState=yu,P.expirationTime=Cc,P.updateQueue=G,P.effectTag|=Dt,P=Gi!==null&&Gi.next!==null,mu=0,Ec=Es=yu=ua=Gi=Ha=null,Cc=0,G=null,Dt=0,P)throw Error(n(300));return D}function mw(){FA.current=wu,mu=0,Ec=Es=yu=ua=Gi=Ha=null,Cc=0,G=null,Dt=0,wl=!1,bi=null,wc=0}function TA(){var P={memoizedState:null,baseState:null,queue:null,baseUpdate:null,next:null};return Es===null?yu=Es=P:Es=Es.next=P,Es}function fp(){if(Ec!==null)Es=Ec,Ec=Es.next,Gi=ua,ua=Gi!==null?Gi.next:null;else{if(ua===null)throw Error(n(310));Gi=ua;var P={memoizedState:Gi.memoizedState,baseState:Gi.baseState,queue:Gi.queue,baseUpdate:Gi.baseUpdate,next:null};Es=Es===null?yu=P:Es.next=P,ua=Gi.next}return Es}function Br(P,D){return typeof D=="function"?D(P):D}function Cs(P){var D=fp(),R=D.queue;if(R===null)throw Error(n(311));if(R.lastRenderedReducer=P,0<wc){var j=R.dispatch;if(bi!==null){var Y=bi.get(R);if(Y!==void 0){bi.delete(R);var fe=D.memoizedState;do fe=P(fe,Y.action),Y=Y.next;while(Y!==null);return hs(fe,D.memoizedState)||(qo=!0),D.memoizedState=fe,D.baseUpdate===R.last&&(D.baseState=fe),R.lastRenderedState=fe,[fe,j]}}return[D.memoizedState,j]}j=R.last;var ve=D.baseUpdate;if(fe=D.baseState,ve!==null?(j!==null&&(j.next=null),j=ve.next):j=j!==null?j.next:null,j!==null){var vt=Y=null,wt=j,bt=!1;do{var _r=wt.expirationTime;_r<mu?(bt||(bt=!0,vt=ve,Y=fe),_r>Cc&&(Cc=_r,_m(Cc))):(Pw(_r,wt.suspenseConfig),fe=wt.eagerReducer===P?wt.eagerState:P(fe,wt.action)),ve=wt,wt=wt.next}while(wt!==null&&wt!==j);bt||(vt=ve,Y=fe),hs(fe,D.memoizedState)||(qo=!0),D.memoizedState=fe,D.baseUpdate=vt,D.baseState=Y,R.lastRenderedState=fe}return[D.memoizedState,R.dispatch]}function cg(P){var D=TA();return typeof P=="function"&&(P=P()),D.memoizedState=D.baseState=P,P=D.queue={last:null,dispatch:null,lastRenderedReducer:Br,lastRenderedState:P},P=P.dispatch=hg.bind(null,Ha,P),[D.memoizedState,P]}function ug(P){return Cs(Br,P)}function Ag(P,D,R,j){return P={tag:P,create:D,destroy:R,deps:j,next:null},G===null?(G={lastEffect:null},G.lastEffect=P.next=P):(D=G.lastEffect,D===null?G.lastEffect=P.next=P:(R=D.next,D.next=P,P.next=R,G.lastEffect=P)),P}function pp(P,D,R,j){var Y=TA();Dt|=P,Y.memoizedState=Ag(D,R,void 0,j===void 0?null:j)}function Ic(P,D,R,j){var Y=fp();j=j===void 0?null:j;var fe=void 0;if(Gi!==null){var ve=Gi.memoizedState;if(fe=ve.destroy,j!==null&&Eu(j,ve.deps)){Ag(0,R,fe,j);return}}Dt|=P,Y.memoizedState=Ag(D,R,fe,j)}function Ct(P,D){return pp(516,192,P,D)}function Sm(P,D){return Ic(516,192,P,D)}function fg(P,D){if(typeof D=="function")return P=P(),D(P),function(){D(null)};if(D!=null)return P=P(),D.current=P,function(){D.current=null}}function pg(){}function Cu(P,D){return TA().memoizedState=[P,D===void 0?null:D],P}function xm(P,D){var R=fp();D=D===void 0?null:D;var j=R.memoizedState;return j!==null&&D!==null&&Eu(D,j[1])?j[0]:(R.memoizedState=[P,D],P)}function hg(P,D,R){if(!(25>wc))throw Error(n(301));var j=P.alternate;if(P===Ha||j!==null&&j===Ha)if(wl=!0,P={expirationTime:mu,suspenseConfig:null,action:R,eagerReducer:null,eagerState:null,next:null},bi===null&&(bi=new Map),R=bi.get(D),R===void 0)bi.set(D,P);else{for(D=R;D.next!==null;)D=D.next;D.next=P}else{var Y=ga(),fe=pt.suspense;Y=HA(Y,P,fe),fe={expirationTime:Y,suspenseConfig:fe,action:R,eagerReducer:null,eagerState:null,next:null};var ve=D.last;if(ve===null)fe.next=fe;else{var vt=ve.next;vt!==null&&(fe.next=vt),ve.next=fe}if(D.last=fe,P.expirationTime===0&&(j===null||j.expirationTime===0)&&(j=D.lastRenderedReducer,j!==null))try{var wt=D.lastRenderedState,bt=j(wt,R);if(fe.eagerReducer=j,fe.eagerState=bt,hs(bt,wt))return}catch{}finally{}Sc(P,Y)}}var wu={readContext:ms,useCallback:ct,useContext:ct,useEffect:ct,useImperativeHandle:ct,useLayoutEffect:ct,useMemo:ct,useReducer:ct,useRef:ct,useState:ct,useDebugValue:ct,useResponder:ct,useDeferredValue:ct,useTransition:ct},yw={readContext:ms,useCallback:Cu,useContext:ms,useEffect:Ct,useImperativeHandle:function(P,D,R){return R=R!=null?R.concat([P]):null,pp(4,36,fg.bind(null,D,P),R)},useLayoutEffect:function(P,D){return pp(4,36,P,D)},useMemo:function(P,D){var R=TA();return D=D===void 0?null:D,P=P(),R.memoizedState=[P,D],P},useReducer:function(P,D,R){var j=TA();return D=R!==void 0?R(D):D,j.memoizedState=j.baseState=D,P=j.queue={last:null,dispatch:null,lastRenderedReducer:P,lastRenderedState:D},P=P.dispatch=hg.bind(null,Ha,P),[j.memoizedState,P]},useRef:function(P){var D=TA();return P={current:P},D.memoizedState=P},useState:cg,useDebugValue:pg,useResponder:ag,useDeferredValue:function(P,D){var R=cg(P),j=R[0],Y=R[1];return Ct(function(){a.unstable_next(function(){var fe=Hs.suspense;Hs.suspense=D===void 0?null:D;try{Y(P)}finally{Hs.suspense=fe}})},[P,D]),j},useTransition:function(P){var D=cg(!1),R=D[0],j=D[1];return[Cu(function(Y){j(!0),a.unstable_next(function(){var fe=Hs.suspense;Hs.suspense=P===void 0?null:P;try{j(!1),Y()}finally{Hs.suspense=fe}})},[P,R]),R]}},bm={readContext:ms,useCallback:xm,useContext:ms,useEffect:Sm,useImperativeHandle:function(P,D,R){return R=R!=null?R.concat([P]):null,Ic(4,36,fg.bind(null,D,P),R)},useLayoutEffect:function(P,D){return Ic(4,36,P,D)},useMemo:function(P,D){var R=fp();D=D===void 0?null:D;var j=R.memoizedState;return j!==null&&D!==null&&Eu(D,j[1])?j[0]:(P=P(),R.memoizedState=[P,D],P)},useReducer:Cs,useRef:function(){return fp().memoizedState},useState:ug,useDebugValue:pg,useResponder:ag,useDeferredValue:function(P,D){var R=ug(P),j=R[0],Y=R[1];return Sm(function(){a.unstable_next(function(){var fe=Hs.suspense;Hs.suspense=D===void 0?null:D;try{Y(P)}finally{Hs.suspense=fe}})},[P,D]),j},useTransition:function(P){var D=ug(!1),R=D[0],j=D[1];return[xm(function(Y){j(!0),a.unstable_next(function(){var fe=Hs.suspense;Hs.suspense=P===void 0?null:P;try{j(!1),Y()}finally{Hs.suspense=fe}})},[P,R]),R]}},Aa=null,Bc=null,Il=!1;function Iu(P,D){var R=Dl(5,null,null,0);R.elementType="DELETED",R.type="DELETED",R.stateNode=D,R.return=P,R.effectTag=8,P.lastEffect!==null?(P.lastEffect.nextEffect=R,P.lastEffect=R):P.firstEffect=P.lastEffect=R}function gg(P,D){switch(P.tag){case 5:return D=io(D,P.type,P.pendingProps),D!==null?(P.stateNode=D,!0):!1;case 6:return D=Si(D,P.pendingProps),D!==null?(P.stateNode=D,!0):!1;case 13:return!1;default:return!1}}function RA(P){if(Il){var D=Bc;if(D){var R=D;if(!gg(P,D)){if(D=cc(R),!D||!gg(P,D)){P.effectTag=P.effectTag&-1025|2,Il=!1,Aa=P;return}Iu(Aa,R)}Aa=P,Bc=cu(D)}else P.effectTag=P.effectTag&-1025|2,Il=!1,Aa=P}}function hp(P){for(P=P.return;P!==null&&P.tag!==5&&P.tag!==3&&P.tag!==13;)P=P.return;Aa=P}function ja(P){if(!y||P!==Aa)return!1;if(!Il)return hp(P),Il=!0,!1;var D=P.type;if(P.tag!==5||D!=="head"&&D!=="body"&&!Qe(D,P.memoizedProps))for(D=Bc;D;)Iu(P,D),D=cc(D);if(hp(P),P.tag===13){if(!y)throw Error(n(316));if(P=P.memoizedState,P=P!==null?P.dehydrated:null,!P)throw Error(n(317));Bc=Ms(P)}else Bc=Aa?cc(P.stateNode):null;return!0}function dg(){y&&(Bc=Aa=null,Il=!1)}var gp=u.ReactCurrentOwner,qo=!1;function ws(P,D,R,j){D.child=P===null?ig(D,null,R,j):gu(D,P.child,R,j)}function Ii(P,D,R,j,Y){R=R.render;var fe=D.ref;return ds(D,Y),j=lg(P,D,R,j,fe,Y),P!==null&&!qo?(D.updateQueue=P.updateQueue,D.effectTag&=-517,P.expirationTime<=Y&&(P.expirationTime=0),si(P,D,Y)):(D.effectTag|=1,ws(P,D,j,Y),D.child)}function km(P,D,R,j,Y,fe){if(P===null){var ve=R.type;return typeof ve=="function"&&!kw(ve)&&ve.defaultProps===void 0&&R.compare===null&&R.defaultProps===void 0?(D.tag=15,D.type=ve,Qm(P,D,ve,j,Y,fe)):(P=Hm(R.type,null,j,null,D.mode,fe),P.ref=D.ref,P.return=D,D.child=P)}return ve=P.child,Y<fe&&(Y=ve.memoizedProps,R=R.compare,R=R!==null?R:Fn,R(Y,j)&&P.ref===D.ref)?si(P,D,fe):(D.effectTag|=1,P=YA(ve,j,fe),P.ref=D.ref,P.return=D,D.child=P)}function Qm(P,D,R,j,Y,fe){return P!==null&&Fn(P.memoizedProps,j)&&P.ref===D.ref&&(qo=!1,Y<fe)?si(P,D,fe):NA(P,D,R,j,fe)}function Go(P,D){var R=D.ref;(P===null&&R!==null||P!==null&&P.ref!==R)&&(D.effectTag|=128)}function NA(P,D,R,j,Y){var fe=ii(R)?tr:On.current;return fe=Me(D,fe),ds(D,Y),R=lg(P,D,R,j,fe,Y),P!==null&&!qo?(D.updateQueue=P.updateQueue,D.effectTag&=-517,P.expirationTime<=Y&&(P.expirationTime=0),si(P,D,Y)):(D.effectTag|=1,ws(P,D,R,Y),D.child)}function dp(P,D,R,j,Y){if(ii(R)){var fe=!0;Ac(D)}else fe=!1;if(ds(D,Y),D.stateNode===null)P!==null&&(P.alternate=null,D.alternate=null,D.effectTag|=2),es(D,R,j,Y),jo(D,R,j,Y),j=!0;else if(P===null){var ve=D.stateNode,vt=D.memoizedProps;ve.props=vt;var wt=ve.context,bt=R.contextType;typeof bt=="object"&&bt!==null?bt=ms(bt):(bt=ii(R)?tr:On.current,bt=Me(D,bt));var _r=R.getDerivedStateFromProps,is=typeof _r=="function"||typeof ve.getSnapshotBeforeUpdate=="function";is||typeof ve.UNSAFE_componentWillReceiveProps!="function"&&typeof ve.componentWillReceiveProps!="function"||(vt!==j||wt!==bt)&&xi(D,ve,j,bt),_s=!1;var di=D.memoizedState;wt=ve.state=di;var po=D.updateQueue;po!==null&&(me(D,po,j,ve,Y),wt=D.memoizedState),vt!==j||di!==wt||_i.current||_s?(typeof _r=="function"&&(er(D,R,_r,j),wt=D.memoizedState),(vt=_s||qi(D,R,vt,j,di,wt,bt))?(is||typeof ve.UNSAFE_componentWillMount!="function"&&typeof ve.componentWillMount!="function"||(typeof ve.componentWillMount=="function"&&ve.componentWillMount(),typeof ve.UNSAFE_componentWillMount=="function"&&ve.UNSAFE_componentWillMount()),typeof ve.componentDidMount=="function"&&(D.effectTag|=4)):(typeof ve.componentDidMount=="function"&&(D.effectTag|=4),D.memoizedProps=j,D.memoizedState=wt),ve.props=j,ve.state=wt,ve.context=bt,j=vt):(typeof ve.componentDidMount=="function"&&(D.effectTag|=4),j=!1)}else ve=D.stateNode,vt=D.memoizedProps,ve.props=D.type===D.elementType?vt:Ci(D.type,vt),wt=ve.context,bt=R.contextType,typeof bt=="object"&&bt!==null?bt=ms(bt):(bt=ii(R)?tr:On.current,bt=Me(D,bt)),_r=R.getDerivedStateFromProps,(is=typeof _r=="function"||typeof ve.getSnapshotBeforeUpdate=="function")||typeof ve.UNSAFE_componentWillReceiveProps!="function"&&typeof ve.componentWillReceiveProps!="function"||(vt!==j||wt!==bt)&&xi(D,ve,j,bt),_s=!1,wt=D.memoizedState,di=ve.state=wt,po=D.updateQueue,po!==null&&(me(D,po,j,ve,Y),di=D.memoizedState),vt!==j||wt!==di||_i.current||_s?(typeof _r=="function"&&(er(D,R,_r,j),di=D.memoizedState),(_r=_s||qi(D,R,vt,j,wt,di,bt))?(is||typeof ve.UNSAFE_componentWillUpdate!="function"&&typeof ve.componentWillUpdate!="function"||(typeof ve.componentWillUpdate=="function"&&ve.componentWillUpdate(j,di,bt),typeof ve.UNSAFE_componentWillUpdate=="function"&&ve.UNSAFE_componentWillUpdate(j,di,bt)),typeof ve.componentDidUpdate=="function"&&(D.effectTag|=4),typeof ve.getSnapshotBeforeUpdate=="function"&&(D.effectTag|=256)):(typeof ve.componentDidUpdate!="function"||vt===P.memoizedProps&&wt===P.memoizedState||(D.effectTag|=4),typeof ve.getSnapshotBeforeUpdate!="function"||vt===P.memoizedProps&&wt===P.memoizedState||(D.effectTag|=256),D.memoizedProps=j,D.memoizedState=di),ve.props=j,ve.state=di,ve.context=bt,j=_r):(typeof ve.componentDidUpdate!="function"||vt===P.memoizedProps&&wt===P.memoizedState||(D.effectTag|=4),typeof ve.getSnapshotBeforeUpdate!="function"||vt===P.memoizedProps&&wt===P.memoizedState||(D.effectTag|=256),j=!1);return mp(P,D,R,j,fe,Y)}function mp(P,D,R,j,Y,fe){Go(P,D);var ve=(D.effectTag&64)!==0;if(!j&&!ve)return Y&&El(D,R,!1),si(P,D,fe);j=D.stateNode,gp.current=D;var vt=ve&&typeof R.getDerivedStateFromError!="function"?null:j.render();return D.effectTag|=1,P!==null&&ve?(D.child=gu(D,P.child,null,fe),D.child=gu(D,null,vt,fe)):ws(P,D,vt,fe),D.memoizedState=j.state,Y&&El(D,R,!0),D.child}function mg(P){var D=P.stateNode;D.pendingContext?uc(P,D.pendingContext,D.pendingContext!==D.context):D.context&&uc(P,D.context,!1),sg(P,D.containerInfo)}var fa={dehydrated:null,retryTime:0};function ln(P,D,R){var j=D.mode,Y=D.pendingProps,fe=$n.current,ve=!1,vt;if((vt=(D.effectTag&64)!==0)||(vt=(fe&2)!==0&&(P===null||P.memoizedState!==null)),vt?(ve=!0,D.effectTag&=-65):P!==null&&P.memoizedState===null||Y.fallback===void 0||Y.unstable_avoidThisFallback===!0||(fe|=1),Mn($n,fe&1,D),P===null){if(Y.fallback!==void 0&&RA(D),ve){if(ve=Y.fallback,Y=xu(null,j,0,null),Y.return=D,(D.mode&2)===0)for(P=D.memoizedState!==null?D.child.child:D.child,Y.child=P;P!==null;)P.return=Y,P=P.sibling;return R=xu(ve,j,R,null),R.return=D,Y.sibling=R,D.memoizedState=fa,D.child=Y,R}return j=Y.children,D.memoizedState=null,D.child=ig(D,null,j,R)}if(P.memoizedState!==null){if(P=P.child,j=P.sibling,ve){if(Y=Y.fallback,R=YA(P,P.pendingProps,0),R.return=D,(D.mode&2)===0&&(ve=D.memoizedState!==null?D.child.child:D.child,ve!==P.child))for(R.child=ve;ve!==null;)ve.return=R,ve=ve.sibling;return j=YA(j,Y,j.expirationTime),j.return=D,R.sibling=j,R.childExpirationTime=0,D.memoizedState=fa,D.child=R,j}return R=gu(D,P.child,Y.children,R),D.memoizedState=null,D.child=R}if(P=P.child,ve){if(ve=Y.fallback,Y=xu(null,j,0,null),Y.return=D,Y.child=P,P!==null&&(P.return=Y),(D.mode&2)===0)for(P=D.memoizedState!==null?D.child.child:D.child,Y.child=P;P!==null;)P.return=Y,P=P.sibling;return R=xu(ve,j,R,null),R.return=D,Y.sibling=R,R.effectTag|=2,Y.childExpirationTime=0,D.memoizedState=fa,D.child=Y,R}return D.memoizedState=null,D.child=gu(D,P,Y.children,R)}function Ao(P,D){P.expirationTime<D&&(P.expirationTime=D);var R=P.alternate;R!==null&&R.expirationTime<D&&(R.expirationTime=D),gs(P.return,D)}function LA(P,D,R,j,Y,fe){var ve=P.memoizedState;ve===null?P.memoizedState={isBackwards:D,rendering:null,last:j,tail:R,tailExpiration:0,tailMode:Y,lastEffect:fe}:(ve.isBackwards=D,ve.rendering=null,ve.last=j,ve.tail=R,ve.tailExpiration=0,ve.tailMode=Y,ve.lastEffect=fe)}function qa(P,D,R){var j=D.pendingProps,Y=j.revealOrder,fe=j.tail;if(ws(P,D,j.children,R),j=$n.current,(j&2)!==0)j=j&1|2,D.effectTag|=64;else{if(P!==null&&(P.effectTag&64)!==0)e:for(P=D.child;P!==null;){if(P.tag===13)P.memoizedState!==null&&Ao(P,R);else if(P.tag===19)Ao(P,R);else if(P.child!==null){P.child.return=P,P=P.child;continue}if(P===D)break e;for(;P.sibling===null;){if(P.return===null||P.return===D)break e;P=P.return}P.sibling.return=P.return,P=P.sibling}j&=1}if(Mn($n,j,D),(D.mode&2)===0)D.memoizedState=null;else switch(Y){case"forwards":for(R=D.child,Y=null;R!==null;)P=R.alternate,P!==null&&Ap(P)===null&&(Y=R),R=R.sibling;R=Y,R===null?(Y=D.child,D.child=null):(Y=R.sibling,R.sibling=null),LA(D,!1,Y,R,fe,D.lastEffect);break;case"backwards":for(R=null,Y=D.child,D.child=null;Y!==null;){if(P=Y.alternate,P!==null&&Ap(P)===null){D.child=Y;break}P=Y.sibling,Y.sibling=R,R=Y,Y=P}LA(D,!0,R,null,fe,D.lastEffect);break;case"together":LA(D,!1,null,null,void 0,D.lastEffect);break;default:D.memoizedState=null}return D.child}function si(P,D,R){P!==null&&(D.dependencies=P.dependencies);var j=D.expirationTime;if(j!==0&&_m(j),D.childExpirationTime<R)return null;if(P!==null&&D.child!==P.child)throw Error(n(153));if(D.child!==null){for(P=D.child,R=YA(P,P.pendingProps,P.expirationTime),D.child=R,R.return=D;P.sibling!==null;)P=P.sibling,R=R.sibling=YA(P,P.pendingProps,P.expirationTime),R.return=D;R.sibling=null}return D.child}function pa(P){P.effectTag|=4}var vc,Bl,ts,Gr;if(w)vc=function(P,D){for(var R=D.child;R!==null;){if(R.tag===5||R.tag===6)H(P,R.stateNode);else if(R.tag!==4&&R.child!==null){R.child.return=R,R=R.child;continue}if(R===D)break;for(;R.sibling===null;){if(R.return===null||R.return===D)return;R=R.return}R.sibling.return=R.return,R=R.sibling}},Bl=function(){},ts=function(P,D,R,j,Y){if(P=P.memoizedProps,P!==j){var fe=D.stateNode,ve=ca(uo.current);R=Re(fe,R,P,j,Y,ve),(D.updateQueue=R)&&pa(D)}},Gr=function(P,D,R,j){R!==j&&pa(D)};else if(S){vc=function(P,D,R,j){for(var Y=D.child;Y!==null;){if(Y.tag===5){var fe=Y.stateNode;R&&j&&(fe=Ri(fe,Y.type,Y.memoizedProps,Y)),H(P,fe)}else if(Y.tag===6)fe=Y.stateNode,R&&j&&(fe=ps(fe,Y.memoizedProps,Y)),H(P,fe);else if(Y.tag!==4){if(Y.tag===13&&(Y.effectTag&4)!==0&&(fe=Y.memoizedState!==null)){var ve=Y.child;if(ve!==null&&(ve.child!==null&&(ve.child.return=ve,vc(P,ve,!0,fe)),fe=ve.sibling,fe!==null)){fe.return=Y,Y=fe;continue}}if(Y.child!==null){Y.child.return=Y,Y=Y.child;continue}}if(Y===D)break;for(;Y.sibling===null;){if(Y.return===null||Y.return===D)return;Y=Y.return}Y.sibling.return=Y.return,Y=Y.sibling}};var yp=function(P,D,R,j){for(var Y=D.child;Y!==null;){if(Y.tag===5){var fe=Y.stateNode;R&&j&&(fe=Ri(fe,Y.type,Y.memoizedProps,Y)),Wr(P,fe)}else if(Y.tag===6)fe=Y.stateNode,R&&j&&(fe=ps(fe,Y.memoizedProps,Y)),Wr(P,fe);else if(Y.tag!==4){if(Y.tag===13&&(Y.effectTag&4)!==0&&(fe=Y.memoizedState!==null)){var ve=Y.child;if(ve!==null&&(ve.child!==null&&(ve.child.return=ve,yp(P,ve,!0,fe)),fe=ve.sibling,fe!==null)){fe.return=Y,Y=fe;continue}}if(Y.child!==null){Y.child.return=Y,Y=Y.child;continue}}if(Y===D)break;for(;Y.sibling===null;){if(Y.return===null||Y.return===D)return;Y=Y.return}Y.sibling.return=Y.return,Y=Y.sibling}};Bl=function(P){var D=P.stateNode;if(P.firstEffect!==null){var R=D.containerInfo,j=xr(R);yp(j,P,!1,!1),D.pendingChildren=j,pa(P),Vn(R,j)}},ts=function(P,D,R,j,Y){var fe=P.stateNode,ve=P.memoizedProps;if((P=D.firstEffect===null)&&ve===j)D.stateNode=fe;else{var vt=D.stateNode,wt=ca(uo.current),bt=null;ve!==j&&(bt=Re(vt,R,ve,j,Y,wt)),P&&bt===null?D.stateNode=fe:(fe=mr(fe,bt,R,ve,j,D,P,vt),lt(fe,R,j,Y,wt)&&pa(D),D.stateNode=fe,P?pa(D):vc(fe,D,!1,!1))}},Gr=function(P,D,R,j){R!==j&&(P=ca(mc.current),R=ca(uo.current),D.stateNode=_e(j,P,R,D),pa(D))}}else Bl=function(){},ts=function(){},Gr=function(){};function Dc(P,D){switch(P.tailMode){case"hidden":D=P.tail;for(var R=null;D!==null;)D.alternate!==null&&(R=D),D=D.sibling;R===null?P.tail=null:R.sibling=null;break;case"collapsed":R=P.tail;for(var j=null;R!==null;)R.alternate!==null&&(j=R),R=R.sibling;j===null?D||P.tail===null?P.tail=null:P.tail.sibling=null:j.sibling=null}}function Ew(P){switch(P.tag){case 1:ii(P.type)&&Oa(P);var D=P.effectTag;return D&4096?(P.effectTag=D&-4097|64,P):null;case 3:if(yc(P),hr(P),D=P.effectTag,(D&64)!==0)throw Error(n(285));return P.effectTag=D&-4097|64,P;case 5:return og(P),null;case 13:return Kn($n,P),D=P.effectTag,D&4096?(P.effectTag=D&-4097|64,P):null;case 19:return Kn($n,P),null;case 4:return yc(P),null;case 10:return wi(P),null;default:return null}}function yg(P,D){return{value:P,source:D,stack:ml(D)}}var Eg=typeof WeakSet=="function"?WeakSet:Set;function Ga(P,D){var R=D.source,j=D.stack;j===null&&R!==null&&(j=ml(R)),R!==null&&ae(R.type),D=D.value,P!==null&&P.tag===1&&ae(P.type);try{console.error(D)}catch(Y){setTimeout(function(){throw Y})}}function Fm(P,D){try{D.props=P.memoizedProps,D.state=P.memoizedState,D.componentWillUnmount()}catch(R){GA(P,R)}}function Cg(P){var D=P.ref;if(D!==null)if(typeof D=="function")try{D(null)}catch(R){GA(P,R)}else D.current=null}function Qt(P,D){switch(D.tag){case 0:case 11:case 15:N(2,0,D);break;case 1:if(D.effectTag&256&&P!==null){var R=P.memoizedProps,j=P.memoizedState;P=D.stateNode,D=P.getSnapshotBeforeUpdate(D.elementType===D.type?R:Ci(D.type,R),j),P.__reactInternalSnapshotBeforeUpdate=D}break;case 3:case 5:case 6:case 4:case 17:break;default:throw Error(n(163))}}function N(P,D,R){if(R=R.updateQueue,R=R!==null?R.lastEffect:null,R!==null){var j=R=R.next;do{if((j.tag&P)!==0){var Y=j.destroy;j.destroy=void 0,Y!==void 0&&Y()}(j.tag&D)!==0&&(Y=j.create,j.destroy=Y()),j=j.next}while(j!==R)}}function V(P,D,R){switch(typeof bw=="function"&&bw(D),D.tag){case 0:case 11:case 14:case 15:if(P=D.updateQueue,P!==null&&(P=P.lastEffect,P!==null)){var j=P.next;lo(97<R?97:R,function(){var Y=j;do{var fe=Y.destroy;if(fe!==void 0){var ve=D;try{fe()}catch(vt){GA(ve,vt)}}Y=Y.next}while(Y!==j)})}break;case 1:Cg(D),R=D.stateNode,typeof R.componentWillUnmount=="function"&&Fm(D,R);break;case 5:Cg(D);break;case 4:w?Cr(P,D,R):S&&ze(D)}}function re(P,D,R){for(var j=D;;)if(V(P,j,R),j.child===null||w&&j.tag===4){if(j===D)break;for(;j.sibling===null;){if(j.return===null||j.return===D)return;j=j.return}j.sibling.return=j.return,j=j.sibling}else j.child.return=j,j=j.child}function he(P){var D=P.alternate;P.return=null,P.child=null,P.memoizedState=null,P.updateQueue=null,P.dependencies=null,P.alternate=null,P.firstEffect=null,P.lastEffect=null,P.pendingProps=null,P.memoizedProps=null,D!==null&&he(D)}function ze(P){if(S){P=P.stateNode.containerInfo;var D=xr(P);Ns(P,D)}}function mt(P){return P.tag===5||P.tag===3||P.tag===4}function fr(P){if(w){e:{for(var D=P.return;D!==null;){if(mt(D)){var R=D;break e}D=D.return}throw Error(n(160))}switch(D=R.stateNode,R.tag){case 5:var j=!1;break;case 3:D=D.containerInfo,j=!0;break;case 4:D=D.containerInfo,j=!0;break;default:throw Error(n(161))}R.effectTag&16&&(jt(D),R.effectTag&=-17);e:t:for(R=P;;){for(;R.sibling===null;){if(R.return===null||mt(R.return)){R=null;break e}R=R.return}for(R.sibling.return=R.return,R=R.sibling;R.tag!==5&&R.tag!==6&&R.tag!==18;){if(R.effectTag&2||R.child===null||R.tag===4)continue t;R.child.return=R,R=R.child}if(!(R.effectTag&2)){R=R.stateNode;break e}}for(var Y=P;;){var fe=Y.tag===5||Y.tag===6;if(fe)fe=fe?Y.stateNode:Y.stateNode.instance,R?j?Ne(D,fe,R):Se(D,fe,R):j?z(D,fe):F(D,fe);else if(Y.tag!==4&&Y.child!==null){Y.child.return=Y,Y=Y.child;continue}if(Y===P)break;for(;Y.sibling===null;){if(Y.return===null||Y.return===P)return;Y=Y.return}Y.sibling.return=Y.return,Y=Y.sibling}}}function Cr(P,D,R){for(var j=D,Y=!1,fe,ve;;){if(!Y){Y=j.return;e:for(;;){if(Y===null)throw Error(n(160));switch(fe=Y.stateNode,Y.tag){case 5:ve=!1;break e;case 3:fe=fe.containerInfo,ve=!0;break e;case 4:fe=fe.containerInfo,ve=!0;break e}Y=Y.return}Y=!0}if(j.tag===5||j.tag===6)re(P,j,R),ve?dt(fe,j.stateNode):ot(fe,j.stateNode);else if(j.tag===4){if(j.child!==null){fe=j.stateNode.containerInfo,ve=!0,j.child.return=j,j=j.child;continue}}else if(V(P,j,R),j.child!==null){j.child.return=j,j=j.child;continue}if(j===D)break;for(;j.sibling===null;){if(j.return===null||j.return===D)return;j=j.return,j.tag===4&&(Y=!1)}j.sibling.return=j.return,j=j.sibling}}function yn(P,D){if(w)switch(D.tag){case 0:case 11:case 14:case 15:N(4,8,D);break;case 1:break;case 5:var R=D.stateNode;if(R!=null){var j=D.memoizedProps;P=P!==null?P.memoizedProps:j;var Y=D.type,fe=D.updateQueue;D.updateQueue=null,fe!==null&&ie(R,fe,Y,P,j,D)}break;case 6:if(D.stateNode===null)throw Error(n(162));R=D.memoizedProps,X(D.stateNode,P!==null?P.memoizedProps:R,R);break;case 3:y&&(D=D.stateNode,D.hydrate&&(D.hydrate=!1,Dn(D.containerInfo)));break;case 12:break;case 13:oi(D),Mi(D);break;case 19:Mi(D);break;case 17:break;case 20:break;case 21:break;default:throw Error(n(163))}else{switch(D.tag){case 0:case 11:case 14:case 15:N(4,8,D);return;case 12:return;case 13:oi(D),Mi(D);return;case 19:Mi(D);return;case 3:y&&(R=D.stateNode,R.hydrate&&(R.hydrate=!1,Dn(R.containerInfo)))}e:if(S)switch(D.tag){case 1:case 5:case 6:case 20:break e;case 3:case 4:D=D.stateNode,Ns(D.containerInfo,D.pendingChildren);break e;default:throw Error(n(163))}}}function oi(P){var D=P;if(P.memoizedState===null)var R=!1;else R=!0,D=P.child,Iw=Li();if(w&&D!==null){e:if(P=D,w)for(D=P;;){if(D.tag===5){var j=D.stateNode;R?$t(j):an(D.stateNode,D.memoizedProps)}else if(D.tag===6)j=D.stateNode,R?xt(j):Qr(j,D.memoizedProps);else if(D.tag===13&&D.memoizedState!==null&&D.memoizedState.dehydrated===null){j=D.child.sibling,j.return=D,D=j;continue}else if(D.child!==null){D.child.return=D,D=D.child;continue}if(D===P)break e;for(;D.sibling===null;){if(D.return===null||D.return===P)break e;D=D.return}D.sibling.return=D.return,D=D.sibling}}}function Mi(P){var D=P.updateQueue;if(D!==null){P.updateQueue=null;var R=P.stateNode;R===null&&(R=P.stateNode=new Eg),D.forEach(function(j){var Y=CF.bind(null,P,j);R.has(j)||(R.add(j),j.then(Y,Y))})}}var wg=typeof WeakMap=="function"?WeakMap:Map;function Gv(P,D,R){R=ys(R,null),R.tag=3,R.payload={element:null};var j=D.value;return R.callback=function(){vu||(vu=!0,Mm=j),Ga(P,D)},R}function Yv(P,D,R){R=ys(R,null),R.tag=3;var j=P.type.getDerivedStateFromError;if(typeof j=="function"){var Y=D.value;R.payload=function(){return Ga(P,D),j(Y)}}var fe=P.stateNode;return fe!==null&&typeof fe.componentDidCatch=="function"&&(R.callback=function(){typeof j!="function"&&(Du===null?Du=new Set([this]):Du.add(this),Ga(P,D));var ve=D.stack;this.componentDidCatch(D.value,{componentStack:ve!==null?ve:""})}),R}var Cw=Math.ceil,Ep=u.ReactCurrentDispatcher,ww=u.ReactCurrentOwner,En=0,Tm=8,rs=16,js=32,Bu=0,Rm=1,Bi=2,ha=3,vl=4,Pc=5,yr=En,gi=null,Mr=null,ns=0,Yi=Bu,Nm=null,Ya=1073741823,MA=1073741823,Lm=null,Cp=0,OA=!1,Iw=0,Bw=500,sr=null,vu=!1,Mm=null,Du=null,wp=!1,Ig=null,UA=90,_A=null,Bg=0,vw=null,Om=0;function ga(){return(yr&(rs|js))!==En?1073741821-(Li()/10|0):Om!==0?Om:Om=1073741821-(Li()/10|0)}function HA(P,D,R){if(D=D.mode,(D&2)===0)return 1073741823;var j=_o();if((D&4)===0)return j===99?1073741823:1073741822;if((yr&rs)!==En)return ns;if(R!==null)P=Ua(P,R.timeoutMs|0||5e3,250);else switch(j){case 99:P=1073741823;break;case 98:P=Ua(P,150,100);break;case 97:case 96:P=Ua(P,5e3,250);break;case 95:P=2;break;default:throw Error(n(326))}return gi!==null&&P===ns&&--P,P}function Sc(P,D){if(50<Bg)throw Bg=0,vw=null,Error(n(185));if(P=vg(P,D),P!==null){var R=_o();D===1073741823?(yr&Tm)!==En&&(yr&(rs|js))===En?Dw(P):(fo(P),yr===En&&ji()):fo(P),(yr&4)===En||R!==98&&R!==99||(_A===null?_A=new Map([[P,D]]):(R=_A.get(P),(R===void 0||R>D)&&_A.set(P,D)))}}function vg(P,D){P.expirationTime<D&&(P.expirationTime=D);var R=P.alternate;R!==null&&R.expirationTime<D&&(R.expirationTime=D);var j=P.return,Y=null;if(j===null&&P.tag===3)Y=P.stateNode;else for(;j!==null;){if(R=j.alternate,j.childExpirationTime<D&&(j.childExpirationTime=D),R!==null&&R.childExpirationTime<D&&(R.childExpirationTime=D),j.return===null&&j.tag===3){Y=j.stateNode;break}j=j.return}return Y!==null&&(gi===Y&&(_m(D),Yi===vl&&WA(Y,ns)),eD(Y,D)),Y}function Um(P){var D=P.lastExpiredTime;return D!==0||(D=P.firstPendingTime,!$v(P,D))?D:(D=P.lastPingedTime,P=P.nextKnownPendingLevel,D>P?D:P)}function fo(P){if(P.lastExpiredTime!==0)P.callbackExpirationTime=1073741823,P.callbackPriority=99,P.callbackNode=pu(Dw.bind(null,P));else{var D=Um(P),R=P.callbackNode;if(D===0)R!==null&&(P.callbackNode=null,P.callbackExpirationTime=0,P.callbackPriority=90);else{var j=ga();if(D===1073741823?j=99:D===1||D===2?j=95:(j=10*(1073741821-D)-10*(1073741821-j),j=0>=j?99:250>=j?98:5250>=j?97:95),R!==null){var Y=P.callbackPriority;if(P.callbackExpirationTime===D&&Y>=j)return;R!==PA&&Ce(R)}P.callbackExpirationTime=D,P.callbackPriority=j,D=D===1073741823?pu(Dw.bind(null,P)):gc(j,Wv.bind(null,P),{timeout:10*(1073741821-D)-Li()}),P.callbackNode=D}}}function Wv(P,D){if(Om=0,D)return D=ga(),jm(P,D),fo(P),null;var R=Um(P);if(R!==0){if(D=P.callbackNode,(yr&(rs|js))!==En)throw Error(n(327));if(Ip(),P===gi&&R===ns||Pu(P,R),Mr!==null){var j=yr;yr|=rs;var Y=qA(P);do try{gF();break}catch(vt){jA(P,vt)}while(1);if(la(),yr=j,Ep.current=Y,Yi===Rm)throw D=Nm,Pu(P,R),WA(P,R),fo(P),D;if(Mr===null)switch(Y=P.finishedWork=P.current.alternate,P.finishedExpirationTime=R,j=Yi,gi=null,j){case Bu:case Rm:throw Error(n(345));case Bi:jm(P,2<R?2:R);break;case ha:if(WA(P,R),j=P.lastSuspendedTime,R===j&&(P.nextKnownPendingLevel=Sw(Y)),Ya===1073741823&&(Y=Iw+Bw-Li(),10<Y)){if(OA){var fe=P.lastPingedTime;if(fe===0||fe>=R){P.lastPingedTime=R,Pu(P,R);break}}if(fe=Um(P),fe!==0&&fe!==R)break;if(j!==0&&j!==R){P.lastPingedTime=j;break}P.timeoutHandle=Te(Su.bind(null,P),Y);break}Su(P);break;case vl:if(WA(P,R),j=P.lastSuspendedTime,R===j&&(P.nextKnownPendingLevel=Sw(Y)),OA&&(Y=P.lastPingedTime,Y===0||Y>=R)){P.lastPingedTime=R,Pu(P,R);break}if(Y=Um(P),Y!==0&&Y!==R)break;if(j!==0&&j!==R){P.lastPingedTime=j;break}if(MA!==1073741823?j=10*(1073741821-MA)-Li():Ya===1073741823?j=0:(j=10*(1073741821-Ya)-5e3,Y=Li(),R=10*(1073741821-R)-Y,j=Y-j,0>j&&(j=0),j=(120>j?120:480>j?480:1080>j?1080:1920>j?1920:3e3>j?3e3:4320>j?4320:1960*Cw(j/1960))-j,R<j&&(j=R)),10<j){P.timeoutHandle=Te(Su.bind(null,P),j);break}Su(P);break;case Pc:if(Ya!==1073741823&&Lm!==null){fe=Ya;var ve=Lm;if(j=ve.busyMinDurationMs|0,0>=j?j=0:(Y=ve.busyDelayMs|0,fe=Li()-(10*(1073741821-fe)-(ve.timeoutMs|0||5e3)),j=fe<=Y?0:Y+j-fe),10<j){WA(P,R),P.timeoutHandle=Te(Su.bind(null,P),j);break}}Su(P);break;default:throw Error(n(329))}if(fo(P),P.callbackNode===D)return Wv.bind(null,P)}}return null}function Dw(P){var D=P.lastExpiredTime;if(D=D!==0?D:1073741823,P.finishedExpirationTime===D)Su(P);else{if((yr&(rs|js))!==En)throw Error(n(327));if(Ip(),P===gi&&D===ns||Pu(P,D),Mr!==null){var R=yr;yr|=rs;var j=qA(P);do try{hF();break}catch(Y){jA(P,Y)}while(1);if(la(),yr=R,Ep.current=j,Yi===Rm)throw R=Nm,Pu(P,D),WA(P,D),fo(P),R;if(Mr!==null)throw Error(n(261));P.finishedWork=P.current.alternate,P.finishedExpirationTime=D,gi=null,Su(P),fo(P)}}return null}function Vv(P,D){jm(P,D),fo(P),(yr&(rs|js))===En&&ji()}function pF(){if(_A!==null){var P=_A;_A=null,P.forEach(function(D,R){jm(R,D),fo(R)}),ji()}}function Kv(P,D){if((yr&(rs|js))!==En)throw Error(n(187));var R=yr;yr|=1;try{return lo(99,P.bind(null,D))}finally{yr=R,ji()}}function Pu(P,D){P.finishedWork=null,P.finishedExpirationTime=0;var R=P.timeoutHandle;if(R!==He&&(P.timeoutHandle=He,Je(R)),Mr!==null)for(R=Mr.return;R!==null;){var j=R;switch(j.tag){case 1:var Y=j.type.childContextTypes;Y!=null&&Oa(j);break;case 3:yc(j),hr(j);break;case 5:og(j);break;case 4:yc(j);break;case 13:Kn($n,j);break;case 19:Kn($n,j);break;case 10:wi(j)}R=R.return}gi=P,Mr=YA(P.current,null,D),ns=D,Yi=Bu,Nm=null,MA=Ya=1073741823,Lm=null,Cp=0,OA=!1}function jA(P,D){do{try{if(la(),mw(),Mr===null||Mr.return===null)return Yi=Rm,Nm=D,null;e:{var R=P,j=Mr.return,Y=Mr,fe=D;if(D=ns,Y.effectTag|=2048,Y.firstEffect=Y.lastEffect=null,fe!==null&&typeof fe=="object"&&typeof fe.then=="function"){var ve=fe,vt=($n.current&1)!==0,wt=j;do{var bt;if(bt=wt.tag===13){var _r=wt.memoizedState;if(_r!==null)bt=_r.dehydrated!==null;else{var is=wt.memoizedProps;bt=is.fallback===void 0?!1:is.unstable_avoidThisFallback!==!0?!0:!vt}}if(bt){var di=wt.updateQueue;if(di===null){var po=new Set;po.add(ve),wt.updateQueue=po}else di.add(ve);if((wt.mode&2)===0){if(wt.effectTag|=64,Y.effectTag&=-2981,Y.tag===1)if(Y.alternate===null)Y.tag=17;else{var VA=ys(1073741823,null);VA.tag=2,tt(Y,VA)}Y.expirationTime=1073741823;break e}fe=void 0,Y=D;var Yo=R.pingCache;if(Yo===null?(Yo=R.pingCache=new wg,fe=new Set,Yo.set(ve,fe)):(fe=Yo.get(ve),fe===void 0&&(fe=new Set,Yo.set(ve,fe))),!fe.has(Y)){fe.add(Y);var rt=EF.bind(null,R,ve,Y);ve.then(rt,rt)}wt.effectTag|=4096,wt.expirationTime=D;break e}wt=wt.return}while(wt!==null);fe=Error((ae(Y.type)||"A React component")+` suspended while rendering, but no fallback UI was specified. + +Add a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.`+ml(Y))}Yi!==Pc&&(Yi=Bi),fe=yg(fe,Y),wt=j;do{switch(wt.tag){case 3:ve=fe,wt.effectTag|=4096,wt.expirationTime=D;var Ke=Gv(wt,ve,D);It(wt,Ke);break e;case 1:ve=fe;var At=wt.type,Wt=wt.stateNode;if((wt.effectTag&64)===0&&(typeof At.getDerivedStateFromError=="function"||Wt!==null&&typeof Wt.componentDidCatch=="function"&&(Du===null||!Du.has(Wt)))){wt.effectTag|=4096,wt.expirationTime=D;var vr=Yv(wt,ve,D);It(wt,vr);break e}}wt=wt.return}while(wt!==null)}Mr=zv(Mr)}catch(Sn){D=Sn;continue}break}while(1)}function qA(){var P=Ep.current;return Ep.current=wu,P===null?wu:P}function Pw(P,D){P<Ya&&2<P&&(Ya=P),D!==null&&P<MA&&2<P&&(MA=P,Lm=D)}function _m(P){P>Cp&&(Cp=P)}function hF(){for(;Mr!==null;)Mr=Jv(Mr)}function gF(){for(;Mr!==null&&!Tt();)Mr=Jv(Mr)}function Jv(P){var D=Zv(P.alternate,P,ns);return P.memoizedProps=P.pendingProps,D===null&&(D=zv(P)),ww.current=null,D}function zv(P){Mr=P;do{var D=Mr.alternate;if(P=Mr.return,(Mr.effectTag&2048)===0){e:{var R=D;D=Mr;var j=ns,Y=D.pendingProps;switch(D.tag){case 2:break;case 16:break;case 15:case 0:break;case 1:ii(D.type)&&Oa(D);break;case 3:yc(D),hr(D),Y=D.stateNode,Y.pendingContext&&(Y.context=Y.pendingContext,Y.pendingContext=null),(R===null||R.child===null)&&ja(D)&&pa(D),Bl(D);break;case 5:og(D);var fe=ca(mc.current);if(j=D.type,R!==null&&D.stateNode!=null)ts(R,D,j,Y,fe),R.ref!==D.ref&&(D.effectTag|=128);else if(Y){if(R=ca(uo.current),ja(D)){if(Y=D,!y)throw Error(n(175));R=ap(Y.stateNode,Y.type,Y.memoizedProps,fe,R,Y),Y.updateQueue=R,R=R!==null,R&&pa(D)}else{var ve=ht(j,Y,fe,R,D);vc(ve,D,!1,!1),D.stateNode=ve,lt(ve,j,Y,fe,R)&&pa(D)}D.ref!==null&&(D.effectTag|=128)}else if(D.stateNode===null)throw Error(n(166));break;case 6:if(R&&D.stateNode!=null)Gr(R,D,R.memoizedProps,Y);else{if(typeof Y!="string"&&D.stateNode===null)throw Error(n(166));if(R=ca(mc.current),fe=ca(uo.current),ja(D)){if(R=D,!y)throw Error(n(176));(R=lp(R.stateNode,R.memoizedProps,R))&&pa(D)}else D.stateNode=_e(Y,R,fe,D)}break;case 11:break;case 13:if(Kn($n,D),Y=D.memoizedState,(D.effectTag&64)!==0){D.expirationTime=j;break e}Y=Y!==null,fe=!1,R===null?D.memoizedProps.fallback!==void 0&&ja(D):(j=R.memoizedState,fe=j!==null,Y||j===null||(j=R.child.sibling,j!==null&&(ve=D.firstEffect,ve!==null?(D.firstEffect=j,j.nextEffect=ve):(D.firstEffect=D.lastEffect=j,j.nextEffect=null),j.effectTag=8))),Y&&!fe&&(D.mode&2)!==0&&(R===null&&D.memoizedProps.unstable_avoidThisFallback!==!0||($n.current&1)!==0?Yi===Bu&&(Yi=ha):((Yi===Bu||Yi===ha)&&(Yi=vl),Cp!==0&&gi!==null&&(WA(gi,ns),eD(gi,Cp)))),S&&Y&&(D.effectTag|=4),w&&(Y||fe)&&(D.effectTag|=4);break;case 7:break;case 8:break;case 12:break;case 4:yc(D),Bl(D);break;case 10:wi(D);break;case 9:break;case 14:break;case 17:ii(D.type)&&Oa(D);break;case 19:if(Kn($n,D),Y=D.memoizedState,Y===null)break;if(fe=(D.effectTag&64)!==0,ve=Y.rendering,ve===null){if(fe)Dc(Y,!1);else if(Yi!==Bu||R!==null&&(R.effectTag&64)!==0)for(R=D.child;R!==null;){if(ve=Ap(R),ve!==null){for(D.effectTag|=64,Dc(Y,!1),R=ve.updateQueue,R!==null&&(D.updateQueue=R,D.effectTag|=4),Y.lastEffect===null&&(D.firstEffect=null),D.lastEffect=Y.lastEffect,R=j,Y=D.child;Y!==null;)fe=Y,j=R,fe.effectTag&=2,fe.nextEffect=null,fe.firstEffect=null,fe.lastEffect=null,ve=fe.alternate,ve===null?(fe.childExpirationTime=0,fe.expirationTime=j,fe.child=null,fe.memoizedProps=null,fe.memoizedState=null,fe.updateQueue=null,fe.dependencies=null):(fe.childExpirationTime=ve.childExpirationTime,fe.expirationTime=ve.expirationTime,fe.child=ve.child,fe.memoizedProps=ve.memoizedProps,fe.memoizedState=ve.memoizedState,fe.updateQueue=ve.updateQueue,j=ve.dependencies,fe.dependencies=j===null?null:{expirationTime:j.expirationTime,firstContext:j.firstContext,responders:j.responders}),Y=Y.sibling;Mn($n,$n.current&1|2,D),D=D.child;break e}R=R.sibling}}else{if(!fe)if(R=Ap(ve),R!==null){if(D.effectTag|=64,fe=!0,R=R.updateQueue,R!==null&&(D.updateQueue=R,D.effectTag|=4),Dc(Y,!0),Y.tail===null&&Y.tailMode==="hidden"&&!ve.alternate){D=D.lastEffect=Y.lastEffect,D!==null&&(D.nextEffect=null);break}}else Li()>Y.tailExpiration&&1<j&&(D.effectTag|=64,fe=!0,Dc(Y,!1),D.expirationTime=D.childExpirationTime=j-1);Y.isBackwards?(ve.sibling=D.child,D.child=ve):(R=Y.last,R!==null?R.sibling=ve:D.child=ve,Y.last=ve)}if(Y.tail!==null){Y.tailExpiration===0&&(Y.tailExpiration=Li()+500),R=Y.tail,Y.rendering=R,Y.tail=R.sibling,Y.lastEffect=D.lastEffect,R.sibling=null,Y=$n.current,Y=fe?Y&1|2:Y&1,Mn($n,Y,D),D=R;break e}break;case 20:break;case 21:break;default:throw Error(n(156,D.tag))}D=null}if(R=Mr,ns===1||R.childExpirationTime!==1){for(Y=0,fe=R.child;fe!==null;)j=fe.expirationTime,ve=fe.childExpirationTime,j>Y&&(Y=j),ve>Y&&(Y=ve),fe=fe.sibling;R.childExpirationTime=Y}if(D!==null)return D;P!==null&&(P.effectTag&2048)===0&&(P.firstEffect===null&&(P.firstEffect=Mr.firstEffect),Mr.lastEffect!==null&&(P.lastEffect!==null&&(P.lastEffect.nextEffect=Mr.firstEffect),P.lastEffect=Mr.lastEffect),1<Mr.effectTag&&(P.lastEffect!==null?P.lastEffect.nextEffect=Mr:P.firstEffect=Mr,P.lastEffect=Mr))}else{if(D=Ew(Mr,ns),D!==null)return D.effectTag&=2047,D;P!==null&&(P.firstEffect=P.lastEffect=null,P.effectTag|=2048)}if(D=Mr.sibling,D!==null)return D;Mr=P}while(Mr!==null);return Yi===Bu&&(Yi=Pc),null}function Sw(P){var D=P.expirationTime;return P=P.childExpirationTime,D>P?D:P}function Su(P){var D=_o();return lo(99,dF.bind(null,P,D)),null}function dF(P,D){do Ip();while(Ig!==null);if((yr&(rs|js))!==En)throw Error(n(327));var R=P.finishedWork,j=P.finishedExpirationTime;if(R===null)return null;if(P.finishedWork=null,P.finishedExpirationTime=0,R===P.current)throw Error(n(177));P.callbackNode=null,P.callbackExpirationTime=0,P.callbackPriority=90,P.nextKnownPendingLevel=0;var Y=Sw(R);if(P.firstPendingTime=Y,j<=P.lastSuspendedTime?P.firstSuspendedTime=P.lastSuspendedTime=P.nextKnownPendingLevel=0:j<=P.firstSuspendedTime&&(P.firstSuspendedTime=j-1),j<=P.lastPingedTime&&(P.lastPingedTime=0),j<=P.lastExpiredTime&&(P.lastExpiredTime=0),P===gi&&(Mr=gi=null,ns=0),1<R.effectTag?R.lastEffect!==null?(R.lastEffect.nextEffect=R,Y=R.firstEffect):Y=R:Y=R.firstEffect,Y!==null){var fe=yr;yr|=js,ww.current=null,Ie(P.containerInfo),sr=Y;do try{mF()}catch(ho){if(sr===null)throw Error(n(330));GA(sr,ho),sr=sr.nextEffect}while(sr!==null);sr=Y;do try{for(var ve=P,vt=D;sr!==null;){var wt=sr.effectTag;if(wt&16&&w&&jt(sr.stateNode),wt&128){var bt=sr.alternate;if(bt!==null){var _r=bt.ref;_r!==null&&(typeof _r=="function"?_r(null):_r.current=null)}}switch(wt&1038){case 2:fr(sr),sr.effectTag&=-3;break;case 6:fr(sr),sr.effectTag&=-3,yn(sr.alternate,sr);break;case 1024:sr.effectTag&=-1025;break;case 1028:sr.effectTag&=-1025,yn(sr.alternate,sr);break;case 4:yn(sr.alternate,sr);break;case 8:var is=ve,di=sr,po=vt;w?Cr(is,di,po):re(is,di,po),he(di)}sr=sr.nextEffect}}catch(ho){if(sr===null)throw Error(n(330));GA(sr,ho),sr=sr.nextEffect}while(sr!==null);ke(P.containerInfo),P.current=R,sr=Y;do try{for(wt=j;sr!==null;){var VA=sr.effectTag;if(VA&36){var Yo=sr.alternate;switch(bt=sr,_r=wt,bt.tag){case 0:case 11:case 15:N(16,32,bt);break;case 1:var rt=bt.stateNode;if(bt.effectTag&4)if(Yo===null)rt.componentDidMount();else{var Ke=bt.elementType===bt.type?Yo.memoizedProps:Ci(bt.type,Yo.memoizedProps);rt.componentDidUpdate(Ke,Yo.memoizedState,rt.__reactInternalSnapshotBeforeUpdate)}var At=bt.updateQueue;At!==null&&Le(bt,At,rt,_r);break;case 3:var Wt=bt.updateQueue;if(Wt!==null){if(ve=null,bt.child!==null)switch(bt.child.tag){case 5:ve=ce(bt.child.stateNode);break;case 1:ve=bt.child.stateNode}Le(bt,Wt,ve,_r)}break;case 5:var vr=bt.stateNode;Yo===null&&bt.effectTag&4&&Z(vr,bt.type,bt.memoizedProps,bt);break;case 6:break;case 4:break;case 12:break;case 13:if(y&&bt.memoizedState===null){var Sn=bt.alternate;if(Sn!==null){var Fr=Sn.memoizedState;if(Fr!==null){var xn=Fr.dehydrated;xn!==null&&oo(xn)}}}break;case 19:case 17:case 20:case 21:break;default:throw Error(n(163))}}if(VA&128){bt=void 0;var ai=sr.ref;if(ai!==null){var en=sr.stateNode;switch(sr.tag){case 5:bt=ce(en);break;default:bt=en}typeof ai=="function"?ai(bt):ai.current=bt}}sr=sr.nextEffect}}catch(ho){if(sr===null)throw Error(n(330));GA(sr,ho),sr=sr.nextEffect}while(sr!==null);sr=null,Qn(),yr=fe}else P.current=R;if(wp)wp=!1,Ig=P,UA=D;else for(sr=Y;sr!==null;)D=sr.nextEffect,sr.nextEffect=null,sr=D;if(D=P.firstPendingTime,D===0&&(Du=null),D===1073741823?P===vw?Bg++:(Bg=0,vw=P):Bg=0,typeof xw=="function"&&xw(R.stateNode,j),fo(P),vu)throw vu=!1,P=Mm,Mm=null,P;return(yr&Tm)!==En||ji(),null}function mF(){for(;sr!==null;){var P=sr.effectTag;(P&256)!==0&&Qt(sr.alternate,sr),(P&512)===0||wp||(wp=!0,gc(97,function(){return Ip(),null})),sr=sr.nextEffect}}function Ip(){if(UA!==90){var P=97<UA?97:UA;return UA=90,lo(P,yF)}}function yF(){if(Ig===null)return!1;var P=Ig;if(Ig=null,(yr&(rs|js))!==En)throw Error(n(331));var D=yr;for(yr|=js,P=P.current.firstEffect;P!==null;){try{var R=P;if((R.effectTag&512)!==0)switch(R.tag){case 0:case 11:case 15:N(128,0,R),N(0,64,R)}}catch(j){if(P===null)throw Error(n(330));GA(P,j)}R=P.nextEffect,P.nextEffect=null,P=R}return yr=D,ji(),!0}function Xv(P,D,R){D=yg(R,D),D=Gv(P,D,1073741823),tt(P,D),P=vg(P,1073741823),P!==null&&fo(P)}function GA(P,D){if(P.tag===3)Xv(P,P,D);else for(var R=P.return;R!==null;){if(R.tag===3){Xv(R,P,D);break}else if(R.tag===1){var j=R.stateNode;if(typeof R.type.getDerivedStateFromError=="function"||typeof j.componentDidCatch=="function"&&(Du===null||!Du.has(j))){P=yg(D,P),P=Yv(R,P,1073741823),tt(R,P),R=vg(R,1073741823),R!==null&&fo(R);break}}R=R.return}}function EF(P,D,R){var j=P.pingCache;j!==null&&j.delete(D),gi===P&&ns===R?Yi===vl||Yi===ha&&Ya===1073741823&&Li()-Iw<Bw?Pu(P,ns):OA=!0:$v(P,R)&&(D=P.lastPingedTime,D!==0&&D<R||(P.lastPingedTime=R,P.finishedExpirationTime===R&&(P.finishedExpirationTime=0,P.finishedWork=null),fo(P)))}function CF(P,D){var R=P.stateNode;R!==null&&R.delete(D),D=0,D===0&&(D=ga(),D=HA(D,P,null)),P=vg(P,D),P!==null&&fo(P)}var Zv;Zv=function(P,D,R){var j=D.expirationTime;if(P!==null){var Y=D.pendingProps;if(P.memoizedProps!==Y||_i.current)qo=!0;else{if(j<R){switch(qo=!1,D.tag){case 3:mg(D),dg();break;case 5:if(Pm(D),D.mode&4&&R!==1&&be(D.type,Y))return D.expirationTime=D.childExpirationTime=1,null;break;case 1:ii(D.type)&&Ac(D);break;case 4:sg(D,D.stateNode.containerInfo);break;case 10:Ho(D,D.memoizedProps.value);break;case 13:if(D.memoizedState!==null)return j=D.child.childExpirationTime,j!==0&&j>=R?ln(P,D,R):(Mn($n,$n.current&1,D),D=si(P,D,R),D!==null?D.sibling:null);Mn($n,$n.current&1,D);break;case 19:if(j=D.childExpirationTime>=R,(P.effectTag&64)!==0){if(j)return qa(P,D,R);D.effectTag|=64}if(Y=D.memoizedState,Y!==null&&(Y.rendering=null,Y.tail=null),Mn($n,$n.current,D),!j)return null}return si(P,D,R)}qo=!1}}else qo=!1;switch(D.expirationTime=0,D.tag){case 2:if(j=D.type,P!==null&&(P.alternate=null,D.alternate=null,D.effectTag|=2),P=D.pendingProps,Y=Me(D,On.current),ds(D,R),Y=lg(null,D,j,P,Y,R),D.effectTag|=1,typeof Y=="object"&&Y!==null&&typeof Y.render=="function"&&Y.$$typeof===void 0){if(D.tag=1,mw(),ii(j)){var fe=!0;Ac(D)}else fe=!1;D.memoizedState=Y.state!==null&&Y.state!==void 0?Y.state:null;var ve=j.getDerivedStateFromProps;typeof ve=="function"&&er(D,j,ve,P),Y.updater=Zr,D.stateNode=Y,Y._reactInternalFiber=D,jo(D,j,P,R),D=mp(null,D,j,!0,fe,R)}else D.tag=0,ws(null,D,Y,R),D=D.child;return D;case 16:if(Y=D.elementType,P!==null&&(P.alternate=null,D.alternate=null,D.effectTag|=2),P=D.pendingProps,ye(Y),Y._status!==1)throw Y._result;switch(Y=Y._result,D.type=Y,fe=D.tag=BF(Y),P=Ci(Y,P),fe){case 0:D=NA(null,D,Y,P,R);break;case 1:D=dp(null,D,Y,P,R);break;case 11:D=Ii(null,D,Y,P,R);break;case 14:D=km(null,D,Y,Ci(Y.type,P),j,R);break;default:throw Error(n(306,Y,""))}return D;case 0:return j=D.type,Y=D.pendingProps,Y=D.elementType===j?Y:Ci(j,Y),NA(P,D,j,Y,R);case 1:return j=D.type,Y=D.pendingProps,Y=D.elementType===j?Y:Ci(j,Y),dp(P,D,j,Y,R);case 3:if(mg(D),j=D.updateQueue,j===null)throw Error(n(282));if(Y=D.memoizedState,Y=Y!==null?Y.element:null,me(D,j,D.pendingProps,null,R),j=D.memoizedState.element,j===Y)dg(),D=si(P,D,R);else{if((Y=D.stateNode.hydrate)&&(y?(Bc=cu(D.stateNode.containerInfo),Aa=D,Y=Il=!0):Y=!1),Y)for(R=ig(D,null,j,R),D.child=R;R;)R.effectTag=R.effectTag&-3|1024,R=R.sibling;else ws(P,D,j,R),dg();D=D.child}return D;case 5:return Pm(D),P===null&&RA(D),j=D.type,Y=D.pendingProps,fe=P!==null?P.memoizedProps:null,ve=Y.children,Qe(j,Y)?ve=null:fe!==null&&Qe(j,fe)&&(D.effectTag|=16),Go(P,D),D.mode&4&&R!==1&&be(j,Y)?(D.expirationTime=D.childExpirationTime=1,D=null):(ws(P,D,ve,R),D=D.child),D;case 6:return P===null&&RA(D),null;case 13:return ln(P,D,R);case 4:return sg(D,D.stateNode.containerInfo),j=D.pendingProps,P===null?D.child=gu(D,null,j,R):ws(P,D,j,R),D.child;case 11:return j=D.type,Y=D.pendingProps,Y=D.elementType===j?Y:Ci(j,Y),Ii(P,D,j,Y,R);case 7:return ws(P,D,D.pendingProps,R),D.child;case 8:return ws(P,D,D.pendingProps.children,R),D.child;case 12:return ws(P,D,D.pendingProps.children,R),D.child;case 10:e:{if(j=D.type._context,Y=D.pendingProps,ve=D.memoizedProps,fe=Y.value,Ho(D,fe),ve!==null){var vt=ve.value;if(fe=hs(vt,fe)?0:(typeof j._calculateChangedBits=="function"?j._calculateChangedBits(vt,fe):1073741823)|0,fe===0){if(ve.children===Y.children&&!_i.current){D=si(P,D,R);break e}}else for(vt=D.child,vt!==null&&(vt.return=D);vt!==null;){var wt=vt.dependencies;if(wt!==null){ve=vt.child;for(var bt=wt.firstContext;bt!==null;){if(bt.context===j&&(bt.observedBits&fe)!==0){vt.tag===1&&(bt=ys(R,null),bt.tag=2,tt(vt,bt)),vt.expirationTime<R&&(vt.expirationTime=R),bt=vt.alternate,bt!==null&&bt.expirationTime<R&&(bt.expirationTime=R),gs(vt.return,R),wt.expirationTime<R&&(wt.expirationTime=R);break}bt=bt.next}}else ve=vt.tag===10&&vt.type===D.type?null:vt.child;if(ve!==null)ve.return=vt;else for(ve=vt;ve!==null;){if(ve===D){ve=null;break}if(vt=ve.sibling,vt!==null){vt.return=ve.return,ve=vt;break}ve=ve.return}vt=ve}}ws(P,D,Y.children,R),D=D.child}return D;case 9:return Y=D.type,fe=D.pendingProps,j=fe.children,ds(D,R),Y=ms(Y,fe.unstable_observedBits),j=j(Y),D.effectTag|=1,ws(P,D,j,R),D.child;case 14:return Y=D.type,fe=Ci(Y,D.pendingProps),fe=Ci(Y.type,fe),km(P,D,Y,fe,j,R);case 15:return Qm(P,D,D.type,D.pendingProps,j,R);case 17:return j=D.type,Y=D.pendingProps,Y=D.elementType===j?Y:Ci(j,Y),P!==null&&(P.alternate=null,D.alternate=null,D.effectTag|=2),D.tag=1,ii(j)?(P=!0,Ac(D)):P=!1,ds(D,R),es(D,j,Y,R),jo(D,j,Y,R),mp(null,D,j,!0,P,R);case 19:return qa(P,D,R)}throw Error(n(156,D.tag))};var xw=null,bw=null;function wF(P){if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u")return!1;var D=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(D.isDisabled||!D.supportsFiber)return!0;try{var R=D.inject(P);xw=function(j){try{D.onCommitFiberRoot(R,j,void 0,(j.current.effectTag&64)===64)}catch{}},bw=function(j){try{D.onCommitFiberUnmount(R,j)}catch{}}}catch{}return!0}function IF(P,D,R,j){this.tag=P,this.key=R,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=D,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=j,this.effectTag=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childExpirationTime=this.expirationTime=0,this.alternate=null}function Dl(P,D,R,j){return new IF(P,D,R,j)}function kw(P){return P=P.prototype,!(!P||!P.isReactComponent)}function BF(P){if(typeof P=="function")return kw(P)?1:0;if(P!=null){if(P=P.$$typeof,P===L)return 11;if(P===te)return 14}return 2}function YA(P,D){var R=P.alternate;return R===null?(R=Dl(P.tag,D,P.key,P.mode),R.elementType=P.elementType,R.type=P.type,R.stateNode=P.stateNode,R.alternate=P,P.alternate=R):(R.pendingProps=D,R.effectTag=0,R.nextEffect=null,R.firstEffect=null,R.lastEffect=null),R.childExpirationTime=P.childExpirationTime,R.expirationTime=P.expirationTime,R.child=P.child,R.memoizedProps=P.memoizedProps,R.memoizedState=P.memoizedState,R.updateQueue=P.updateQueue,D=P.dependencies,R.dependencies=D===null?null:{expirationTime:D.expirationTime,firstContext:D.firstContext,responders:D.responders},R.sibling=P.sibling,R.index=P.index,R.ref=P.ref,R}function Hm(P,D,R,j,Y,fe){var ve=2;if(j=P,typeof P=="function")kw(P)&&(ve=1);else if(typeof P=="string")ve=5;else e:switch(P){case E:return xu(R.children,Y,fe,D);case T:ve=8,Y|=7;break;case I:ve=8,Y|=1;break;case v:return P=Dl(12,R,D,Y|8),P.elementType=v,P.type=v,P.expirationTime=fe,P;case U:return P=Dl(13,R,D,Y),P.type=U,P.elementType=U,P.expirationTime=fe,P;case J:return P=Dl(19,R,D,Y),P.elementType=J,P.expirationTime=fe,P;default:if(typeof P=="object"&&P!==null)switch(P.$$typeof){case b:ve=10;break e;case C:ve=9;break e;case L:ve=11;break e;case te:ve=14;break e;case le:ve=16,j=null;break e}throw Error(n(130,P==null?P:typeof P,""))}return D=Dl(ve,R,D,Y),D.elementType=P,D.type=j,D.expirationTime=fe,D}function xu(P,D,R,j){return P=Dl(7,P,j,D),P.expirationTime=R,P}function Qw(P,D,R){return P=Dl(6,P,null,D),P.expirationTime=R,P}function Fw(P,D,R){return D=Dl(4,P.children!==null?P.children:[],P.key,D),D.expirationTime=R,D.stateNode={containerInfo:P.containerInfo,pendingChildren:null,implementation:P.implementation},D}function vF(P,D,R){this.tag=D,this.current=null,this.containerInfo=P,this.pingCache=this.pendingChildren=null,this.finishedExpirationTime=0,this.finishedWork=null,this.timeoutHandle=He,this.pendingContext=this.context=null,this.hydrate=R,this.callbackNode=null,this.callbackPriority=90,this.lastExpiredTime=this.lastPingedTime=this.nextKnownPendingLevel=this.lastSuspendedTime=this.firstSuspendedTime=this.firstPendingTime=0}function $v(P,D){var R=P.firstSuspendedTime;return P=P.lastSuspendedTime,R!==0&&R>=D&&P<=D}function WA(P,D){var R=P.firstSuspendedTime,j=P.lastSuspendedTime;R<D&&(P.firstSuspendedTime=D),(j>D||R===0)&&(P.lastSuspendedTime=D),D<=P.lastPingedTime&&(P.lastPingedTime=0),D<=P.lastExpiredTime&&(P.lastExpiredTime=0)}function eD(P,D){D>P.firstPendingTime&&(P.firstPendingTime=D);var R=P.firstSuspendedTime;R!==0&&(D>=R?P.firstSuspendedTime=P.lastSuspendedTime=P.nextKnownPendingLevel=0:D>=P.lastSuspendedTime&&(P.lastSuspendedTime=D+1),D>P.nextKnownPendingLevel&&(P.nextKnownPendingLevel=D))}function jm(P,D){var R=P.lastExpiredTime;(R===0||R>D)&&(P.lastExpiredTime=D)}function tD(P){var D=P._reactInternalFiber;if(D===void 0)throw typeof P.render=="function"?Error(n(188)):Error(n(268,Object.keys(P)));return P=Ee(D),P===null?null:P.stateNode}function rD(P,D){P=P.memoizedState,P!==null&&P.dehydrated!==null&&P.retryTime<D&&(P.retryTime=D)}function qm(P,D){rD(P,D),(P=P.alternate)&&rD(P,D)}var nD={createContainer:function(P,D,R){return P=new vF(P,D,R),D=Dl(3,null,null,D===2?7:D===1?3:0),P.current=D,D.stateNode=P},updateContainer:function(P,D,R,j){var Y=D.current,fe=ga(),ve=pt.suspense;fe=HA(fe,Y,ve);e:if(R){R=R._reactInternalFiber;t:{if(we(R)!==R||R.tag!==1)throw Error(n(170));var vt=R;do{switch(vt.tag){case 3:vt=vt.stateNode.context;break t;case 1:if(ii(vt.type)){vt=vt.stateNode.__reactInternalMemoizedMergedChildContext;break t}}vt=vt.return}while(vt!==null);throw Error(n(171))}if(R.tag===1){var wt=R.type;if(ii(wt)){R=uu(R,wt,vt);break e}}R=vt}else R=Ni;return D.context===null?D.context=R:D.pendingContext=R,D=ys(fe,ve),D.payload={element:P},j=j===void 0?null:j,j!==null&&(D.callback=j),tt(Y,D),Sc(Y,fe),fe},batchedEventUpdates:function(P,D){var R=yr;yr|=2;try{return P(D)}finally{yr=R,yr===En&&ji()}},batchedUpdates:function(P,D){var R=yr;yr|=1;try{return P(D)}finally{yr=R,yr===En&&ji()}},unbatchedUpdates:function(P,D){var R=yr;yr&=-2,yr|=Tm;try{return P(D)}finally{yr=R,yr===En&&ji()}},deferredUpdates:function(P){return lo(97,P)},syncUpdates:function(P,D,R,j){return lo(99,P.bind(null,D,R,j))},discreteUpdates:function(P,D,R,j){var Y=yr;yr|=4;try{return lo(98,P.bind(null,D,R,j))}finally{yr=Y,yr===En&&ji()}},flushDiscreteUpdates:function(){(yr&(1|rs|js))===En&&(pF(),Ip())},flushControlled:function(P){var D=yr;yr|=1;try{lo(99,P)}finally{yr=D,yr===En&&ji()}},flushSync:Kv,flushPassiveEffects:Ip,IsThisRendererActing:{current:!1},getPublicRootInstance:function(P){if(P=P.current,!P.child)return null;switch(P.child.tag){case 5:return ce(P.child.stateNode);default:return P.child.stateNode}},attemptSynchronousHydration:function(P){switch(P.tag){case 3:var D=P.stateNode;D.hydrate&&Vv(D,D.firstPendingTime);break;case 13:Kv(function(){return Sc(P,1073741823)}),D=Ua(ga(),150,100),qm(P,D)}},attemptUserBlockingHydration:function(P){if(P.tag===13){var D=Ua(ga(),150,100);Sc(P,D),qm(P,D)}},attemptContinuousHydration:function(P){if(P.tag===13){ga();var D=xA++;Sc(P,D),qm(P,D)}},attemptHydrationAtCurrentPriority:function(P){if(P.tag===13){var D=ga();D=HA(D,P,null),Sc(P,D),qm(P,D)}},findHostInstance:tD,findHostInstanceWithWarning:function(P){return tD(P)},findHostInstanceWithNoPortals:function(P){return P=De(P),P===null?null:P.tag===20?P.stateNode.instance:P.stateNode},shouldSuspend:function(){return!1},injectIntoDevTools:function(P){var D=P.findFiberByHostInstance;return wF(r({},P,{overrideHookState:null,overrideProps:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:u.ReactCurrentDispatcher,findHostInstanceByFiber:function(R){return R=Ee(R),R===null?null:R.stateNode},findFiberByHostInstance:function(R){return D?D(R):null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null}))}};aB.exports=nD.default||nD;var DF=aB.exports;return aB.exports=t,DF}});var kEe=_((mVt,bEe)=>{"use strict";bEe.exports=xEe()});var FEe=_((yVt,QEe)=>{"use strict";var Wyt={ALIGN_COUNT:8,ALIGN_AUTO:0,ALIGN_FLEX_START:1,ALIGN_CENTER:2,ALIGN_FLEX_END:3,ALIGN_STRETCH:4,ALIGN_BASELINE:5,ALIGN_SPACE_BETWEEN:6,ALIGN_SPACE_AROUND:7,DIMENSION_COUNT:2,DIMENSION_WIDTH:0,DIMENSION_HEIGHT:1,DIRECTION_COUNT:3,DIRECTION_INHERIT:0,DIRECTION_LTR:1,DIRECTION_RTL:2,DISPLAY_COUNT:2,DISPLAY_FLEX:0,DISPLAY_NONE:1,EDGE_COUNT:9,EDGE_LEFT:0,EDGE_TOP:1,EDGE_RIGHT:2,EDGE_BOTTOM:3,EDGE_START:4,EDGE_END:5,EDGE_HORIZONTAL:6,EDGE_VERTICAL:7,EDGE_ALL:8,EXPERIMENTAL_FEATURE_COUNT:1,EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS:0,FLEX_DIRECTION_COUNT:4,FLEX_DIRECTION_COLUMN:0,FLEX_DIRECTION_COLUMN_REVERSE:1,FLEX_DIRECTION_ROW:2,FLEX_DIRECTION_ROW_REVERSE:3,JUSTIFY_COUNT:6,JUSTIFY_FLEX_START:0,JUSTIFY_CENTER:1,JUSTIFY_FLEX_END:2,JUSTIFY_SPACE_BETWEEN:3,JUSTIFY_SPACE_AROUND:4,JUSTIFY_SPACE_EVENLY:5,LOG_LEVEL_COUNT:6,LOG_LEVEL_ERROR:0,LOG_LEVEL_WARN:1,LOG_LEVEL_INFO:2,LOG_LEVEL_DEBUG:3,LOG_LEVEL_VERBOSE:4,LOG_LEVEL_FATAL:5,MEASURE_MODE_COUNT:3,MEASURE_MODE_UNDEFINED:0,MEASURE_MODE_EXACTLY:1,MEASURE_MODE_AT_MOST:2,NODE_TYPE_COUNT:2,NODE_TYPE_DEFAULT:0,NODE_TYPE_TEXT:1,OVERFLOW_COUNT:3,OVERFLOW_VISIBLE:0,OVERFLOW_HIDDEN:1,OVERFLOW_SCROLL:2,POSITION_TYPE_COUNT:2,POSITION_TYPE_RELATIVE:0,POSITION_TYPE_ABSOLUTE:1,PRINT_OPTIONS_COUNT:3,PRINT_OPTIONS_LAYOUT:1,PRINT_OPTIONS_STYLE:2,PRINT_OPTIONS_CHILDREN:4,UNIT_COUNT:4,UNIT_UNDEFINED:0,UNIT_POINT:1,UNIT_PERCENT:2,UNIT_AUTO:3,WRAP_COUNT:3,WRAP_NO_WRAP:0,WRAP_WRAP:1,WRAP_WRAP_REVERSE:2};QEe.exports=Wyt});var LEe=_((EVt,NEe)=>{"use strict";var Vyt=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(t[o]=r[o])}return t},Kk=function(){function t(e,r){for(var o=0;o<r.length;o++){var a=r[o];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}return function(e,r,o){return r&&t(e.prototype,r),o&&t(e,o),e}}();function b6(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function k6(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var tu=FEe(),Kyt=function(){function t(e,r,o,a,n,u){k6(this,t),this.left=e,this.right=r,this.top=o,this.bottom=a,this.width=n,this.height=u}return Kk(t,[{key:"fromJS",value:function(r){r(this.left,this.right,this.top,this.bottom,this.width,this.height)}},{key:"toString",value:function(){return"<Layout#"+this.left+":"+this.right+";"+this.top+":"+this.bottom+";"+this.width+":"+this.height+">"}}]),t}(),TEe=function(){Kk(t,null,[{key:"fromJS",value:function(r){var o=r.width,a=r.height;return new t(o,a)}}]);function t(e,r){k6(this,t),this.width=e,this.height=r}return Kk(t,[{key:"fromJS",value:function(r){r(this.width,this.height)}},{key:"toString",value:function(){return"<Size#"+this.width+"x"+this.height+">"}}]),t}(),REe=function(){function t(e,r){k6(this,t),this.unit=e,this.value=r}return Kk(t,[{key:"fromJS",value:function(r){r(this.unit,this.value)}},{key:"toString",value:function(){switch(this.unit){case tu.UNIT_POINT:return String(this.value);case tu.UNIT_PERCENT:return this.value+"%";case tu.UNIT_AUTO:return"auto";default:return this.value+"?"}}},{key:"valueOf",value:function(){return this.value}}]),t}();NEe.exports=function(t,e){function r(u,A,p){var h=u[A];u[A]=function(){for(var E=arguments.length,I=Array(E),v=0;v<E;v++)I[v]=arguments[v];return p.call.apply(p,[this,h].concat(I))}}for(var o=["setPosition","setMargin","setFlexBasis","setWidth","setHeight","setMinWidth","setMinHeight","setMaxWidth","setMaxHeight","setPadding"],a=function(){var A,p=o[n],h=(A={},b6(A,tu.UNIT_POINT,e.Node.prototype[p]),b6(A,tu.UNIT_PERCENT,e.Node.prototype[p+"Percent"]),b6(A,tu.UNIT_AUTO,e.Node.prototype[p+"Auto"]),A);r(e.Node.prototype,p,function(E){for(var I=arguments.length,v=Array(I>1?I-1:0),b=1;b<I;b++)v[b-1]=arguments[b];var C=v.pop(),T=void 0,L=void 0;if(C==="auto")T=tu.UNIT_AUTO,L=void 0;else if(C instanceof REe)T=C.unit,L=C.valueOf();else if(T=typeof C=="string"&&C.endsWith("%")?tu.UNIT_PERCENT:tu.UNIT_POINT,L=parseFloat(C),!Number.isNaN(C)&&Number.isNaN(L))throw new Error("Invalid value "+C+" for "+p);if(!h[T])throw new Error('Failed to execute "'+p+`": Unsupported unit '`+C+"'");if(L!==void 0){var U;return(U=h[T]).call.apply(U,[this].concat(v,[L]))}else{var J;return(J=h[T]).call.apply(J,[this].concat(v))}})},n=0;n<o.length;n++)a();return r(e.Config.prototype,"free",function(){e.Config.destroy(this)}),r(e.Node,"create",function(u,A){return A?e.Node.createWithConfig(A):e.Node.createDefault()}),r(e.Node.prototype,"free",function(){e.Node.destroy(this)}),r(e.Node.prototype,"freeRecursive",function(){for(var u=0,A=this.getChildCount();u<A;++u)this.getChild(0).freeRecursive();this.free()}),r(e.Node.prototype,"setMeasureFunc",function(u,A){return A?u.call(this,function(){return TEe.fromJS(A.apply(void 0,arguments))}):this.unsetMeasureFunc()}),r(e.Node.prototype,"calculateLayout",function(u){var A=arguments.length>1&&arguments[1]!==void 0?arguments[1]:NaN,p=arguments.length>2&&arguments[2]!==void 0?arguments[2]:NaN,h=arguments.length>3&&arguments[3]!==void 0?arguments[3]:tu.DIRECTION_LTR;return u.call(this,A,p,h)}),Vyt({Config:e.Config,Node:e.Node,Layout:t("Layout",Kyt),Size:t("Size",TEe),Value:t("Value",REe),getInstanceCount:function(){return e.getInstanceCount.apply(e,arguments)}},tu)}});var MEe=_((exports,module)=>{(function(t,e){typeof define=="function"&&define.amd?define([],function(){return e}):typeof module=="object"&&module.exports?module.exports=e:(t.nbind=t.nbind||{}).init=e})(exports,function(Module,cb){typeof Module=="function"&&(cb=Module,Module={}),Module.onRuntimeInitialized=function(t,e){return function(){t&&t.apply(this,arguments);try{Module.ccall("nbind_init")}catch(r){e(r);return}e(null,{bind:Module._nbind_value,reflect:Module.NBind.reflect,queryType:Module.NBind.queryType,toggleLightGC:Module.toggleLightGC,lib:Module})}}(Module.onRuntimeInitialized,cb);var Module;Module||(Module=(typeof Module<"u"?Module:null)||{});var moduleOverrides={};for(var key in Module)Module.hasOwnProperty(key)&&(moduleOverrides[key]=Module[key]);var ENVIRONMENT_IS_WEB=!1,ENVIRONMENT_IS_WORKER=!1,ENVIRONMENT_IS_NODE=!1,ENVIRONMENT_IS_SHELL=!1;if(Module.ENVIRONMENT)if(Module.ENVIRONMENT==="WEB")ENVIRONMENT_IS_WEB=!0;else if(Module.ENVIRONMENT==="WORKER")ENVIRONMENT_IS_WORKER=!0;else if(Module.ENVIRONMENT==="NODE")ENVIRONMENT_IS_NODE=!0;else if(Module.ENVIRONMENT==="SHELL")ENVIRONMENT_IS_SHELL=!0;else throw new Error("The provided Module['ENVIRONMENT'] value is not valid. It must be one of: WEB|WORKER|NODE|SHELL.");else ENVIRONMENT_IS_WEB=typeof window=="object",ENVIRONMENT_IS_WORKER=typeof importScripts=="function",ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof Be=="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER,ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){Module.print||(Module.print=console.log),Module.printErr||(Module.printErr=console.warn);var nodeFS,nodePath;Module.read=function(e,r){nodeFS||(nodeFS={}("")),nodePath||(nodePath={}("")),e=nodePath.normalize(e);var o=nodeFS.readFileSync(e);return r?o:o.toString()},Module.readBinary=function(e){var r=Module.read(e,!0);return r.buffer||(r=new Uint8Array(r)),assert(r.buffer),r},Module.load=function(e){globalEval(read(e))},Module.thisProgram||(process.argv.length>1?Module.thisProgram=process.argv[1].replace(/\\/g,"/"):Module.thisProgram="unknown-program"),Module.arguments=process.argv.slice(2),typeof module<"u"&&(module.exports=Module),Module.inspect=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL)Module.print||(Module.print=print),typeof printErr<"u"&&(Module.printErr=printErr),typeof read<"u"?Module.read=read:Module.read=function(){throw"no read() available"},Module.readBinary=function(e){if(typeof readbuffer=="function")return new Uint8Array(readbuffer(e));var r=read(e,"binary");return assert(typeof r=="object"),r},typeof scriptArgs<"u"?Module.arguments=scriptArgs:typeof arguments<"u"&&(Module.arguments=arguments),typeof quit=="function"&&(Module.quit=function(t,e){quit(t)});else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(Module.read=function(e){var r=new XMLHttpRequest;return r.open("GET",e,!1),r.send(null),r.responseText},ENVIRONMENT_IS_WORKER&&(Module.readBinary=function(e){var r=new XMLHttpRequest;return r.open("GET",e,!1),r.responseType="arraybuffer",r.send(null),new Uint8Array(r.response)}),Module.readAsync=function(e,r,o){var a=new XMLHttpRequest;a.open("GET",e,!0),a.responseType="arraybuffer",a.onload=function(){a.status==200||a.status==0&&a.response?r(a.response):o()},a.onerror=o,a.send(null)},typeof arguments<"u"&&(Module.arguments=arguments),typeof console<"u")Module.print||(Module.print=function(e){console.log(e)}),Module.printErr||(Module.printErr=function(e){console.warn(e)});else{var TRY_USE_DUMP=!1;Module.print||(Module.print=TRY_USE_DUMP&&typeof dump<"u"?function(t){dump(t)}:function(t){})}ENVIRONMENT_IS_WORKER&&(Module.load=importScripts),typeof Module.setWindowTitle>"u"&&(Module.setWindowTitle=function(t){document.title=t})}else throw"Unknown runtime environment. Where are we?";function globalEval(t){eval.call(null,t)}!Module.load&&Module.read&&(Module.load=function(e){globalEval(Module.read(e))}),Module.print||(Module.print=function(){}),Module.printErr||(Module.printErr=Module.print),Module.arguments||(Module.arguments=[]),Module.thisProgram||(Module.thisProgram="./this.program"),Module.quit||(Module.quit=function(t,e){throw e}),Module.print=Module.print,Module.printErr=Module.printErr,Module.preRun=[],Module.postRun=[];for(var key in moduleOverrides)moduleOverrides.hasOwnProperty(key)&&(Module[key]=moduleOverrides[key]);moduleOverrides=void 0;var Runtime={setTempRet0:function(t){return tempRet0=t,t},getTempRet0:function(){return tempRet0},stackSave:function(){return STACKTOP},stackRestore:function(t){STACKTOP=t},getNativeTypeSize:function(t){switch(t){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(t[t.length-1]==="*")return Runtime.QUANTUM_SIZE;if(t[0]==="i"){var e=parseInt(t.substr(1));return assert(e%8===0),e/8}else return 0}}},getNativeFieldSize:function(t){return Math.max(Runtime.getNativeTypeSize(t),Runtime.QUANTUM_SIZE)},STACK_ALIGN:16,prepVararg:function(t,e){return e==="double"||e==="i64"?t&7&&(assert((t&7)===4),t+=4):assert((t&3)===0),t},getAlignSize:function(t,e,r){return!r&&(t=="i64"||t=="double")?8:t?Math.min(e||(t?Runtime.getNativeFieldSize(t):0),Runtime.QUANTUM_SIZE):Math.min(e,8)},dynCall:function(t,e,r){return r&&r.length?Module["dynCall_"+t].apply(null,[e].concat(r)):Module["dynCall_"+t].call(null,e)},functionPointers:[],addFunction:function(t){for(var e=0;e<Runtime.functionPointers.length;e++)if(!Runtime.functionPointers[e])return Runtime.functionPointers[e]=t,2*(1+e);throw"Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS."},removeFunction:function(t){Runtime.functionPointers[(t-2)/2]=null},warnOnce:function(t){Runtime.warnOnce.shown||(Runtime.warnOnce.shown={}),Runtime.warnOnce.shown[t]||(Runtime.warnOnce.shown[t]=1,Module.printErr(t))},funcWrappers:{},getFuncWrapper:function(t,e){if(!!t){assert(e),Runtime.funcWrappers[e]||(Runtime.funcWrappers[e]={});var r=Runtime.funcWrappers[e];return r[t]||(e.length===1?r[t]=function(){return Runtime.dynCall(e,t)}:e.length===2?r[t]=function(a){return Runtime.dynCall(e,t,[a])}:r[t]=function(){return Runtime.dynCall(e,t,Array.prototype.slice.call(arguments))}),r[t]}},getCompilerSetting:function(t){throw"You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work"},stackAlloc:function(t){var e=STACKTOP;return STACKTOP=STACKTOP+t|0,STACKTOP=STACKTOP+15&-16,e},staticAlloc:function(t){var e=STATICTOP;return STATICTOP=STATICTOP+t|0,STATICTOP=STATICTOP+15&-16,e},dynamicAlloc:function(t){var e=HEAP32[DYNAMICTOP_PTR>>2],r=(e+t+15|0)&-16;if(HEAP32[DYNAMICTOP_PTR>>2]=r,r>=TOTAL_MEMORY){var o=enlargeMemory();if(!o)return HEAP32[DYNAMICTOP_PTR>>2]=e,0}return e},alignMemory:function(t,e){var r=t=Math.ceil(t/(e||16))*(e||16);return r},makeBigInt:function(t,e,r){var o=r?+(t>>>0)+ +(e>>>0)*4294967296:+(t>>>0)+ +(e|0)*4294967296;return o},GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module.Runtime=Runtime;var ABORT=0,EXITSTATUS=0;function assert(t,e){t||abort("Assertion failed: "+e)}function getCFunc(ident){var func=Module["_"+ident];if(!func)try{func=eval("_"+ident)}catch(t){}return assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)"),func}var cwrap,ccall;(function(){var JSfuncs={stackSave:function(){Runtime.stackSave()},stackRestore:function(){Runtime.stackRestore()},arrayToC:function(t){var e=Runtime.stackAlloc(t.length);return writeArrayToMemory(t,e),e},stringToC:function(t){var e=0;if(t!=null&&t!==0){var r=(t.length<<2)+1;e=Runtime.stackAlloc(r),stringToUTF8(t,e,r)}return e}},toC={string:JSfuncs.stringToC,array:JSfuncs.arrayToC};ccall=function(e,r,o,a,n){var u=getCFunc(e),A=[],p=0;if(a)for(var h=0;h<a.length;h++){var E=toC[o[h]];E?(p===0&&(p=Runtime.stackSave()),A[h]=E(a[h])):A[h]=a[h]}var I=u.apply(null,A);if(r==="string"&&(I=Pointer_stringify(I)),p!==0){if(n&&n.async){EmterpreterAsync.asyncFinalizers.push(function(){Runtime.stackRestore(p)});return}Runtime.stackRestore(p)}return I};var sourceRegex=/^function\s*[a-zA-Z$_0-9]*\s*\(([^)]*)\)\s*{\s*([^*]*?)[\s;]*(?:return\s*(.*?)[;\s]*)?}$/;function parseJSFunc(t){var e=t.toString().match(sourceRegex).slice(1);return{arguments:e[0],body:e[1],returnValue:e[2]}}var JSsource=null;function ensureJSsource(){if(!JSsource){JSsource={};for(var t in JSfuncs)JSfuncs.hasOwnProperty(t)&&(JSsource[t]=parseJSFunc(JSfuncs[t]))}}cwrap=function cwrap(ident,returnType,argTypes){argTypes=argTypes||[];var cfunc=getCFunc(ident),numericArgs=argTypes.every(function(t){return t==="number"}),numericRet=returnType!=="string";if(numericRet&&numericArgs)return cfunc;var argNames=argTypes.map(function(t,e){return"$"+e}),funcstr="(function("+argNames.join(",")+") {",nargs=argTypes.length;if(!numericArgs){ensureJSsource(),funcstr+="var stack = "+JSsource.stackSave.body+";";for(var i=0;i<nargs;i++){var arg=argNames[i],type=argTypes[i];if(type!=="number"){var convertCode=JSsource[type+"ToC"];funcstr+="var "+convertCode.arguments+" = "+arg+";",funcstr+=convertCode.body+";",funcstr+=arg+"=("+convertCode.returnValue+");"}}}var cfuncname=parseJSFunc(function(){return cfunc}).returnValue;if(funcstr+="var ret = "+cfuncname+"("+argNames.join(",")+");",!numericRet){var strgfy=parseJSFunc(function(){return Pointer_stringify}).returnValue;funcstr+="ret = "+strgfy+"(ret);"}return numericArgs||(ensureJSsource(),funcstr+=JSsource.stackRestore.body.replace("()","(stack)")+";"),funcstr+="return ret})",eval(funcstr)}})(),Module.ccall=ccall,Module.cwrap=cwrap;function setValue(t,e,r,o){switch(r=r||"i8",r.charAt(r.length-1)==="*"&&(r="i32"),r){case"i1":HEAP8[t>>0]=e;break;case"i8":HEAP8[t>>0]=e;break;case"i16":HEAP16[t>>1]=e;break;case"i32":HEAP32[t>>2]=e;break;case"i64":tempI64=[e>>>0,(tempDouble=e,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[t>>2]=tempI64[0],HEAP32[t+4>>2]=tempI64[1];break;case"float":HEAPF32[t>>2]=e;break;case"double":HEAPF64[t>>3]=e;break;default:abort("invalid type for setValue: "+r)}}Module.setValue=setValue;function getValue(t,e,r){switch(e=e||"i8",e.charAt(e.length-1)==="*"&&(e="i32"),e){case"i1":return HEAP8[t>>0];case"i8":return HEAP8[t>>0];case"i16":return HEAP16[t>>1];case"i32":return HEAP32[t>>2];case"i64":return HEAP32[t>>2];case"float":return HEAPF32[t>>2];case"double":return HEAPF64[t>>3];default:abort("invalid type for setValue: "+e)}return null}Module.getValue=getValue;var ALLOC_NORMAL=0,ALLOC_STACK=1,ALLOC_STATIC=2,ALLOC_DYNAMIC=3,ALLOC_NONE=4;Module.ALLOC_NORMAL=ALLOC_NORMAL,Module.ALLOC_STACK=ALLOC_STACK,Module.ALLOC_STATIC=ALLOC_STATIC,Module.ALLOC_DYNAMIC=ALLOC_DYNAMIC,Module.ALLOC_NONE=ALLOC_NONE;function allocate(t,e,r,o){var a,n;typeof t=="number"?(a=!0,n=t):(a=!1,n=t.length);var u=typeof e=="string"?e:null,A;if(r==ALLOC_NONE?A=o:A=[typeof _malloc=="function"?_malloc:Runtime.staticAlloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][r===void 0?ALLOC_STATIC:r](Math.max(n,u?1:e.length)),a){var o=A,p;for(assert((A&3)==0),p=A+(n&-4);o<p;o+=4)HEAP32[o>>2]=0;for(p=A+n;o<p;)HEAP8[o++>>0]=0;return A}if(u==="i8")return t.subarray||t.slice?HEAPU8.set(t,A):HEAPU8.set(new Uint8Array(t),A),A;for(var h=0,E,I,v;h<n;){var b=t[h];if(typeof b=="function"&&(b=Runtime.getFunctionIndex(b)),E=u||e[h],E===0){h++;continue}E=="i64"&&(E="i32"),setValue(A+h,b,E),v!==E&&(I=Runtime.getNativeTypeSize(E),v=E),h+=I}return A}Module.allocate=allocate;function getMemory(t){return staticSealed?runtimeInitialized?_malloc(t):Runtime.dynamicAlloc(t):Runtime.staticAlloc(t)}Module.getMemory=getMemory;function Pointer_stringify(t,e){if(e===0||!t)return"";for(var r=0,o,a=0;o=HEAPU8[t+a>>0],r|=o,!(o==0&&!e||(a++,e&&a==e)););e||(e=a);var n="";if(r<128){for(var u=1024,A;e>0;)A=String.fromCharCode.apply(String,HEAPU8.subarray(t,t+Math.min(e,u))),n=n?n+A:A,t+=u,e-=u;return n}return Module.UTF8ToString(t)}Module.Pointer_stringify=Pointer_stringify;function AsciiToString(t){for(var e="";;){var r=HEAP8[t++>>0];if(!r)return e;e+=String.fromCharCode(r)}}Module.AsciiToString=AsciiToString;function stringToAscii(t,e){return writeAsciiToMemory(t,e,!1)}Module.stringToAscii=stringToAscii;var UTF8Decoder=typeof TextDecoder<"u"?new TextDecoder("utf8"):void 0;function UTF8ArrayToString(t,e){for(var r=e;t[r];)++r;if(r-e>16&&t.subarray&&UTF8Decoder)return UTF8Decoder.decode(t.subarray(e,r));for(var o,a,n,u,A,p,h="";;){if(o=t[e++],!o)return h;if(!(o&128)){h+=String.fromCharCode(o);continue}if(a=t[e++]&63,(o&224)==192){h+=String.fromCharCode((o&31)<<6|a);continue}if(n=t[e++]&63,(o&240)==224?o=(o&15)<<12|a<<6|n:(u=t[e++]&63,(o&248)==240?o=(o&7)<<18|a<<12|n<<6|u:(A=t[e++]&63,(o&252)==248?o=(o&3)<<24|a<<18|n<<12|u<<6|A:(p=t[e++]&63,o=(o&1)<<30|a<<24|n<<18|u<<12|A<<6|p))),o<65536)h+=String.fromCharCode(o);else{var E=o-65536;h+=String.fromCharCode(55296|E>>10,56320|E&1023)}}}Module.UTF8ArrayToString=UTF8ArrayToString;function UTF8ToString(t){return UTF8ArrayToString(HEAPU8,t)}Module.UTF8ToString=UTF8ToString;function stringToUTF8Array(t,e,r,o){if(!(o>0))return 0;for(var a=r,n=r+o-1,u=0;u<t.length;++u){var A=t.charCodeAt(u);if(A>=55296&&A<=57343&&(A=65536+((A&1023)<<10)|t.charCodeAt(++u)&1023),A<=127){if(r>=n)break;e[r++]=A}else if(A<=2047){if(r+1>=n)break;e[r++]=192|A>>6,e[r++]=128|A&63}else if(A<=65535){if(r+2>=n)break;e[r++]=224|A>>12,e[r++]=128|A>>6&63,e[r++]=128|A&63}else if(A<=2097151){if(r+3>=n)break;e[r++]=240|A>>18,e[r++]=128|A>>12&63,e[r++]=128|A>>6&63,e[r++]=128|A&63}else if(A<=67108863){if(r+4>=n)break;e[r++]=248|A>>24,e[r++]=128|A>>18&63,e[r++]=128|A>>12&63,e[r++]=128|A>>6&63,e[r++]=128|A&63}else{if(r+5>=n)break;e[r++]=252|A>>30,e[r++]=128|A>>24&63,e[r++]=128|A>>18&63,e[r++]=128|A>>12&63,e[r++]=128|A>>6&63,e[r++]=128|A&63}}return e[r]=0,r-a}Module.stringToUTF8Array=stringToUTF8Array;function stringToUTF8(t,e,r){return stringToUTF8Array(t,HEAPU8,e,r)}Module.stringToUTF8=stringToUTF8;function lengthBytesUTF8(t){for(var e=0,r=0;r<t.length;++r){var o=t.charCodeAt(r);o>=55296&&o<=57343&&(o=65536+((o&1023)<<10)|t.charCodeAt(++r)&1023),o<=127?++e:o<=2047?e+=2:o<=65535?e+=3:o<=2097151?e+=4:o<=67108863?e+=5:e+=6}return e}Module.lengthBytesUTF8=lengthBytesUTF8;var UTF16Decoder=typeof TextDecoder<"u"?new TextDecoder("utf-16le"):void 0;function demangle(t){var e=Module.___cxa_demangle||Module.__cxa_demangle;if(e){try{var r=t.substr(1),o=lengthBytesUTF8(r)+1,a=_malloc(o);stringToUTF8(r,a,o);var n=_malloc(4),u=e(a,0,0,n);if(getValue(n,"i32")===0&&u)return Pointer_stringify(u)}catch{}finally{a&&_free(a),n&&_free(n),u&&_free(u)}return t}return Runtime.warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling"),t}function demangleAll(t){var e=/__Z[\w\d_]+/g;return t.replace(e,function(r){var o=demangle(r);return r===o?r:r+" ["+o+"]"})}function jsStackTrace(){var t=new Error;if(!t.stack){try{throw new Error(0)}catch(e){t=e}if(!t.stack)return"(no stack trace available)"}return t.stack.toString()}function stackTrace(){var t=jsStackTrace();return Module.extraStackTrace&&(t+=` +`+Module.extraStackTrace()),demangleAll(t)}Module.stackTrace=stackTrace;var HEAP,buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferViews(){Module.HEAP8=HEAP8=new Int8Array(buffer),Module.HEAP16=HEAP16=new Int16Array(buffer),Module.HEAP32=HEAP32=new Int32Array(buffer),Module.HEAPU8=HEAPU8=new Uint8Array(buffer),Module.HEAPU16=HEAPU16=new Uint16Array(buffer),Module.HEAPU32=HEAPU32=new Uint32Array(buffer),Module.HEAPF32=HEAPF32=new Float32Array(buffer),Module.HEAPF64=HEAPF64=new Float64Array(buffer)}var STATIC_BASE,STATICTOP,staticSealed,STACK_BASE,STACKTOP,STACK_MAX,DYNAMIC_BASE,DYNAMICTOP_PTR;STATIC_BASE=STATICTOP=STACK_BASE=STACKTOP=STACK_MAX=DYNAMIC_BASE=DYNAMICTOP_PTR=0,staticSealed=!1;function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or (4) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}function enlargeMemory(){abortOnCannotGrowMemory()}var TOTAL_STACK=Module.TOTAL_STACK||5242880,TOTAL_MEMORY=Module.TOTAL_MEMORY||134217728;TOTAL_MEMORY<TOTAL_STACK&&Module.printErr("TOTAL_MEMORY should be larger than TOTAL_STACK, was "+TOTAL_MEMORY+"! (TOTAL_STACK="+TOTAL_STACK+")"),Module.buffer?buffer=Module.buffer:buffer=new ArrayBuffer(TOTAL_MEMORY),updateGlobalBufferViews();function getTotalMemory(){return TOTAL_MEMORY}if(HEAP32[0]=1668509029,HEAP16[1]=25459,HEAPU8[2]!==115||HEAPU8[3]!==99)throw"Runtime error: expected the system to be little-endian!";Module.HEAP=HEAP,Module.buffer=buffer,Module.HEAP8=HEAP8,Module.HEAP16=HEAP16,Module.HEAP32=HEAP32,Module.HEAPU8=HEAPU8,Module.HEAPU16=HEAPU16,Module.HEAPU32=HEAPU32,Module.HEAPF32=HEAPF32,Module.HEAPF64=HEAPF64;function callRuntimeCallbacks(t){for(;t.length>0;){var e=t.shift();if(typeof e=="function"){e();continue}var r=e.func;typeof r=="number"?e.arg===void 0?Module.dynCall_v(r):Module.dynCall_vi(r,e.arg):r(e.arg===void 0?null:e.arg)}}var __ATPRERUN__=[],__ATINIT__=[],__ATMAIN__=[],__ATEXIT__=[],__ATPOSTRUN__=[],runtimeInitialized=!1,runtimeExited=!1;function preRun(){if(Module.preRun)for(typeof Module.preRun=="function"&&(Module.preRun=[Module.preRun]);Module.preRun.length;)addOnPreRun(Module.preRun.shift());callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){runtimeInitialized||(runtimeInitialized=!0,callRuntimeCallbacks(__ATINIT__))}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__),runtimeExited=!0}function postRun(){if(Module.postRun)for(typeof Module.postRun=="function"&&(Module.postRun=[Module.postRun]);Module.postRun.length;)addOnPostRun(Module.postRun.shift());callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(t){__ATPRERUN__.unshift(t)}Module.addOnPreRun=addOnPreRun;function addOnInit(t){__ATINIT__.unshift(t)}Module.addOnInit=addOnInit;function addOnPreMain(t){__ATMAIN__.unshift(t)}Module.addOnPreMain=addOnPreMain;function addOnExit(t){__ATEXIT__.unshift(t)}Module.addOnExit=addOnExit;function addOnPostRun(t){__ATPOSTRUN__.unshift(t)}Module.addOnPostRun=addOnPostRun;function intArrayFromString(t,e,r){var o=r>0?r:lengthBytesUTF8(t)+1,a=new Array(o),n=stringToUTF8Array(t,a,0,a.length);return e&&(a.length=n),a}Module.intArrayFromString=intArrayFromString;function intArrayToString(t){for(var e=[],r=0;r<t.length;r++){var o=t[r];o>255&&(o&=255),e.push(String.fromCharCode(o))}return e.join("")}Module.intArrayToString=intArrayToString;function writeStringToMemory(t,e,r){Runtime.warnOnce("writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!");var o,a;r&&(a=e+lengthBytesUTF8(t),o=HEAP8[a]),stringToUTF8(t,e,1/0),r&&(HEAP8[a]=o)}Module.writeStringToMemory=writeStringToMemory;function writeArrayToMemory(t,e){HEAP8.set(t,e)}Module.writeArrayToMemory=writeArrayToMemory;function writeAsciiToMemory(t,e,r){for(var o=0;o<t.length;++o)HEAP8[e++>>0]=t.charCodeAt(o);r||(HEAP8[e>>0]=0)}if(Module.writeAsciiToMemory=writeAsciiToMemory,(!Math.imul||Math.imul(4294967295,5)!==-5)&&(Math.imul=function t(e,r){var o=e>>>16,a=e&65535,n=r>>>16,u=r&65535;return a*u+(o*u+a*n<<16)|0}),Math.imul=Math.imul,!Math.fround){var froundBuffer=new Float32Array(1);Math.fround=function(t){return froundBuffer[0]=t,froundBuffer[0]}}Math.fround=Math.fround,Math.clz32||(Math.clz32=function(t){t=t>>>0;for(var e=0;e<32;e++)if(t&1<<31-e)return e;return 32}),Math.clz32=Math.clz32,Math.trunc||(Math.trunc=function(t){return t<0?Math.ceil(t):Math.floor(t)}),Math.trunc=Math.trunc;var Math_abs=Math.abs,Math_cos=Math.cos,Math_sin=Math.sin,Math_tan=Math.tan,Math_acos=Math.acos,Math_asin=Math.asin,Math_atan=Math.atan,Math_atan2=Math.atan2,Math_exp=Math.exp,Math_log=Math.log,Math_sqrt=Math.sqrt,Math_ceil=Math.ceil,Math_floor=Math.floor,Math_pow=Math.pow,Math_imul=Math.imul,Math_fround=Math.fround,Math_round=Math.round,Math_min=Math.min,Math_clz32=Math.clz32,Math_trunc=Math.trunc,runDependencies=0,runDependencyWatcher=null,dependenciesFulfilled=null;function getUniqueRunDependency(t){return t}function addRunDependency(t){runDependencies++,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies)}Module.addRunDependency=addRunDependency;function removeRunDependency(t){if(runDependencies--,Module.monitorRunDependencies&&Module.monitorRunDependencies(runDependencies),runDependencies==0&&(runDependencyWatcher!==null&&(clearInterval(runDependencyWatcher),runDependencyWatcher=null),dependenciesFulfilled)){var e=dependenciesFulfilled;dependenciesFulfilled=null,e()}}Module.removeRunDependency=removeRunDependency,Module.preloadedImages={},Module.preloadedAudios={};var ASM_CONSTS=[function(t,e,r,o,a,n,u,A){return _nbind.callbackSignatureList[t].apply(this,arguments)}];function _emscripten_asm_const_iiiiiiii(t,e,r,o,a,n,u,A){return ASM_CONSTS[t](e,r,o,a,n,u,A)}function _emscripten_asm_const_iiiii(t,e,r,o,a){return ASM_CONSTS[t](e,r,o,a)}function _emscripten_asm_const_iiidddddd(t,e,r,o,a,n,u,A,p){return ASM_CONSTS[t](e,r,o,a,n,u,A,p)}function _emscripten_asm_const_iiididi(t,e,r,o,a,n,u){return ASM_CONSTS[t](e,r,o,a,n,u)}function _emscripten_asm_const_iiii(t,e,r,o){return ASM_CONSTS[t](e,r,o)}function _emscripten_asm_const_iiiid(t,e,r,o,a){return ASM_CONSTS[t](e,r,o,a)}function _emscripten_asm_const_iiiiii(t,e,r,o,a,n){return ASM_CONSTS[t](e,r,o,a,n)}STATIC_BASE=Runtime.GLOBAL_BASE,STATICTOP=STATIC_BASE+12800,__ATINIT__.push({func:function(){__GLOBAL__sub_I_Yoga_cpp()}},{func:function(){__GLOBAL__sub_I_nbind_cc()}},{func:function(){__GLOBAL__sub_I_common_cc()}},{func:function(){__GLOBAL__sub_I_Binding_cc()}}),allocate([0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,192,127,0,0,192,127,3,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,3,0,0,0,0,0,192,127,3,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,192,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,127,0,0,192,127,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,0,0,128,191,0,0,128,191,0,0,192,127,0,0,0,0,0,0,0,0,0,0,128,63,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,190,12,0,0,200,12,0,0,208,12,0,0,216,12,0,0,230,12,0,0,242,12,0,0,1,0,0,0,3,0,0,0,0,0,0,0,2,0,0,0,0,0,192,127,3,0,0,0,180,45,0,0,181,45,0,0,182,45,0,0,181,45,0,0,182,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,4,0,0,0,183,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,181,45,0,0,184,45,0,0,185,45,0,0,181,45,0,0,181,45,0,0,182,45,0,0,186,45,0,0,185,45,0,0,148,4,0,0,3,0,0,0,187,45,0,0,164,4,0,0,188,45,0,0,2,0,0,0,189,45,0,0,164,4,0,0,188,45,0,0,185,45,0,0,164,4,0,0,185,45,0,0,164,4,0,0,188,45,0,0,181,45,0,0,182,45,0,0,181,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,5,0,0,0,6,0,0,0,1,0,0,0,7,0,0,0,183,45,0,0,182,45,0,0,181,45,0,0,190,45,0,0,190,45,0,0,182,45,0,0,182,45,0,0,185,45,0,0,181,45,0,0,185,45,0,0,182,45,0,0,181,45,0,0,185,45,0,0,182,45,0,0,185,45,0,0,48,5,0,0,3,0,0,0,56,5,0,0,1,0,0,0,189,45,0,0,185,45,0,0,164,4,0,0,76,5,0,0,2,0,0,0,191,45,0,0,186,45,0,0,182,45,0,0,185,45,0,0,192,45,0,0,185,45,0,0,182,45,0,0,186,45,0,0,185,45,0,0,76,5,0,0,76,5,0,0,136,5,0,0,182,45,0,0,181,45,0,0,2,0,0,0,190,45,0,0,136,5,0,0,56,19,0,0,156,5,0,0,2,0,0,0,184,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0,0,9,0,0,0,1,0,0,0,10,0,0,0,204,5,0,0,181,45,0,0,181,45,0,0,2,0,0,0,180,45,0,0,204,5,0,0,2,0,0,0,195,45,0,0,236,5,0,0,97,19,0,0,198,45,0,0,211,45,0,0,212,45,0,0,213,45,0,0,214,45,0,0,215,45,0,0,188,45,0,0,182,45,0,0,216,45,0,0,217,45,0,0,218,45,0,0,219,45,0,0,192,45,0,0,181,45,0,0,0,0,0,0,185,45,0,0,110,19,0,0,186,45,0,0,115,19,0,0,221,45,0,0,120,19,0,0,148,4,0,0,132,19,0,0,96,6,0,0,145,19,0,0,222,45,0,0,164,19,0,0,223,45,0,0,173,19,0,0,0,0,0,0,3,0,0,0,104,6,0,0,1,0,0,0,187,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,12,0,0,0,1,0,0,0,13,0,0,0,185,45,0,0,224,45,0,0,164,6,0,0,188,45,0,0,172,6,0,0,180,6,0,0,2,0,0,0,188,6,0,0,7,0,0,0,224,45,0,0,7,0,0,0,164,6,0,0,1,0,0,0,213,45,0,0,185,45,0,0,224,45,0,0,172,6,0,0,185,45,0,0,224,45,0,0,164,6,0,0,185,45,0,0,224,45,0,0,211,45,0,0,211,45,0,0,222,45,0,0,211,45,0,0,224,45,0,0,222,45,0,0,211,45,0,0,224,45,0,0,172,6,0,0,222,45,0,0,211,45,0,0,224,45,0,0,188,45,0,0,222,45,0,0,211,45,0,0,40,7,0,0,188,45,0,0,2,0,0,0,224,45,0,0,185,45,0,0,188,45,0,0,188,45,0,0,188,45,0,0,188,45,0,0,222,45,0,0,224,45,0,0,148,4,0,0,185,45,0,0,148,4,0,0,148,4,0,0,148,4,0,0,148,4,0,0,148,4,0,0,185,45,0,0,164,6,0,0,148,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,14,0,0,0,15,0,0,0,1,0,0,0,16,0,0,0,148,7,0,0,2,0,0,0,225,45,0,0,183,45,0,0,188,45,0,0,168,7,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,234,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,148,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,9,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,242,45,0,0,0,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67,111,117,108,100,32,110,111,116,32,97,108,108,111,99,97,116,101,32,109,101,109,111,114,121,32,102,111,114,32,110,111,100,101,0,67,97,110,110,111,116,32,114,101,115,101,116,32,97,32,110,111,100,101,32,119,104,105,99,104,32,115,116,105,108,108,32,104,97,115,32,99,104,105,108,100,114,101,110,32,97,116,116,97,99,104,101,100,0,67,97,110,110,111,116,32,114,101,115,101,116,32,97,32,110,111,100,101,32,115,116,105,108,108,32,97,116,116,97,99,104,101,100,32,116,111,32,97,32,112,97,114,101,110,116,0,67,111,117,108,100,32,110,111,116,32,97,108,108,111,99,97,116,101,32,109,101,109,111,114,121,32,102,111,114,32,99,111,110,102,105,103,0,67,97,110,110,111,116,32,115,101,116,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,58,32,78,111,100,101,115,32,119,105,116,104,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,32,99,97,110,110,111,116,32,104,97,118,101,32,99,104,105,108,100,114,101,110,46,0,67,104,105,108,100,32,97,108,114,101,97,100,121,32,104,97,115,32,97,32,112,97,114,101,110,116,44,32,105,116,32,109,117,115,116,32,98,101,32,114,101,109,111,118,101,100,32,102,105,114,115,116,46,0,67,97,110,110,111,116,32,97,100,100,32,99,104,105,108,100,58,32,78,111,100,101,115,32,119,105,116,104,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,32,99,97,110,110,111,116,32,104,97,118,101,32,99,104,105,108,100,114,101,110,46,0,79,110,108,121,32,108,101,97,102,32,110,111,100,101,115,32,119,105,116,104,32,99,117,115,116,111,109,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,115,115,104,111,117,108,100,32,109,97,110,117,97,108,108,121,32,109,97,114,107,32,116,104,101,109,115,101,108,118,101,115,32,97,115,32,100,105,114,116,121,0,67,97,110,110,111,116,32,103,101,116,32,108,97,121,111,117,116,32,112,114,111,112,101,114,116,105,101,115,32,111,102,32,109,117,108,116,105,45,101,100,103,101,32,115,104,111,114,116,104,97,110,100,115,0,37,115,37,100,46,123,91,115,107,105,112,112,101,100,93,32,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,97,119,58,32,37,102,32,97,104,58,32,37,102,32,61,62,32,100,58,32,40,37,102,44,32,37,102,41,32,37,115,10,0,37,115,37,100,46,123,37,115,0,42,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,97,119,58,32,37,102,32,97,104,58,32,37,102,32,37,115,10,0,37,115,37,100,46,125,37,115,0,119,109,58,32,37,115,44,32,104,109,58,32,37,115,44,32,100,58,32,40,37,102,44,32,37,102,41,32,37,115,10,0,79,117,116,32,111,102,32,99,97,99,104,101,32,101,110,116,114,105,101,115,33,10,0,83,99,97,108,101,32,102,97,99,116,111,114,32,115,104,111,117,108,100,32,110,111,116,32,98,101,32,108,101,115,115,32,116,104,97,110,32,122,101,114,111,0,105,110,105,116,105,97,108,0,37,115,10,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,85,78,68,69,70,73,78,69,68,0,69,88,65,67,84,76,89,0,65,84,95,77,79,83,84,0,76,65,89,95,85,78,68,69,70,73,78,69,68,0,76,65,89,95,69,88,65,67,84,76,89,0,76,65,89,95,65,84,95,77,79,83,84,0,97,118,97,105,108,97,98,108,101,87,105,100,116,104,32,105,115,32,105,110,100,101,102,105,110,105,116,101,32,115,111,32,119,105,100,116,104,77,101,97,115,117,114,101,77,111,100,101,32,109,117,115,116,32,98,101,32,89,71,77,101,97,115,117,114,101,77,111,100,101,85,110,100,101,102,105,110,101,100,0,97,118,97,105,108,97,98,108,101,72,101,105,103,104,116,32,105,115,32,105,110,100,101,102,105,110,105,116,101,32,115,111,32,104,101,105,103,104,116,77,101,97,115,117,114,101,77,111,100,101,32,109,117,115,116,32,98,101,32,89,71,77,101,97,115,117,114,101,77,111,100,101,85,110,100,101,102,105,110,101,100,0,102,108,101,120,0,115,116,114,101,116,99,104,0,109,117,108,116,105,108,105,110,101,45,115,116,114,101,116,99,104,0,69,120,112,101,99,116,101,100,32,110,111,100,101,32,116,111,32,104,97,118,101,32,99,117,115,116,111,109,32,109,101,97,115,117,114,101,32,102,117,110,99,116,105,111,110,0,109,101,97,115,117,114,101,0,69,120,112,101,99,116,32,99,117,115,116,111,109,32,98,97,115,101,108,105,110,101,32,102,117,110,99,116,105,111,110,32,116,111,32,110,111,116,32,114,101,116,117,114,110,32,78,97,78,0,97,98,115,45,109,101,97,115,117,114,101,0,97,98,115,45,108,97,121,111,117,116,0,78,111,100,101,0,99,114,101,97,116,101,68,101,102,97,117,108,116,0,99,114,101,97,116,101,87,105,116,104,67,111,110,102,105,103,0,100,101,115,116,114,111,121,0,114,101,115,101,116,0,99,111,112,121,83,116,121,108,101,0,115,101,116,80,111,115,105,116,105,111,110,84,121,112,101,0,115,101,116,80,111,115,105,116,105,111,110,0,115,101,116,80,111,115,105,116,105,111,110,80,101,114,99,101,110,116,0,115,101,116,65,108,105,103,110,67,111,110,116,101,110,116,0,115,101,116,65,108,105,103,110,73,116,101,109,115,0,115,101,116,65,108,105,103,110,83,101,108,102,0,115,101,116,70,108,101,120,68,105,114,101,99,116,105,111,110,0,115,101,116,70,108,101,120,87,114,97,112,0,115,101,116,74,117,115,116,105,102,121,67,111,110,116,101,110,116,0,115,101,116,77,97,114,103,105,110,0,115,101,116,77,97,114,103,105,110,80,101,114,99,101,110,116,0,115,101,116,77,97,114,103,105,110,65,117,116,111,0,115,101,116,79,118,101,114,102,108,111,119,0,115,101,116,68,105,115,112,108,97,121,0,115,101,116,70,108,101,120,0,115,101,116,70,108,101,120,66,97,115,105,115,0,115,101,116,70,108,101,120,66,97,115,105,115,80,101,114,99,101,110,116,0,115,101,116,70,108,101,120,71,114,111,119,0,115,101,116,70,108,101,120,83,104,114,105,110,107,0,115,101,116,87,105,100,116,104,0,115,101,116,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,87,105,100,116,104,65,117,116,111,0,115,101,116,72,101,105,103,104,116,0,115,101,116,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,72,101,105,103,104,116,65,117,116,111,0,115,101,116,77,105,110,87,105,100,116,104,0,115,101,116,77,105,110,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,77,105,110,72,101,105,103,104,116,0,115,101,116,77,105,110,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,77,97,120,87,105,100,116,104,0,115,101,116,77,97,120,87,105,100,116,104,80,101,114,99,101,110,116,0,115,101,116,77,97,120,72,101,105,103,104,116,0,115,101,116,77,97,120,72,101,105,103,104,116,80,101,114,99,101,110,116,0,115,101,116,65,115,112,101,99,116,82,97,116,105,111,0,115,101,116,66,111,114,100,101,114,0,115,101,116,80,97,100,100,105,110,103,0,115,101,116,80,97,100,100,105,110,103,80,101,114,99,101,110,116,0,103,101,116,80,111,115,105,116,105,111,110,84,121,112,101,0,103,101,116,80,111,115,105,116,105,111,110,0,103,101,116,65,108,105,103,110,67,111,110,116,101,110,116,0,103,101,116,65,108,105,103,110,73,116,101,109,115,0,103,101,116,65,108,105,103,110,83,101,108,102,0,103,101,116,70,108,101,120,68,105,114,101,99,116,105,111,110,0,103,101,116,70,108,101,120,87,114,97,112,0,103,101,116,74,117,115,116,105,102,121,67,111,110,116,101,110,116,0,103,101,116,77,97,114,103,105,110,0,103,101,116,70,108,101,120,66,97,115,105,115,0,103,101,116,70,108,101,120,71,114,111,119,0,103,101,116,70,108,101,120,83,104,114,105,110,107,0,103,101,116,87,105,100,116,104,0,103,101,116,72,101,105,103,104,116,0,103,101,116,77,105,110,87,105,100,116,104,0,103,101,116,77,105,110,72,101,105,103,104,116,0,103,101,116,77,97,120,87,105,100,116,104,0,103,101,116,77,97,120,72,101,105,103,104,116,0,103,101,116,65,115,112,101,99,116,82,97,116,105,111,0,103,101,116,66,111,114,100,101,114,0,103,101,116,79,118,101,114,102,108,111,119,0,103,101,116,68,105,115,112,108,97,121,0,103,101,116,80,97,100,100,105,110,103,0,105,110,115,101,114,116,67,104,105,108,100,0,114,101,109,111,118,101,67,104,105,108,100,0,103,101,116,67,104,105,108,100,67,111,117,110,116,0,103,101,116,80,97,114,101,110,116,0,103,101,116,67,104,105,108,100,0,115,101,116,77,101,97,115,117,114,101,70,117,110,99,0,117,110,115,101,116,77,101,97,115,117,114,101,70,117,110,99,0,109,97,114,107,68,105,114,116,121,0,105,115,68,105,114,116,121,0,99,97,108,99,117,108,97,116,101,76,97,121,111,117,116,0,103,101,116,67,111,109,112,117,116,101,100,76,101,102,116,0,103,101,116,67,111,109,112,117,116,101,100,82,105,103,104,116,0,103,101,116,67,111,109,112,117,116,101,100,84,111,112,0,103,101,116,67,111,109,112,117,116,101,100,66,111,116,116,111,109,0,103,101,116,67,111,109,112,117,116,101,100,87,105,100,116,104,0,103,101,116,67,111,109,112,117,116,101,100,72,101,105,103,104,116,0,103,101,116,67,111,109,112,117,116,101,100,76,97,121,111,117,116,0,103,101,116,67,111,109,112,117,116,101,100,77,97,114,103,105,110,0,103,101,116,67,111,109,112,117,116,101,100,66,111,114,100,101,114,0,103,101,116,67,111,109,112,117,116,101,100,80,97,100,100,105,110,103,0,67,111,110,102,105,103,0,99,114,101,97,116,101,0,115,101,116,69,120,112,101,114,105,109,101,110,116,97,108,70,101,97,116,117,114,101,69,110,97,98,108,101,100,0,115,101,116,80,111,105,110,116,83,99,97,108,101,70,97,99,116,111,114,0,105,115,69,120,112,101,114,105,109,101,110,116,97,108,70,101,97,116,117,114,101,69,110,97,98,108,101,100,0,86,97,108,117,101,0,76,97,121,111,117,116,0,83,105,122,101,0,103,101,116,73,110,115,116,97,110,99,101,67,111,117,110,116,0,73,110,116,54,52,0,1,1,1,2,2,4,4,4,4,8,8,4,8,118,111,105,100,0,98,111,111,108,0,115,116,100,58,58,115,116,114,105,110,103,0,99,98,70,117,110,99,116,105,111,110,32,38,0,99,111,110,115,116,32,99,98,70,117,110,99,116,105,111,110,32,38,0,69,120,116,101,114,110,97,108,0,66,117,102,102,101,114,0,78,66,105,110,100,73,68,0,78,66,105,110,100,0,98,105,110,100,95,118,97,108,117,101,0,114,101,102,108,101,99,116,0,113,117,101,114,121,84,121,112,101,0,108,97,108,108,111,99,0,108,114,101,115,101,116,0,123,114,101,116,117,114,110,40,95,110,98,105,110,100,46,99,97,108,108,98,97,99,107,83,105,103,110,97,116,117,114,101,76,105,115,116,91,36,48,93,46,97,112,112,108,121,40,116,104,105,115,44,97,114,103,117,109,101,110,116,115,41,41,59,125,0,95,110,98,105,110,100,95,110,101,119,0,17,0,10,0,17,17,17,0,0,0,0,5,0,0,0,0,0,0,9,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,15,10,17,17,17,3,10,7,0,1,19,9,11,11,0,0,9,6,11,0,0,11,0,6,17,0,0,0,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,10,10,17,17,17,0,10,0,0,2,0,9,11,0,0,0,9,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,13,0,0,0,0,9,14,0,0,0,0,0,14,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,15,0,0,0,0,9,16,0,0,0,0,0,16,0,0,16,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,10,0,0,0,0,9,11,0,0,0,0,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,45,43,32,32,32,48,88,48,120,0,40,110,117,108,108,41,0,45,48,88,43,48,88,32,48,88,45,48,120,43,48,120,32,48,120,0,105,110,102,0,73,78,70,0,110,97,110,0,78,65,78,0,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,46,0,84,33,34,25,13,1,2,3,17,75,28,12,16,4,11,29,18,30,39,104,110,111,112,113,98,32,5,6,15,19,20,21,26,8,22,7,40,36,23,24,9,10,14,27,31,37,35,131,130,125,38,42,43,60,61,62,63,67,71,74,77,88,89,90,91,92,93,94,95,96,97,99,100,101,102,103,105,106,107,108,114,115,116,121,122,123,124,0,73,108,108,101,103,97,108,32,98,121,116,101,32,115,101,113,117,101,110,99,101,0,68,111,109,97,105,110,32,101,114,114,111,114,0,82,101,115,117,108,116,32,110,111,116,32,114,101,112,114,101,115,101,110,116,97,98,108,101,0,78,111,116,32,97,32,116,116,121,0,80,101,114,109,105,115,115,105,111,110,32,100,101,110,105,101,100,0,79,112,101,114,97,116,105,111,110,32,110,111,116,32,112,101,114,109,105,116,116,101,100,0,78,111,32,115,117,99,104,32,102,105,108,101,32,111,114,32,100,105,114,101,99,116,111,114,121,0,78,111,32,115,117,99,104,32,112,114,111,99,101,115,115,0,70,105,108,101,32,101,120,105,115,116,115,0,86,97,108,117,101,32,116,111,111,32,108,97,114,103,101,32,102,111,114,32,100,97,116,97,32,116,121,112,101,0,78,111,32,115,112,97,99,101,32,108,101,102,116,32,111,110,32,100,101,118,105,99,101,0,79,117,116,32,111,102,32,109,101,109,111,114,121,0,82,101,115,111,117,114,99,101,32,98,117,115,121,0,73,110,116,101,114,114,117,112,116,101,100,32,115,121,115,116,101,109,32,99,97,108,108,0,82,101,115,111,117,114,99,101,32,116,101,109,112,111,114,97,114,105,108,121,32,117,110,97,118,97,105,108,97,98,108,101,0,73,110,118,97,108,105,100,32,115,101,101,107,0,67,114,111,115,115,45,100,101,118,105,99,101,32,108,105,110,107,0,82,101,97,100,45,111,110,108,121,32,102,105,108,101,32,115,121,115,116,101,109,0,68,105,114,101,99,116,111,114,121,32,110,111,116,32,101,109,112,116,121,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,112,101,101,114,0,79,112,101,114,97,116,105,111,110,32,116,105,109,101,100,32,111,117,116,0,67,111,110,110,101,99,116,105,111,110,32,114,101,102,117,115,101,100,0,72,111,115,116,32,105,115,32,100,111,119,110,0,72,111,115,116,32,105,115,32,117,110,114,101,97,99,104,97,98,108,101,0,65,100,100,114,101,115,115,32,105,110,32,117,115,101,0,66,114,111,107,101,110,32,112,105,112,101,0,73,47,79,32,101,114,114,111,114,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,32,111,114,32,97,100,100,114,101,115,115,0,66,108,111,99,107,32,100,101,118,105,99,101,32,114,101,113,117,105,114,101,100,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,0,78,111,116,32,97,32,100,105,114,101,99,116,111,114,121,0,73,115,32,97,32,100,105,114,101,99,116,111,114,121,0,84,101,120,116,32,102,105,108,101,32,98,117,115,121,0,69,120,101,99,32,102,111,114,109,97,116,32,101,114,114,111,114,0,73,110,118,97,108,105,100,32,97,114,103,117,109,101,110,116,0,65,114,103,117,109,101,110,116,32,108,105,115,116,32,116,111,111,32,108,111,110,103,0,83,121,109,98,111,108,105,99,32,108,105,110,107,32,108,111,111,112,0,70,105,108,101,110,97,109,101,32,116,111,111,32,108,111,110,103,0,84,111,111,32,109,97,110,121,32,111,112,101,110,32,102,105,108,101,115,32,105,110,32,115,121,115,116,101,109,0,78,111,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,115,32,97,118,97,105,108,97,98,108,101,0,66,97,100,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,0,78,111,32,99,104,105,108,100,32,112,114,111,99,101,115,115,0,66,97,100,32,97,100,100,114,101,115,115,0,70,105,108,101,32,116,111,111,32,108,97,114,103,101,0,84,111,111,32,109,97,110,121,32,108,105,110,107,115,0,78,111,32,108,111,99,107,115,32,97,118,97,105,108,97,98,108,101,0,82,101,115,111,117,114,99,101,32,100,101,97,100,108,111,99,107,32,119,111,117,108,100,32,111,99,99,117,114,0,83,116,97,116,101,32,110,111,116,32,114,101,99,111,118,101,114,97,98,108,101,0,80,114,101,118,105,111,117,115,32,111,119,110,101,114,32,100,105,101,100,0,79,112,101,114,97,116,105,111,110,32,99,97,110,99,101,108,101,100,0,70,117,110,99,116,105,111,110,32,110,111,116,32,105,109,112,108,101,109,101,110,116,101,100,0,78,111,32,109,101,115,115,97,103,101,32,111,102,32,100,101,115,105,114,101,100,32,116,121,112,101,0,73,100,101,110,116,105,102,105,101,114,32,114,101,109,111,118,101,100,0,68,101,118,105,99,101,32,110,111,116,32,97,32,115,116,114,101,97,109,0,78,111,32,100,97,116,97,32,97,118,97,105,108,97,98,108,101,0,68,101,118,105,99,101,32,116,105,109,101,111,117,116,0,79,117,116,32,111,102,32,115,116,114,101,97,109,115,32,114,101,115,111,117,114,99,101,115,0,76,105,110,107,32,104,97,115,32,98,101,101,110,32,115,101,118,101,114,101,100,0,80,114,111,116,111,99,111,108,32,101,114,114,111,114,0,66,97,100,32,109,101,115,115,97,103,101,0,70,105,108,101,32,100,101,115,99,114,105,112,116,111,114,32,105,110,32,98,97,100,32,115,116,97,116,101,0,78,111,116,32,97,32,115,111,99,107,101,116,0,68,101,115,116,105,110,97,116,105,111,110,32,97,100,100,114,101,115,115,32,114,101,113,117,105,114,101,100,0,77,101,115,115,97,103,101,32,116,111,111,32,108,97,114,103,101,0,80,114,111,116,111,99,111,108,32,119,114,111,110,103,32,116,121,112,101,32,102,111,114,32,115,111,99,107,101,116,0,80,114,111,116,111,99,111,108,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,80,114,111,116,111,99,111,108,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,83,111,99,107,101,116,32,116,121,112,101,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,78,111,116,32,115,117,112,112,111,114,116,101,100,0,80,114,111,116,111,99,111,108,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,65,100,100,114,101,115,115,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,32,98,121,32,112,114,111,116,111,99,111,108,0,65,100,100,114,101,115,115,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,78,101,116,119,111,114,107,32,105,115,32,100,111,119,110,0,78,101,116,119,111,114,107,32,117,110,114,101,97,99,104,97,98,108,101,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,110,101,116,119,111,114,107,0,67,111,110,110,101,99,116,105,111,110,32,97,98,111,114,116,101,100,0,78,111,32,98,117,102,102,101,114,32,115,112,97,99,101,32,97,118,97,105,108,97,98,108,101,0,83,111,99,107,101,116,32,105,115,32,99,111,110,110,101,99,116,101,100,0,83,111,99,107,101,116,32,110,111,116,32,99,111,110,110,101,99,116,101,100,0,67,97,110,110,111,116,32,115,101,110,100,32,97,102,116,101,114,32,115,111,99,107,101,116,32,115,104,117,116,100,111,119,110,0,79,112,101,114,97,116,105,111,110,32,97,108,114,101,97,100,121,32,105,110,32,112,114,111,103,114,101,115,115,0,79,112,101,114,97,116,105,111,110,32,105,110,32,112,114,111,103,114,101,115,115,0,83,116,97,108,101,32,102,105,108,101,32,104,97,110,100,108,101,0,82,101,109,111,116,101,32,73,47,79,32,101,114,114,111,114,0,81,117,111,116,97,32,101,120,99,101,101,100,101,100,0,78,111,32,109,101,100,105,117,109,32,102,111,117,110,100,0,87,114,111,110,103,32,109,101,100,105,117,109,32,116,121,112,101,0,78,111,32,101,114,114,111,114,32,105,110,102,111,114,109,97,116,105,111,110,0,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);var tempDoublePtr=STATICTOP;STATICTOP+=16;function _atexit(t,e){__ATEXIT__.unshift({func:t,arg:e})}function ___cxa_atexit(){return _atexit.apply(null,arguments)}function _abort(){Module.abort()}function __ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj(){Module.printErr("missing function: _ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj"),abort(-1)}function __decorate(t,e,r,o){var a=arguments.length,n=a<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,r):o,u;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")n=Reflect.decorate(t,e,r,o);else for(var A=t.length-1;A>=0;A--)(u=t[A])&&(n=(a<3?u(n):a>3?u(e,r,n):u(e,r))||n);return a>3&&n&&Object.defineProperty(e,r,n),n}function _defineHidden(t){return function(e,r){Object.defineProperty(e,r,{configurable:!1,enumerable:!1,value:t,writable:!0})}}var _nbind={};function __nbind_free_external(t){_nbind.externalList[t].dereference(t)}function __nbind_reference_external(t){_nbind.externalList[t].reference()}function _llvm_stackrestore(t){var e=_llvm_stacksave,r=e.LLVM_SAVEDSTACKS[t];e.LLVM_SAVEDSTACKS.splice(t,1),Runtime.stackRestore(r)}function __nbind_register_pool(t,e,r,o){_nbind.Pool.pageSize=t,_nbind.Pool.usedPtr=e/4,_nbind.Pool.rootPtr=r,_nbind.Pool.pagePtr=o/4,HEAP32[e/4]=16909060,HEAP8[e]==1&&(_nbind.bigEndian=!0),HEAP32[e/4]=0,_nbind.makeTypeKindTbl=(n={},n[1024]=_nbind.PrimitiveType,n[64]=_nbind.Int64Type,n[2048]=_nbind.BindClass,n[3072]=_nbind.BindClassPtr,n[4096]=_nbind.SharedClassPtr,n[5120]=_nbind.ArrayType,n[6144]=_nbind.ArrayType,n[7168]=_nbind.CStringType,n[9216]=_nbind.CallbackType,n[10240]=_nbind.BindType,n),_nbind.makeTypeNameTbl={Buffer:_nbind.BufferType,External:_nbind.ExternalType,Int64:_nbind.Int64Type,_nbind_new:_nbind.CreateValueType,bool:_nbind.BooleanType,"cbFunction &":_nbind.CallbackType,"const cbFunction &":_nbind.CallbackType,"const std::string &":_nbind.StringType,"std::string":_nbind.StringType},Module.toggleLightGC=_nbind.toggleLightGC,_nbind.callUpcast=Module.dynCall_ii;var a=_nbind.makeType(_nbind.constructType,{flags:2048,id:0,name:""});a.proto=Module,_nbind.BindClass.list.push(a);var n}function _emscripten_set_main_loop_timing(t,e){if(Browser.mainLoop.timingMode=t,Browser.mainLoop.timingValue=e,!Browser.mainLoop.func)return 1;if(t==0)Browser.mainLoop.scheduler=function(){var u=Math.max(0,Browser.mainLoop.tickStartTime+e-_emscripten_get_now())|0;setTimeout(Browser.mainLoop.runner,u)},Browser.mainLoop.method="timeout";else if(t==1)Browser.mainLoop.scheduler=function(){Browser.requestAnimationFrame(Browser.mainLoop.runner)},Browser.mainLoop.method="rAF";else if(t==2){if(!window.setImmediate){let n=function(u){u.source===window&&u.data===o&&(u.stopPropagation(),r.shift()())};var a=n,r=[],o="setimmediate";window.addEventListener("message",n,!0),window.setImmediate=function(A){r.push(A),ENVIRONMENT_IS_WORKER?(Module.setImmediates===void 0&&(Module.setImmediates=[]),Module.setImmediates.push(A),window.postMessage({target:o})):window.postMessage(o,"*")}}Browser.mainLoop.scheduler=function(){window.setImmediate(Browser.mainLoop.runner)},Browser.mainLoop.method="immediate"}return 0}function _emscripten_get_now(){abort()}function _emscripten_set_main_loop(t,e,r,o,a){Module.noExitRuntime=!0,assert(!Browser.mainLoop.func,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters."),Browser.mainLoop.func=t,Browser.mainLoop.arg=o;var n;typeof o<"u"?n=function(){Module.dynCall_vi(t,o)}:n=function(){Module.dynCall_v(t)};var u=Browser.mainLoop.currentlyRunningMainloop;if(Browser.mainLoop.runner=function(){if(!ABORT){if(Browser.mainLoop.queue.length>0){var p=Date.now(),h=Browser.mainLoop.queue.shift();if(h.func(h.arg),Browser.mainLoop.remainingBlockers){var E=Browser.mainLoop.remainingBlockers,I=E%1==0?E-1:Math.floor(E);h.counted?Browser.mainLoop.remainingBlockers=I:(I=I+.5,Browser.mainLoop.remainingBlockers=(8*E+I)/9)}if(console.log('main loop blocker "'+h.name+'" took '+(Date.now()-p)+" ms"),Browser.mainLoop.updateStatus(),u<Browser.mainLoop.currentlyRunningMainloop)return;setTimeout(Browser.mainLoop.runner,0);return}if(!(u<Browser.mainLoop.currentlyRunningMainloop)){if(Browser.mainLoop.currentFrameNumber=Browser.mainLoop.currentFrameNumber+1|0,Browser.mainLoop.timingMode==1&&Browser.mainLoop.timingValue>1&&Browser.mainLoop.currentFrameNumber%Browser.mainLoop.timingValue!=0){Browser.mainLoop.scheduler();return}else Browser.mainLoop.timingMode==0&&(Browser.mainLoop.tickStartTime=_emscripten_get_now());Browser.mainLoop.method==="timeout"&&Module.ctx&&(Module.printErr("Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!"),Browser.mainLoop.method=""),Browser.mainLoop.runIter(n),!(u<Browser.mainLoop.currentlyRunningMainloop)&&(typeof SDL=="object"&&SDL.audio&&SDL.audio.queueNewAudioData&&SDL.audio.queueNewAudioData(),Browser.mainLoop.scheduler())}}},a||(e&&e>0?_emscripten_set_main_loop_timing(0,1e3/e):_emscripten_set_main_loop_timing(1,1),Browser.mainLoop.scheduler()),r)throw"SimulateInfiniteLoop"}var Browser={mainLoop:{scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:function(){Browser.mainLoop.scheduler=null,Browser.mainLoop.currentlyRunningMainloop++},resume:function(){Browser.mainLoop.currentlyRunningMainloop++;var t=Browser.mainLoop.timingMode,e=Browser.mainLoop.timingValue,r=Browser.mainLoop.func;Browser.mainLoop.func=null,_emscripten_set_main_loop(r,0,!1,Browser.mainLoop.arg,!0),_emscripten_set_main_loop_timing(t,e),Browser.mainLoop.scheduler()},updateStatus:function(){if(Module.setStatus){var t=Module.statusMessage||"Please wait...",e=Browser.mainLoop.remainingBlockers,r=Browser.mainLoop.expectedBlockers;e?e<r?Module.setStatus(t+" ("+(r-e)+"/"+r+")"):Module.setStatus(t):Module.setStatus("")}},runIter:function(t){if(!ABORT){if(Module.preMainLoop){var e=Module.preMainLoop();if(e===!1)return}try{t()}catch(r){if(r instanceof ExitStatus)return;throw r&&typeof r=="object"&&r.stack&&Module.printErr("exception thrown: "+[r,r.stack]),r}Module.postMainLoop&&Module.postMainLoop()}}},isFullscreen:!1,pointerLock:!1,moduleContextCreatedCallbacks:[],workers:[],init:function(){if(Module.preloadPlugins||(Module.preloadPlugins=[]),Browser.initted)return;Browser.initted=!0;try{new Blob,Browser.hasBlobConstructor=!0}catch{Browser.hasBlobConstructor=!1,console.log("warning: no blob constructor, cannot create blobs with mimetypes")}Browser.BlobBuilder=typeof MozBlobBuilder<"u"?MozBlobBuilder:typeof WebKitBlobBuilder<"u"?WebKitBlobBuilder:Browser.hasBlobConstructor?null:console.log("warning: no BlobBuilder"),Browser.URLObject=typeof window<"u"?window.URL?window.URL:window.webkitURL:void 0,!Module.noImageDecoding&&typeof Browser.URLObject>"u"&&(console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available."),Module.noImageDecoding=!0);var t={};t.canHandle=function(n){return!Module.noImageDecoding&&/\.(jpg|jpeg|png|bmp)$/i.test(n)},t.handle=function(n,u,A,p){var h=null;if(Browser.hasBlobConstructor)try{h=new Blob([n],{type:Browser.getMimetype(u)}),h.size!==n.length&&(h=new Blob([new Uint8Array(n).buffer],{type:Browser.getMimetype(u)}))}catch(b){Runtime.warnOnce("Blob constructor present but fails: "+b+"; falling back to blob builder")}if(!h){var E=new Browser.BlobBuilder;E.append(new Uint8Array(n).buffer),h=E.getBlob()}var I=Browser.URLObject.createObjectURL(h),v=new Image;v.onload=function(){assert(v.complete,"Image "+u+" could not be decoded");var C=document.createElement("canvas");C.width=v.width,C.height=v.height;var T=C.getContext("2d");T.drawImage(v,0,0),Module.preloadedImages[u]=C,Browser.URLObject.revokeObjectURL(I),A&&A(n)},v.onerror=function(C){console.log("Image "+I+" could not be decoded"),p&&p()},v.src=I},Module.preloadPlugins.push(t);var e={};e.canHandle=function(n){return!Module.noAudioDecoding&&n.substr(-4)in{".ogg":1,".wav":1,".mp3":1}},e.handle=function(n,u,A,p){var h=!1;function E(T){h||(h=!0,Module.preloadedAudios[u]=T,A&&A(n))}function I(){h||(h=!0,Module.preloadedAudios[u]=new Audio,p&&p())}if(Browser.hasBlobConstructor){try{var v=new Blob([n],{type:Browser.getMimetype(u)})}catch{return I()}var b=Browser.URLObject.createObjectURL(v),C=new Audio;C.addEventListener("canplaythrough",function(){E(C)},!1),C.onerror=function(L){if(h)return;console.log("warning: browser could not fully decode audio "+u+", trying slower base64 approach");function U(J){for(var te="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",le="=",pe="",Ae=0,ye=0,ae=0;ae<J.length;ae++)for(Ae=Ae<<8|J[ae],ye+=8;ye>=6;){var we=Ae>>ye-6&63;ye-=6,pe+=te[we]}return ye==2?(pe+=te[(Ae&3)<<4],pe+=le+le):ye==4&&(pe+=te[(Ae&15)<<2],pe+=le),pe}C.src="data:audio/x-"+u.substr(-3)+";base64,"+U(n),E(C)},C.src=b,Browser.safeSetTimeout(function(){E(C)},1e4)}else return I()},Module.preloadPlugins.push(e);function r(){Browser.pointerLock=document.pointerLockElement===Module.canvas||document.mozPointerLockElement===Module.canvas||document.webkitPointerLockElement===Module.canvas||document.msPointerLockElement===Module.canvas}var o=Module.canvas;o&&(o.requestPointerLock=o.requestPointerLock||o.mozRequestPointerLock||o.webkitRequestPointerLock||o.msRequestPointerLock||function(){},o.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock||document.msExitPointerLock||function(){},o.exitPointerLock=o.exitPointerLock.bind(document),document.addEventListener("pointerlockchange",r,!1),document.addEventListener("mozpointerlockchange",r,!1),document.addEventListener("webkitpointerlockchange",r,!1),document.addEventListener("mspointerlockchange",r,!1),Module.elementPointerLock&&o.addEventListener("click",function(a){!Browser.pointerLock&&Module.canvas.requestPointerLock&&(Module.canvas.requestPointerLock(),a.preventDefault())},!1))},createContext:function(t,e,r,o){if(e&&Module.ctx&&t==Module.canvas)return Module.ctx;var a,n;if(e){var u={antialias:!1,alpha:!1};if(o)for(var A in o)u[A]=o[A];n=GL.createContext(t,u),n&&(a=GL.getContext(n).GLctx)}else a=t.getContext("2d");return a?(r&&(e||assert(typeof GLctx>"u","cannot set in module if GLctx is used, but we are a non-GL context that would replace it"),Module.ctx=a,e&&GL.makeContextCurrent(n),Module.useWebGL=e,Browser.moduleContextCreatedCallbacks.forEach(function(p){p()}),Browser.init()),a):null},destroyContext:function(t,e,r){},fullscreenHandlersInstalled:!1,lockPointer:void 0,resizeCanvas:void 0,requestFullscreen:function(t,e,r){Browser.lockPointer=t,Browser.resizeCanvas=e,Browser.vrDevice=r,typeof Browser.lockPointer>"u"&&(Browser.lockPointer=!0),typeof Browser.resizeCanvas>"u"&&(Browser.resizeCanvas=!1),typeof Browser.vrDevice>"u"&&(Browser.vrDevice=null);var o=Module.canvas;function a(){Browser.isFullscreen=!1;var u=o.parentNode;(document.fullscreenElement||document.mozFullScreenElement||document.msFullscreenElement||document.webkitFullscreenElement||document.webkitCurrentFullScreenElement)===u?(o.exitFullscreen=document.exitFullscreen||document.cancelFullScreen||document.mozCancelFullScreen||document.msExitFullscreen||document.webkitCancelFullScreen||function(){},o.exitFullscreen=o.exitFullscreen.bind(document),Browser.lockPointer&&o.requestPointerLock(),Browser.isFullscreen=!0,Browser.resizeCanvas&&Browser.setFullscreenCanvasSize()):(u.parentNode.insertBefore(o,u),u.parentNode.removeChild(u),Browser.resizeCanvas&&Browser.setWindowedCanvasSize()),Module.onFullScreen&&Module.onFullScreen(Browser.isFullscreen),Module.onFullscreen&&Module.onFullscreen(Browser.isFullscreen),Browser.updateCanvasDimensions(o)}Browser.fullscreenHandlersInstalled||(Browser.fullscreenHandlersInstalled=!0,document.addEventListener("fullscreenchange",a,!1),document.addEventListener("mozfullscreenchange",a,!1),document.addEventListener("webkitfullscreenchange",a,!1),document.addEventListener("MSFullscreenChange",a,!1));var n=document.createElement("div");o.parentNode.insertBefore(n,o),n.appendChild(o),n.requestFullscreen=n.requestFullscreen||n.mozRequestFullScreen||n.msRequestFullscreen||(n.webkitRequestFullscreen?function(){n.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}:null)||(n.webkitRequestFullScreen?function(){n.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}:null),r?n.requestFullscreen({vrDisplay:r}):n.requestFullscreen()},requestFullScreen:function(t,e,r){return Module.printErr("Browser.requestFullScreen() is deprecated. Please call Browser.requestFullscreen instead."),Browser.requestFullScreen=function(o,a,n){return Browser.requestFullscreen(o,a,n)},Browser.requestFullscreen(t,e,r)},nextRAF:0,fakeRequestAnimationFrame:function(t){var e=Date.now();if(Browser.nextRAF===0)Browser.nextRAF=e+1e3/60;else for(;e+2>=Browser.nextRAF;)Browser.nextRAF+=1e3/60;var r=Math.max(Browser.nextRAF-e,0);setTimeout(t,r)},requestAnimationFrame:function t(e){typeof window>"u"?Browser.fakeRequestAnimationFrame(e):(window.requestAnimationFrame||(window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame||Browser.fakeRequestAnimationFrame),window.requestAnimationFrame(e))},safeCallback:function(t){return function(){if(!ABORT)return t.apply(null,arguments)}},allowAsyncCallbacks:!0,queuedAsyncCallbacks:[],pauseAsyncCallbacks:function(){Browser.allowAsyncCallbacks=!1},resumeAsyncCallbacks:function(){if(Browser.allowAsyncCallbacks=!0,Browser.queuedAsyncCallbacks.length>0){var t=Browser.queuedAsyncCallbacks;Browser.queuedAsyncCallbacks=[],t.forEach(function(e){e()})}},safeRequestAnimationFrame:function(t){return Browser.requestAnimationFrame(function(){ABORT||(Browser.allowAsyncCallbacks?t():Browser.queuedAsyncCallbacks.push(t))})},safeSetTimeout:function(t,e){return Module.noExitRuntime=!0,setTimeout(function(){ABORT||(Browser.allowAsyncCallbacks?t():Browser.queuedAsyncCallbacks.push(t))},e)},safeSetInterval:function(t,e){return Module.noExitRuntime=!0,setInterval(function(){ABORT||Browser.allowAsyncCallbacks&&t()},e)},getMimetype:function(t){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",bmp:"image/bmp",ogg:"audio/ogg",wav:"audio/wav",mp3:"audio/mpeg"}[t.substr(t.lastIndexOf(".")+1)]},getUserMedia:function(t){window.getUserMedia||(window.getUserMedia=navigator.getUserMedia||navigator.mozGetUserMedia),window.getUserMedia(t)},getMovementX:function(t){return t.movementX||t.mozMovementX||t.webkitMovementX||0},getMovementY:function(t){return t.movementY||t.mozMovementY||t.webkitMovementY||0},getMouseWheelDelta:function(t){var e=0;switch(t.type){case"DOMMouseScroll":e=t.detail;break;case"mousewheel":e=t.wheelDelta;break;case"wheel":e=t.deltaY;break;default:throw"unrecognized mouse wheel event: "+t.type}return e},mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:function(t){if(Browser.pointerLock)t.type!="mousemove"&&"mozMovementX"in t?Browser.mouseMovementX=Browser.mouseMovementY=0:(Browser.mouseMovementX=Browser.getMovementX(t),Browser.mouseMovementY=Browser.getMovementY(t)),typeof SDL<"u"?(Browser.mouseX=SDL.mouseX+Browser.mouseMovementX,Browser.mouseY=SDL.mouseY+Browser.mouseMovementY):(Browser.mouseX+=Browser.mouseMovementX,Browser.mouseY+=Browser.mouseMovementY);else{var e=Module.canvas.getBoundingClientRect(),r=Module.canvas.width,o=Module.canvas.height,a=typeof window.scrollX<"u"?window.scrollX:window.pageXOffset,n=typeof window.scrollY<"u"?window.scrollY:window.pageYOffset;if(t.type==="touchstart"||t.type==="touchend"||t.type==="touchmove"){var u=t.touch;if(u===void 0)return;var A=u.pageX-(a+e.left),p=u.pageY-(n+e.top);A=A*(r/e.width),p=p*(o/e.height);var h={x:A,y:p};if(t.type==="touchstart")Browser.lastTouches[u.identifier]=h,Browser.touches[u.identifier]=h;else if(t.type==="touchend"||t.type==="touchmove"){var E=Browser.touches[u.identifier];E||(E=h),Browser.lastTouches[u.identifier]=E,Browser.touches[u.identifier]=h}return}var I=t.pageX-(a+e.left),v=t.pageY-(n+e.top);I=I*(r/e.width),v=v*(o/e.height),Browser.mouseMovementX=I-Browser.mouseX,Browser.mouseMovementY=v-Browser.mouseY,Browser.mouseX=I,Browser.mouseY=v}},asyncLoad:function(t,e,r,o){var a=o?"":"al "+t;Module.readAsync(t,function(n){assert(n,'Loading data file "'+t+'" failed (no arrayBuffer).'),e(new Uint8Array(n)),a&&removeRunDependency(a)},function(n){if(r)r();else throw'Loading data file "'+t+'" failed.'}),a&&addRunDependency(a)},resizeListeners:[],updateResizeListeners:function(){var t=Module.canvas;Browser.resizeListeners.forEach(function(e){e(t.width,t.height)})},setCanvasSize:function(t,e,r){var o=Module.canvas;Browser.updateCanvasDimensions(o,t,e),r||Browser.updateResizeListeners()},windowedWidth:0,windowedHeight:0,setFullscreenCanvasSize:function(){if(typeof SDL<"u"){var t=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];t=t|8388608,HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=t}Browser.updateResizeListeners()},setWindowedCanvasSize:function(){if(typeof SDL<"u"){var t=HEAPU32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2];t=t&-8388609,HEAP32[SDL.screen+Runtime.QUANTUM_SIZE*0>>2]=t}Browser.updateResizeListeners()},updateCanvasDimensions:function(t,e,r){e&&r?(t.widthNative=e,t.heightNative=r):(e=t.widthNative,r=t.heightNative);var o=e,a=r;if(Module.forcedAspectRatio&&Module.forcedAspectRatio>0&&(o/a<Module.forcedAspectRatio?o=Math.round(a*Module.forcedAspectRatio):a=Math.round(o/Module.forcedAspectRatio)),(document.fullscreenElement||document.mozFullScreenElement||document.msFullscreenElement||document.webkitFullscreenElement||document.webkitCurrentFullScreenElement)===t.parentNode&&typeof screen<"u"){var n=Math.min(screen.width/o,screen.height/a);o=Math.round(o*n),a=Math.round(a*n)}Browser.resizeCanvas?(t.width!=o&&(t.width=o),t.height!=a&&(t.height=a),typeof t.style<"u"&&(t.style.removeProperty("width"),t.style.removeProperty("height"))):(t.width!=e&&(t.width=e),t.height!=r&&(t.height=r),typeof t.style<"u"&&(o!=e||a!=r?(t.style.setProperty("width",o+"px","important"),t.style.setProperty("height",a+"px","important")):(t.style.removeProperty("width"),t.style.removeProperty("height"))))},wgetRequests:{},nextWgetRequestHandle:0,getNextWgetRequestHandle:function(){var t=Browser.nextWgetRequestHandle;return Browser.nextWgetRequestHandle++,t}},SYSCALLS={varargs:0,get:function(t){SYSCALLS.varargs+=4;var e=HEAP32[SYSCALLS.varargs-4>>2];return e},getStr:function(){var t=Pointer_stringify(SYSCALLS.get());return t},get64:function(){var t=SYSCALLS.get(),e=SYSCALLS.get();return t>=0?assert(e===0):assert(e===-1),t},getZero:function(){assert(SYSCALLS.get()===0)}};function ___syscall6(t,e){SYSCALLS.varargs=e;try{var r=SYSCALLS.getStreamFromFD();return FS.close(r),0}catch(o){return(typeof FS>"u"||!(o instanceof FS.ErrnoError))&&abort(o),-o.errno}}function ___syscall54(t,e){SYSCALLS.varargs=e;try{return 0}catch(r){return(typeof FS>"u"||!(r instanceof FS.ErrnoError))&&abort(r),-r.errno}}function _typeModule(t){var e=[[0,1,"X"],[1,1,"const X"],[128,1,"X *"],[256,1,"X &"],[384,1,"X &&"],[512,1,"std::shared_ptr<X>"],[640,1,"std::unique_ptr<X>"],[5120,1,"std::vector<X>"],[6144,2,"std::array<X, Y>"],[9216,-1,"std::function<X (Y)>"]];function r(p,h,E,I,v,b){if(h==1){var C=I&896;(C==128||C==256||C==384)&&(p="X const")}var T;return b?T=E.replace("X",p).replace("Y",v):T=p.replace("X",E).replace("Y",v),T.replace(/([*&]) (?=[*&])/g,"$1")}function o(p,h,E,I,v){throw new Error(p+" type "+E.replace("X",h+"?")+(I?" with flag "+I:"")+" in "+v)}function a(p,h,E,I,v,b,C,T){b===void 0&&(b="X"),T===void 0&&(T=1);var L=E(p);if(L)return L;var U=I(p),J=U.placeholderFlag,te=e[J];C&&te&&(b=r(C[2],C[0],b,te[0],"?",!0));var le;J==0&&(le="Unbound"),J>=10&&(le="Corrupt"),T>20&&(le="Deeply nested"),le&&o(le,p,b,J,v||"?");var pe=U.paramList[0],Ae=a(pe,h,E,I,v,b,te,T+1),ye,ae={flags:te[0],id:p,name:"",paramList:[Ae]},we=[],Pe="?";switch(U.placeholderFlag){case 1:ye=Ae.spec;break;case 2:if((Ae.flags&15360)==1024&&Ae.spec.ptrSize==1){ae.flags=7168;break}case 3:case 6:case 5:ye=Ae.spec,Ae.flags&15360;break;case 8:Pe=""+U.paramList[1],ae.paramList.push(U.paramList[1]);break;case 9:for(var g=0,Ee=U.paramList[1];g<Ee.length;g++){var De=Ee[g],ce=a(De,h,E,I,v,b,te,T+1);we.push(ce.name),ae.paramList.push(ce)}Pe=we.join(", ");break;default:break}if(ae.name=r(te[2],te[0],Ae.name,Ae.flags,Pe),ye){for(var ne=0,ee=Object.keys(ye);ne<ee.length;ne++){var Ie=ee[ne];ae[Ie]=ae[Ie]||ye[Ie]}ae.flags|=ye.flags}return n(h,ae)}function n(p,h){var E=h.flags,I=E&896,v=E&15360;return!h.name&&v==1024&&(h.ptrSize==1?h.name=(E&16?"":(E&8?"un":"")+"signed ")+"char":h.name=(E&8?"u":"")+(E&32?"float":"int")+(h.ptrSize*8+"_t")),h.ptrSize==8&&!(E&32)&&(v=64),v==2048&&(I==512||I==640?v=4096:I&&(v=3072)),p(v,h)}var u=function(){function p(h){this.id=h.id,this.name=h.name,this.flags=h.flags,this.spec=h}return p.prototype.toString=function(){return this.name},p}(),A={Type:u,getComplexType:a,makeType:n,structureList:e};return t.output=A,t.output||A}function __nbind_register_type(t,e){var r=_nbind.readAsciiString(e),o={flags:10240,id:t,name:r};_nbind.makeType(_nbind.constructType,o)}function __nbind_register_callback_signature(t,e){var r=_nbind.readTypeIdList(t,e),o=_nbind.callbackSignatureList.length;return _nbind.callbackSignatureList[o]=_nbind.makeJSCaller(r),o}function __extends(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);function o(){this.constructor=t}o.prototype=e.prototype,t.prototype=new o}function __nbind_register_class(t,e,r,o,a,n,u){var A=_nbind.readAsciiString(u),p=_nbind.readPolicyList(e),h=HEAPU32.subarray(t/4,t/4+2),E={flags:2048|(p.Value?2:0),id:h[0],name:A},I=_nbind.makeType(_nbind.constructType,E);I.ptrType=_nbind.getComplexType(h[1],_nbind.constructType,_nbind.getType,_nbind.queryType),I.destroy=_nbind.makeMethodCaller(I.ptrType,{boundID:E.id,flags:0,name:"destroy",num:0,ptr:n,title:I.name+".free",typeList:["void","uint32_t","uint32_t"]}),a&&(I.superIdList=Array.prototype.slice.call(HEAPU32.subarray(r/4,r/4+a)),I.upcastList=Array.prototype.slice.call(HEAPU32.subarray(o/4,o/4+a))),Module[I.name]=I.makeBound(p),_nbind.BindClass.list.push(I)}function _removeAccessorPrefix(t){var e=/^[Gg]et_?([A-Z]?([A-Z]?))/;return t.replace(e,function(r,o,a){return a?o:o.toLowerCase()})}function __nbind_register_function(t,e,r,o,a,n,u,A,p,h){var E=_nbind.getType(t),I=_nbind.readPolicyList(e),v=_nbind.readTypeIdList(r,o),b;if(u==5)b=[{direct:a,name:"__nbindConstructor",ptr:0,title:E.name+" constructor",typeList:["uint32_t"].concat(v.slice(1))},{direct:n,name:"__nbindValueConstructor",ptr:0,title:E.name+" value constructor",typeList:["void","uint32_t"].concat(v.slice(1))}];else{var C=_nbind.readAsciiString(A),T=(E.name&&E.name+".")+C;(u==3||u==4)&&(C=_removeAccessorPrefix(C)),b=[{boundID:t,direct:n,name:C,ptr:a,title:T,typeList:v}]}for(var L=0,U=b;L<U.length;L++){var J=U[L];J.signatureType=u,J.policyTbl=I,J.num=p,J.flags=h,E.addMethod(J)}}function _nbind_value(t,e){_nbind.typeNameTbl[t]||_nbind.throwError("Unknown value type "+t),Module.NBind.bind_value(t,e),_defineHidden(_nbind.typeNameTbl[t].proto.prototype.__nbindValueConstructor)(e.prototype,"__nbindValueConstructor")}Module._nbind_value=_nbind_value;function __nbind_get_value_object(t,e){var r=_nbind.popValue(t);if(!r.fromJS)throw new Error("Object "+r+" has no fromJS function");r.fromJS(function(){r.__nbindValueConstructor.apply(this,Array.prototype.concat.apply([e],arguments))})}function _emscripten_memcpy_big(t,e,r){return HEAPU8.set(HEAPU8.subarray(e,e+r),t),t}function __nbind_register_primitive(t,e,r){var o={flags:1024|r,id:t,ptrSize:e};_nbind.makeType(_nbind.constructType,o)}var cttz_i8=allocate([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0],"i8",ALLOC_STATIC);function ___setErrNo(t){return Module.___errno_location&&(HEAP32[Module.___errno_location()>>2]=t),t}function _llvm_stacksave(){var t=_llvm_stacksave;return t.LLVM_SAVEDSTACKS||(t.LLVM_SAVEDSTACKS=[]),t.LLVM_SAVEDSTACKS.push(Runtime.stackSave()),t.LLVM_SAVEDSTACKS.length-1}function ___syscall140(t,e){SYSCALLS.varargs=e;try{var r=SYSCALLS.getStreamFromFD(),o=SYSCALLS.get(),a=SYSCALLS.get(),n=SYSCALLS.get(),u=SYSCALLS.get(),A=a;return FS.llseek(r,A,u),HEAP32[n>>2]=r.position,r.getdents&&A===0&&u===0&&(r.getdents=null),0}catch(p){return(typeof FS>"u"||!(p instanceof FS.ErrnoError))&&abort(p),-p.errno}}function ___syscall146(t,e){SYSCALLS.varargs=e;try{var r=SYSCALLS.get(),o=SYSCALLS.get(),a=SYSCALLS.get(),n=0;___syscall146.buffer||(___syscall146.buffers=[null,[],[]],___syscall146.printChar=function(E,I){var v=___syscall146.buffers[E];assert(v),I===0||I===10?((E===1?Module.print:Module.printErr)(UTF8ArrayToString(v,0)),v.length=0):v.push(I)});for(var u=0;u<a;u++){for(var A=HEAP32[o+u*8>>2],p=HEAP32[o+(u*8+4)>>2],h=0;h<p;h++)___syscall146.printChar(r,HEAPU8[A+h]);n+=p}return n}catch(E){return(typeof FS>"u"||!(E instanceof FS.ErrnoError))&&abort(E),-E.errno}}function __nbind_finish(){for(var t=0,e=_nbind.BindClass.list;t<e.length;t++){var r=e[t];r.finish()}}var ___dso_handle=STATICTOP;STATICTOP+=16,function(_nbind){var typeIdTbl={};_nbind.typeNameTbl={};var Pool=function(){function t(){}return t.lalloc=function(e){e=e+7&-8;var r=HEAPU32[t.usedPtr];if(e>t.pageSize/2||e>t.pageSize-r){var o=_nbind.typeNameTbl.NBind.proto;return o.lalloc(e)}else return HEAPU32[t.usedPtr]=r+e,t.rootPtr+r},t.lreset=function(e,r){var o=HEAPU32[t.pagePtr];if(o){var a=_nbind.typeNameTbl.NBind.proto;a.lreset(e,r)}else HEAPU32[t.usedPtr]=e},t}();_nbind.Pool=Pool;function constructType(t,e){var r=t==10240?_nbind.makeTypeNameTbl[e.name]||_nbind.BindType:_nbind.makeTypeKindTbl[t],o=new r(e);return typeIdTbl[e.id]=o,_nbind.typeNameTbl[e.name]=o,o}_nbind.constructType=constructType;function getType(t){return typeIdTbl[t]}_nbind.getType=getType;function queryType(t){var e=HEAPU8[t],r=_nbind.structureList[e][1];t/=4,r<0&&(++t,r=HEAPU32[t]+1);var o=Array.prototype.slice.call(HEAPU32.subarray(t+1,t+1+r));return e==9&&(o=[o[0],o.slice(1)]),{paramList:o,placeholderFlag:e}}_nbind.queryType=queryType;function getTypes(t,e){return t.map(function(r){return typeof r=="number"?_nbind.getComplexType(r,constructType,getType,queryType,e):_nbind.typeNameTbl[r]})}_nbind.getTypes=getTypes;function readTypeIdList(t,e){return Array.prototype.slice.call(HEAPU32,t/4,t/4+e)}_nbind.readTypeIdList=readTypeIdList;function readAsciiString(t){for(var e=t;HEAPU8[e++];);return String.fromCharCode.apply("",HEAPU8.subarray(t,e-1))}_nbind.readAsciiString=readAsciiString;function readPolicyList(t){var e={};if(t)for(;;){var r=HEAPU32[t/4];if(!r)break;e[readAsciiString(r)]=!0,t+=4}return e}_nbind.readPolicyList=readPolicyList;function getDynCall(t,e){var r={float32_t:"d",float64_t:"d",int64_t:"d",uint64_t:"d",void:"v"},o=t.map(function(n){return r[n.name]||"i"}).join(""),a=Module["dynCall_"+o];if(!a)throw new Error("dynCall_"+o+" not found for "+e+"("+t.map(function(n){return n.name}).join(", ")+")");return a}_nbind.getDynCall=getDynCall;function addMethod(t,e,r,o){var a=t[e];t.hasOwnProperty(e)&&a?((a.arity||a.arity===0)&&(a=_nbind.makeOverloader(a,a.arity),t[e]=a),a.addMethod(r,o)):(r.arity=o,t[e]=r)}_nbind.addMethod=addMethod;function throwError(t){throw new Error(t)}_nbind.throwError=throwError,_nbind.bigEndian=!1,_a=_typeModule(_typeModule),_nbind.Type=_a.Type,_nbind.makeType=_a.makeType,_nbind.getComplexType=_a.getComplexType,_nbind.structureList=_a.structureList;var BindType=function(t){__extends(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.heap=HEAPU32,r.ptrSize=4,r}return e.prototype.needsWireRead=function(r){return!!this.wireRead||!!this.makeWireRead},e.prototype.needsWireWrite=function(r){return!!this.wireWrite||!!this.makeWireWrite},e}(_nbind.Type);_nbind.BindType=BindType;var PrimitiveType=function(t){__extends(e,t);function e(r){var o=t.call(this,r)||this,a=r.flags&32?{32:HEAPF32,64:HEAPF64}:r.flags&8?{8:HEAPU8,16:HEAPU16,32:HEAPU32}:{8:HEAP8,16:HEAP16,32:HEAP32};return o.heap=a[r.ptrSize*8],o.ptrSize=r.ptrSize,o}return e.prototype.needsWireWrite=function(r){return!!r&&!!r.Strict},e.prototype.makeWireWrite=function(r,o){return o&&o.Strict&&function(a){if(typeof a=="number")return a;throw new Error("Type mismatch")}},e}(BindType);_nbind.PrimitiveType=PrimitiveType;function pushCString(t,e){if(t==null){if(e&&e.Nullable)return 0;throw new Error("Type mismatch")}if(e&&e.Strict){if(typeof t!="string")throw new Error("Type mismatch")}else t=t.toString();var r=Module.lengthBytesUTF8(t)+1,o=_nbind.Pool.lalloc(r);return Module.stringToUTF8Array(t,HEAPU8,o,r),o}_nbind.pushCString=pushCString;function popCString(t){return t===0?null:Module.Pointer_stringify(t)}_nbind.popCString=popCString;var CStringType=function(t){__extends(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.wireRead=popCString,r.wireWrite=pushCString,r.readResources=[_nbind.resources.pool],r.writeResources=[_nbind.resources.pool],r}return e.prototype.makeWireWrite=function(r,o){return function(a){return pushCString(a,o)}},e}(BindType);_nbind.CStringType=CStringType;var BooleanType=function(t){__extends(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.wireRead=function(o){return!!o},r}return e.prototype.needsWireWrite=function(r){return!!r&&!!r.Strict},e.prototype.makeWireRead=function(r){return"!!("+r+")"},e.prototype.makeWireWrite=function(r,o){return o&&o.Strict&&function(a){if(typeof a=="boolean")return a;throw new Error("Type mismatch")}||r},e}(BindType);_nbind.BooleanType=BooleanType;var Wrapper=function(){function t(){}return t.prototype.persist=function(){this.__nbindState|=1},t}();_nbind.Wrapper=Wrapper;function makeBound(t,e){var r=function(o){__extends(a,o);function a(n,u,A,p){var h=o.call(this)||this;if(!(h instanceof a))return new(Function.prototype.bind.apply(a,Array.prototype.concat.apply([null],arguments)));var E=u,I=A,v=p;if(n!==_nbind.ptrMarker){var b=h.__nbindConstructor.apply(h,arguments);E=4608,v=HEAPU32[b/4],I=HEAPU32[b/4+1]}var C={configurable:!0,enumerable:!1,value:null,writable:!1},T={__nbindFlags:E,__nbindPtr:I};v&&(T.__nbindShared=v,_nbind.mark(h));for(var L=0,U=Object.keys(T);L<U.length;L++){var J=U[L];C.value=T[J],Object.defineProperty(h,J,C)}return _defineHidden(0)(h,"__nbindState"),h}return a.prototype.free=function(){e.destroy.call(this,this.__nbindShared,this.__nbindFlags),this.__nbindState|=2,disableMember(this,"__nbindShared"),disableMember(this,"__nbindPtr")},a}(Wrapper);return __decorate([_defineHidden()],r.prototype,"__nbindConstructor",void 0),__decorate([_defineHidden()],r.prototype,"__nbindValueConstructor",void 0),__decorate([_defineHidden(t)],r.prototype,"__nbindPolicies",void 0),r}_nbind.makeBound=makeBound;function disableMember(t,e){function r(){throw new Error("Accessing deleted object")}Object.defineProperty(t,e,{configurable:!1,enumerable:!1,get:r,set:r})}_nbind.ptrMarker={};var BindClass=function(t){__extends(e,t);function e(r){var o=t.call(this,r)||this;return o.wireRead=function(a){return _nbind.popValue(a,o.ptrType)},o.wireWrite=function(a){return pushPointer(a,o.ptrType,!0)},o.pendingSuperCount=0,o.ready=!1,o.methodTbl={},r.paramList?(o.classType=r.paramList[0].classType,o.proto=o.classType.proto):o.classType=o,o}return e.prototype.makeBound=function(r){var o=_nbind.makeBound(r,this);return this.proto=o,this.ptrType.proto=o,o},e.prototype.addMethod=function(r){var o=this.methodTbl[r.name]||[];o.push(r),this.methodTbl[r.name]=o},e.prototype.registerMethods=function(r,o){for(var a,n=0,u=Object.keys(r.methodTbl);n<u.length;n++)for(var A=u[n],p=r.methodTbl[A],h=0,E=p;h<E.length;h++){var I=E[h],v=void 0,b=void 0;if(v=this.proto.prototype,!(o&&I.signatureType!=1))switch(I.signatureType){case 1:v=this.proto;case 5:b=_nbind.makeCaller(I),_nbind.addMethod(v,I.name,b,I.typeList.length-1);break;case 4:a=_nbind.makeMethodCaller(r.ptrType,I);break;case 3:Object.defineProperty(v,I.name,{configurable:!0,enumerable:!1,get:_nbind.makeMethodCaller(r.ptrType,I),set:a});break;case 2:b=_nbind.makeMethodCaller(r.ptrType,I),_nbind.addMethod(v,I.name,b,I.typeList.length-1);break;default:break}}},e.prototype.registerSuperMethods=function(r,o,a){if(!a[r.name]){a[r.name]=!0;for(var n=0,u,A=0,p=r.superIdList||[];A<p.length;A++){var h=p[A],E=_nbind.getType(h);n++<o||o<0?u=-1:u=0,this.registerSuperMethods(E,u,a)}this.registerMethods(r,o<0)}},e.prototype.finish=function(){if(this.ready)return this;this.ready=!0,this.superList=(this.superIdList||[]).map(function(a){return _nbind.getType(a).finish()});var r=this.proto;if(this.superList.length){var o=function(){this.constructor=r};o.prototype=this.superList[0].proto.prototype,r.prototype=new o}return r!=Module&&(r.prototype.__nbindType=this),this.registerSuperMethods(this,1,{}),this},e.prototype.upcastStep=function(r,o){if(r==this)return o;for(var a=0;a<this.superList.length;++a){var n=this.superList[a].upcastStep(r,_nbind.callUpcast(this.upcastList[a],o));if(n)return n}return 0},e}(_nbind.BindType);BindClass.list=[],_nbind.BindClass=BindClass;function popPointer(t,e){return t?new e.proto(_nbind.ptrMarker,e.flags,t):null}_nbind.popPointer=popPointer;function pushPointer(t,e,r){if(!(t instanceof _nbind.Wrapper)){if(r)return _nbind.pushValue(t);throw new Error("Type mismatch")}var o=t.__nbindPtr,a=t.__nbindType.classType,n=e.classType;if(t instanceof e.proto)for(;a!=n;)o=_nbind.callUpcast(a.upcastList[0],o),a=a.superList[0];else if(o=a.upcastStep(n,o),!o)throw new Error("Type mismatch");return o}_nbind.pushPointer=pushPointer;function pushMutablePointer(t,e){var r=pushPointer(t,e);if(t.__nbindFlags&1)throw new Error("Passing a const value as a non-const argument");return r}var BindClassPtr=function(t){__extends(e,t);function e(r){var o=t.call(this,r)||this;o.classType=r.paramList[0].classType,o.proto=o.classType.proto;var a=r.flags&1,n=(o.flags&896)==256&&r.flags&2,u=a?pushPointer:pushMutablePointer,A=n?_nbind.popValue:popPointer;return o.makeWireWrite=function(p,h){return h.Nullable?function(E){return E?u(E,o):0}:function(E){return u(E,o)}},o.wireRead=function(p){return A(p,o)},o.wireWrite=function(p){return u(p,o)},o}return e}(_nbind.BindType);_nbind.BindClassPtr=BindClassPtr;function popShared(t,e){var r=HEAPU32[t/4],o=HEAPU32[t/4+1];return o?new e.proto(_nbind.ptrMarker,e.flags,o,r):null}_nbind.popShared=popShared;function pushShared(t,e){if(!(t instanceof e.proto))throw new Error("Type mismatch");return t.__nbindShared}function pushMutableShared(t,e){if(!(t instanceof e.proto))throw new Error("Type mismatch");if(t.__nbindFlags&1)throw new Error("Passing a const value as a non-const argument");return t.__nbindShared}var SharedClassPtr=function(t){__extends(e,t);function e(r){var o=t.call(this,r)||this;o.readResources=[_nbind.resources.pool],o.classType=r.paramList[0].classType,o.proto=o.classType.proto;var a=r.flags&1,n=a?pushShared:pushMutableShared;return o.wireRead=function(u){return popShared(u,o)},o.wireWrite=function(u){return n(u,o)},o}return e}(_nbind.BindType);_nbind.SharedClassPtr=SharedClassPtr,_nbind.externalList=[0];var firstFreeExternal=0,External=function(){function t(e){this.refCount=1,this.data=e}return t.prototype.register=function(){var e=firstFreeExternal;return e?firstFreeExternal=_nbind.externalList[e]:e=_nbind.externalList.length,_nbind.externalList[e]=this,e},t.prototype.reference=function(){++this.refCount},t.prototype.dereference=function(e){--this.refCount==0&&(this.free&&this.free(),_nbind.externalList[e]=firstFreeExternal,firstFreeExternal=e)},t}();_nbind.External=External;function popExternal(t){var e=_nbind.externalList[t];return e.dereference(t),e.data}function pushExternal(t){var e=new External(t);return e.reference(),e.register()}var ExternalType=function(t){__extends(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.wireRead=popExternal,r.wireWrite=pushExternal,r}return e}(_nbind.BindType);_nbind.ExternalType=ExternalType,_nbind.callbackSignatureList=[];var CallbackType=function(t){__extends(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.wireWrite=function(o){return typeof o!="function"&&_nbind.throwError("Type mismatch"),new _nbind.External(o).register()},r}return e}(_nbind.BindType);_nbind.CallbackType=CallbackType,_nbind.valueList=[0];var firstFreeValue=0;function pushValue(t){var e=firstFreeValue;return e?firstFreeValue=_nbind.valueList[e]:e=_nbind.valueList.length,_nbind.valueList[e]=t,e*2+1}_nbind.pushValue=pushValue;function popValue(t,e){if(t||_nbind.throwError("Value type JavaScript class is missing or not registered"),t&1){t>>=1;var r=_nbind.valueList[t];return _nbind.valueList[t]=firstFreeValue,firstFreeValue=t,r}else{if(e)return _nbind.popShared(t,e);throw new Error("Invalid value slot "+t)}}_nbind.popValue=popValue;var valueBase=18446744073709552e3;function push64(t){return typeof t=="number"?t:pushValue(t)*4096+valueBase}function pop64(t){return t<valueBase?t:popValue((t-valueBase)/4096)}var CreateValueType=function(t){__extends(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.makeWireWrite=function(r){return"(_nbind.pushValue(new "+r+"))"},e}(_nbind.BindType);_nbind.CreateValueType=CreateValueType;var Int64Type=function(t){__extends(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.wireWrite=push64,r.wireRead=pop64,r}return e}(_nbind.BindType);_nbind.Int64Type=Int64Type;function pushArray(t,e){if(!t)return 0;var r=t.length;if((e.size||e.size===0)&&r<e.size)throw new Error("Type mismatch");var o=e.memberType.ptrSize,a=_nbind.Pool.lalloc(4+r*o);HEAPU32[a/4]=r;var n=e.memberType.heap,u=(a+4)/o,A=e.memberType.wireWrite,p=0;if(A)for(;p<r;)n[u++]=A(t[p++]);else for(;p<r;)n[u++]=t[p++];return a}_nbind.pushArray=pushArray;function popArray(t,e){if(t===0)return null;var r=HEAPU32[t/4],o=new Array(r),a=e.memberType.heap;t=(t+4)/e.memberType.ptrSize;var n=e.memberType.wireRead,u=0;if(n)for(;u<r;)o[u++]=n(a[t++]);else for(;u<r;)o[u++]=a[t++];return o}_nbind.popArray=popArray;var ArrayType=function(t){__extends(e,t);function e(r){var o=t.call(this,r)||this;return o.wireRead=function(a){return popArray(a,o)},o.wireWrite=function(a){return pushArray(a,o)},o.readResources=[_nbind.resources.pool],o.writeResources=[_nbind.resources.pool],o.memberType=r.paramList[0],r.paramList[1]&&(o.size=r.paramList[1]),o}return e}(_nbind.BindType);_nbind.ArrayType=ArrayType;function pushString(t,e){if(t==null)if(e&&e.Nullable)t="";else throw new Error("Type mismatch");if(e&&e.Strict){if(typeof t!="string")throw new Error("Type mismatch")}else t=t.toString();var r=Module.lengthBytesUTF8(t),o=_nbind.Pool.lalloc(4+r+1);return HEAPU32[o/4]=r,Module.stringToUTF8Array(t,HEAPU8,o+4,r+1),o}_nbind.pushString=pushString;function popString(t){if(t===0)return null;var e=HEAPU32[t/4];return Module.Pointer_stringify(t+4,e)}_nbind.popString=popString;var StringType=function(t){__extends(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.wireRead=popString,r.wireWrite=pushString,r.readResources=[_nbind.resources.pool],r.writeResources=[_nbind.resources.pool],r}return e.prototype.makeWireWrite=function(r,o){return function(a){return pushString(a,o)}},e}(_nbind.BindType);_nbind.StringType=StringType;function makeArgList(t){return Array.apply(null,Array(t)).map(function(e,r){return"a"+(r+1)})}function anyNeedsWireWrite(t,e){return t.reduce(function(r,o){return r||o.needsWireWrite(e)},!1)}function anyNeedsWireRead(t,e){return t.reduce(function(r,o){return r||!!o.needsWireRead(e)},!1)}function makeWireRead(t,e,r,o){var a=t.length;return r.makeWireRead?r.makeWireRead(o,t,a):r.wireRead?(t[a]=r.wireRead,"(convertParamList["+a+"]("+o+"))"):o}function makeWireWrite(t,e,r,o){var a,n=t.length;return r.makeWireWrite?a=r.makeWireWrite(o,e,t,n):a=r.wireWrite,a?typeof a=="string"?a:(t[n]=a,"(convertParamList["+n+"]("+o+"))"):o}function buildCallerFunction(dynCall,ptrType,ptr,num,policyTbl,needsWireWrite,prefix,returnType,argTypeList,mask,err){var argList=makeArgList(argTypeList.length),convertParamList=[],callExpression=makeWireRead(convertParamList,policyTbl,returnType,"dynCall("+[prefix].concat(argList.map(function(t,e){return makeWireWrite(convertParamList,policyTbl,argTypeList[e],t)})).join(",")+")"),resourceSet=_nbind.listResources([returnType],argTypeList),sourceCode="function("+argList.join(",")+"){"+(mask?"this.__nbindFlags&mask&&err();":"")+resourceSet.makeOpen()+"var r="+callExpression+";"+resourceSet.makeClose()+"return r;}";return eval("("+sourceCode+")")}function buildJSCallerFunction(returnType,argTypeList){var argList=makeArgList(argTypeList.length),convertParamList=[],callExpression=makeWireWrite(convertParamList,null,returnType,"_nbind.externalList[num].data("+argList.map(function(t,e){return makeWireRead(convertParamList,null,argTypeList[e],t)}).join(",")+")"),resourceSet=_nbind.listResources(argTypeList,[returnType]);resourceSet.remove(_nbind.resources.pool);var sourceCode="function("+["dummy","num"].concat(argList).join(",")+"){"+resourceSet.makeOpen()+"var r="+callExpression+";"+resourceSet.makeClose()+"return r;}";return eval("("+sourceCode+")")}_nbind.buildJSCallerFunction=buildJSCallerFunction;function makeJSCaller(t){var e=t.length-1,r=_nbind.getTypes(t,"callback"),o=r[0],a=r.slice(1),n=anyNeedsWireRead(a,null),u=o.needsWireWrite(null);if(!u&&!n)switch(e){case 0:return function(A,p){return _nbind.externalList[p].data()};case 1:return function(A,p,h){return _nbind.externalList[p].data(h)};case 2:return function(A,p,h,E){return _nbind.externalList[p].data(h,E)};case 3:return function(A,p,h,E,I){return _nbind.externalList[p].data(h,E,I)};default:break}return buildJSCallerFunction(o,a)}_nbind.makeJSCaller=makeJSCaller;function makeMethodCaller(t,e){var r=e.typeList.length-1,o=e.typeList.slice(0);o.splice(1,0,"uint32_t",e.boundID);var a=_nbind.getTypes(o,e.title),n=a[0],u=a.slice(3),A=n.needsWireRead(e.policyTbl),p=anyNeedsWireWrite(u,e.policyTbl),h=e.ptr,E=e.num,I=_nbind.getDynCall(a,e.title),v=~e.flags&1;function b(){throw new Error("Calling a non-const method on a const object")}if(!A&&!p)switch(r){case 0:return function(){return this.__nbindFlags&v?b():I(h,E,_nbind.pushPointer(this,t))};case 1:return function(C){return this.__nbindFlags&v?b():I(h,E,_nbind.pushPointer(this,t),C)};case 2:return function(C,T){return this.__nbindFlags&v?b():I(h,E,_nbind.pushPointer(this,t),C,T)};case 3:return function(C,T,L){return this.__nbindFlags&v?b():I(h,E,_nbind.pushPointer(this,t),C,T,L)};default:break}return buildCallerFunction(I,t,h,E,e.policyTbl,p,"ptr,num,pushPointer(this,ptrType)",n,u,v,b)}_nbind.makeMethodCaller=makeMethodCaller;function makeCaller(t){var e=t.typeList.length-1,r=_nbind.getTypes(t.typeList,t.title),o=r[0],a=r.slice(1),n=o.needsWireRead(t.policyTbl),u=anyNeedsWireWrite(a,t.policyTbl),A=t.direct,p=t.ptr;if(t.direct&&!n&&!u){var h=_nbind.getDynCall(r,t.title);switch(e){case 0:return function(){return h(A)};case 1:return function(b){return h(A,b)};case 2:return function(b,C){return h(A,b,C)};case 3:return function(b,C,T){return h(A,b,C,T)};default:break}p=0}var E;if(p){var I=t.typeList.slice(0);I.splice(1,0,"uint32_t"),r=_nbind.getTypes(I,t.title),E="ptr,num"}else p=A,E="ptr";var v=_nbind.getDynCall(r,t.title);return buildCallerFunction(v,null,p,t.num,t.policyTbl,u,E,o,a)}_nbind.makeCaller=makeCaller;function makeOverloader(t,e){var r=[];function o(){return r[arguments.length].apply(this,arguments)}return o.addMethod=function(a,n){r[n]=a},o.addMethod(t,e),o}_nbind.makeOverloader=makeOverloader;var Resource=function(){function t(e,r){var o=this;this.makeOpen=function(){return Object.keys(o.openTbl).join("")},this.makeClose=function(){return Object.keys(o.closeTbl).join("")},this.openTbl={},this.closeTbl={},e&&(this.openTbl[e]=!0),r&&(this.closeTbl[r]=!0)}return t.prototype.add=function(e){for(var r=0,o=Object.keys(e.openTbl);r<o.length;r++){var a=o[r];this.openTbl[a]=!0}for(var n=0,u=Object.keys(e.closeTbl);n<u.length;n++){var a=u[n];this.closeTbl[a]=!0}},t.prototype.remove=function(e){for(var r=0,o=Object.keys(e.openTbl);r<o.length;r++){var a=o[r];delete this.openTbl[a]}for(var n=0,u=Object.keys(e.closeTbl);n<u.length;n++){var a=u[n];delete this.closeTbl[a]}},t}();_nbind.Resource=Resource;function listResources(t,e){for(var r=new Resource,o=0,a=t;o<a.length;o++)for(var n=a[o],u=0,A=n.readResources||[];u<A.length;u++){var p=A[u];r.add(p)}for(var h=0,E=e;h<E.length;h++)for(var n=E[h],I=0,v=n.writeResources||[];I<v.length;I++){var p=v[I];r.add(p)}return r}_nbind.listResources=listResources,_nbind.resources={pool:new Resource("var used=HEAPU32[_nbind.Pool.usedPtr],page=HEAPU32[_nbind.Pool.pagePtr];","_nbind.Pool.lreset(used,page);")};var ExternalBuffer=function(t){__extends(e,t);function e(r,o){var a=t.call(this,r)||this;return a.ptr=o,a}return e.prototype.free=function(){_free(this.ptr)},e}(_nbind.External);function getBuffer(t){return t instanceof ArrayBuffer?new Uint8Array(t):t instanceof DataView?new Uint8Array(t.buffer,t.byteOffset,t.byteLength):t}function pushBuffer(t,e){if(t==null&&e&&e.Nullable&&(t=[]),typeof t!="object")throw new Error("Type mismatch");var r=t,o=r.byteLength||r.length;if(!o&&o!==0&&r.byteLength!==0)throw new Error("Type mismatch");var a=_nbind.Pool.lalloc(8),n=_malloc(o),u=a/4;return HEAPU32[u++]=o,HEAPU32[u++]=n,HEAPU32[u++]=new ExternalBuffer(t,n).register(),HEAPU8.set(getBuffer(t),n),a}var BufferType=function(t){__extends(e,t);function e(){var r=t!==null&&t.apply(this,arguments)||this;return r.wireWrite=pushBuffer,r.readResources=[_nbind.resources.pool],r.writeResources=[_nbind.resources.pool],r}return e.prototype.makeWireWrite=function(r,o){return function(a){return pushBuffer(a,o)}},e}(_nbind.BindType);_nbind.BufferType=BufferType;function commitBuffer(t,e,r){var o=_nbind.externalList[t].data,a=Buffer;if(typeof Buffer!="function"&&(a=function(){}),!(o instanceof Array)){var n=HEAPU8.subarray(e,e+r);if(o instanceof a){var u=void 0;typeof Buffer.from=="function"&&Buffer.from.length>=3?u=Buffer.from(n):u=new Buffer(n),u.copy(o)}else getBuffer(o).set(n)}}_nbind.commitBuffer=commitBuffer;var dirtyList=[],gcTimer=0;function sweep(){for(var t=0,e=dirtyList;t<e.length;t++){var r=e[t];r.__nbindState&3||r.free()}dirtyList=[],gcTimer=0}_nbind.mark=function(t){};function toggleLightGC(t){t?_nbind.mark=function(e){dirtyList.push(e),gcTimer||(gcTimer=setTimeout(sweep,0))}:_nbind.mark=function(e){}}_nbind.toggleLightGC=toggleLightGC}(_nbind),Module.requestFullScreen=function t(e,r,o){Module.printErr("Module.requestFullScreen is deprecated. Please call Module.requestFullscreen instead."),Module.requestFullScreen=Module.requestFullscreen,Browser.requestFullScreen(e,r,o)},Module.requestFullscreen=function t(e,r,o){Browser.requestFullscreen(e,r,o)},Module.requestAnimationFrame=function t(e){Browser.requestAnimationFrame(e)},Module.setCanvasSize=function t(e,r,o){Browser.setCanvasSize(e,r,o)},Module.pauseMainLoop=function t(){Browser.mainLoop.pause()},Module.resumeMainLoop=function t(){Browser.mainLoop.resume()},Module.getUserMedia=function t(){Browser.getUserMedia()},Module.createContext=function t(e,r,o,a){return Browser.createContext(e,r,o,a)},ENVIRONMENT_IS_NODE?_emscripten_get_now=function(){var e=process.hrtime();return e[0]*1e3+e[1]/1e6}:typeof dateNow<"u"?_emscripten_get_now=dateNow:typeof self=="object"&&self.performance&&typeof self.performance.now=="function"?_emscripten_get_now=function(){return self.performance.now()}:typeof performance=="object"&&typeof performance.now=="function"?_emscripten_get_now=function(){return performance.now()}:_emscripten_get_now=Date.now,__ATEXIT__.push(function(){var t=Module._fflush;t&&t(0);var e=___syscall146.printChar;if(!!e){var r=___syscall146.buffers;r[1].length&&e(1,10),r[2].length&&e(2,10)}}),DYNAMICTOP_PTR=allocate(1,"i32",ALLOC_STATIC),STACK_BASE=STACKTOP=Runtime.alignMemory(STATICTOP),STACK_MAX=STACK_BASE+TOTAL_STACK,DYNAMIC_BASE=Runtime.alignMemory(STACK_MAX),HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE,staticSealed=!0;function invoke_viiiii(t,e,r,o,a,n){try{Module.dynCall_viiiii(t,e,r,o,a,n)}catch(u){if(typeof u!="number"&&u!=="longjmp")throw u;Module.setThrew(1,0)}}function invoke_vif(t,e,r){try{Module.dynCall_vif(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_vid(t,e,r){try{Module.dynCall_vid(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_fiff(t,e,r,o){try{return Module.dynCall_fiff(t,e,r,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_vi(t,e){try{Module.dynCall_vi(t,e)}catch(r){if(typeof r!="number"&&r!=="longjmp")throw r;Module.setThrew(1,0)}}function invoke_vii(t,e,r){try{Module.dynCall_vii(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_ii(t,e){try{return Module.dynCall_ii(t,e)}catch(r){if(typeof r!="number"&&r!=="longjmp")throw r;Module.setThrew(1,0)}}function invoke_viddi(t,e,r,o,a){try{Module.dynCall_viddi(t,e,r,o,a)}catch(n){if(typeof n!="number"&&n!=="longjmp")throw n;Module.setThrew(1,0)}}function invoke_vidd(t,e,r,o){try{Module.dynCall_vidd(t,e,r,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_iiii(t,e,r,o){try{return Module.dynCall_iiii(t,e,r,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_diii(t,e,r,o){try{return Module.dynCall_diii(t,e,r,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_di(t,e){try{return Module.dynCall_di(t,e)}catch(r){if(typeof r!="number"&&r!=="longjmp")throw r;Module.setThrew(1,0)}}function invoke_iid(t,e,r){try{return Module.dynCall_iid(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_iii(t,e,r){try{return Module.dynCall_iii(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_viiddi(t,e,r,o,a,n){try{Module.dynCall_viiddi(t,e,r,o,a,n)}catch(u){if(typeof u!="number"&&u!=="longjmp")throw u;Module.setThrew(1,0)}}function invoke_viiiiii(t,e,r,o,a,n,u){try{Module.dynCall_viiiiii(t,e,r,o,a,n,u)}catch(A){if(typeof A!="number"&&A!=="longjmp")throw A;Module.setThrew(1,0)}}function invoke_dii(t,e,r){try{return Module.dynCall_dii(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_i(t){try{return Module.dynCall_i(t)}catch(e){if(typeof e!="number"&&e!=="longjmp")throw e;Module.setThrew(1,0)}}function invoke_iiiiii(t,e,r,o,a,n){try{return Module.dynCall_iiiiii(t,e,r,o,a,n)}catch(u){if(typeof u!="number"&&u!=="longjmp")throw u;Module.setThrew(1,0)}}function invoke_viiid(t,e,r,o,a){try{Module.dynCall_viiid(t,e,r,o,a)}catch(n){if(typeof n!="number"&&n!=="longjmp")throw n;Module.setThrew(1,0)}}function invoke_viififi(t,e,r,o,a,n,u){try{Module.dynCall_viififi(t,e,r,o,a,n,u)}catch(A){if(typeof A!="number"&&A!=="longjmp")throw A;Module.setThrew(1,0)}}function invoke_viii(t,e,r,o){try{Module.dynCall_viii(t,e,r,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_v(t){try{Module.dynCall_v(t)}catch(e){if(typeof e!="number"&&e!=="longjmp")throw e;Module.setThrew(1,0)}}function invoke_viid(t,e,r,o){try{Module.dynCall_viid(t,e,r,o)}catch(a){if(typeof a!="number"&&a!=="longjmp")throw a;Module.setThrew(1,0)}}function invoke_idd(t,e,r){try{return Module.dynCall_idd(t,e,r)}catch(o){if(typeof o!="number"&&o!=="longjmp")throw o;Module.setThrew(1,0)}}function invoke_viiii(t,e,r,o,a){try{Module.dynCall_viiii(t,e,r,o,a)}catch(n){if(typeof n!="number"&&n!=="longjmp")throw n;Module.setThrew(1,0)}}Module.asmGlobalArg={Math,Int8Array,Int16Array,Int32Array,Uint8Array,Uint16Array,Uint32Array,Float32Array,Float64Array,NaN:NaN,Infinity:1/0},Module.asmLibraryArg={abort,assert,enlargeMemory,getTotalMemory,abortOnCannotGrowMemory,invoke_viiiii,invoke_vif,invoke_vid,invoke_fiff,invoke_vi,invoke_vii,invoke_ii,invoke_viddi,invoke_vidd,invoke_iiii,invoke_diii,invoke_di,invoke_iid,invoke_iii,invoke_viiddi,invoke_viiiiii,invoke_dii,invoke_i,invoke_iiiiii,invoke_viiid,invoke_viififi,invoke_viii,invoke_v,invoke_viid,invoke_idd,invoke_viiii,_emscripten_asm_const_iiiii,_emscripten_asm_const_iiidddddd,_emscripten_asm_const_iiiid,__nbind_reference_external,_emscripten_asm_const_iiiiiiii,_removeAccessorPrefix,_typeModule,__nbind_register_pool,__decorate,_llvm_stackrestore,___cxa_atexit,__extends,__nbind_get_value_object,__ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj,_emscripten_set_main_loop_timing,__nbind_register_primitive,__nbind_register_type,_emscripten_memcpy_big,__nbind_register_function,___setErrNo,__nbind_register_class,__nbind_finish,_abort,_nbind_value,_llvm_stacksave,___syscall54,_defineHidden,_emscripten_set_main_loop,_emscripten_get_now,__nbind_register_callback_signature,_emscripten_asm_const_iiiiii,__nbind_free_external,_emscripten_asm_const_iiii,_emscripten_asm_const_iiididi,___syscall6,_atexit,___syscall140,___syscall146,DYNAMICTOP_PTR,tempDoublePtr,ABORT,STACKTOP,STACK_MAX,cttz_i8,___dso_handle};var asm=function(t,e,r){var o=new t.Int8Array(r),a=new t.Int16Array(r),n=new t.Int32Array(r),u=new t.Uint8Array(r),A=new t.Uint16Array(r),p=new t.Uint32Array(r),h=new t.Float32Array(r),E=new t.Float64Array(r),I=e.DYNAMICTOP_PTR|0,v=e.tempDoublePtr|0,b=e.ABORT|0,C=e.STACKTOP|0,T=e.STACK_MAX|0,L=e.cttz_i8|0,U=e.___dso_handle|0,J=0,te=0,le=0,pe=0,Ae=t.NaN,ye=t.Infinity,ae=0,we=0,Pe=0,g=0,Ee=0,De=0,ce=t.Math.floor,ne=t.Math.abs,ee=t.Math.sqrt,Ie=t.Math.pow,ke=t.Math.cos,ht=t.Math.sin,H=t.Math.tan,lt=t.Math.acos,Re=t.Math.asin,Qe=t.Math.atan,be=t.Math.atan2,_e=t.Math.exp,Te=t.Math.log,Je=t.Math.ceil,He=t.Math.imul,x=t.Math.min,w=t.Math.max,S=t.Math.clz32,y=t.Math.fround,F=e.abort,z=e.assert,X=e.enlargeMemory,Z=e.getTotalMemory,ie=e.abortOnCannotGrowMemory,Se=e.invoke_viiiii,Ne=e.invoke_vif,ot=e.invoke_vid,dt=e.invoke_fiff,jt=e.invoke_vi,$t=e.invoke_vii,xt=e.invoke_ii,an=e.invoke_viddi,Qr=e.invoke_vidd,mr=e.invoke_iiii,xr=e.invoke_diii,Wr=e.invoke_di,Vn=e.invoke_iid,Ns=e.invoke_iii,Ri=e.invoke_viiddi,ps=e.invoke_viiiiii,io=e.invoke_dii,Si=e.invoke_i,Ls=e.invoke_iiiiii,so=e.invoke_viiid,cc=e.invoke_viififi,cu=e.invoke_viii,ap=e.invoke_v,lp=e.invoke_viid,Ms=e.invoke_idd,Dn=e.invoke_viiii,oo=e._emscripten_asm_const_iiiii,Os=e._emscripten_asm_const_iiidddddd,ml=e._emscripten_asm_const_iiiid,yl=e.__nbind_reference_external,ao=e._emscripten_asm_const_iiiiiiii,Kn=e._removeAccessorPrefix,Mn=e._typeModule,Ni=e.__nbind_register_pool,On=e.__decorate,_i=e._llvm_stackrestore,tr=e.___cxa_atexit,Me=e.__extends,ii=e.__nbind_get_value_object,Oa=e.__ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj,hr=e._emscripten_set_main_loop_timing,uc=e.__nbind_register_primitive,uu=e.__nbind_register_type,Ac=e._emscripten_memcpy_big,El=e.__nbind_register_function,vA=e.___setErrNo,Au=e.__nbind_register_class,Ce=e.__nbind_finish,Tt=e._abort,fc=e._nbind_value,Hi=e._llvm_stacksave,fu=e.___syscall54,Yt=e._defineHidden,Cl=e._emscripten_set_main_loop,DA=e._emscripten_get_now,cp=e.__nbind_register_callback_signature,pc=e._emscripten_asm_const_iiiiii,PA=e.__nbind_free_external,Qn=e._emscripten_asm_const_iiii,hi=e._emscripten_asm_const_iiididi,hc=e.___syscall6,SA=e._atexit,sa=e.___syscall140,Li=e.___syscall146,_o=y(0);let Ze=y(0);function lo(s){s=s|0;var l=0;return l=C,C=C+s|0,C=C+15&-16,l|0}function gc(){return C|0}function pu(s){s=s|0,C=s}function ji(s,l){s=s|0,l=l|0,C=s,T=l}function hu(s,l){s=s|0,l=l|0,J||(J=s,te=l)}function xA(s){s=s|0,De=s}function Ua(){return De|0}function dc(){var s=0,l=0;Dr(8104,8,400)|0,Dr(8504,408,540)|0,s=9044,l=s+44|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));o[9088]=0,o[9089]=1,n[2273]=0,n[2274]=948,n[2275]=948,tr(17,8104,U|0)|0}function hs(s){s=s|0,ft(s+948|0)}function _t(s){return s=y(s),((Du(s)|0)&2147483647)>>>0>2139095040|0}function Fn(s,l,c){s=s|0,l=l|0,c=c|0;e:do if(n[s+(l<<3)+4>>2]|0)s=s+(l<<3)|0;else{if((l|2|0)==3&&n[s+60>>2]|0){s=s+56|0;break}switch(l|0){case 0:case 2:case 4:case 5:{if(n[s+52>>2]|0){s=s+48|0;break e}break}default:}if(n[s+68>>2]|0){s=s+64|0;break}else{s=(l|1|0)==5?948:c;break}}while(0);return s|0}function Ci(s){s=s|0;var l=0;return l=pD(1e3)|0,oa(s,(l|0)!=0,2456),n[2276]=(n[2276]|0)+1,Dr(l|0,8104,1e3)|0,o[s+2>>0]|0&&(n[l+4>>2]=2,n[l+12>>2]=4),n[l+976>>2]=s,l|0}function oa(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;d=C,C=C+16|0,f=d,l||(n[f>>2]=c,yg(s,5,3197,f)),C=d}function co(){return Ci(956)|0}function Us(s){s=s|0;var l=0;return l=Vt(1e3)|0,aa(l,s),oa(n[s+976>>2]|0,1,2456),n[2276]=(n[2276]|0)+1,n[l+944>>2]=0,l|0}function aa(s,l){s=s|0,l=l|0;var c=0;Dr(s|0,l|0,948)|0,Fm(s+948|0,l+948|0),c=s+960|0,s=l+960|0,l=c+40|0;do n[c>>2]=n[s>>2],c=c+4|0,s=s+4|0;while((c|0)<(l|0))}function la(s){s=s|0;var l=0,c=0,f=0,d=0;if(l=s+944|0,c=n[l>>2]|0,c|0&&(Ho(c+948|0,s)|0,n[l>>2]=0),c=wi(s)|0,c|0){l=0;do n[(gs(s,l)|0)+944>>2]=0,l=l+1|0;while((l|0)!=(c|0))}c=s+948|0,f=n[c>>2]|0,d=s+952|0,l=n[d>>2]|0,(l|0)!=(f|0)&&(n[d>>2]=l+(~((l+-4-f|0)>>>2)<<2)),ds(c),hD(s),n[2276]=(n[2276]|0)+-1}function Ho(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0;f=n[s>>2]|0,k=s+4|0,c=n[k>>2]|0,m=c;e:do if((f|0)==(c|0))d=f,B=4;else for(s=f;;){if((n[s>>2]|0)==(l|0)){d=s,B=4;break e}if(s=s+4|0,(s|0)==(c|0)){s=0;break}}while(0);return(B|0)==4&&((d|0)!=(c|0)?(f=d+4|0,s=m-f|0,l=s>>2,l&&(Mw(d|0,f|0,s|0)|0,c=n[k>>2]|0),s=d+(l<<2)|0,(c|0)==(s|0)||(n[k>>2]=c+(~((c+-4-s|0)>>>2)<<2)),s=1):s=0),s|0}function wi(s){return s=s|0,(n[s+952>>2]|0)-(n[s+948>>2]|0)>>2|0}function gs(s,l){s=s|0,l=l|0;var c=0;return c=n[s+948>>2]|0,(n[s+952>>2]|0)-c>>2>>>0>l>>>0?s=n[c+(l<<2)>>2]|0:s=0,s|0}function ds(s){s=s|0;var l=0,c=0,f=0,d=0;f=C,C=C+32|0,l=f,d=n[s>>2]|0,c=(n[s+4>>2]|0)-d|0,((n[s+8>>2]|0)-d|0)>>>0>c>>>0&&(d=c>>2,wp(l,d,d,s+8|0),Ig(s,l),UA(l)),C=f}function ms(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0;O=wi(s)|0;do if(O|0){if((n[(gs(s,0)|0)+944>>2]|0)==(s|0)){if(!(Ho(s+948|0,l)|0))break;Dr(l+400|0,8504,540)|0,n[l+944>>2]=0,Le(s);break}B=n[(n[s+976>>2]|0)+12>>2]|0,k=s+948|0,Q=(B|0)==0,c=0,m=0;do f=n[(n[k>>2]|0)+(m<<2)>>2]|0,(f|0)==(l|0)?Le(s):(d=Us(f)|0,n[(n[k>>2]|0)+(c<<2)>>2]=d,n[d+944>>2]=s,Q||LT[B&15](f,d,s,c),c=c+1|0),m=m+1|0;while((m|0)!=(O|0));if(c>>>0<O>>>0){Q=s+948|0,k=s+952|0,B=c,c=n[k>>2]|0;do m=(n[Q>>2]|0)+(B<<2)|0,f=m+4|0,d=c-f|0,l=d>>2,l&&(Mw(m|0,f|0,d|0)|0,c=n[k>>2]|0),d=c,f=m+(l<<2)|0,(d|0)!=(f|0)&&(c=d+(~((d+-4-f|0)>>>2)<<2)|0,n[k>>2]=c),B=B+1|0;while((B|0)!=(O|0))}}while(0)}function _s(s){s=s|0;var l=0,c=0,f=0,d=0;Un(s,(wi(s)|0)==0,2491),Un(s,(n[s+944>>2]|0)==0,2545),l=s+948|0,c=n[l>>2]|0,f=s+952|0,d=n[f>>2]|0,(d|0)!=(c|0)&&(n[f>>2]=d+(~((d+-4-c|0)>>>2)<<2)),ds(l),l=s+976|0,c=n[l>>2]|0,Dr(s|0,8104,1e3)|0,o[c+2>>0]|0&&(n[s+4>>2]=2,n[s+12>>2]=4),n[l>>2]=c}function Un(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;d=C,C=C+16|0,f=d,l||(n[f>>2]=c,Ao(s,5,3197,f)),C=d}function Pn(){return n[2276]|0}function ys(){var s=0;return s=pD(20)|0,We((s|0)!=0,2592),n[2277]=(n[2277]|0)+1,n[s>>2]=n[239],n[s+4>>2]=n[240],n[s+8>>2]=n[241],n[s+12>>2]=n[242],n[s+16>>2]=n[243],s|0}function We(s,l){s=s|0,l=l|0;var c=0,f=0;f=C,C=C+16|0,c=f,s||(n[c>>2]=l,Ao(0,5,3197,c)),C=f}function tt(s){s=s|0,hD(s),n[2277]=(n[2277]|0)+-1}function It(s,l){s=s|0,l=l|0;var c=0;l?(Un(s,(wi(s)|0)==0,2629),c=1):(c=0,l=0),n[s+964>>2]=l,n[s+988>>2]=c}function nr(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,m=f+8|0,d=f+4|0,B=f,n[d>>2]=l,Un(s,(n[l+944>>2]|0)==0,2709),Un(s,(n[s+964>>2]|0)==0,2763),$(s),l=s+948|0,n[B>>2]=(n[l>>2]|0)+(c<<2),n[m>>2]=n[B>>2],me(l,m,d)|0,n[(n[d>>2]|0)+944>>2]=s,Le(s),C=f}function $(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0;if(c=wi(s)|0,c|0&&(n[(gs(s,0)|0)+944>>2]|0)!=(s|0)){f=n[(n[s+976>>2]|0)+12>>2]|0,d=s+948|0,m=(f|0)==0,l=0;do B=n[(n[d>>2]|0)+(l<<2)>>2]|0,k=Us(B)|0,n[(n[d>>2]|0)+(l<<2)>>2]=k,n[k+944>>2]=s,m||LT[f&15](B,k,s,l),l=l+1|0;while((l|0)!=(c|0))}}function me(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0,Ge=0,Oe=0,Fe=0,et=0,Xe=0;et=C,C=C+64|0,q=et+52|0,k=et+48|0,se=et+28|0,Ge=et+24|0,Oe=et+20|0,Fe=et,f=n[s>>2]|0,m=f,l=f+((n[l>>2]|0)-m>>2<<2)|0,f=s+4|0,d=n[f>>2]|0,B=s+8|0;do if(d>>>0<(n[B>>2]|0)>>>0){if((l|0)==(d|0)){n[l>>2]=n[c>>2],n[f>>2]=(n[f>>2]|0)+4;break}_A(s,l,d,l+4|0),l>>>0<=c>>>0&&(c=(n[f>>2]|0)>>>0>c>>>0?c+4|0:c),n[l>>2]=n[c>>2]}else{f=(d-m>>2)+1|0,d=N(s)|0,d>>>0<f>>>0&&zr(s),M=n[s>>2]|0,O=(n[B>>2]|0)-M|0,m=O>>1,wp(Fe,O>>2>>>0<d>>>1>>>0?m>>>0<f>>>0?f:m:d,l-M>>2,s+8|0),M=Fe+8|0,f=n[M>>2]|0,m=Fe+12|0,O=n[m>>2]|0,B=O,Q=f;do if((f|0)==(O|0)){if(O=Fe+4|0,f=n[O>>2]|0,Xe=n[Fe>>2]|0,d=Xe,f>>>0<=Xe>>>0){f=B-d>>1,f=(f|0)==0?1:f,wp(se,f,f>>>2,n[Fe+16>>2]|0),n[Ge>>2]=n[O>>2],n[Oe>>2]=n[M>>2],n[k>>2]=n[Ge>>2],n[q>>2]=n[Oe>>2],vw(se,k,q),f=n[Fe>>2]|0,n[Fe>>2]=n[se>>2],n[se>>2]=f,f=se+4|0,Xe=n[O>>2]|0,n[O>>2]=n[f>>2],n[f>>2]=Xe,f=se+8|0,Xe=n[M>>2]|0,n[M>>2]=n[f>>2],n[f>>2]=Xe,f=se+12|0,Xe=n[m>>2]|0,n[m>>2]=n[f>>2],n[f>>2]=Xe,UA(se),f=n[M>>2]|0;break}m=f,B=((m-d>>2)+1|0)/-2|0,k=f+(B<<2)|0,d=Q-m|0,m=d>>2,m&&(Mw(k|0,f|0,d|0)|0,f=n[O>>2]|0),Xe=k+(m<<2)|0,n[M>>2]=Xe,n[O>>2]=f+(B<<2),f=Xe}while(0);n[f>>2]=n[c>>2],n[M>>2]=(n[M>>2]|0)+4,l=Bg(s,Fe,l)|0,UA(Fe)}while(0);return C=et,l|0}function Le(s){s=s|0;var l=0;do{if(l=s+984|0,o[l>>0]|0)break;o[l>>0]=1,h[s+504>>2]=y(Ae),s=n[s+944>>2]|0}while((s|0)!=0)}function ft(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-4-f|0)>>>2)<<2)),gt(c))}function pt(s){return s=s|0,n[s+944>>2]|0}function Rt(s){s=s|0,Un(s,(n[s+964>>2]|0)!=0,2832),Le(s)}function er(s){return s=s|0,(o[s+984>>0]|0)!=0|0}function Zr(s,l){s=s|0,l=l|0,LUe(s,l,400)|0&&(Dr(s|0,l|0,400)|0,Le(s))}function qi(s){s=s|0;var l=Ze;return l=y(h[s+44>>2]),s=_t(l)|0,y(s?y(0):l)}function es(s){s=s|0;var l=Ze;return l=y(h[s+48>>2]),_t(l)|0&&(l=o[(n[s+976>>2]|0)+2>>0]|0?y(1):y(0)),y(l)}function xi(s,l){s=s|0,l=l|0,n[s+980>>2]=l}function jo(s){return s=s|0,n[s+980>>2]|0}function bA(s,l){s=s|0,l=l|0;var c=0;c=s+4|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function kA(s){return s=s|0,n[s+4>>2]|0}function up(s,l){s=s|0,l=l|0;var c=0;c=s+8|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function ng(s){return s=s|0,n[s+8>>2]|0}function gu(s,l){s=s|0,l=l|0;var c=0;c=s+12|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function ig(s){return s=s|0,n[s+12>>2]|0}function du(s,l){s=s|0,l=l|0;var c=0;c=s+16|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function uo(s){return s=s|0,n[s+16>>2]|0}function QA(s,l){s=s|0,l=l|0;var c=0;c=s+20|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function mc(s){return s=s|0,n[s+20>>2]|0}function ca(s,l){s=s|0,l=l|0;var c=0;c=s+24|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function sg(s){return s=s|0,n[s+24>>2]|0}function yc(s,l){s=s|0,l=l|0;var c=0;c=s+28|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function Pm(s){return s=s|0,n[s+28>>2]|0}function og(s,l){s=s|0,l=l|0;var c=0;c=s+32|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function $n(s){return s=s|0,n[s+32>>2]|0}function Ap(s,l){s=s|0,l=l|0;var c=0;c=s+36|0,(n[c>>2]|0)!=(l|0)&&(n[c>>2]=l,Le(s))}function ag(s){return s=s|0,n[s+36>>2]|0}function FA(s,l){s=s|0,l=y(l);var c=0;c=s+40|0,y(h[c>>2])!=l&&(h[c>>2]=l,Le(s))}function Hs(s,l){s=s|0,l=y(l);var c=0;c=s+44|0,y(h[c>>2])!=l&&(h[c>>2]=l,Le(s))}function mu(s,l){s=s|0,l=y(l);var c=0;c=s+48|0,y(h[c>>2])!=l&&(h[c>>2]=l,Le(s))}function Ha(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=_t(l)|0,c=(m^1)&1,f=s+52|0,d=s+56|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function Gi(s,l){s=s|0,l=y(l);var c=0,f=0;f=s+52|0,c=s+56|0,y(h[f>>2])==l&&(n[c>>2]|0)==2||(h[f>>2]=l,f=_t(l)|0,n[c>>2]=f?3:2,Le(s))}function ua(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+52|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function yu(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=_t(c)|0,f=(m^1)&1,d=s+132+(l<<3)|0,l=s+132+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function Es(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=_t(c)|0,f=m?0:2,d=s+132+(l<<3)|0,l=s+132+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function Ec(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=l+132+(c<<3)|0,l=n[f+4>>2]|0,c=s,n[c>>2]=n[f>>2],n[c+4>>2]=l}function Cc(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=_t(c)|0,f=(m^1)&1,d=s+60+(l<<3)|0,l=s+60+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function G(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=_t(c)|0,f=m?0:2,d=s+60+(l<<3)|0,l=s+60+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function Dt(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=l+60+(c<<3)|0,l=n[f+4>>2]|0,c=s,n[c>>2]=n[f>>2],n[c+4>>2]=l}function wl(s,l){s=s|0,l=l|0;var c=0;c=s+60+(l<<3)+4|0,(n[c>>2]|0)!=3&&(h[s+60+(l<<3)>>2]=y(Ae),n[c>>2]=3,Le(s))}function bi(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=_t(c)|0,f=(m^1)&1,d=s+204+(l<<3)|0,l=s+204+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function wc(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=_t(c)|0,f=m?0:2,d=s+204+(l<<3)|0,l=s+204+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function ct(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=l+204+(c<<3)|0,l=n[f+4>>2]|0,c=s,n[c>>2]=n[f>>2],n[c+4>>2]=l}function Eu(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0,m=0;m=_t(c)|0,f=(m^1)&1,d=s+276+(l<<3)|0,l=s+276+(l<<3)+4|0,m|y(h[d>>2])==c&&(n[l>>2]|0)==(f|0)||(h[d>>2]=c,n[l>>2]=f,Le(s))}function lg(s,l){return s=s|0,l=l|0,y(h[s+276+(l<<3)>>2])}function mw(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=_t(l)|0,c=(m^1)&1,f=s+348|0,d=s+352|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function TA(s,l){s=s|0,l=y(l);var c=0,f=0;f=s+348|0,c=s+352|0,y(h[f>>2])==l&&(n[c>>2]|0)==2||(h[f>>2]=l,f=_t(l)|0,n[c>>2]=f?3:2,Le(s))}function fp(s){s=s|0;var l=0;l=s+352|0,(n[l>>2]|0)!=3&&(h[s+348>>2]=y(Ae),n[l>>2]=3,Le(s))}function Br(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+348|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function Cs(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=_t(l)|0,c=(m^1)&1,f=s+356|0,d=s+360|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function cg(s,l){s=s|0,l=y(l);var c=0,f=0;f=s+356|0,c=s+360|0,y(h[f>>2])==l&&(n[c>>2]|0)==2||(h[f>>2]=l,f=_t(l)|0,n[c>>2]=f?3:2,Le(s))}function ug(s){s=s|0;var l=0;l=s+360|0,(n[l>>2]|0)!=3&&(h[s+356>>2]=y(Ae),n[l>>2]=3,Le(s))}function Ag(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+356|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function pp(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=_t(l)|0,c=(m^1)&1,f=s+364|0,d=s+368|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function Ic(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=_t(l)|0,c=m?0:2,f=s+364|0,d=s+368|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function Ct(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+364|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function Sm(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=_t(l)|0,c=(m^1)&1,f=s+372|0,d=s+376|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function fg(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=_t(l)|0,c=m?0:2,f=s+372|0,d=s+376|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function pg(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+372|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function Cu(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=_t(l)|0,c=(m^1)&1,f=s+380|0,d=s+384|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function xm(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=_t(l)|0,c=m?0:2,f=s+380|0,d=s+384|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function hg(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+380|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function wu(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=_t(l)|0,c=(m^1)&1,f=s+388|0,d=s+392|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function yw(s,l){s=s|0,l=y(l);var c=0,f=0,d=0,m=0;m=_t(l)|0,c=m?0:2,f=s+388|0,d=s+392|0,m|y(h[f>>2])==l&&(n[d>>2]|0)==(c|0)||(h[f>>2]=l,n[d>>2]=c,Le(s))}function bm(s,l){s=s|0,l=l|0;var c=0,f=0;f=l+388|0,c=n[f+4>>2]|0,l=s,n[l>>2]=n[f>>2],n[l+4>>2]=c}function Aa(s,l){s=s|0,l=y(l);var c=0;c=s+396|0,y(h[c>>2])!=l&&(h[c>>2]=l,Le(s))}function Bc(s){return s=s|0,y(h[s+396>>2])}function Il(s){return s=s|0,y(h[s+400>>2])}function Iu(s){return s=s|0,y(h[s+404>>2])}function gg(s){return s=s|0,y(h[s+408>>2])}function RA(s){return s=s|0,y(h[s+412>>2])}function hp(s){return s=s|0,y(h[s+416>>2])}function ja(s){return s=s|0,y(h[s+420>>2])}function dg(s,l){switch(s=s|0,l=l|0,Un(s,(l|0)<6,2918),l|0){case 0:{l=(n[s+496>>2]|0)==2?5:4;break}case 2:{l=(n[s+496>>2]|0)==2?4:5;break}default:}return y(h[s+424+(l<<2)>>2])}function gp(s,l){switch(s=s|0,l=l|0,Un(s,(l|0)<6,2918),l|0){case 0:{l=(n[s+496>>2]|0)==2?5:4;break}case 2:{l=(n[s+496>>2]|0)==2?4:5;break}default:}return y(h[s+448+(l<<2)>>2])}function qo(s,l){switch(s=s|0,l=l|0,Un(s,(l|0)<6,2918),l|0){case 0:{l=(n[s+496>>2]|0)==2?5:4;break}case 2:{l=(n[s+496>>2]|0)==2?4:5;break}default:}return y(h[s+472+(l<<2)>>2])}function ws(s,l){s=s|0,l=l|0;var c=0,f=Ze;return c=n[s+4>>2]|0,(c|0)==(n[l+4>>2]|0)?c?(f=y(h[s>>2]),s=y(ne(y(f-y(h[l>>2]))))<y(999999974e-13)):s=1:s=0,s|0}function Ii(s,l){s=y(s),l=y(l);var c=0;return _t(s)|0?c=_t(l)|0:c=y(ne(y(s-l)))<y(999999974e-13),c|0}function km(s,l){s=s|0,l=l|0,Qm(s,l)}function Qm(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c+4|0,n[f>>2]=0,n[f+4>>2]=0,n[f+8>>2]=0,Oa(f|0,s|0,l|0,0),Ao(s,3,(o[f+11>>0]|0)<0?n[f>>2]|0:f,c),s3e(f),C=c}function Go(s,l,c,f){s=y(s),l=y(l),c=c|0,f=f|0;var d=Ze;s=y(s*l),d=y(kT(s,y(1)));do if(Ii(d,y(0))|0)s=y(s-d);else{if(s=y(s-d),Ii(d,y(1))|0){s=y(s+y(1));break}if(c){s=y(s+y(1));break}f||(d>y(.5)?d=y(1):(f=Ii(d,y(.5))|0,d=y(f?1:0)),s=y(s+d))}while(0);return y(s/l)}function NA(s,l,c,f,d,m,B,k,Q,O,M,q,se){s=s|0,l=y(l),c=c|0,f=y(f),d=d|0,m=y(m),B=B|0,k=y(k),Q=y(Q),O=y(O),M=y(M),q=y(q),se=se|0;var Ge=0,Oe=Ze,Fe=Ze,et=Ze,Xe=Ze,at=Ze,Ue=Ze;return Q<y(0)|O<y(0)?se=0:((se|0)!=0&&(Oe=y(h[se+4>>2]),Oe!=y(0))?(et=y(Go(l,Oe,0,0)),Xe=y(Go(f,Oe,0,0)),Fe=y(Go(m,Oe,0,0)),Oe=y(Go(k,Oe,0,0))):(Fe=m,et=l,Oe=k,Xe=f),(d|0)==(s|0)?Ge=Ii(Fe,et)|0:Ge=0,(B|0)==(c|0)?se=Ii(Oe,Xe)|0:se=0,!Ge&&(at=y(l-M),!(dp(s,at,Q)|0))&&!(mp(s,at,d,Q)|0)?Ge=mg(s,at,d,m,Q)|0:Ge=1,!se&&(Ue=y(f-q),!(dp(c,Ue,O)|0))&&!(mp(c,Ue,B,O)|0)?se=mg(c,Ue,B,k,O)|0:se=1,se=Ge&se),se|0}function dp(s,l,c){return s=s|0,l=y(l),c=y(c),(s|0)==1?s=Ii(l,c)|0:s=0,s|0}function mp(s,l,c,f){return s=s|0,l=y(l),c=c|0,f=y(f),(s|0)==2&(c|0)==0?l>=f?s=1:s=Ii(l,f)|0:s=0,s|0}function mg(s,l,c,f,d){return s=s|0,l=y(l),c=c|0,f=y(f),d=y(d),(s|0)==2&(c|0)==2&f>l?d<=l?s=1:s=Ii(l,d)|0:s=0,s|0}function fa(s,l,c,f,d,m,B,k,Q,O,M){s=s|0,l=y(l),c=y(c),f=f|0,d=d|0,m=m|0,B=y(B),k=y(k),Q=Q|0,O=O|0,M=M|0;var q=0,se=0,Ge=0,Oe=0,Fe=Ze,et=Ze,Xe=0,at=0,Ue=0,qe=0,Lt=0,Or=0,or=0,Xt=0,Pr=0,Nr=0,ir=0,bn=Ze,go=Ze,mo=Ze,yo=0,ya=0;ir=C,C=C+160|0,Xt=ir+152|0,or=ir+120|0,Or=ir+104|0,Ue=ir+72|0,Oe=ir+56|0,Lt=ir+8|0,at=ir,qe=(n[2279]|0)+1|0,n[2279]=qe,Pr=s+984|0,(o[Pr>>0]|0)!=0&&(n[s+512>>2]|0)!=(n[2278]|0)?Xe=4:(n[s+516>>2]|0)==(f|0)?Nr=0:Xe=4,(Xe|0)==4&&(n[s+520>>2]=0,n[s+924>>2]=-1,n[s+928>>2]=-1,h[s+932>>2]=y(-1),h[s+936>>2]=y(-1),Nr=1);e:do if(n[s+964>>2]|0)if(Fe=y(ln(s,2,B)),et=y(ln(s,0,B)),q=s+916|0,mo=y(h[q>>2]),go=y(h[s+920>>2]),bn=y(h[s+932>>2]),NA(d,l,m,c,n[s+924>>2]|0,mo,n[s+928>>2]|0,go,bn,y(h[s+936>>2]),Fe,et,M)|0)Xe=22;else if(Ge=n[s+520>>2]|0,!Ge)Xe=21;else for(se=0;;){if(q=s+524+(se*24|0)|0,bn=y(h[q>>2]),go=y(h[s+524+(se*24|0)+4>>2]),mo=y(h[s+524+(se*24|0)+16>>2]),NA(d,l,m,c,n[s+524+(se*24|0)+8>>2]|0,bn,n[s+524+(se*24|0)+12>>2]|0,go,mo,y(h[s+524+(se*24|0)+20>>2]),Fe,et,M)|0){Xe=22;break e}if(se=se+1|0,se>>>0>=Ge>>>0){Xe=21;break}}else{if(Q){if(q=s+916|0,!(Ii(y(h[q>>2]),l)|0)){Xe=21;break}if(!(Ii(y(h[s+920>>2]),c)|0)){Xe=21;break}if((n[s+924>>2]|0)!=(d|0)){Xe=21;break}q=(n[s+928>>2]|0)==(m|0)?q:0,Xe=22;break}if(Ge=n[s+520>>2]|0,!Ge)Xe=21;else for(se=0;;){if(q=s+524+(se*24|0)|0,Ii(y(h[q>>2]),l)|0&&Ii(y(h[s+524+(se*24|0)+4>>2]),c)|0&&(n[s+524+(se*24|0)+8>>2]|0)==(d|0)&&(n[s+524+(se*24|0)+12>>2]|0)==(m|0)){Xe=22;break e}if(se=se+1|0,se>>>0>=Ge>>>0){Xe=21;break}}}while(0);do if((Xe|0)==21)o[11697]|0?(q=0,Xe=28):(q=0,Xe=31);else if((Xe|0)==22){if(se=(o[11697]|0)!=0,!((q|0)!=0&(Nr^1)))if(se){Xe=28;break}else{Xe=31;break}Oe=q+16|0,n[s+908>>2]=n[Oe>>2],Ge=q+20|0,n[s+912>>2]=n[Ge>>2],(o[11698]|0)==0|se^1||(n[at>>2]=LA(qe)|0,n[at+4>>2]=qe,Ao(s,4,2972,at),se=n[s+972>>2]|0,se|0&&ef[se&127](s),d=qa(d,Q)|0,m=qa(m,Q)|0,ya=+y(h[Oe>>2]),yo=+y(h[Ge>>2]),n[Lt>>2]=d,n[Lt+4>>2]=m,E[Lt+8>>3]=+l,E[Lt+16>>3]=+c,E[Lt+24>>3]=ya,E[Lt+32>>3]=yo,n[Lt+40>>2]=O,Ao(s,4,2989,Lt))}while(0);return(Xe|0)==28&&(se=LA(qe)|0,n[Oe>>2]=se,n[Oe+4>>2]=qe,n[Oe+8>>2]=Nr?3047:11699,Ao(s,4,3038,Oe),se=n[s+972>>2]|0,se|0&&ef[se&127](s),Lt=qa(d,Q)|0,Xe=qa(m,Q)|0,n[Ue>>2]=Lt,n[Ue+4>>2]=Xe,E[Ue+8>>3]=+l,E[Ue+16>>3]=+c,n[Ue+24>>2]=O,Ao(s,4,3049,Ue),Xe=31),(Xe|0)==31&&(si(s,l,c,f,d,m,B,k,Q,M),o[11697]|0&&(se=n[2279]|0,Lt=LA(se)|0,n[Or>>2]=Lt,n[Or+4>>2]=se,n[Or+8>>2]=Nr?3047:11699,Ao(s,4,3083,Or),se=n[s+972>>2]|0,se|0&&ef[se&127](s),Lt=qa(d,Q)|0,Or=qa(m,Q)|0,yo=+y(h[s+908>>2]),ya=+y(h[s+912>>2]),n[or>>2]=Lt,n[or+4>>2]=Or,E[or+8>>3]=yo,E[or+16>>3]=ya,n[or+24>>2]=O,Ao(s,4,3092,or)),n[s+516>>2]=f,q||(se=s+520|0,q=n[se>>2]|0,(q|0)==16&&(o[11697]|0&&Ao(s,4,3124,Xt),n[se>>2]=0,q=0),Q?q=s+916|0:(n[se>>2]=q+1,q=s+524+(q*24|0)|0),h[q>>2]=l,h[q+4>>2]=c,n[q+8>>2]=d,n[q+12>>2]=m,n[q+16>>2]=n[s+908>>2],n[q+20>>2]=n[s+912>>2],q=0)),Q&&(n[s+416>>2]=n[s+908>>2],n[s+420>>2]=n[s+912>>2],o[s+985>>0]=1,o[Pr>>0]=0),n[2279]=(n[2279]|0)+-1,n[s+512>>2]=n[2278],C=ir,Nr|(q|0)==0|0}function ln(s,l,c){s=s|0,l=l|0,c=y(c);var f=Ze;return f=y(V(s,l,c)),y(f+y(re(s,l,c)))}function Ao(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=C,C=C+16|0,d=m,n[d>>2]=f,s?f=n[s+976>>2]|0:f=0,Eg(f,s,l,c,d),C=m}function LA(s){return s=s|0,(s>>>0>60?3201:3201+(60-s)|0)|0}function qa(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;return d=C,C=C+32|0,c=d+12|0,f=d,n[c>>2]=n[254],n[c+4>>2]=n[255],n[c+8>>2]=n[256],n[f>>2]=n[257],n[f+4>>2]=n[258],n[f+8>>2]=n[259],(s|0)>2?s=11699:s=n[(l?f:c)+(s<<2)>>2]|0,C=d,s|0}function si(s,l,c,f,d,m,B,k,Q,O){s=s|0,l=y(l),c=y(c),f=f|0,d=d|0,m=m|0,B=y(B),k=y(k),Q=Q|0,O=O|0;var M=0,q=0,se=0,Ge=0,Oe=Ze,Fe=Ze,et=Ze,Xe=Ze,at=Ze,Ue=Ze,qe=Ze,Lt=0,Or=0,or=0,Xt=Ze,Pr=Ze,Nr=0,ir=Ze,bn=0,go=0,mo=0,yo=0,ya=0,Qp=0,Fp=0,xl=0,Tp=0,Fu=0,Tu=0,Rp=0,Np=0,Lp=0,Xr=0,bl=0,Mp=0,bc=0,Op=Ze,Up=Ze,Ru=Ze,Nu=Ze,kc=Ze,qs=0,za=0,Wo=0,kl=0,rf=0,nf=Ze,Lu=Ze,sf=Ze,of=Ze,Gs=Ze,vs=Ze,Ql=0,Tn=Ze,af=Ze,Eo=Ze,Qc=Ze,Co=Ze,Fc=Ze,lf=0,cf=0,Tc=Ze,Ys=Ze,Fl=0,uf=0,Af=0,ff=0,br=Ze,Jn=0,Ds=0,wo=0,Ws=0,Tr=0,ur=0,Tl=0,Jt=Ze,pf=0,li=0;Tl=C,C=C+16|0,qs=Tl+12|0,za=Tl+8|0,Wo=Tl+4|0,kl=Tl,Un(s,(d|0)==0|(_t(l)|0)^1,3326),Un(s,(m|0)==0|(_t(c)|0)^1,3406),Ds=mt(s,f)|0,n[s+496>>2]=Ds,Tr=fr(2,Ds)|0,ur=fr(0,Ds)|0,h[s+440>>2]=y(V(s,Tr,B)),h[s+444>>2]=y(re(s,Tr,B)),h[s+428>>2]=y(V(s,ur,B)),h[s+436>>2]=y(re(s,ur,B)),h[s+464>>2]=y(Cr(s,Tr)),h[s+468>>2]=y(yn(s,Tr)),h[s+452>>2]=y(Cr(s,ur)),h[s+460>>2]=y(yn(s,ur)),h[s+488>>2]=y(oi(s,Tr,B)),h[s+492>>2]=y(Mi(s,Tr,B)),h[s+476>>2]=y(oi(s,ur,B)),h[s+484>>2]=y(Mi(s,ur,B));do if(n[s+964>>2]|0)wg(s,l,c,d,m,B,k);else{if(wo=s+948|0,Ws=(n[s+952>>2]|0)-(n[wo>>2]|0)>>2,!Ws){Gv(s,l,c,d,m,B,k);break}if(!Q&&Yv(s,l,c,d,m,B,k)|0)break;$(s),bl=s+508|0,o[bl>>0]=0,Tr=fr(n[s+4>>2]|0,Ds)|0,ur=Cw(Tr,Ds)|0,Jn=he(Tr)|0,Mp=n[s+8>>2]|0,uf=s+28|0,bc=(n[uf>>2]|0)!=0,Co=Jn?B:k,Tc=Jn?k:B,Op=y(Ep(s,Tr,B)),Up=y(ww(s,Tr,B)),Oe=y(Ep(s,ur,B)),Fc=y(En(s,Tr,B)),Ys=y(En(s,ur,B)),or=Jn?d:m,Fl=Jn?m:d,br=Jn?Fc:Ys,at=Jn?Ys:Fc,Qc=y(ln(s,2,B)),Xe=y(ln(s,0,B)),Fe=y(y(Gr(s+364|0,B))-br),et=y(y(Gr(s+380|0,B))-br),Ue=y(y(Gr(s+372|0,k))-at),qe=y(y(Gr(s+388|0,k))-at),Ru=Jn?Fe:Ue,Nu=Jn?et:qe,Qc=y(l-Qc),l=y(Qc-br),_t(l)|0?br=l:br=y(_n(y(Tg(l,et)),Fe)),af=y(c-Xe),l=y(af-at),_t(l)|0?Eo=l:Eo=y(_n(y(Tg(l,qe)),Ue)),Fe=Jn?br:Eo,Tn=Jn?Eo:br;e:do if((or|0)==1)for(f=0,q=0;;){if(M=gs(s,q)|0,!f)y(rs(M))>y(0)&&y(js(M))>y(0)?f=M:f=0;else if(Tm(M)|0){Ge=0;break e}if(q=q+1|0,q>>>0>=Ws>>>0){Ge=f;break}}else Ge=0;while(0);Lt=Ge+500|0,Or=Ge+504|0,f=0,M=0,l=y(0),se=0;do{if(q=n[(n[wo>>2]|0)+(se<<2)>>2]|0,(n[q+36>>2]|0)==1)Bu(q),o[q+985>>0]=1,o[q+984>>0]=0;else{Bl(q),Q&&yp(q,mt(q,Ds)|0,Fe,Tn,br);do if((n[q+24>>2]|0)!=1)if((q|0)==(Ge|0)){n[Lt>>2]=n[2278],h[Or>>2]=y(0);break}else{Rm(s,q,br,d,Eo,br,Eo,m,Ds,O);break}else M|0&&(n[M+960>>2]=q),n[q+960>>2]=0,M=q,f=(f|0)==0?q:f;while(0);vs=y(h[q+504>>2]),l=y(l+y(vs+y(ln(q,Tr,br))))}se=se+1|0}while((se|0)!=(Ws|0));for(mo=l>Fe,Ql=bc&((or|0)==2&mo)?1:or,bn=(Fl|0)==1,ya=bn&(Q^1),Qp=(Ql|0)==1,Fp=(Ql|0)==2,xl=976+(Tr<<2)|0,Tp=(Fl|2|0)==2,Lp=bn&(bc^1),Fu=1040+(ur<<2)|0,Tu=1040+(Tr<<2)|0,Rp=976+(ur<<2)|0,Np=(Fl|0)!=1,mo=bc&((or|0)!=0&mo),go=s+976|0,bn=bn^1,l=Fe,Nr=0,yo=0,vs=y(0),kc=y(0);;){e:do if(Nr>>>0<Ws>>>0)for(Or=n[wo>>2]|0,se=0,qe=y(0),Ue=y(0),et=y(0),Fe=y(0),q=0,M=0,Ge=Nr;;){if(Lt=n[Or+(Ge<<2)>>2]|0,(n[Lt+36>>2]|0)!=1&&(n[Lt+940>>2]=yo,(n[Lt+24>>2]|0)!=1)){if(Xe=y(ln(Lt,Tr,br)),Xr=n[xl>>2]|0,c=y(Gr(Lt+380+(Xr<<3)|0,Co)),at=y(h[Lt+504>>2]),c=y(Tg(c,at)),c=y(_n(y(Gr(Lt+364+(Xr<<3)|0,Co)),c)),bc&(se|0)!=0&y(Xe+y(Ue+c))>l){m=se,Xe=qe,or=Ge;break e}Xe=y(Xe+c),c=y(Ue+Xe),Xe=y(qe+Xe),Tm(Lt)|0&&(et=y(et+y(rs(Lt))),Fe=y(Fe-y(at*y(js(Lt))))),M|0&&(n[M+960>>2]=Lt),n[Lt+960>>2]=0,se=se+1|0,M=Lt,q=(q|0)==0?Lt:q}else Xe=qe,c=Ue;if(Ge=Ge+1|0,Ge>>>0<Ws>>>0)qe=Xe,Ue=c;else{m=se,or=Ge;break}}else m=0,Xe=y(0),et=y(0),Fe=y(0),q=0,or=Nr;while(0);Xr=et>y(0)&et<y(1),Xt=Xr?y(1):et,Xr=Fe>y(0)&Fe<y(1),qe=Xr?y(1):Fe;do if(Qp)Xr=51;else if(Xe<Ru&((_t(Ru)|0)^1))l=Ru,Xr=51;else if(Xe>Nu&((_t(Nu)|0)^1))l=Nu,Xr=51;else if(o[(n[go>>2]|0)+3>>0]|0)Xr=51;else{if(Xt!=y(0)&&y(rs(s))!=y(0)){Xr=53;break}l=Xe,Xr=53}while(0);if((Xr|0)==51&&(Xr=0,_t(l)|0?Xr=53:(Pr=y(l-Xe),ir=l)),(Xr|0)==53&&(Xr=0,Xe<y(0)?(Pr=y(-Xe),ir=l):(Pr=y(0),ir=l)),!ya&&(rf=(q|0)==0,!rf)){se=n[xl>>2]|0,Ge=Pr<y(0),at=y(Pr/qe),Lt=Pr>y(0),Ue=y(Pr/Xt),et=y(0),Xe=y(0),l=y(0),M=q;do c=y(Gr(M+380+(se<<3)|0,Co)),Fe=y(Gr(M+364+(se<<3)|0,Co)),Fe=y(Tg(c,y(_n(Fe,y(h[M+504>>2]))))),Ge?(c=y(Fe*y(js(M))),c!=y(-0)&&(Jt=y(Fe-y(at*c)),nf=y(Bi(M,Tr,Jt,ir,br)),Jt!=nf)&&(et=y(et-y(nf-Fe)),l=y(l+c))):Lt&&(Lu=y(rs(M)),Lu!=y(0))&&(Jt=y(Fe+y(Ue*Lu)),sf=y(Bi(M,Tr,Jt,ir,br)),Jt!=sf)&&(et=y(et-y(sf-Fe)),Xe=y(Xe-Lu)),M=n[M+960>>2]|0;while((M|0)!=0);if(l=y(qe+l),Fe=y(Pr+et),rf)l=y(0);else{at=y(Xt+Xe),Ge=n[xl>>2]|0,Lt=Fe<y(0),Or=l==y(0),Ue=y(Fe/l),se=Fe>y(0),at=y(Fe/at),l=y(0);do{Jt=y(Gr(q+380+(Ge<<3)|0,Co)),et=y(Gr(q+364+(Ge<<3)|0,Co)),et=y(Tg(Jt,y(_n(et,y(h[q+504>>2]))))),Lt?(Jt=y(et*y(js(q))),Fe=y(-Jt),Jt!=y(-0)?(Jt=y(Ue*Fe),Fe=y(Bi(q,Tr,y(et+(Or?Fe:Jt)),ir,br))):Fe=et):se&&(of=y(rs(q)),of!=y(0))?Fe=y(Bi(q,Tr,y(et+y(at*of)),ir,br)):Fe=et,l=y(l-y(Fe-et)),Xe=y(ln(q,Tr,br)),c=y(ln(q,ur,br)),Fe=y(Fe+Xe),h[za>>2]=Fe,n[kl>>2]=1,et=y(h[q+396>>2]);e:do if(_t(et)|0){M=_t(Tn)|0;do if(!M){if(mo|(ts(q,ur,Tn)|0|bn)||(ha(s,q)|0)!=4||(n[(vl(q,ur)|0)+4>>2]|0)==3||(n[(Pc(q,ur)|0)+4>>2]|0)==3)break;h[qs>>2]=Tn,n[Wo>>2]=1;break e}while(0);if(ts(q,ur,Tn)|0){M=n[q+992+(n[Rp>>2]<<2)>>2]|0,Jt=y(c+y(Gr(M,Tn))),h[qs>>2]=Jt,M=Np&(n[M+4>>2]|0)==2,n[Wo>>2]=((_t(Jt)|0|M)^1)&1;break}else{h[qs>>2]=Tn,n[Wo>>2]=M?0:2;break}}else Jt=y(Fe-Xe),Xt=y(Jt/et),Jt=y(et*Jt),n[Wo>>2]=1,h[qs>>2]=y(c+(Jn?Xt:Jt));while(0);yr(q,Tr,ir,br,kl,za),yr(q,ur,Tn,br,Wo,qs);do if(!(ts(q,ur,Tn)|0)&&(ha(s,q)|0)==4){if((n[(vl(q,ur)|0)+4>>2]|0)==3){M=0;break}M=(n[(Pc(q,ur)|0)+4>>2]|0)!=3}else M=0;while(0);Jt=y(h[za>>2]),Xt=y(h[qs>>2]),pf=n[kl>>2]|0,li=n[Wo>>2]|0,fa(q,Jn?Jt:Xt,Jn?Xt:Jt,Ds,Jn?pf:li,Jn?li:pf,br,Eo,Q&(M^1),3488,O)|0,o[bl>>0]=o[bl>>0]|o[q+508>>0],q=n[q+960>>2]|0}while((q|0)!=0)}}else l=y(0);if(l=y(Pr+l),li=l<y(0)&1,o[bl>>0]=li|u[bl>>0],Fp&l>y(0)?(M=n[xl>>2]|0,(n[s+364+(M<<3)+4>>2]|0)!=0&&(Gs=y(Gr(s+364+(M<<3)|0,Co)),Gs>=y(0))?Fe=y(_n(y(0),y(Gs-y(ir-l)))):Fe=y(0)):Fe=l,Lt=Nr>>>0<or>>>0,Lt){Ge=n[wo>>2]|0,se=Nr,M=0;do q=n[Ge+(se<<2)>>2]|0,n[q+24>>2]|0||(M=((n[(vl(q,Tr)|0)+4>>2]|0)==3&1)+M|0,M=M+((n[(Pc(q,Tr)|0)+4>>2]|0)==3&1)|0),se=se+1|0;while((se|0)!=(or|0));M?(Xe=y(0),c=y(0)):Xr=101}else Xr=101;e:do if((Xr|0)==101)switch(Xr=0,Mp|0){case 1:{M=0,Xe=y(Fe*y(.5)),c=y(0);break e}case 2:{M=0,Xe=Fe,c=y(0);break e}case 3:{if(m>>>0<=1){M=0,Xe=y(0),c=y(0);break e}c=y((m+-1|0)>>>0),M=0,Xe=y(0),c=y(y(_n(Fe,y(0)))/c);break e}case 5:{c=y(Fe/y((m+1|0)>>>0)),M=0,Xe=c;break e}case 4:{c=y(Fe/y(m>>>0)),M=0,Xe=y(c*y(.5));break e}default:{M=0,Xe=y(0),c=y(0);break e}}while(0);if(l=y(Op+Xe),Lt){et=y(Fe/y(M|0)),se=n[wo>>2]|0,q=Nr,Fe=y(0);do{M=n[se+(q<<2)>>2]|0;e:do if((n[M+36>>2]|0)!=1){switch(n[M+24>>2]|0){case 1:{if(gi(M,Tr)|0){if(!Q)break e;Jt=y(Mr(M,Tr,ir)),Jt=y(Jt+y(Cr(s,Tr))),Jt=y(Jt+y(V(M,Tr,br))),h[M+400+(n[Tu>>2]<<2)>>2]=Jt;break e}break}case 0:if(li=(n[(vl(M,Tr)|0)+4>>2]|0)==3,Jt=y(et+l),l=li?Jt:l,Q&&(li=M+400+(n[Tu>>2]<<2)|0,h[li>>2]=y(l+y(h[li>>2]))),li=(n[(Pc(M,Tr)|0)+4>>2]|0)==3,Jt=y(et+l),l=li?Jt:l,ya){Jt=y(c+y(ln(M,Tr,br))),Fe=Tn,l=y(l+y(Jt+y(h[M+504>>2])));break e}else{l=y(l+y(c+y(ns(M,Tr,br)))),Fe=y(_n(Fe,y(ns(M,ur,br))));break e}default:}Q&&(Jt=y(Xe+y(Cr(s,Tr))),li=M+400+(n[Tu>>2]<<2)|0,h[li>>2]=y(Jt+y(h[li>>2])))}while(0);q=q+1|0}while((q|0)!=(or|0))}else Fe=y(0);if(c=y(Up+l),Tp?Xe=y(y(Bi(s,ur,y(Ys+Fe),Tc,B))-Ys):Xe=Tn,et=y(y(Bi(s,ur,y(Ys+(Lp?Tn:Fe)),Tc,B))-Ys),Lt&Q){q=Nr;do{se=n[(n[wo>>2]|0)+(q<<2)>>2]|0;do if((n[se+36>>2]|0)!=1){if((n[se+24>>2]|0)==1){if(gi(se,ur)|0){if(Jt=y(Mr(se,ur,Tn)),Jt=y(Jt+y(Cr(s,ur))),Jt=y(Jt+y(V(se,ur,br))),M=n[Fu>>2]|0,h[se+400+(M<<2)>>2]=Jt,!(_t(Jt)|0))break}else M=n[Fu>>2]|0;Jt=y(Cr(s,ur)),h[se+400+(M<<2)>>2]=y(Jt+y(V(se,ur,br)));break}M=ha(s,se)|0;do if((M|0)==4){if((n[(vl(se,ur)|0)+4>>2]|0)==3){Xr=139;break}if((n[(Pc(se,ur)|0)+4>>2]|0)==3){Xr=139;break}if(ts(se,ur,Tn)|0){l=Oe;break}pf=n[se+908+(n[xl>>2]<<2)>>2]|0,n[qs>>2]=pf,l=y(h[se+396>>2]),li=_t(l)|0,Fe=(n[v>>2]=pf,y(h[v>>2])),li?l=et:(Pr=y(ln(se,ur,br)),Jt=y(Fe/l),l=y(l*Fe),l=y(Pr+(Jn?Jt:l))),h[za>>2]=l,h[qs>>2]=y(y(ln(se,Tr,br))+Fe),n[Wo>>2]=1,n[kl>>2]=1,yr(se,Tr,ir,br,Wo,qs),yr(se,ur,Tn,br,kl,za),l=y(h[qs>>2]),Pr=y(h[za>>2]),Jt=Jn?l:Pr,l=Jn?Pr:l,li=((_t(Jt)|0)^1)&1,fa(se,Jt,l,Ds,li,((_t(l)|0)^1)&1,br,Eo,1,3493,O)|0,l=Oe}else Xr=139;while(0);e:do if((Xr|0)==139){Xr=0,l=y(Xe-y(ns(se,ur,br)));do if((n[(vl(se,ur)|0)+4>>2]|0)==3){if((n[(Pc(se,ur)|0)+4>>2]|0)!=3)break;l=y(Oe+y(_n(y(0),y(l*y(.5)))));break e}while(0);if((n[(Pc(se,ur)|0)+4>>2]|0)==3){l=Oe;break}if((n[(vl(se,ur)|0)+4>>2]|0)==3){l=y(Oe+y(_n(y(0),l)));break}switch(M|0){case 1:{l=Oe;break e}case 2:{l=y(Oe+y(l*y(.5)));break e}default:{l=y(Oe+l);break e}}}while(0);Jt=y(vs+l),li=se+400+(n[Fu>>2]<<2)|0,h[li>>2]=y(Jt+y(h[li>>2]))}while(0);q=q+1|0}while((q|0)!=(or|0))}if(vs=y(vs+et),kc=y(_n(kc,c)),m=yo+1|0,or>>>0>=Ws>>>0)break;l=ir,Nr=or,yo=m}do if(Q){if(M=m>>>0>1,!M&&!(Yi(s)|0))break;if(!(_t(Tn)|0)){l=y(Tn-vs);e:do switch(n[s+12>>2]|0){case 3:{Oe=y(Oe+l),Ue=y(0);break}case 2:{Oe=y(Oe+y(l*y(.5))),Ue=y(0);break}case 4:{Tn>vs?Ue=y(l/y(m>>>0)):Ue=y(0);break}case 7:if(Tn>vs){Oe=y(Oe+y(l/y(m<<1>>>0))),Ue=y(l/y(m>>>0)),Ue=M?Ue:y(0);break e}else{Oe=y(Oe+y(l*y(.5))),Ue=y(0);break e}case 6:{Ue=y(l/y(yo>>>0)),Ue=Tn>vs&M?Ue:y(0);break}default:Ue=y(0)}while(0);if(m|0)for(Lt=1040+(ur<<2)|0,Or=976+(ur<<2)|0,Ge=0,q=0;;){e:do if(q>>>0<Ws>>>0)for(Fe=y(0),et=y(0),l=y(0),se=q;;){M=n[(n[wo>>2]|0)+(se<<2)>>2]|0;do if((n[M+36>>2]|0)!=1&&(n[M+24>>2]|0)==0){if((n[M+940>>2]|0)!=(Ge|0))break e;if(Nm(M,ur)|0&&(Jt=y(h[M+908+(n[Or>>2]<<2)>>2]),l=y(_n(l,y(Jt+y(ln(M,ur,br)))))),(ha(s,M)|0)!=5)break;Gs=y(Ya(M)),Gs=y(Gs+y(V(M,0,br))),Jt=y(h[M+912>>2]),Jt=y(y(Jt+y(ln(M,0,br)))-Gs),Gs=y(_n(et,Gs)),Jt=y(_n(Fe,Jt)),Fe=Jt,et=Gs,l=y(_n(l,y(Gs+Jt)))}while(0);if(M=se+1|0,M>>>0<Ws>>>0)se=M;else{se=M;break}}else et=y(0),l=y(0),se=q;while(0);if(at=y(Ue+l),c=Oe,Oe=y(Oe+at),q>>>0<se>>>0){Xe=y(c+et),M=q;do{q=n[(n[wo>>2]|0)+(M<<2)>>2]|0;e:do if((n[q+36>>2]|0)!=1&&(n[q+24>>2]|0)==0)switch(ha(s,q)|0){case 1:{Jt=y(c+y(V(q,ur,br))),h[q+400+(n[Lt>>2]<<2)>>2]=Jt;break e}case 3:{Jt=y(y(Oe-y(re(q,ur,br)))-y(h[q+908+(n[Or>>2]<<2)>>2])),h[q+400+(n[Lt>>2]<<2)>>2]=Jt;break e}case 2:{Jt=y(c+y(y(at-y(h[q+908+(n[Or>>2]<<2)>>2]))*y(.5))),h[q+400+(n[Lt>>2]<<2)>>2]=Jt;break e}case 4:{if(Jt=y(c+y(V(q,ur,br))),h[q+400+(n[Lt>>2]<<2)>>2]=Jt,ts(q,ur,Tn)|0||(Jn?(Fe=y(h[q+908>>2]),l=y(Fe+y(ln(q,Tr,br))),et=at):(et=y(h[q+912>>2]),et=y(et+y(ln(q,ur,br))),l=at,Fe=y(h[q+908>>2])),Ii(l,Fe)|0&&Ii(et,y(h[q+912>>2]))|0))break e;fa(q,l,et,Ds,1,1,br,Eo,1,3501,O)|0;break e}case 5:{h[q+404>>2]=y(y(Xe-y(Ya(q)))+y(Mr(q,0,Tn)));break e}default:break e}while(0);M=M+1|0}while((M|0)!=(se|0))}if(Ge=Ge+1|0,(Ge|0)==(m|0))break;q=se}}}while(0);if(h[s+908>>2]=y(Bi(s,2,Qc,B,B)),h[s+912>>2]=y(Bi(s,0,af,k,B)),(Ql|0)!=0&&(lf=n[s+32>>2]|0,cf=(Ql|0)==2,!(cf&(lf|0)!=2))?cf&(lf|0)==2&&(l=y(Fc+ir),l=y(_n(y(Tg(l,y(MA(s,Tr,kc,Co)))),Fc)),Xr=198):(l=y(Bi(s,Tr,kc,Co,B)),Xr=198),(Xr|0)==198&&(h[s+908+(n[976+(Tr<<2)>>2]<<2)>>2]=l),(Fl|0)!=0&&(Af=n[s+32>>2]|0,ff=(Fl|0)==2,!(ff&(Af|0)!=2))?ff&(Af|0)==2&&(l=y(Ys+Tn),l=y(_n(y(Tg(l,y(MA(s,ur,y(Ys+vs),Tc)))),Ys)),Xr=204):(l=y(Bi(s,ur,y(Ys+vs),Tc,B)),Xr=204),(Xr|0)==204&&(h[s+908+(n[976+(ur<<2)>>2]<<2)>>2]=l),Q){if((n[uf>>2]|0)==2){q=976+(ur<<2)|0,se=1040+(ur<<2)|0,M=0;do Ge=gs(s,M)|0,n[Ge+24>>2]|0||(pf=n[q>>2]|0,Jt=y(h[s+908+(pf<<2)>>2]),li=Ge+400+(n[se>>2]<<2)|0,Jt=y(Jt-y(h[li>>2])),h[li>>2]=y(Jt-y(h[Ge+908+(pf<<2)>>2]))),M=M+1|0;while((M|0)!=(Ws|0))}if(f|0){M=Jn?Ql:d;do Lm(s,f,br,M,Eo,Ds,O),f=n[f+960>>2]|0;while((f|0)!=0)}if(M=(Tr|2|0)==3,q=(ur|2|0)==3,M|q){f=0;do se=n[(n[wo>>2]|0)+(f<<2)>>2]|0,(n[se+36>>2]|0)!=1&&(M&&Cp(s,se,Tr),q&&Cp(s,se,ur)),f=f+1|0;while((f|0)!=(Ws|0))}}}while(0);C=Tl}function pa(s,l){s=s|0,l=y(l);var c=0;oa(s,l>=y(0),3147),c=l==y(0),h[s+4>>2]=c?y(0):l}function vc(s,l,c,f){s=s|0,l=y(l),c=y(c),f=f|0;var d=Ze,m=Ze,B=0,k=0,Q=0;n[2278]=(n[2278]|0)+1,Bl(s),ts(s,2,l)|0?(d=y(Gr(n[s+992>>2]|0,l)),Q=1,d=y(d+y(ln(s,2,l)))):(d=y(Gr(s+380|0,l)),d>=y(0)?Q=2:(Q=((_t(l)|0)^1)&1,d=l)),ts(s,0,c)|0?(m=y(Gr(n[s+996>>2]|0,c)),k=1,m=y(m+y(ln(s,0,l)))):(m=y(Gr(s+388|0,c)),m>=y(0)?k=2:(k=((_t(c)|0)^1)&1,m=c)),B=s+976|0,fa(s,d,m,f,Q,k,l,c,1,3189,n[B>>2]|0)|0&&(yp(s,n[s+496>>2]|0,l,c,l),Dc(s,y(h[(n[B>>2]|0)+4>>2]),y(0),y(0)),o[11696]|0)&&km(s,7)}function Bl(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;k=C,C=C+32|0,B=k+24|0,m=k+16|0,f=k+8|0,d=k,c=0;do l=s+380+(c<<3)|0,(n[s+380+(c<<3)+4>>2]|0)!=0&&(Q=l,O=n[Q+4>>2]|0,M=f,n[M>>2]=n[Q>>2],n[M+4>>2]=O,M=s+364+(c<<3)|0,O=n[M+4>>2]|0,Q=d,n[Q>>2]=n[M>>2],n[Q+4>>2]=O,n[m>>2]=n[f>>2],n[m+4>>2]=n[f+4>>2],n[B>>2]=n[d>>2],n[B+4>>2]=n[d+4>>2],ws(m,B)|0)||(l=s+348+(c<<3)|0),n[s+992+(c<<2)>>2]=l,c=c+1|0;while((c|0)!=2);C=k}function ts(s,l,c){s=s|0,l=l|0,c=y(c);var f=0;switch(s=n[s+992+(n[976+(l<<2)>>2]<<2)>>2]|0,n[s+4>>2]|0){case 0:case 3:{s=0;break}case 1:{y(h[s>>2])<y(0)?s=0:f=5;break}case 2:{y(h[s>>2])<y(0)?s=0:s=(_t(c)|0)^1;break}default:f=5}return(f|0)==5&&(s=1),s|0}function Gr(s,l){switch(s=s|0,l=y(l),n[s+4>>2]|0){case 2:{l=y(y(y(h[s>>2])*l)/y(100));break}case 1:{l=y(h[s>>2]);break}default:l=y(Ae)}return y(l)}function yp(s,l,c,f,d){s=s|0,l=l|0,c=y(c),f=y(f),d=y(d);var m=0,B=Ze;l=n[s+944>>2]|0?l:1,m=fr(n[s+4>>2]|0,l)|0,l=Cw(m,l)|0,c=y(Mm(s,m,c)),f=y(Mm(s,l,f)),B=y(c+y(V(s,m,d))),h[s+400+(n[1040+(m<<2)>>2]<<2)>>2]=B,c=y(c+y(re(s,m,d))),h[s+400+(n[1e3+(m<<2)>>2]<<2)>>2]=c,c=y(f+y(V(s,l,d))),h[s+400+(n[1040+(l<<2)>>2]<<2)>>2]=c,d=y(f+y(re(s,l,d))),h[s+400+(n[1e3+(l<<2)>>2]<<2)>>2]=d}function Dc(s,l,c,f){s=s|0,l=y(l),c=y(c),f=y(f);var d=0,m=0,B=Ze,k=Ze,Q=0,O=0,M=Ze,q=0,se=Ze,Ge=Ze,Oe=Ze,Fe=Ze;if(l!=y(0)&&(d=s+400|0,Fe=y(h[d>>2]),m=s+404|0,Oe=y(h[m>>2]),q=s+416|0,Ge=y(h[q>>2]),O=s+420|0,B=y(h[O>>2]),se=y(Fe+c),M=y(Oe+f),f=y(se+Ge),k=y(M+B),Q=(n[s+988>>2]|0)==1,h[d>>2]=y(Go(Fe,l,0,Q)),h[m>>2]=y(Go(Oe,l,0,Q)),c=y(kT(y(Ge*l),y(1))),Ii(c,y(0))|0?m=0:m=(Ii(c,y(1))|0)^1,c=y(kT(y(B*l),y(1))),Ii(c,y(0))|0?d=0:d=(Ii(c,y(1))|0)^1,Fe=y(Go(f,l,Q&m,Q&(m^1))),h[q>>2]=y(Fe-y(Go(se,l,0,Q))),Fe=y(Go(k,l,Q&d,Q&(d^1))),h[O>>2]=y(Fe-y(Go(M,l,0,Q))),m=(n[s+952>>2]|0)-(n[s+948>>2]|0)>>2,m|0)){d=0;do Dc(gs(s,d)|0,l,se,M),d=d+1|0;while((d|0)!=(m|0))}}function Ew(s,l,c,f,d){switch(s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,c|0){case 5:case 0:{s=a7(n[489]|0,f,d)|0;break}default:s=t3e(f,d)|0}return s|0}function yg(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;d=C,C=C+16|0,m=d,n[m>>2]=f,Eg(s,0,l,c,m),C=d}function Eg(s,l,c,f,d){if(s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,s=s|0?s:956,x7[n[s+8>>2]&1](s,l,c,f,d)|0,(c|0)==5)Tt();else return}function Ga(s,l,c){s=s|0,l=l|0,c=c|0,o[s+l>>0]=c&1}function Fm(s,l){s=s|0,l=l|0;var c=0,f=0;n[s>>2]=0,n[s+4>>2]=0,n[s+8>>2]=0,c=l+4|0,f=(n[c>>2]|0)-(n[l>>2]|0)>>2,f|0&&(Cg(s,f),Qt(s,n[l>>2]|0,n[c>>2]|0,f))}function Cg(s,l){s=s|0,l=l|0;var c=0;if((N(s)|0)>>>0<l>>>0&&zr(s),l>>>0>1073741823)Tt();else{c=Vt(l<<2)|0,n[s+4>>2]=c,n[s>>2]=c,n[s+8>>2]=c+(l<<2);return}}function Qt(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,f=s+4|0,s=c-l|0,(s|0)>0&&(Dr(n[f>>2]|0,l|0,s|0)|0,n[f>>2]=(n[f>>2]|0)+(s>>>2<<2))}function N(s){return s=s|0,1073741823}function V(s,l,c){return s=s|0,l=l|0,c=y(c),he(l)|0&&(n[s+96>>2]|0)!=0?s=s+92|0:s=Fn(s+60|0,n[1040+(l<<2)>>2]|0,992)|0,y(ze(s,c))}function re(s,l,c){return s=s|0,l=l|0,c=y(c),he(l)|0&&(n[s+104>>2]|0)!=0?s=s+100|0:s=Fn(s+60|0,n[1e3+(l<<2)>>2]|0,992)|0,y(ze(s,c))}function he(s){return s=s|0,(s|1|0)==3|0}function ze(s,l){return s=s|0,l=y(l),(n[s+4>>2]|0)==3?l=y(0):l=y(Gr(s,l)),y(l)}function mt(s,l){return s=s|0,l=l|0,s=n[s>>2]|0,((s|0)==0?(l|0)>1?l:1:s)|0}function fr(s,l){s=s|0,l=l|0;var c=0;e:do if((l|0)==2){switch(s|0){case 2:{s=3;break e}case 3:break;default:{c=4;break e}}s=2}else c=4;while(0);return s|0}function Cr(s,l){s=s|0,l=l|0;var c=Ze;return he(l)|0&&(n[s+312>>2]|0)!=0&&(c=y(h[s+308>>2]),c>=y(0))||(c=y(_n(y(h[(Fn(s+276|0,n[1040+(l<<2)>>2]|0,992)|0)>>2]),y(0)))),y(c)}function yn(s,l){s=s|0,l=l|0;var c=Ze;return he(l)|0&&(n[s+320>>2]|0)!=0&&(c=y(h[s+316>>2]),c>=y(0))||(c=y(_n(y(h[(Fn(s+276|0,n[1e3+(l<<2)>>2]|0,992)|0)>>2]),y(0)))),y(c)}function oi(s,l,c){s=s|0,l=l|0,c=y(c);var f=Ze;return he(l)|0&&(n[s+240>>2]|0)!=0&&(f=y(Gr(s+236|0,c)),f>=y(0))||(f=y(_n(y(Gr(Fn(s+204|0,n[1040+(l<<2)>>2]|0,992)|0,c)),y(0)))),y(f)}function Mi(s,l,c){s=s|0,l=l|0,c=y(c);var f=Ze;return he(l)|0&&(n[s+248>>2]|0)!=0&&(f=y(Gr(s+244|0,c)),f>=y(0))||(f=y(_n(y(Gr(Fn(s+204|0,n[1e3+(l<<2)>>2]|0,992)|0,c)),y(0)))),y(f)}function wg(s,l,c,f,d,m,B){s=s|0,l=y(l),c=y(c),f=f|0,d=d|0,m=y(m),B=y(B);var k=Ze,Q=Ze,O=Ze,M=Ze,q=Ze,se=Ze,Ge=0,Oe=0,Fe=0;Fe=C,C=C+16|0,Ge=Fe,Oe=s+964|0,Un(s,(n[Oe>>2]|0)!=0,3519),k=y(En(s,2,l)),Q=y(En(s,0,l)),O=y(ln(s,2,l)),M=y(ln(s,0,l)),_t(l)|0?q=l:q=y(_n(y(0),y(y(l-O)-k))),_t(c)|0?se=c:se=y(_n(y(0),y(y(c-M)-Q))),(f|0)==1&(d|0)==1?(h[s+908>>2]=y(Bi(s,2,y(l-O),m,m)),l=y(Bi(s,0,y(c-M),B,m))):(b7[n[Oe>>2]&1](Ge,s,q,f,se,d),q=y(k+y(h[Ge>>2])),se=y(l-O),h[s+908>>2]=y(Bi(s,2,(f|2|0)==2?q:se,m,m)),se=y(Q+y(h[Ge+4>>2])),l=y(c-M),l=y(Bi(s,0,(d|2|0)==2?se:l,B,m))),h[s+912>>2]=l,C=Fe}function Gv(s,l,c,f,d,m,B){s=s|0,l=y(l),c=y(c),f=f|0,d=d|0,m=y(m),B=y(B);var k=Ze,Q=Ze,O=Ze,M=Ze;O=y(En(s,2,m)),k=y(En(s,0,m)),M=y(ln(s,2,m)),Q=y(ln(s,0,m)),l=y(l-M),h[s+908>>2]=y(Bi(s,2,(f|2|0)==2?O:l,m,m)),c=y(c-Q),h[s+912>>2]=y(Bi(s,0,(d|2|0)==2?k:c,B,m))}function Yv(s,l,c,f,d,m,B){s=s|0,l=y(l),c=y(c),f=f|0,d=d|0,m=y(m),B=y(B);var k=0,Q=Ze,O=Ze;return k=(f|0)==2,!(l<=y(0)&k)&&!(c<=y(0)&(d|0)==2)&&!((f|0)==1&(d|0)==1)?s=0:(Q=y(ln(s,0,m)),O=y(ln(s,2,m)),k=l<y(0)&k|(_t(l)|0),l=y(l-O),h[s+908>>2]=y(Bi(s,2,k?y(0):l,m,m)),l=y(c-Q),k=c<y(0)&(d|0)==2|(_t(c)|0),h[s+912>>2]=y(Bi(s,0,k?y(0):l,B,m)),s=1),s|0}function Cw(s,l){return s=s|0,l=l|0,OA(s)|0?s=fr(2,l)|0:s=0,s|0}function Ep(s,l,c){return s=s|0,l=l|0,c=y(c),c=y(oi(s,l,c)),y(c+y(Cr(s,l)))}function ww(s,l,c){return s=s|0,l=l|0,c=y(c),c=y(Mi(s,l,c)),y(c+y(yn(s,l)))}function En(s,l,c){s=s|0,l=l|0,c=y(c);var f=Ze;return f=y(Ep(s,l,c)),y(f+y(ww(s,l,c)))}function Tm(s){return s=s|0,n[s+24>>2]|0?s=0:y(rs(s))!=y(0)?s=1:s=y(js(s))!=y(0),s|0}function rs(s){s=s|0;var l=Ze;if(n[s+944>>2]|0){if(l=y(h[s+44>>2]),_t(l)|0)return l=y(h[s+40>>2]),s=l>y(0)&((_t(l)|0)^1),y(s?l:y(0))}else l=y(0);return y(l)}function js(s){s=s|0;var l=Ze,c=0,f=Ze;do if(n[s+944>>2]|0){if(l=y(h[s+48>>2]),_t(l)|0){if(c=o[(n[s+976>>2]|0)+2>>0]|0,c<<24>>24==0&&(f=y(h[s+40>>2]),f<y(0)&((_t(f)|0)^1))){l=y(-f);break}l=c<<24>>24?y(1):y(0)}}else l=y(0);while(0);return y(l)}function Bu(s){s=s|0;var l=0,c=0;if(zm(s+400|0,0,540)|0,o[s+985>>0]=1,$(s),c=wi(s)|0,c|0){l=s+948|0,s=0;do Bu(n[(n[l>>2]|0)+(s<<2)>>2]|0),s=s+1|0;while((s|0)!=(c|0))}}function Rm(s,l,c,f,d,m,B,k,Q,O){s=s|0,l=l|0,c=y(c),f=f|0,d=y(d),m=y(m),B=y(B),k=k|0,Q=Q|0,O=O|0;var M=0,q=Ze,se=0,Ge=0,Oe=Ze,Fe=Ze,et=0,Xe=Ze,at=0,Ue=Ze,qe=0,Lt=0,Or=0,or=0,Xt=0,Pr=0,Nr=0,ir=0,bn=0,go=0;bn=C,C=C+16|0,Or=bn+12|0,or=bn+8|0,Xt=bn+4|0,Pr=bn,ir=fr(n[s+4>>2]|0,Q)|0,qe=he(ir)|0,q=y(Gr(Iw(l)|0,qe?m:B)),Lt=ts(l,2,m)|0,Nr=ts(l,0,B)|0;do if(!(_t(q)|0)&&!(_t(qe?c:d)|0)){if(M=l+504|0,!(_t(y(h[M>>2]))|0)&&(!(Bw(n[l+976>>2]|0,0)|0)||(n[l+500>>2]|0)==(n[2278]|0)))break;h[M>>2]=y(_n(q,y(En(l,ir,m))))}else se=7;while(0);do if((se|0)==7){if(at=qe^1,!(at|Lt^1)){B=y(Gr(n[l+992>>2]|0,m)),h[l+504>>2]=y(_n(B,y(En(l,2,m))));break}if(!(qe|Nr^1)){B=y(Gr(n[l+996>>2]|0,B)),h[l+504>>2]=y(_n(B,y(En(l,0,m))));break}h[Or>>2]=y(Ae),h[or>>2]=y(Ae),n[Xt>>2]=0,n[Pr>>2]=0,Xe=y(ln(l,2,m)),Ue=y(ln(l,0,m)),Lt?(Oe=y(Xe+y(Gr(n[l+992>>2]|0,m))),h[Or>>2]=Oe,n[Xt>>2]=1,Ge=1):(Ge=0,Oe=y(Ae)),Nr?(q=y(Ue+y(Gr(n[l+996>>2]|0,B))),h[or>>2]=q,n[Pr>>2]=1,M=1):(M=0,q=y(Ae)),se=n[s+32>>2]|0,qe&(se|0)==2?se=2:_t(Oe)|0&&!(_t(c)|0)&&(h[Or>>2]=c,n[Xt>>2]=2,Ge=2,Oe=c),!((se|0)==2&at)&&_t(q)|0&&!(_t(d)|0)&&(h[or>>2]=d,n[Pr>>2]=2,M=2,q=d),Fe=y(h[l+396>>2]),et=_t(Fe)|0;do if(et)se=Ge;else{if((Ge|0)==1&at){h[or>>2]=y(y(Oe-Xe)/Fe),n[Pr>>2]=1,M=1,se=1;break}qe&(M|0)==1?(h[Or>>2]=y(Fe*y(q-Ue)),n[Xt>>2]=1,M=1,se=1):se=Ge}while(0);go=_t(c)|0,Ge=(ha(s,l)|0)!=4,!(qe|Lt|((f|0)!=1|go)|(Ge|(se|0)==1))&&(h[Or>>2]=c,n[Xt>>2]=1,!et)&&(h[or>>2]=y(y(c-Xe)/Fe),n[Pr>>2]=1,M=1),!(Nr|at|((k|0)!=1|(_t(d)|0))|(Ge|(M|0)==1))&&(h[or>>2]=d,n[Pr>>2]=1,!et)&&(h[Or>>2]=y(Fe*y(d-Ue)),n[Xt>>2]=1),yr(l,2,m,m,Xt,Or),yr(l,0,B,m,Pr,or),c=y(h[Or>>2]),d=y(h[or>>2]),fa(l,c,d,Q,n[Xt>>2]|0,n[Pr>>2]|0,m,B,0,3565,O)|0,B=y(h[l+908+(n[976+(ir<<2)>>2]<<2)>>2]),h[l+504>>2]=y(_n(B,y(En(l,ir,m))))}while(0);n[l+500>>2]=n[2278],C=bn}function Bi(s,l,c,f,d){return s=s|0,l=l|0,c=y(c),f=y(f),d=y(d),f=y(MA(s,l,c,f)),y(_n(f,y(En(s,l,d))))}function ha(s,l){return s=s|0,l=l|0,l=l+20|0,l=n[((n[l>>2]|0)==0?s+16|0:l)>>2]|0,(l|0)==5&&OA(n[s+4>>2]|0)|0&&(l=1),l|0}function vl(s,l){return s=s|0,l=l|0,he(l)|0&&(n[s+96>>2]|0)!=0?l=4:l=n[1040+(l<<2)>>2]|0,s+60+(l<<3)|0}function Pc(s,l){return s=s|0,l=l|0,he(l)|0&&(n[s+104>>2]|0)!=0?l=5:l=n[1e3+(l<<2)>>2]|0,s+60+(l<<3)|0}function yr(s,l,c,f,d,m){switch(s=s|0,l=l|0,c=y(c),f=y(f),d=d|0,m=m|0,c=y(Gr(s+380+(n[976+(l<<2)>>2]<<3)|0,c)),c=y(c+y(ln(s,l,f))),n[d>>2]|0){case 2:case 1:{d=_t(c)|0,f=y(h[m>>2]),h[m>>2]=d|f<c?f:c;break}case 0:{_t(c)|0||(n[d>>2]=2,h[m>>2]=c);break}default:}}function gi(s,l){return s=s|0,l=l|0,s=s+132|0,he(l)|0&&(n[(Fn(s,4,948)|0)+4>>2]|0)!=0?s=1:s=(n[(Fn(s,n[1040+(l<<2)>>2]|0,948)|0)+4>>2]|0)!=0,s|0}function Mr(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0;return s=s+132|0,he(l)|0&&(f=Fn(s,4,948)|0,(n[f+4>>2]|0)!=0)?d=4:(f=Fn(s,n[1040+(l<<2)>>2]|0,948)|0,n[f+4>>2]|0?d=4:c=y(0)),(d|0)==4&&(c=y(Gr(f,c))),y(c)}function ns(s,l,c){s=s|0,l=l|0,c=y(c);var f=Ze;return f=y(h[s+908+(n[976+(l<<2)>>2]<<2)>>2]),f=y(f+y(V(s,l,c))),y(f+y(re(s,l,c)))}function Yi(s){s=s|0;var l=0,c=0,f=0;e:do if(OA(n[s+4>>2]|0)|0)l=0;else if((n[s+16>>2]|0)!=5)if(c=wi(s)|0,!c)l=0;else for(l=0;;){if(f=gs(s,l)|0,(n[f+24>>2]|0)==0&&(n[f+20>>2]|0)==5){l=1;break e}if(l=l+1|0,l>>>0>=c>>>0){l=0;break}}else l=1;while(0);return l|0}function Nm(s,l){s=s|0,l=l|0;var c=Ze;return c=y(h[s+908+(n[976+(l<<2)>>2]<<2)>>2]),c>=y(0)&((_t(c)|0)^1)|0}function Ya(s){s=s|0;var l=Ze,c=0,f=0,d=0,m=0,B=0,k=0,Q=Ze;if(c=n[s+968>>2]|0,c)Q=y(h[s+908>>2]),l=y(h[s+912>>2]),l=y(v7[c&0](s,Q,l)),Un(s,(_t(l)|0)^1,3573);else{m=wi(s)|0;do if(m|0){for(c=0,d=0;;){if(f=gs(s,d)|0,n[f+940>>2]|0){B=8;break}if((n[f+24>>2]|0)!=1)if(k=(ha(s,f)|0)==5,k){c=f;break}else c=(c|0)==0?f:c;if(d=d+1|0,d>>>0>=m>>>0){B=8;break}}if((B|0)==8&&!c)break;return l=y(Ya(c)),y(l+y(h[c+404>>2]))}while(0);l=y(h[s+912>>2])}return y(l)}function MA(s,l,c,f){s=s|0,l=l|0,c=y(c),f=y(f);var d=Ze,m=0;return OA(l)|0?(l=1,m=3):he(l)|0?(l=0,m=3):(f=y(Ae),d=y(Ae)),(m|0)==3&&(d=y(Gr(s+364+(l<<3)|0,f)),f=y(Gr(s+380+(l<<3)|0,f))),m=f<c&(f>=y(0)&((_t(f)|0)^1)),c=m?f:c,m=d>=y(0)&((_t(d)|0)^1)&c<d,y(m?d:c)}function Lm(s,l,c,f,d,m,B){s=s|0,l=l|0,c=y(c),f=f|0,d=y(d),m=m|0,B=B|0;var k=Ze,Q=Ze,O=0,M=0,q=Ze,se=Ze,Ge=Ze,Oe=0,Fe=0,et=0,Xe=0,at=Ze,Ue=0;et=fr(n[s+4>>2]|0,m)|0,Oe=Cw(et,m)|0,Fe=he(et)|0,q=y(ln(l,2,c)),se=y(ln(l,0,c)),ts(l,2,c)|0?k=y(q+y(Gr(n[l+992>>2]|0,c))):gi(l,2)|0&&sr(l,2)|0?(k=y(h[s+908>>2]),Q=y(Cr(s,2)),Q=y(k-y(Q+y(yn(s,2)))),k=y(Mr(l,2,c)),k=y(Bi(l,2,y(Q-y(k+y(vu(l,2,c)))),c,c))):k=y(Ae),ts(l,0,d)|0?Q=y(se+y(Gr(n[l+996>>2]|0,d))):gi(l,0)|0&&sr(l,0)|0?(Q=y(h[s+912>>2]),at=y(Cr(s,0)),at=y(Q-y(at+y(yn(s,0)))),Q=y(Mr(l,0,d)),Q=y(Bi(l,0,y(at-y(Q+y(vu(l,0,d)))),d,c))):Q=y(Ae),O=_t(k)|0,M=_t(Q)|0;do if(O^M&&(Ge=y(h[l+396>>2]),!(_t(Ge)|0)))if(O){k=y(q+y(y(Q-se)*Ge));break}else{at=y(se+y(y(k-q)/Ge)),Q=M?at:Q;break}while(0);M=_t(k)|0,O=_t(Q)|0,M|O&&(Ue=(M^1)&1,f=c>y(0)&((f|0)!=0&M),k=Fe?k:f?c:k,fa(l,k,Q,m,Fe?Ue:f?2:Ue,M&(O^1)&1,k,Q,0,3623,B)|0,k=y(h[l+908>>2]),k=y(k+y(ln(l,2,c))),Q=y(h[l+912>>2]),Q=y(Q+y(ln(l,0,c)))),fa(l,k,Q,m,1,1,k,Q,1,3635,B)|0,sr(l,et)|0&&!(gi(l,et)|0)?(Ue=n[976+(et<<2)>>2]|0,at=y(h[s+908+(Ue<<2)>>2]),at=y(at-y(h[l+908+(Ue<<2)>>2])),at=y(at-y(yn(s,et))),at=y(at-y(re(l,et,c))),at=y(at-y(vu(l,et,Fe?c:d))),h[l+400+(n[1040+(et<<2)>>2]<<2)>>2]=at):Xe=21;do if((Xe|0)==21){if(!(gi(l,et)|0)&&(n[s+8>>2]|0)==1){Ue=n[976+(et<<2)>>2]|0,at=y(h[s+908+(Ue<<2)>>2]),at=y(y(at-y(h[l+908+(Ue<<2)>>2]))*y(.5)),h[l+400+(n[1040+(et<<2)>>2]<<2)>>2]=at;break}!(gi(l,et)|0)&&(n[s+8>>2]|0)==2&&(Ue=n[976+(et<<2)>>2]|0,at=y(h[s+908+(Ue<<2)>>2]),at=y(at-y(h[l+908+(Ue<<2)>>2])),h[l+400+(n[1040+(et<<2)>>2]<<2)>>2]=at)}while(0);sr(l,Oe)|0&&!(gi(l,Oe)|0)?(Ue=n[976+(Oe<<2)>>2]|0,at=y(h[s+908+(Ue<<2)>>2]),at=y(at-y(h[l+908+(Ue<<2)>>2])),at=y(at-y(yn(s,Oe))),at=y(at-y(re(l,Oe,c))),at=y(at-y(vu(l,Oe,Fe?d:c))),h[l+400+(n[1040+(Oe<<2)>>2]<<2)>>2]=at):Xe=30;do if((Xe|0)==30&&!(gi(l,Oe)|0)){if((ha(s,l)|0)==2){Ue=n[976+(Oe<<2)>>2]|0,at=y(h[s+908+(Ue<<2)>>2]),at=y(y(at-y(h[l+908+(Ue<<2)>>2]))*y(.5)),h[l+400+(n[1040+(Oe<<2)>>2]<<2)>>2]=at;break}Ue=(ha(s,l)|0)==3,Ue^(n[s+28>>2]|0)==2&&(Ue=n[976+(Oe<<2)>>2]|0,at=y(h[s+908+(Ue<<2)>>2]),at=y(at-y(h[l+908+(Ue<<2)>>2])),h[l+400+(n[1040+(Oe<<2)>>2]<<2)>>2]=at)}while(0)}function Cp(s,l,c){s=s|0,l=l|0,c=c|0;var f=Ze,d=0;d=n[976+(c<<2)>>2]|0,f=y(h[l+908+(d<<2)>>2]),f=y(y(h[s+908+(d<<2)>>2])-f),f=y(f-y(h[l+400+(n[1040+(c<<2)>>2]<<2)>>2])),h[l+400+(n[1e3+(c<<2)>>2]<<2)>>2]=f}function OA(s){return s=s|0,(s|1|0)==1|0}function Iw(s){s=s|0;var l=Ze;switch(n[s+56>>2]|0){case 0:case 3:{l=y(h[s+40>>2]),l>y(0)&((_t(l)|0)^1)?s=o[(n[s+976>>2]|0)+2>>0]|0?1056:992:s=1056;break}default:s=s+52|0}return s|0}function Bw(s,l){return s=s|0,l=l|0,(o[s+l>>0]|0)!=0|0}function sr(s,l){return s=s|0,l=l|0,s=s+132|0,he(l)|0&&(n[(Fn(s,5,948)|0)+4>>2]|0)!=0?s=1:s=(n[(Fn(s,n[1e3+(l<<2)>>2]|0,948)|0)+4>>2]|0)!=0,s|0}function vu(s,l,c){s=s|0,l=l|0,c=y(c);var f=0,d=0;return s=s+132|0,he(l)|0&&(f=Fn(s,5,948)|0,(n[f+4>>2]|0)!=0)?d=4:(f=Fn(s,n[1e3+(l<<2)>>2]|0,948)|0,n[f+4>>2]|0?d=4:c=y(0)),(d|0)==4&&(c=y(Gr(f,c))),y(c)}function Mm(s,l,c){return s=s|0,l=l|0,c=y(c),gi(s,l)|0?c=y(Mr(s,l,c)):c=y(-y(vu(s,l,c))),y(c)}function Du(s){return s=y(s),h[v>>2]=s,n[v>>2]|0|0}function wp(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>1073741823)Tt();else{d=Vt(l<<2)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<2)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<2)}function Ig(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>2)<<2)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function UA(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-4-l|0)>>>2)<<2)),s=n[s>>2]|0,s|0&>(s)}function _A(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;if(B=s+4|0,k=n[B>>2]|0,d=k-f|0,m=d>>2,s=l+(m<<2)|0,s>>>0<c>>>0){f=k;do n[f>>2]=n[s>>2],s=s+4|0,f=(n[B>>2]|0)+4|0,n[B>>2]=f;while(s>>>0<c>>>0)}m|0&&Mw(k+(0-m<<2)|0,l|0,d|0)|0}function Bg(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0;return k=l+4|0,Q=n[k>>2]|0,d=n[s>>2]|0,B=c,m=B-d|0,f=Q+(0-(m>>2)<<2)|0,n[k>>2]=f,(m|0)>0&&Dr(f|0,d|0,m|0)|0,d=s+4|0,m=l+8|0,f=(n[d>>2]|0)-B|0,(f|0)>0&&(Dr(n[m>>2]|0,c|0,f|0)|0,n[m>>2]=(n[m>>2]|0)+(f>>>2<<2)),B=n[s>>2]|0,n[s>>2]=n[k>>2],n[k>>2]=B,B=n[d>>2]|0,n[d>>2]=n[m>>2],n[m>>2]=B,B=s+8|0,c=l+12|0,s=n[B>>2]|0,n[B>>2]=n[c>>2],n[c>>2]=s,n[l>>2]=n[k>>2],Q|0}function vw(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;if(B=n[l>>2]|0,m=n[c>>2]|0,(B|0)!=(m|0)){d=s+8|0,c=((m+-4-B|0)>>>2)+1|0,s=B,f=n[d>>2]|0;do n[f>>2]=n[s>>2],f=(n[d>>2]|0)+4|0,n[d>>2]=f,s=s+4|0;while((s|0)!=(m|0));n[l>>2]=B+(c<<2)}}function Om(){dc()}function ga(){var s=0;return s=Vt(4)|0,HA(s),s|0}function HA(s){s=s|0,n[s>>2]=ys()|0}function Sc(s){s=s|0,s|0&&(vg(s),gt(s))}function vg(s){s=s|0,tt(n[s>>2]|0)}function Um(s,l,c){s=s|0,l=l|0,c=c|0,Ga(n[s>>2]|0,l,c)}function fo(s,l){s=s|0,l=y(l),pa(n[s>>2]|0,l)}function Wv(s,l){return s=s|0,l=l|0,Bw(n[s>>2]|0,l)|0}function Dw(){var s=0;return s=Vt(8)|0,Vv(s,0),s|0}function Vv(s,l){s=s|0,l=l|0,l?l=Ci(n[l>>2]|0)|0:l=co()|0,n[s>>2]=l,n[s+4>>2]=0,xi(l,s)}function pF(s){s=s|0;var l=0;return l=Vt(8)|0,Vv(l,s),l|0}function Kv(s){s=s|0,s|0&&(Pu(s),gt(s))}function Pu(s){s=s|0;var l=0;la(n[s>>2]|0),l=s+4|0,s=n[l>>2]|0,n[l>>2]=0,s|0&&(jA(s),gt(s))}function jA(s){s=s|0,qA(s)}function qA(s){s=s|0,s=n[s>>2]|0,s|0&&PA(s|0)}function Pw(s){return s=s|0,jo(s)|0}function _m(s){s=s|0;var l=0,c=0;c=s+4|0,l=n[c>>2]|0,n[c>>2]=0,l|0&&(jA(l),gt(l)),_s(n[s>>2]|0)}function hF(s,l){s=s|0,l=l|0,Zr(n[s>>2]|0,n[l>>2]|0)}function gF(s,l){s=s|0,l=l|0,ca(n[s>>2]|0,l)}function Jv(s,l,c){s=s|0,l=l|0,c=+c,yu(n[s>>2]|0,l,y(c))}function zv(s,l,c){s=s|0,l=l|0,c=+c,Es(n[s>>2]|0,l,y(c))}function Sw(s,l){s=s|0,l=l|0,gu(n[s>>2]|0,l)}function Su(s,l){s=s|0,l=l|0,du(n[s>>2]|0,l)}function dF(s,l){s=s|0,l=l|0,QA(n[s>>2]|0,l)}function mF(s,l){s=s|0,l=l|0,bA(n[s>>2]|0,l)}function Ip(s,l){s=s|0,l=l|0,yc(n[s>>2]|0,l)}function yF(s,l){s=s|0,l=l|0,up(n[s>>2]|0,l)}function Xv(s,l,c){s=s|0,l=l|0,c=+c,Cc(n[s>>2]|0,l,y(c))}function GA(s,l,c){s=s|0,l=l|0,c=+c,G(n[s>>2]|0,l,y(c))}function EF(s,l){s=s|0,l=l|0,wl(n[s>>2]|0,l)}function CF(s,l){s=s|0,l=l|0,og(n[s>>2]|0,l)}function Zv(s,l){s=s|0,l=l|0,Ap(n[s>>2]|0,l)}function xw(s,l){s=s|0,l=+l,FA(n[s>>2]|0,y(l))}function bw(s,l){s=s|0,l=+l,Ha(n[s>>2]|0,y(l))}function wF(s,l){s=s|0,l=+l,Gi(n[s>>2]|0,y(l))}function IF(s,l){s=s|0,l=+l,Hs(n[s>>2]|0,y(l))}function Dl(s,l){s=s|0,l=+l,mu(n[s>>2]|0,y(l))}function kw(s,l){s=s|0,l=+l,mw(n[s>>2]|0,y(l))}function BF(s,l){s=s|0,l=+l,TA(n[s>>2]|0,y(l))}function YA(s){s=s|0,fp(n[s>>2]|0)}function Hm(s,l){s=s|0,l=+l,Cs(n[s>>2]|0,y(l))}function xu(s,l){s=s|0,l=+l,cg(n[s>>2]|0,y(l))}function Qw(s){s=s|0,ug(n[s>>2]|0)}function Fw(s,l){s=s|0,l=+l,pp(n[s>>2]|0,y(l))}function vF(s,l){s=s|0,l=+l,Ic(n[s>>2]|0,y(l))}function $v(s,l){s=s|0,l=+l,Sm(n[s>>2]|0,y(l))}function WA(s,l){s=s|0,l=+l,fg(n[s>>2]|0,y(l))}function eD(s,l){s=s|0,l=+l,Cu(n[s>>2]|0,y(l))}function jm(s,l){s=s|0,l=+l,xm(n[s>>2]|0,y(l))}function tD(s,l){s=s|0,l=+l,wu(n[s>>2]|0,y(l))}function rD(s,l){s=s|0,l=+l,yw(n[s>>2]|0,y(l))}function qm(s,l){s=s|0,l=+l,Aa(n[s>>2]|0,y(l))}function nD(s,l,c){s=s|0,l=l|0,c=+c,Eu(n[s>>2]|0,l,y(c))}function DF(s,l,c){s=s|0,l=l|0,c=+c,bi(n[s>>2]|0,l,y(c))}function P(s,l,c){s=s|0,l=l|0,c=+c,wc(n[s>>2]|0,l,y(c))}function D(s){return s=s|0,sg(n[s>>2]|0)|0}function R(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;f=C,C=C+16|0,d=f,Ec(d,n[l>>2]|0,c),j(s,d),C=f}function j(s,l){s=s|0,l=l|0,Y(s,n[l+4>>2]|0,+y(h[l>>2]))}function Y(s,l,c){s=s|0,l=l|0,c=+c,n[s>>2]=l,E[s+8>>3]=c}function fe(s){return s=s|0,ig(n[s>>2]|0)|0}function ve(s){return s=s|0,uo(n[s>>2]|0)|0}function vt(s){return s=s|0,mc(n[s>>2]|0)|0}function wt(s){return s=s|0,kA(n[s>>2]|0)|0}function bt(s){return s=s|0,Pm(n[s>>2]|0)|0}function _r(s){return s=s|0,ng(n[s>>2]|0)|0}function is(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;f=C,C=C+16|0,d=f,Dt(d,n[l>>2]|0,c),j(s,d),C=f}function di(s){return s=s|0,$n(n[s>>2]|0)|0}function po(s){return s=s|0,ag(n[s>>2]|0)|0}function VA(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,ua(f,n[l>>2]|0),j(s,f),C=c}function Yo(s){return s=s|0,+ +y(qi(n[s>>2]|0))}function rt(s){return s=s|0,+ +y(es(n[s>>2]|0))}function Ke(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,Br(f,n[l>>2]|0),j(s,f),C=c}function At(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,Ag(f,n[l>>2]|0),j(s,f),C=c}function Wt(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,Ct(f,n[l>>2]|0),j(s,f),C=c}function vr(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,pg(f,n[l>>2]|0),j(s,f),C=c}function Sn(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,hg(f,n[l>>2]|0),j(s,f),C=c}function Fr(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,bm(f,n[l>>2]|0),j(s,f),C=c}function xn(s){return s=s|0,+ +y(Bc(n[s>>2]|0))}function ai(s,l){return s=s|0,l=l|0,+ +y(lg(n[s>>2]|0,l))}function en(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;f=C,C=C+16|0,d=f,ct(d,n[l>>2]|0,c),j(s,d),C=f}function ho(s,l,c){s=s|0,l=l|0,c=c|0,nr(n[s>>2]|0,n[l>>2]|0,c)}function PF(s,l){s=s|0,l=l|0,ms(n[s>>2]|0,n[l>>2]|0)}function sve(s){return s=s|0,wi(n[s>>2]|0)|0}function ove(s){return s=s|0,s=pt(n[s>>2]|0)|0,s?s=Pw(s)|0:s=0,s|0}function ave(s,l){return s=s|0,l=l|0,s=gs(n[s>>2]|0,l)|0,s?s=Pw(s)|0:s=0,s|0}function lve(s,l){s=s|0,l=l|0;var c=0,f=0;f=Vt(4)|0,$G(f,l),c=s+4|0,l=n[c>>2]|0,n[c>>2]=f,l|0&&(jA(l),gt(l)),It(n[s>>2]|0,1)}function $G(s,l){s=s|0,l=l|0,Cve(s,l)}function cve(s,l,c,f,d,m){s=s|0,l=l|0,c=y(c),f=f|0,d=y(d),m=m|0;var B=0,k=0;B=C,C=C+16|0,k=B,uve(k,jo(l)|0,+c,f,+d,m),h[s>>2]=y(+E[k>>3]),h[s+4>>2]=y(+E[k+8>>3]),C=B}function uve(s,l,c,f,d,m){s=s|0,l=l|0,c=+c,f=f|0,d=+d,m=m|0;var B=0,k=0,Q=0,O=0,M=0;B=C,C=C+32|0,M=B+8|0,O=B+20|0,Q=B,k=B+16|0,E[M>>3]=c,n[O>>2]=f,E[Q>>3]=d,n[k>>2]=m,Ave(s,n[l+4>>2]|0,M,O,Q,k),C=B}function Ave(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0;var B=0,k=0;B=C,C=C+16|0,k=B,Va(k),l=da(l)|0,fve(s,l,+E[c>>3],n[f>>2]|0,+E[d>>3],n[m>>2]|0),Ka(k),C=B}function da(s){return s=s|0,n[s>>2]|0}function fve(s,l,c,f,d,m){s=s|0,l=l|0,c=+c,f=f|0,d=+d,m=m|0;var B=0;B=Pl(pve()|0)|0,c=+KA(c),f=SF(f)|0,d=+KA(d),hve(s,hi(0,B|0,l|0,+c,f|0,+d,SF(m)|0)|0)}function pve(){var s=0;return o[7608]|0||(yve(9120),s=7608,n[s>>2]=1,n[s+4>>2]=0),9120}function Pl(s){return s=s|0,n[s+8>>2]|0}function KA(s){return s=+s,+ +xF(s)}function SF(s){return s=s|0,t5(s)|0}function hve(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;d=C,C=C+32|0,c=d,f=l,f&1?(gve(c,0),ii(f|0,c|0)|0,dve(s,c),mve(c)):(n[s>>2]=n[l>>2],n[s+4>>2]=n[l+4>>2],n[s+8>>2]=n[l+8>>2],n[s+12>>2]=n[l+12>>2]),C=d}function gve(s,l){s=s|0,l=l|0,e5(s,l),n[s+8>>2]=0,o[s+24>>0]=0}function dve(s,l){s=s|0,l=l|0,l=l+8|0,n[s>>2]=n[l>>2],n[s+4>>2]=n[l+4>>2],n[s+8>>2]=n[l+8>>2],n[s+12>>2]=n[l+12>>2]}function mve(s){s=s|0,o[s+24>>0]=0}function e5(s,l){s=s|0,l=l|0,n[s>>2]=l}function t5(s){return s=s|0,s|0}function xF(s){return s=+s,+s}function yve(s){s=s|0,Sl(s,Eve()|0,4)}function Eve(){return 1064}function Sl(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c,n[s+8>>2]=cp(l|0,c+1|0)|0}function Cve(s,l){s=s|0,l=l|0,l=n[l>>2]|0,n[s>>2]=l,yl(l|0)}function wve(s){s=s|0;var l=0,c=0;c=s+4|0,l=n[c>>2]|0,n[c>>2]=0,l|0&&(jA(l),gt(l)),It(n[s>>2]|0,0)}function Ive(s){s=s|0,Rt(n[s>>2]|0)}function Bve(s){return s=s|0,er(n[s>>2]|0)|0}function vve(s,l,c,f){s=s|0,l=+l,c=+c,f=f|0,vc(n[s>>2]|0,y(l),y(c),f)}function Dve(s){return s=s|0,+ +y(Il(n[s>>2]|0))}function Pve(s){return s=s|0,+ +y(gg(n[s>>2]|0))}function Sve(s){return s=s|0,+ +y(Iu(n[s>>2]|0))}function xve(s){return s=s|0,+ +y(RA(n[s>>2]|0))}function bve(s){return s=s|0,+ +y(hp(n[s>>2]|0))}function kve(s){return s=s|0,+ +y(ja(n[s>>2]|0))}function Qve(s,l){s=s|0,l=l|0,E[s>>3]=+y(Il(n[l>>2]|0)),E[s+8>>3]=+y(gg(n[l>>2]|0)),E[s+16>>3]=+y(Iu(n[l>>2]|0)),E[s+24>>3]=+y(RA(n[l>>2]|0)),E[s+32>>3]=+y(hp(n[l>>2]|0)),E[s+40>>3]=+y(ja(n[l>>2]|0))}function Fve(s,l){return s=s|0,l=l|0,+ +y(dg(n[s>>2]|0,l))}function Tve(s,l){return s=s|0,l=l|0,+ +y(gp(n[s>>2]|0,l))}function Rve(s,l){return s=s|0,l=l|0,+ +y(qo(n[s>>2]|0,l))}function Nve(){return Pn()|0}function Lve(){Mve(),Ove(),Uve(),_ve(),Hve(),jve()}function Mve(){HNe(11713,4938,1)}function Ove(){oNe(10448)}function Uve(){HRe(10408)}function _ve(){uRe(10324)}function Hve(){yFe(10096)}function jve(){qve(9132)}function qve(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0,Ge=0,Oe=0,Fe=0,et=0,Xe=0,at=0,Ue=0,qe=0,Lt=0,Or=0,or=0,Xt=0,Pr=0,Nr=0,ir=0,bn=0,go=0,mo=0,yo=0,ya=0,Qp=0,Fp=0,xl=0,Tp=0,Fu=0,Tu=0,Rp=0,Np=0,Lp=0,Xr=0,bl=0,Mp=0,bc=0,Op=0,Up=0,Ru=0,Nu=0,kc=0,qs=0,za=0,Wo=0,kl=0,rf=0,nf=0,Lu=0,sf=0,of=0,Gs=0,vs=0,Ql=0,Tn=0,af=0,Eo=0,Qc=0,Co=0,Fc=0,lf=0,cf=0,Tc=0,Ys=0,Fl=0,uf=0,Af=0,ff=0,br=0,Jn=0,Ds=0,wo=0,Ws=0,Tr=0,ur=0,Tl=0;l=C,C=C+672|0,c=l+656|0,Tl=l+648|0,ur=l+640|0,Tr=l+632|0,Ws=l+624|0,wo=l+616|0,Ds=l+608|0,Jn=l+600|0,br=l+592|0,ff=l+584|0,Af=l+576|0,uf=l+568|0,Fl=l+560|0,Ys=l+552|0,Tc=l+544|0,cf=l+536|0,lf=l+528|0,Fc=l+520|0,Co=l+512|0,Qc=l+504|0,Eo=l+496|0,af=l+488|0,Tn=l+480|0,Ql=l+472|0,vs=l+464|0,Gs=l+456|0,of=l+448|0,sf=l+440|0,Lu=l+432|0,nf=l+424|0,rf=l+416|0,kl=l+408|0,Wo=l+400|0,za=l+392|0,qs=l+384|0,kc=l+376|0,Nu=l+368|0,Ru=l+360|0,Up=l+352|0,Op=l+344|0,bc=l+336|0,Mp=l+328|0,bl=l+320|0,Xr=l+312|0,Lp=l+304|0,Np=l+296|0,Rp=l+288|0,Tu=l+280|0,Fu=l+272|0,Tp=l+264|0,xl=l+256|0,Fp=l+248|0,Qp=l+240|0,ya=l+232|0,yo=l+224|0,mo=l+216|0,go=l+208|0,bn=l+200|0,ir=l+192|0,Nr=l+184|0,Pr=l+176|0,Xt=l+168|0,or=l+160|0,Or=l+152|0,Lt=l+144|0,qe=l+136|0,Ue=l+128|0,at=l+120|0,Xe=l+112|0,et=l+104|0,Fe=l+96|0,Oe=l+88|0,Ge=l+80|0,se=l+72|0,q=l+64|0,M=l+56|0,O=l+48|0,Q=l+40|0,k=l+32|0,B=l+24|0,m=l+16|0,d=l+8|0,f=l,Gve(s,3646),Yve(s,3651,2)|0,Wve(s,3665,2)|0,Vve(s,3682,18)|0,n[Tl>>2]=19,n[Tl+4>>2]=0,n[c>>2]=n[Tl>>2],n[c+4>>2]=n[Tl+4>>2],Tw(s,3690,c)|0,n[ur>>2]=1,n[ur+4>>2]=0,n[c>>2]=n[ur>>2],n[c+4>>2]=n[ur+4>>2],Kve(s,3696,c)|0,n[Tr>>2]=2,n[Tr+4>>2]=0,n[c>>2]=n[Tr>>2],n[c+4>>2]=n[Tr+4>>2],bu(s,3706,c)|0,n[Ws>>2]=1,n[Ws+4>>2]=0,n[c>>2]=n[Ws>>2],n[c+4>>2]=n[Ws+4>>2],Dg(s,3722,c)|0,n[wo>>2]=2,n[wo+4>>2]=0,n[c>>2]=n[wo>>2],n[c+4>>2]=n[wo+4>>2],Dg(s,3734,c)|0,n[Ds>>2]=3,n[Ds+4>>2]=0,n[c>>2]=n[Ds>>2],n[c+4>>2]=n[Ds+4>>2],bu(s,3753,c)|0,n[Jn>>2]=4,n[Jn+4>>2]=0,n[c>>2]=n[Jn>>2],n[c+4>>2]=n[Jn+4>>2],bu(s,3769,c)|0,n[br>>2]=5,n[br+4>>2]=0,n[c>>2]=n[br>>2],n[c+4>>2]=n[br+4>>2],bu(s,3783,c)|0,n[ff>>2]=6,n[ff+4>>2]=0,n[c>>2]=n[ff>>2],n[c+4>>2]=n[ff+4>>2],bu(s,3796,c)|0,n[Af>>2]=7,n[Af+4>>2]=0,n[c>>2]=n[Af>>2],n[c+4>>2]=n[Af+4>>2],bu(s,3813,c)|0,n[uf>>2]=8,n[uf+4>>2]=0,n[c>>2]=n[uf>>2],n[c+4>>2]=n[uf+4>>2],bu(s,3825,c)|0,n[Fl>>2]=3,n[Fl+4>>2]=0,n[c>>2]=n[Fl>>2],n[c+4>>2]=n[Fl+4>>2],Dg(s,3843,c)|0,n[Ys>>2]=4,n[Ys+4>>2]=0,n[c>>2]=n[Ys>>2],n[c+4>>2]=n[Ys+4>>2],Dg(s,3853,c)|0,n[Tc>>2]=9,n[Tc+4>>2]=0,n[c>>2]=n[Tc>>2],n[c+4>>2]=n[Tc+4>>2],bu(s,3870,c)|0,n[cf>>2]=10,n[cf+4>>2]=0,n[c>>2]=n[cf>>2],n[c+4>>2]=n[cf+4>>2],bu(s,3884,c)|0,n[lf>>2]=11,n[lf+4>>2]=0,n[c>>2]=n[lf>>2],n[c+4>>2]=n[lf+4>>2],bu(s,3896,c)|0,n[Fc>>2]=1,n[Fc+4>>2]=0,n[c>>2]=n[Fc>>2],n[c+4>>2]=n[Fc+4>>2],Is(s,3907,c)|0,n[Co>>2]=2,n[Co+4>>2]=0,n[c>>2]=n[Co>>2],n[c+4>>2]=n[Co+4>>2],Is(s,3915,c)|0,n[Qc>>2]=3,n[Qc+4>>2]=0,n[c>>2]=n[Qc>>2],n[c+4>>2]=n[Qc+4>>2],Is(s,3928,c)|0,n[Eo>>2]=4,n[Eo+4>>2]=0,n[c>>2]=n[Eo>>2],n[c+4>>2]=n[Eo+4>>2],Is(s,3948,c)|0,n[af>>2]=5,n[af+4>>2]=0,n[c>>2]=n[af>>2],n[c+4>>2]=n[af+4>>2],Is(s,3960,c)|0,n[Tn>>2]=6,n[Tn+4>>2]=0,n[c>>2]=n[Tn>>2],n[c+4>>2]=n[Tn+4>>2],Is(s,3974,c)|0,n[Ql>>2]=7,n[Ql+4>>2]=0,n[c>>2]=n[Ql>>2],n[c+4>>2]=n[Ql+4>>2],Is(s,3983,c)|0,n[vs>>2]=20,n[vs+4>>2]=0,n[c>>2]=n[vs>>2],n[c+4>>2]=n[vs+4>>2],Tw(s,3999,c)|0,n[Gs>>2]=8,n[Gs+4>>2]=0,n[c>>2]=n[Gs>>2],n[c+4>>2]=n[Gs+4>>2],Is(s,4012,c)|0,n[of>>2]=9,n[of+4>>2]=0,n[c>>2]=n[of>>2],n[c+4>>2]=n[of+4>>2],Is(s,4022,c)|0,n[sf>>2]=21,n[sf+4>>2]=0,n[c>>2]=n[sf>>2],n[c+4>>2]=n[sf+4>>2],Tw(s,4039,c)|0,n[Lu>>2]=10,n[Lu+4>>2]=0,n[c>>2]=n[Lu>>2],n[c+4>>2]=n[Lu+4>>2],Is(s,4053,c)|0,n[nf>>2]=11,n[nf+4>>2]=0,n[c>>2]=n[nf>>2],n[c+4>>2]=n[nf+4>>2],Is(s,4065,c)|0,n[rf>>2]=12,n[rf+4>>2]=0,n[c>>2]=n[rf>>2],n[c+4>>2]=n[rf+4>>2],Is(s,4084,c)|0,n[kl>>2]=13,n[kl+4>>2]=0,n[c>>2]=n[kl>>2],n[c+4>>2]=n[kl+4>>2],Is(s,4097,c)|0,n[Wo>>2]=14,n[Wo+4>>2]=0,n[c>>2]=n[Wo>>2],n[c+4>>2]=n[Wo+4>>2],Is(s,4117,c)|0,n[za>>2]=15,n[za+4>>2]=0,n[c>>2]=n[za>>2],n[c+4>>2]=n[za+4>>2],Is(s,4129,c)|0,n[qs>>2]=16,n[qs+4>>2]=0,n[c>>2]=n[qs>>2],n[c+4>>2]=n[qs+4>>2],Is(s,4148,c)|0,n[kc>>2]=17,n[kc+4>>2]=0,n[c>>2]=n[kc>>2],n[c+4>>2]=n[kc+4>>2],Is(s,4161,c)|0,n[Nu>>2]=18,n[Nu+4>>2]=0,n[c>>2]=n[Nu>>2],n[c+4>>2]=n[Nu+4>>2],Is(s,4181,c)|0,n[Ru>>2]=5,n[Ru+4>>2]=0,n[c>>2]=n[Ru>>2],n[c+4>>2]=n[Ru+4>>2],Dg(s,4196,c)|0,n[Up>>2]=6,n[Up+4>>2]=0,n[c>>2]=n[Up>>2],n[c+4>>2]=n[Up+4>>2],Dg(s,4206,c)|0,n[Op>>2]=7,n[Op+4>>2]=0,n[c>>2]=n[Op>>2],n[c+4>>2]=n[Op+4>>2],Dg(s,4217,c)|0,n[bc>>2]=3,n[bc+4>>2]=0,n[c>>2]=n[bc>>2],n[c+4>>2]=n[bc+4>>2],JA(s,4235,c)|0,n[Mp>>2]=1,n[Mp+4>>2]=0,n[c>>2]=n[Mp>>2],n[c+4>>2]=n[Mp+4>>2],bF(s,4251,c)|0,n[bl>>2]=4,n[bl+4>>2]=0,n[c>>2]=n[bl>>2],n[c+4>>2]=n[bl+4>>2],JA(s,4263,c)|0,n[Xr>>2]=5,n[Xr+4>>2]=0,n[c>>2]=n[Xr>>2],n[c+4>>2]=n[Xr+4>>2],JA(s,4279,c)|0,n[Lp>>2]=6,n[Lp+4>>2]=0,n[c>>2]=n[Lp>>2],n[c+4>>2]=n[Lp+4>>2],JA(s,4293,c)|0,n[Np>>2]=7,n[Np+4>>2]=0,n[c>>2]=n[Np>>2],n[c+4>>2]=n[Np+4>>2],JA(s,4306,c)|0,n[Rp>>2]=8,n[Rp+4>>2]=0,n[c>>2]=n[Rp>>2],n[c+4>>2]=n[Rp+4>>2],JA(s,4323,c)|0,n[Tu>>2]=9,n[Tu+4>>2]=0,n[c>>2]=n[Tu>>2],n[c+4>>2]=n[Tu+4>>2],JA(s,4335,c)|0,n[Fu>>2]=2,n[Fu+4>>2]=0,n[c>>2]=n[Fu>>2],n[c+4>>2]=n[Fu+4>>2],bF(s,4353,c)|0,n[Tp>>2]=12,n[Tp+4>>2]=0,n[c>>2]=n[Tp>>2],n[c+4>>2]=n[Tp+4>>2],Pg(s,4363,c)|0,n[xl>>2]=1,n[xl+4>>2]=0,n[c>>2]=n[xl>>2],n[c+4>>2]=n[xl+4>>2],zA(s,4376,c)|0,n[Fp>>2]=2,n[Fp+4>>2]=0,n[c>>2]=n[Fp>>2],n[c+4>>2]=n[Fp+4>>2],zA(s,4388,c)|0,n[Qp>>2]=13,n[Qp+4>>2]=0,n[c>>2]=n[Qp>>2],n[c+4>>2]=n[Qp+4>>2],Pg(s,4402,c)|0,n[ya>>2]=14,n[ya+4>>2]=0,n[c>>2]=n[ya>>2],n[c+4>>2]=n[ya+4>>2],Pg(s,4411,c)|0,n[yo>>2]=15,n[yo+4>>2]=0,n[c>>2]=n[yo>>2],n[c+4>>2]=n[yo+4>>2],Pg(s,4421,c)|0,n[mo>>2]=16,n[mo+4>>2]=0,n[c>>2]=n[mo>>2],n[c+4>>2]=n[mo+4>>2],Pg(s,4433,c)|0,n[go>>2]=17,n[go+4>>2]=0,n[c>>2]=n[go>>2],n[c+4>>2]=n[go+4>>2],Pg(s,4446,c)|0,n[bn>>2]=18,n[bn+4>>2]=0,n[c>>2]=n[bn>>2],n[c+4>>2]=n[bn+4>>2],Pg(s,4458,c)|0,n[ir>>2]=3,n[ir+4>>2]=0,n[c>>2]=n[ir>>2],n[c+4>>2]=n[ir+4>>2],zA(s,4471,c)|0,n[Nr>>2]=1,n[Nr+4>>2]=0,n[c>>2]=n[Nr>>2],n[c+4>>2]=n[Nr+4>>2],iD(s,4486,c)|0,n[Pr>>2]=10,n[Pr+4>>2]=0,n[c>>2]=n[Pr>>2],n[c+4>>2]=n[Pr+4>>2],JA(s,4496,c)|0,n[Xt>>2]=11,n[Xt+4>>2]=0,n[c>>2]=n[Xt>>2],n[c+4>>2]=n[Xt+4>>2],JA(s,4508,c)|0,n[or>>2]=3,n[or+4>>2]=0,n[c>>2]=n[or>>2],n[c+4>>2]=n[or+4>>2],bF(s,4519,c)|0,n[Or>>2]=4,n[Or+4>>2]=0,n[c>>2]=n[Or>>2],n[c+4>>2]=n[Or+4>>2],Jve(s,4530,c)|0,n[Lt>>2]=19,n[Lt+4>>2]=0,n[c>>2]=n[Lt>>2],n[c+4>>2]=n[Lt+4>>2],zve(s,4542,c)|0,n[qe>>2]=12,n[qe+4>>2]=0,n[c>>2]=n[qe>>2],n[c+4>>2]=n[qe+4>>2],Xve(s,4554,c)|0,n[Ue>>2]=13,n[Ue+4>>2]=0,n[c>>2]=n[Ue>>2],n[c+4>>2]=n[Ue+4>>2],Zve(s,4568,c)|0,n[at>>2]=2,n[at+4>>2]=0,n[c>>2]=n[at>>2],n[c+4>>2]=n[at+4>>2],$ve(s,4578,c)|0,n[Xe>>2]=20,n[Xe+4>>2]=0,n[c>>2]=n[Xe>>2],n[c+4>>2]=n[Xe+4>>2],eDe(s,4587,c)|0,n[et>>2]=22,n[et+4>>2]=0,n[c>>2]=n[et>>2],n[c+4>>2]=n[et+4>>2],Tw(s,4602,c)|0,n[Fe>>2]=23,n[Fe+4>>2]=0,n[c>>2]=n[Fe>>2],n[c+4>>2]=n[Fe+4>>2],Tw(s,4619,c)|0,n[Oe>>2]=14,n[Oe+4>>2]=0,n[c>>2]=n[Oe>>2],n[c+4>>2]=n[Oe+4>>2],tDe(s,4629,c)|0,n[Ge>>2]=1,n[Ge+4>>2]=0,n[c>>2]=n[Ge>>2],n[c+4>>2]=n[Ge+4>>2],rDe(s,4637,c)|0,n[se>>2]=4,n[se+4>>2]=0,n[c>>2]=n[se>>2],n[c+4>>2]=n[se+4>>2],zA(s,4653,c)|0,n[q>>2]=5,n[q+4>>2]=0,n[c>>2]=n[q>>2],n[c+4>>2]=n[q+4>>2],zA(s,4669,c)|0,n[M>>2]=6,n[M+4>>2]=0,n[c>>2]=n[M>>2],n[c+4>>2]=n[M+4>>2],zA(s,4686,c)|0,n[O>>2]=7,n[O+4>>2]=0,n[c>>2]=n[O>>2],n[c+4>>2]=n[O+4>>2],zA(s,4701,c)|0,n[Q>>2]=8,n[Q+4>>2]=0,n[c>>2]=n[Q>>2],n[c+4>>2]=n[Q+4>>2],zA(s,4719,c)|0,n[k>>2]=9,n[k+4>>2]=0,n[c>>2]=n[k>>2],n[c+4>>2]=n[k+4>>2],zA(s,4736,c)|0,n[B>>2]=21,n[B+4>>2]=0,n[c>>2]=n[B>>2],n[c+4>>2]=n[B+4>>2],nDe(s,4754,c)|0,n[m>>2]=2,n[m+4>>2]=0,n[c>>2]=n[m>>2],n[c+4>>2]=n[m+4>>2],iD(s,4772,c)|0,n[d>>2]=3,n[d+4>>2]=0,n[c>>2]=n[d>>2],n[c+4>>2]=n[d+4>>2],iD(s,4790,c)|0,n[f>>2]=4,n[f+4>>2]=0,n[c>>2]=n[f>>2],n[c+4>>2]=n[f+4>>2],iD(s,4808,c)|0,C=l}function Gve(s,l){s=s|0,l=l|0;var c=0;c=cFe()|0,n[s>>2]=c,uFe(c,l),xp(n[s>>2]|0)}function Yve(s,l,c){return s=s|0,l=l|0,c=c|0,JQe(s,pn(l)|0,c,0),s|0}function Wve(s,l,c){return s=s|0,l=l|0,c=c|0,TQe(s,pn(l)|0,c,0),s|0}function Vve(s,l,c){return s=s|0,l=l|0,c=c|0,EQe(s,pn(l)|0,c,0),s|0}function Tw(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],nQe(s,l,d),C=f,s|0}function Kve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Oke(s,l,d),C=f,s|0}function bu(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Ike(s,l,d),C=f,s|0}function Dg(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],oke(s,l,d),C=f,s|0}function Is(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Gbe(s,l,d),C=f,s|0}function JA(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],xbe(s,l,d),C=f,s|0}function bF(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],fbe(s,l,d),C=f,s|0}function Pg(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Oxe(s,l,d),C=f,s|0}function zA(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Ixe(s,l,d),C=f,s|0}function iD(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],oxe(s,l,d),C=f,s|0}function Jve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],GSe(s,l,d),C=f,s|0}function zve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],xSe(s,l,d),C=f,s|0}function Xve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],pSe(s,l,d),C=f,s|0}function Zve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],ZPe(s,l,d),C=f,s|0}function $ve(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],NPe(s,l,d),C=f,s|0}function eDe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],yPe(s,l,d),C=f,s|0}function tDe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],rPe(s,l,d),C=f,s|0}function rDe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],ODe(s,l,d),C=f,s|0}function nDe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],iDe(s,l,d),C=f,s|0}function iDe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],sDe(s,c,d,1),C=f}function pn(s){return s=s|0,s|0}function sDe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=kF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=oDe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,aDe(m,f)|0,f),C=d}function kF(){var s=0,l=0;if(o[7616]|0||(i5(9136),tr(24,9136,U|0)|0,l=7616,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9136)|0)){s=9136,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));i5(9136)}return 9136}function oDe(s){return s=s|0,0}function aDe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=kF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],n5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(uDe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function hn(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0;var B=0,k=0,Q=0,O=0,M=0,q=0,se=0,Ge=0;B=C,C=C+32|0,se=B+24|0,q=B+20|0,Q=B+16|0,M=B+12|0,O=B+8|0,k=B+4|0,Ge=B,n[q>>2]=l,n[Q>>2]=c,n[M>>2]=f,n[O>>2]=d,n[k>>2]=m,m=s+28|0,n[Ge>>2]=n[m>>2],n[se>>2]=n[Ge>>2],lDe(s+24|0,se,q,M,O,Q,k)|0,n[m>>2]=n[n[m>>2]>>2],C=B}function lDe(s,l,c,f,d,m,B){return s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,B=B|0,s=cDe(l)|0,l=Vt(24)|0,r5(l+4|0,n[c>>2]|0,n[f>>2]|0,n[d>>2]|0,n[m>>2]|0,n[B>>2]|0),n[l>>2]=n[s>>2],n[s>>2]=l,l|0}function cDe(s){return s=s|0,n[s>>2]|0}function r5(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,n[s>>2]=l,n[s+4>>2]=c,n[s+8>>2]=f,n[s+12>>2]=d,n[s+16>>2]=m}function gr(s,l){return s=s|0,l=l|0,l|s|0}function n5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function uDe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=ADe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,fDe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],n5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,pDe(s,k),hDe(k),C=O;return}}function ADe(s){return s=s|0,357913941}function fDe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function pDe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function hDe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function i5(s){s=s|0,mDe(s)}function gDe(s){s=s|0,dDe(s+24|0)}function Rr(s){return s=s|0,n[s>>2]|0}function dDe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function mDe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,3,l,yDe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function Vr(){return 9228}function yDe(){return 1140}function EDe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;return c=C,C=C+16|0,f=c+8|0,d=c,m=CDe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],l=wDe(l,f)|0,C=c,l|0}function Kr(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,n[s>>2]=l,n[s+4>>2]=c,n[s+8>>2]=f,n[s+12>>2]=d,n[s+16>>2]=m}function CDe(s){return s=s|0,(n[(kF()|0)+24>>2]|0)+(s*12|0)|0}function wDe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;return d=C,C=C+48|0,f=d,c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),tf[c&31](f,s),f=IDe(f)|0,C=d,f|0}function IDe(s){s=s|0;var l=0,c=0,f=0,d=0;return d=C,C=C+32|0,l=d+12|0,c=d,f=QF(s5()|0)|0,f?(FF(l,f),TF(c,l),BDe(s,c),s=RF(l)|0):s=vDe(s)|0,C=d,s|0}function s5(){var s=0;return o[7632]|0||(RDe(9184),tr(25,9184,U|0)|0,s=7632,n[s>>2]=1,n[s+4>>2]=0),9184}function QF(s){return s=s|0,n[s+36>>2]|0}function FF(s,l){s=s|0,l=l|0,n[s>>2]=l,n[s+4>>2]=s,n[s+8>>2]=0}function TF(s,l){s=s|0,l=l|0,n[s>>2]=n[l>>2],n[s+4>>2]=n[l+4>>2],n[s+8>>2]=0}function BDe(s,l){s=s|0,l=l|0,xDe(l,s,s+8|0,s+16|0,s+24|0,s+32|0,s+40|0)|0}function RF(s){return s=s|0,n[(n[s+4>>2]|0)+8>>2]|0}function vDe(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0,Q=0;Q=C,C=C+16|0,c=Q+4|0,f=Q,d=Wa(8)|0,m=d,B=Vt(48)|0,k=B,l=k+48|0;do n[k>>2]=n[s>>2],k=k+4|0,s=s+4|0;while((k|0)<(l|0));return l=m+4|0,n[l>>2]=B,k=Vt(8)|0,B=n[l>>2]|0,n[f>>2]=0,n[c>>2]=n[f>>2],o5(k,B,c),n[d>>2]=k,C=Q,m|0}function o5(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,c=Vt(16)|0,n[c+4>>2]=0,n[c+8>>2]=0,n[c>>2]=1092,n[c+12>>2]=l,n[s+4>>2]=c}function DDe(s){s=s|0,Jm(s),gt(s)}function PDe(s){s=s|0,s=n[s+12>>2]|0,s|0&>(s)}function SDe(s){s=s|0,gt(s)}function xDe(s,l,c,f,d,m,B){return s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,B=B|0,m=bDe(n[s>>2]|0,l,c,f,d,m,B)|0,B=s+4|0,n[(n[B>>2]|0)+8>>2]=m,n[(n[B>>2]|0)+8>>2]|0}function bDe(s,l,c,f,d,m,B){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,B=B|0;var k=0,Q=0;return k=C,C=C+16|0,Q=k,Va(Q),s=da(s)|0,B=kDe(s,+E[l>>3],+E[c>>3],+E[f>>3],+E[d>>3],+E[m>>3],+E[B>>3])|0,Ka(Q),C=k,B|0}function kDe(s,l,c,f,d,m,B){s=s|0,l=+l,c=+c,f=+f,d=+d,m=+m,B=+B;var k=0;return k=Pl(QDe()|0)|0,l=+KA(l),c=+KA(c),f=+KA(f),d=+KA(d),m=+KA(m),Os(0,k|0,s|0,+l,+c,+f,+d,+m,+ +KA(B))|0}function QDe(){var s=0;return o[7624]|0||(FDe(9172),s=7624,n[s>>2]=1,n[s+4>>2]=0),9172}function FDe(s){s=s|0,Sl(s,TDe()|0,6)}function TDe(){return 1112}function RDe(s){s=s|0,Bp(s)}function NDe(s){s=s|0,a5(s+24|0),l5(s+16|0)}function a5(s){s=s|0,MDe(s)}function l5(s){s=s|0,LDe(s)}function LDe(s){s=s|0;var l=0,c=0;if(l=n[s>>2]|0,l|0)do c=l,l=n[l>>2]|0,gt(c);while((l|0)!=0);n[s>>2]=0}function MDe(s){s=s|0;var l=0,c=0;if(l=n[s>>2]|0,l|0)do c=l,l=n[l>>2]|0,gt(c);while((l|0)!=0);n[s>>2]=0}function Bp(s){s=s|0;var l=0;n[s+16>>2]=0,n[s+20>>2]=0,l=s+24|0,n[l>>2]=0,n[s+28>>2]=l,n[s+36>>2]=0,o[s+40>>0]=0,o[s+41>>0]=0}function ODe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],UDe(s,c,d,0),C=f}function UDe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=NF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=_De(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,HDe(m,f)|0,f),C=d}function NF(){var s=0,l=0;if(o[7640]|0||(u5(9232),tr(26,9232,U|0)|0,l=7640,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9232)|0)){s=9232,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));u5(9232)}return 9232}function _De(s){return s=s|0,0}function HDe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=NF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],c5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(jDe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function c5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function jDe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=qDe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,GDe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],c5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,YDe(s,k),WDe(k),C=O;return}}function qDe(s){return s=s|0,357913941}function GDe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function YDe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function WDe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function u5(s){s=s|0,JDe(s)}function VDe(s){s=s|0,KDe(s+24|0)}function KDe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function JDe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,1,l,zDe()|0,3),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function zDe(){return 1144}function XDe(s,l,c,f,d){s=s|0,l=l|0,c=+c,f=+f,d=d|0;var m=0,B=0,k=0,Q=0;m=C,C=C+16|0,B=m+8|0,k=m,Q=ZDe(s)|0,s=n[Q+4>>2]|0,n[k>>2]=n[Q>>2],n[k+4>>2]=s,n[B>>2]=n[k>>2],n[B+4>>2]=n[k+4>>2],$De(l,B,c,f,d),C=m}function ZDe(s){return s=s|0,(n[(NF()|0)+24>>2]|0)+(s*12|0)|0}function $De(s,l,c,f,d){s=s|0,l=l|0,c=+c,f=+f,d=d|0;var m=0,B=0,k=0,Q=0,O=0;O=C,C=C+16|0,B=O+2|0,k=O+1|0,Q=O,m=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(m=n[(n[s>>2]|0)+m>>2]|0),ku(B,c),c=+Qu(B,c),ku(k,f),f=+Qu(k,f),XA(Q,d),Q=ZA(Q,d)|0,D7[m&1](s,c,f,Q),C=O}function ku(s,l){s=s|0,l=+l}function Qu(s,l){return s=s|0,l=+l,+ +tPe(l)}function XA(s,l){s=s|0,l=l|0}function ZA(s,l){return s=s|0,l=l|0,ePe(l)|0}function ePe(s){return s=s|0,s|0}function tPe(s){return s=+s,+s}function rPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],nPe(s,c,d,1),C=f}function nPe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=LF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=iPe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,sPe(m,f)|0,f),C=d}function LF(){var s=0,l=0;if(o[7648]|0||(f5(9268),tr(27,9268,U|0)|0,l=7648,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9268)|0)){s=9268,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));f5(9268)}return 9268}function iPe(s){return s=s|0,0}function sPe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=LF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],A5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(oPe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function A5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function oPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=aPe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,lPe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],A5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,cPe(s,k),uPe(k),C=O;return}}function aPe(s){return s=s|0,357913941}function lPe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function cPe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function uPe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function f5(s){s=s|0,pPe(s)}function APe(s){s=s|0,fPe(s+24|0)}function fPe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function pPe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,4,l,hPe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function hPe(){return 1160}function gPe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;return c=C,C=C+16|0,f=c+8|0,d=c,m=dPe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],l=mPe(l,f)|0,C=c,l|0}function dPe(s){return s=s|0,(n[(LF()|0)+24>>2]|0)+(s*12|0)|0}function mPe(s,l){s=s|0,l=l|0;var c=0;return c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),p5(Ng[c&31](s)|0)|0}function p5(s){return s=s|0,s&1|0}function yPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],EPe(s,c,d,0),C=f}function EPe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=MF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=CPe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,wPe(m,f)|0,f),C=d}function MF(){var s=0,l=0;if(o[7656]|0||(g5(9304),tr(28,9304,U|0)|0,l=7656,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9304)|0)){s=9304,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));g5(9304)}return 9304}function CPe(s){return s=s|0,0}function wPe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=MF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],h5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(IPe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function h5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function IPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=BPe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,vPe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],h5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,DPe(s,k),PPe(k),C=O;return}}function BPe(s){return s=s|0,357913941}function vPe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function DPe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function PPe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function g5(s){s=s|0,bPe(s)}function SPe(s){s=s|0,xPe(s+24|0)}function xPe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function bPe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,5,l,kPe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function kPe(){return 1164}function QPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,d=f+8|0,m=f,B=FPe(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],TPe(l,d,c),C=f}function FPe(s){return s=s|0,(n[(MF()|0)+24>>2]|0)+(s*12|0)|0}function TPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),vp(d,c),c=Dp(d,c)|0,tf[f&31](s,c),Pp(d),C=m}function vp(s,l){s=s|0,l=l|0,RPe(s,l)}function Dp(s,l){return s=s|0,l=l|0,s|0}function Pp(s){s=s|0,jA(s)}function RPe(s,l){s=s|0,l=l|0,OF(s,l)}function OF(s,l){s=s|0,l=l|0,n[s>>2]=l}function NPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],LPe(s,c,d,0),C=f}function LPe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=UF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=MPe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,OPe(m,f)|0,f),C=d}function UF(){var s=0,l=0;if(o[7664]|0||(m5(9340),tr(29,9340,U|0)|0,l=7664,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9340)|0)){s=9340,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));m5(9340)}return 9340}function MPe(s){return s=s|0,0}function OPe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=UF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],d5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(UPe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function d5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function UPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=_Pe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,HPe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],d5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,jPe(s,k),qPe(k),C=O;return}}function _Pe(s){return s=s|0,357913941}function HPe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function jPe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function qPe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function m5(s){s=s|0,WPe(s)}function GPe(s){s=s|0,YPe(s+24|0)}function YPe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function WPe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,4,l,VPe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function VPe(){return 1180}function KPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=JPe(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],c=zPe(l,d,c)|0,C=f,c|0}function JPe(s){return s=s|0,(n[(UF()|0)+24>>2]|0)+(s*12|0)|0}function zPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;return m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),Sg(d,c),d=xg(d,c)|0,d=sD(NT[f&15](s,d)|0)|0,C=m,d|0}function Sg(s,l){s=s|0,l=l|0}function xg(s,l){return s=s|0,l=l|0,XPe(l)|0}function sD(s){return s=s|0,s|0}function XPe(s){return s=s|0,s|0}function ZPe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],$Pe(s,c,d,0),C=f}function $Pe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=_F()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=eSe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,tSe(m,f)|0,f),C=d}function _F(){var s=0,l=0;if(o[7672]|0||(E5(9376),tr(30,9376,U|0)|0,l=7672,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9376)|0)){s=9376,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));E5(9376)}return 9376}function eSe(s){return s=s|0,0}function tSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=_F()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],y5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(rSe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function y5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function rSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=nSe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,iSe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],y5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,sSe(s,k),oSe(k),C=O;return}}function nSe(s){return s=s|0,357913941}function iSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function sSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function oSe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function E5(s){s=s|0,cSe(s)}function aSe(s){s=s|0,lSe(s+24|0)}function lSe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function cSe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,5,l,C5()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function C5(){return 1196}function uSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;return c=C,C=C+16|0,f=c+8|0,d=c,m=ASe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],l=fSe(l,f)|0,C=c,l|0}function ASe(s){return s=s|0,(n[(_F()|0)+24>>2]|0)+(s*12|0)|0}function fSe(s,l){s=s|0,l=l|0;var c=0;return c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),sD(Ng[c&31](s)|0)|0}function pSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],hSe(s,c,d,1),C=f}function hSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=HF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=gSe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,dSe(m,f)|0,f),C=d}function HF(){var s=0,l=0;if(o[7680]|0||(I5(9412),tr(31,9412,U|0)|0,l=7680,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9412)|0)){s=9412,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));I5(9412)}return 9412}function gSe(s){return s=s|0,0}function dSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=HF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],w5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(mSe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function w5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function mSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=ySe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,ESe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],w5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,CSe(s,k),wSe(k),C=O;return}}function ySe(s){return s=s|0,357913941}function ESe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function CSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function wSe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function I5(s){s=s|0,vSe(s)}function ISe(s){s=s|0,BSe(s+24|0)}function BSe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function vSe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,6,l,B5()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function B5(){return 1200}function DSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;return c=C,C=C+16|0,f=c+8|0,d=c,m=PSe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],l=SSe(l,f)|0,C=c,l|0}function PSe(s){return s=s|0,(n[(HF()|0)+24>>2]|0)+(s*12|0)|0}function SSe(s,l){s=s|0,l=l|0;var c=0;return c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),oD(Ng[c&31](s)|0)|0}function oD(s){return s=s|0,s|0}function xSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],bSe(s,c,d,0),C=f}function bSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=jF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=kSe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,QSe(m,f)|0,f),C=d}function jF(){var s=0,l=0;if(o[7688]|0||(D5(9448),tr(32,9448,U|0)|0,l=7688,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9448)|0)){s=9448,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));D5(9448)}return 9448}function kSe(s){return s=s|0,0}function QSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=jF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],v5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(FSe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function v5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function FSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=TSe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,RSe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],v5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,NSe(s,k),LSe(k),C=O;return}}function TSe(s){return s=s|0,357913941}function RSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function NSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function LSe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function D5(s){s=s|0,USe(s)}function MSe(s){s=s|0,OSe(s+24|0)}function OSe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function USe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,6,l,P5()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function P5(){return 1204}function _Se(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,d=f+8|0,m=f,B=HSe(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],jSe(l,d,c),C=f}function HSe(s){return s=s|0,(n[(jF()|0)+24>>2]|0)+(s*12|0)|0}function jSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),qF(d,c),d=GF(d,c)|0,tf[f&31](s,d),C=m}function qF(s,l){s=s|0,l=l|0}function GF(s,l){return s=s|0,l=l|0,qSe(l)|0}function qSe(s){return s=s|0,s|0}function GSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],YSe(s,c,d,0),C=f}function YSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=YF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=WSe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,VSe(m,f)|0,f),C=d}function YF(){var s=0,l=0;if(o[7696]|0||(x5(9484),tr(33,9484,U|0)|0,l=7696,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9484)|0)){s=9484,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));x5(9484)}return 9484}function WSe(s){return s=s|0,0}function VSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=YF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],S5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(KSe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function S5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function KSe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=JSe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,zSe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],S5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,XSe(s,k),ZSe(k),C=O;return}}function JSe(s){return s=s|0,357913941}function zSe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function XSe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function ZSe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function x5(s){s=s|0,txe(s)}function $Se(s){s=s|0,exe(s+24|0)}function exe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function txe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,1,l,rxe()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function rxe(){return 1212}function nxe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;d=C,C=C+16|0,m=d+8|0,B=d,k=ixe(s)|0,s=n[k+4>>2]|0,n[B>>2]=n[k>>2],n[B+4>>2]=s,n[m>>2]=n[B>>2],n[m+4>>2]=n[B+4>>2],sxe(l,m,c,f),C=d}function ixe(s){return s=s|0,(n[(YF()|0)+24>>2]|0)+(s*12|0)|0}function sxe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;k=C,C=C+16|0,m=k+1|0,B=k,d=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(d=n[(n[s>>2]|0)+d>>2]|0),qF(m,c),m=GF(m,c)|0,Sg(B,f),B=xg(B,f)|0,_w[d&15](s,m,B),C=k}function oxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],axe(s,c,d,1),C=f}function axe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=WF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=lxe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,cxe(m,f)|0,f),C=d}function WF(){var s=0,l=0;if(o[7704]|0||(k5(9520),tr(34,9520,U|0)|0,l=7704,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9520)|0)){s=9520,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));k5(9520)}return 9520}function lxe(s){return s=s|0,0}function cxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=WF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],b5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(uxe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function b5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function uxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=Axe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,fxe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],b5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,pxe(s,k),hxe(k),C=O;return}}function Axe(s){return s=s|0,357913941}function fxe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function pxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function hxe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function k5(s){s=s|0,mxe(s)}function gxe(s){s=s|0,dxe(s+24|0)}function dxe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function mxe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,1,l,yxe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function yxe(){return 1224}function Exe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;return d=C,C=C+16|0,m=d+8|0,B=d,k=Cxe(s)|0,s=n[k+4>>2]|0,n[B>>2]=n[k>>2],n[B+4>>2]=s,n[m>>2]=n[B>>2],n[m+4>>2]=n[B+4>>2],f=+wxe(l,m,c),C=d,+f}function Cxe(s){return s=s|0,(n[(WF()|0)+24>>2]|0)+(s*12|0)|0}function wxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),XA(d,c),d=ZA(d,c)|0,B=+xF(+S7[f&7](s,d)),C=m,+B}function Ixe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Bxe(s,c,d,1),C=f}function Bxe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=VF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=vxe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,Dxe(m,f)|0,f),C=d}function VF(){var s=0,l=0;if(o[7712]|0||(F5(9556),tr(35,9556,U|0)|0,l=7712,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9556)|0)){s=9556,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));F5(9556)}return 9556}function vxe(s){return s=s|0,0}function Dxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=VF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],Q5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(Pxe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function Q5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function Pxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=Sxe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,xxe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],Q5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,bxe(s,k),kxe(k),C=O;return}}function Sxe(s){return s=s|0,357913941}function xxe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function bxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function kxe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function F5(s){s=s|0,Txe(s)}function Qxe(s){s=s|0,Fxe(s+24|0)}function Fxe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function Txe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,5,l,Rxe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function Rxe(){return 1232}function Nxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=Lxe(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],c=+Mxe(l,d),C=f,+c}function Lxe(s){return s=s|0,(n[(VF()|0)+24>>2]|0)+(s*12|0)|0}function Mxe(s,l){s=s|0,l=l|0;var c=0;return c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),+ +xF(+P7[c&15](s))}function Oxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Uxe(s,c,d,1),C=f}function Uxe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=KF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=_xe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,Hxe(m,f)|0,f),C=d}function KF(){var s=0,l=0;if(o[7720]|0||(R5(9592),tr(36,9592,U|0)|0,l=7720,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9592)|0)){s=9592,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));R5(9592)}return 9592}function _xe(s){return s=s|0,0}function Hxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=KF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],T5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(jxe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function T5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function jxe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=qxe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,Gxe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],T5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,Yxe(s,k),Wxe(k),C=O;return}}function qxe(s){return s=s|0,357913941}function Gxe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function Yxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function Wxe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function R5(s){s=s|0,Jxe(s)}function Vxe(s){s=s|0,Kxe(s+24|0)}function Kxe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function Jxe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,7,l,zxe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function zxe(){return 1276}function Xxe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;return c=C,C=C+16|0,f=c+8|0,d=c,m=Zxe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],l=$xe(l,f)|0,C=c,l|0}function Zxe(s){return s=s|0,(n[(KF()|0)+24>>2]|0)+(s*12|0)|0}function $xe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;return d=C,C=C+16|0,f=d,c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),tf[c&31](f,s),f=N5(f)|0,C=d,f|0}function N5(s){s=s|0;var l=0,c=0,f=0,d=0;return d=C,C=C+32|0,l=d+12|0,c=d,f=QF(L5()|0)|0,f?(FF(l,f),TF(c,l),ebe(s,c),s=RF(l)|0):s=tbe(s)|0,C=d,s|0}function L5(){var s=0;return o[7736]|0||(Abe(9640),tr(25,9640,U|0)|0,s=7736,n[s>>2]=1,n[s+4>>2]=0),9640}function ebe(s,l){s=s|0,l=l|0,sbe(l,s,s+8|0)|0}function tbe(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0;return c=C,C=C+16|0,d=c+4|0,B=c,f=Wa(8)|0,l=f,k=Vt(16)|0,n[k>>2]=n[s>>2],n[k+4>>2]=n[s+4>>2],n[k+8>>2]=n[s+8>>2],n[k+12>>2]=n[s+12>>2],m=l+4|0,n[m>>2]=k,s=Vt(8)|0,m=n[m>>2]|0,n[B>>2]=0,n[d>>2]=n[B>>2],JF(s,m,d),n[f>>2]=s,C=c,l|0}function JF(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,c=Vt(16)|0,n[c+4>>2]=0,n[c+8>>2]=0,n[c>>2]=1244,n[c+12>>2]=l,n[s+4>>2]=c}function rbe(s){s=s|0,Jm(s),gt(s)}function nbe(s){s=s|0,s=n[s+12>>2]|0,s|0&>(s)}function ibe(s){s=s|0,gt(s)}function sbe(s,l,c){return s=s|0,l=l|0,c=c|0,l=obe(n[s>>2]|0,l,c)|0,c=s+4|0,n[(n[c>>2]|0)+8>>2]=l,n[(n[c>>2]|0)+8>>2]|0}function obe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;return f=C,C=C+16|0,d=f,Va(d),s=da(s)|0,c=abe(s,n[l>>2]|0,+E[c>>3])|0,Ka(d),C=f,c|0}function abe(s,l,c){s=s|0,l=l|0,c=+c;var f=0;return f=Pl(lbe()|0)|0,l=SF(l)|0,ml(0,f|0,s|0,l|0,+ +KA(c))|0}function lbe(){var s=0;return o[7728]|0||(cbe(9628),s=7728,n[s>>2]=1,n[s+4>>2]=0),9628}function cbe(s){s=s|0,Sl(s,ube()|0,2)}function ube(){return 1264}function Abe(s){s=s|0,Bp(s)}function fbe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],pbe(s,c,d,1),C=f}function pbe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=zF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=hbe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,gbe(m,f)|0,f),C=d}function zF(){var s=0,l=0;if(o[7744]|0||(O5(9684),tr(37,9684,U|0)|0,l=7744,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9684)|0)){s=9684,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));O5(9684)}return 9684}function hbe(s){return s=s|0,0}function gbe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=zF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],M5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(dbe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function M5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function dbe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=mbe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,ybe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],M5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,Ebe(s,k),Cbe(k),C=O;return}}function mbe(s){return s=s|0,357913941}function ybe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function Ebe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function Cbe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function O5(s){s=s|0,Bbe(s)}function wbe(s){s=s|0,Ibe(s+24|0)}function Ibe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function Bbe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,5,l,vbe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function vbe(){return 1280}function Dbe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=Pbe(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],c=Sbe(l,d,c)|0,C=f,c|0}function Pbe(s){return s=s|0,(n[(zF()|0)+24>>2]|0)+(s*12|0)|0}function Sbe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return B=C,C=C+32|0,d=B,m=B+16|0,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),XA(m,c),m=ZA(m,c)|0,_w[f&15](d,s,m),m=N5(d)|0,C=B,m|0}function xbe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],bbe(s,c,d,1),C=f}function bbe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=XF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=kbe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,Qbe(m,f)|0,f),C=d}function XF(){var s=0,l=0;if(o[7752]|0||(_5(9720),tr(38,9720,U|0)|0,l=7752,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9720)|0)){s=9720,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));_5(9720)}return 9720}function kbe(s){return s=s|0,0}function Qbe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=XF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],U5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(Fbe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function U5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function Fbe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=Tbe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,Rbe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],U5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,Nbe(s,k),Lbe(k),C=O;return}}function Tbe(s){return s=s|0,357913941}function Rbe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function Nbe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function Lbe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function _5(s){s=s|0,Ube(s)}function Mbe(s){s=s|0,Obe(s+24|0)}function Obe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function Ube(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,8,l,_be()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function _be(){return 1288}function Hbe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;return c=C,C=C+16|0,f=c+8|0,d=c,m=jbe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],l=qbe(l,f)|0,C=c,l|0}function jbe(s){return s=s|0,(n[(XF()|0)+24>>2]|0)+(s*12|0)|0}function qbe(s,l){s=s|0,l=l|0;var c=0;return c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),t5(Ng[c&31](s)|0)|0}function Gbe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Ybe(s,c,d,0),C=f}function Ybe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=ZF()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=Wbe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,Vbe(m,f)|0,f),C=d}function ZF(){var s=0,l=0;if(o[7760]|0||(j5(9756),tr(39,9756,U|0)|0,l=7760,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9756)|0)){s=9756,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));j5(9756)}return 9756}function Wbe(s){return s=s|0,0}function Vbe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=ZF()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],H5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(Kbe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function H5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function Kbe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=Jbe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,zbe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],H5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,Xbe(s,k),Zbe(k),C=O;return}}function Jbe(s){return s=s|0,357913941}function zbe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function Xbe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function Zbe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function j5(s){s=s|0,tke(s)}function $be(s){s=s|0,eke(s+24|0)}function eke(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function tke(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,8,l,rke()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function rke(){return 1292}function nke(s,l,c){s=s|0,l=l|0,c=+c;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,d=f+8|0,m=f,B=ike(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],ske(l,d,c),C=f}function ike(s){return s=s|0,(n[(ZF()|0)+24>>2]|0)+(s*12|0)|0}function ske(s,l,c){s=s|0,l=l|0,c=+c;var f=0,d=0,m=0;m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),ku(d,c),c=+Qu(d,c),B7[f&31](s,c),C=m}function oke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],ake(s,c,d,0),C=f}function ake(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=$F()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=lke(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,cke(m,f)|0,f),C=d}function $F(){var s=0,l=0;if(o[7768]|0||(G5(9792),tr(40,9792,U|0)|0,l=7768,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9792)|0)){s=9792,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));G5(9792)}return 9792}function lke(s){return s=s|0,0}function cke(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=$F()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],q5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(uke(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function q5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function uke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=Ake(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,fke(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],q5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,pke(s,k),hke(k),C=O;return}}function Ake(s){return s=s|0,357913941}function fke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function pke(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function hke(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function G5(s){s=s|0,mke(s)}function gke(s){s=s|0,dke(s+24|0)}function dke(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function mke(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,1,l,yke()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function yke(){return 1300}function Eke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=+f;var d=0,m=0,B=0,k=0;d=C,C=C+16|0,m=d+8|0,B=d,k=Cke(s)|0,s=n[k+4>>2]|0,n[B>>2]=n[k>>2],n[B+4>>2]=s,n[m>>2]=n[B>>2],n[m+4>>2]=n[B+4>>2],wke(l,m,c,f),C=d}function Cke(s){return s=s|0,(n[($F()|0)+24>>2]|0)+(s*12|0)|0}function wke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=+f;var d=0,m=0,B=0,k=0;k=C,C=C+16|0,m=k+1|0,B=k,d=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(d=n[(n[s>>2]|0)+d>>2]|0),XA(m,c),m=ZA(m,c)|0,ku(B,f),f=+Qu(B,f),Q7[d&15](s,m,f),C=k}function Ike(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Bke(s,c,d,0),C=f}function Bke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=eT()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=vke(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,Dke(m,f)|0,f),C=d}function eT(){var s=0,l=0;if(o[7776]|0||(W5(9828),tr(41,9828,U|0)|0,l=7776,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9828)|0)){s=9828,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));W5(9828)}return 9828}function vke(s){return s=s|0,0}function Dke(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=eT()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],Y5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(Pke(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function Y5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function Pke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=Ske(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,xke(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],Y5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,bke(s,k),kke(k),C=O;return}}function Ske(s){return s=s|0,357913941}function xke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function bke(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function kke(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function W5(s){s=s|0,Tke(s)}function Qke(s){s=s|0,Fke(s+24|0)}function Fke(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function Tke(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,7,l,Rke()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function Rke(){return 1312}function Nke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,d=f+8|0,m=f,B=Lke(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Mke(l,d,c),C=f}function Lke(s){return s=s|0,(n[(eT()|0)+24>>2]|0)+(s*12|0)|0}function Mke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),XA(d,c),d=ZA(d,c)|0,tf[f&31](s,d),C=m}function Oke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],Uke(s,c,d,0),C=f}function Uke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=tT()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=_ke(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,Hke(m,f)|0,f),C=d}function tT(){var s=0,l=0;if(o[7784]|0||(K5(9864),tr(42,9864,U|0)|0,l=7784,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9864)|0)){s=9864,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));K5(9864)}return 9864}function _ke(s){return s=s|0,0}function Hke(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=tT()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],V5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(jke(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function V5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function jke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=qke(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,Gke(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],V5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,Yke(s,k),Wke(k),C=O;return}}function qke(s){return s=s|0,357913941}function Gke(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function Yke(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function Wke(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function K5(s){s=s|0,Jke(s)}function Vke(s){s=s|0,Kke(s+24|0)}function Kke(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function Jke(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,8,l,zke()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function zke(){return 1320}function Xke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,d=f+8|0,m=f,B=Zke(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],$ke(l,d,c),C=f}function Zke(s){return s=s|0,(n[(tT()|0)+24>>2]|0)+(s*12|0)|0}function $ke(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),eQe(d,c),d=tQe(d,c)|0,tf[f&31](s,d),C=m}function eQe(s,l){s=s|0,l=l|0}function tQe(s,l){return s=s|0,l=l|0,rQe(l)|0}function rQe(s){return s=s|0,s|0}function nQe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],iQe(s,c,d,0),C=f}function iQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=rT()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=sQe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,oQe(m,f)|0,f),C=d}function rT(){var s=0,l=0;if(o[7792]|0||(z5(9900),tr(43,9900,U|0)|0,l=7792,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9900)|0)){s=9900,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));z5(9900)}return 9900}function sQe(s){return s=s|0,0}function oQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=rT()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],J5(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(aQe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function J5(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function aQe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=lQe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,cQe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],J5(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,uQe(s,k),AQe(k),C=O;return}}function lQe(s){return s=s|0,357913941}function cQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function uQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function AQe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function z5(s){s=s|0,hQe(s)}function fQe(s){s=s|0,pQe(s+24|0)}function pQe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function hQe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,22,l,gQe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function gQe(){return 1344}function dQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0;c=C,C=C+16|0,f=c+8|0,d=c,m=mQe(s)|0,s=n[m+4>>2]|0,n[d>>2]=n[m>>2],n[d+4>>2]=s,n[f>>2]=n[d>>2],n[f+4>>2]=n[d+4>>2],yQe(l,f),C=c}function mQe(s){return s=s|0,(n[(rT()|0)+24>>2]|0)+(s*12|0)|0}function yQe(s,l){s=s|0,l=l|0;var c=0;c=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(c=n[(n[s>>2]|0)+c>>2]|0),ef[c&127](s)}function EQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=nT()|0,s=CQe(c)|0,hn(m,l,d,s,wQe(c,f)|0,f)}function nT(){var s=0,l=0;if(o[7800]|0||(Z5(9936),tr(44,9936,U|0)|0,l=7800,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9936)|0)){s=9936,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));Z5(9936)}return 9936}function CQe(s){return s=s|0,s|0}function wQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=nT()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(X5(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(IQe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function X5(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function IQe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=BQe(s)|0,f>>>0<B>>>0)zr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,vQe(d,M>>3>>>0<f>>>1>>>0?O>>>0<B>>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,X5(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,DQe(s,d),PQe(d),C=k;return}}function BQe(s){return s=s|0,536870911}function vQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Vt(l<<3)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function DQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function PQe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function Z5(s){s=s|0,bQe(s)}function SQe(s){s=s|0,xQe(s+24|0)}function xQe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function bQe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,1,23,l,P5()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function kQe(s,l){s=s|0,l=l|0,FQe(n[(QQe(s)|0)>>2]|0,l)}function QQe(s){return s=s|0,(n[(nT()|0)+24>>2]|0)+(s<<3)|0}function FQe(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,qF(f,l),l=GF(f,l)|0,ef[s&127](l),C=c}function TQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=iT()|0,s=RQe(c)|0,hn(m,l,d,s,NQe(c,f)|0,f)}function iT(){var s=0,l=0;if(o[7808]|0||(e9(9972),tr(45,9972,U|0)|0,l=7808,n[l>>2]=1,n[l+4>>2]=0),!(Rr(9972)|0)){s=9972,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));e9(9972)}return 9972}function RQe(s){return s=s|0,s|0}function NQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=iT()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?($5(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(LQe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function $5(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function LQe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=MQe(s)|0,f>>>0<B>>>0)zr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,OQe(d,M>>3>>>0<f>>>1>>>0?O>>>0<B>>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,$5(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,UQe(s,d),_Qe(d),C=k;return}}function MQe(s){return s=s|0,536870911}function OQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Vt(l<<3)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function UQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function _Qe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function e9(s){s=s|0,qQe(s)}function HQe(s){s=s|0,jQe(s+24|0)}function jQe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function qQe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,1,9,l,GQe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function GQe(){return 1348}function YQe(s,l){return s=s|0,l=l|0,VQe(n[(WQe(s)|0)>>2]|0,l)|0}function WQe(s){return s=s|0,(n[(iT()|0)+24>>2]|0)+(s<<3)|0}function VQe(s,l){s=s|0,l=l|0;var c=0,f=0;return c=C,C=C+16|0,f=c,t9(f,l),l=r9(f,l)|0,l=sD(Ng[s&31](l)|0)|0,C=c,l|0}function t9(s,l){s=s|0,l=l|0}function r9(s,l){return s=s|0,l=l|0,KQe(l)|0}function KQe(s){return s=s|0,s|0}function JQe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=sT()|0,s=zQe(c)|0,hn(m,l,d,s,XQe(c,f)|0,f)}function sT(){var s=0,l=0;if(o[7816]|0||(i9(10008),tr(46,10008,U|0)|0,l=7816,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10008)|0)){s=10008,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));i9(10008)}return 10008}function zQe(s){return s=s|0,s|0}function XQe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=sT()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(n9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(ZQe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function n9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function ZQe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=$Qe(s)|0,f>>>0<B>>>0)zr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,eFe(d,M>>3>>>0<f>>>1>>>0?O>>>0<B>>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,n9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,tFe(s,d),rFe(d),C=k;return}}function $Qe(s){return s=s|0,536870911}function eFe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Vt(l<<3)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function tFe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function rFe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function i9(s){s=s|0,sFe(s)}function nFe(s){s=s|0,iFe(s+24|0)}function iFe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function sFe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,1,15,l,C5()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function oFe(s){return s=s|0,lFe(n[(aFe(s)|0)>>2]|0)|0}function aFe(s){return s=s|0,(n[(sT()|0)+24>>2]|0)+(s<<3)|0}function lFe(s){return s=s|0,sD(CD[s&7]()|0)|0}function cFe(){var s=0;return o[7832]|0||(mFe(10052),tr(25,10052,U|0)|0,s=7832,n[s>>2]=1,n[s+4>>2]=0),10052}function uFe(s,l){s=s|0,l=l|0,n[s>>2]=AFe()|0,n[s+4>>2]=fFe()|0,n[s+12>>2]=l,n[s+8>>2]=pFe()|0,n[s+32>>2]=2}function AFe(){return 11709}function fFe(){return 1188}function pFe(){return aD()|0}function hFe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Sp(f,896)|0)==512?c|0&&(gFe(c),gt(c)):l|0&&(Pu(l),gt(l))}function Sp(s,l){return s=s|0,l=l|0,l&s|0}function gFe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function aD(){var s=0;return o[7824]|0||(n[2511]=dFe()|0,n[2512]=0,s=7824,n[s>>2]=1,n[s+4>>2]=0),10044}function dFe(){return 0}function mFe(s){s=s|0,Bp(s)}function yFe(s){s=s|0;var l=0,c=0,f=0,d=0,m=0;l=C,C=C+32|0,c=l+24|0,m=l+16|0,d=l+8|0,f=l,EFe(s,4827),CFe(s,4834,3)|0,wFe(s,3682,47)|0,n[m>>2]=9,n[m+4>>2]=0,n[c>>2]=n[m>>2],n[c+4>>2]=n[m+4>>2],IFe(s,4841,c)|0,n[d>>2]=1,n[d+4>>2]=0,n[c>>2]=n[d>>2],n[c+4>>2]=n[d+4>>2],BFe(s,4871,c)|0,n[f>>2]=10,n[f+4>>2]=0,n[c>>2]=n[f>>2],n[c+4>>2]=n[f+4>>2],vFe(s,4891,c)|0,C=l}function EFe(s,l){s=s|0,l=l|0;var c=0;c=rRe()|0,n[s>>2]=c,nRe(c,l),xp(n[s>>2]|0)}function CFe(s,l,c){return s=s|0,l=l|0,c=c|0,_Te(s,pn(l)|0,c,0),s|0}function wFe(s,l,c){return s=s|0,l=l|0,c=c|0,DTe(s,pn(l)|0,c,0),s|0}function IFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],oTe(s,l,d),C=f,s|0}function BFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],HFe(s,l,d),C=f,s|0}function vFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=n[c+4>>2]|0,n[m>>2]=n[c>>2],n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],DFe(s,l,d),C=f,s|0}function DFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],PFe(s,c,d,1),C=f}function PFe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=oT()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=SFe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,xFe(m,f)|0,f),C=d}function oT(){var s=0,l=0;if(o[7840]|0||(o9(10100),tr(48,10100,U|0)|0,l=7840,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10100)|0)){s=10100,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));o9(10100)}return 10100}function SFe(s){return s=s|0,0}function xFe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=oT()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],s9(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(bFe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function s9(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function bFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=kFe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,QFe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],s9(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,FFe(s,k),TFe(k),C=O;return}}function kFe(s){return s=s|0,357913941}function QFe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function FFe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function TFe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function o9(s){s=s|0,LFe(s)}function RFe(s){s=s|0,NFe(s+24|0)}function NFe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function LFe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,6,l,MFe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function MFe(){return 1364}function OFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;return f=C,C=C+16|0,d=f+8|0,m=f,B=UFe(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],c=_Fe(l,d,c)|0,C=f,c|0}function UFe(s){return s=s|0,(n[(oT()|0)+24>>2]|0)+(s*12|0)|0}function _Fe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;return m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),XA(d,c),d=ZA(d,c)|0,d=p5(NT[f&15](s,d)|0)|0,C=m,d|0}function HFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],jFe(s,c,d,0),C=f}function jFe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=aT()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=qFe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,GFe(m,f)|0,f),C=d}function aT(){var s=0,l=0;if(o[7848]|0||(l9(10136),tr(49,10136,U|0)|0,l=7848,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10136)|0)){s=10136,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));l9(10136)}return 10136}function qFe(s){return s=s|0,0}function GFe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=aT()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],a9(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(YFe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function a9(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function YFe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=WFe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,VFe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],a9(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,KFe(s,k),JFe(k),C=O;return}}function WFe(s){return s=s|0,357913941}function VFe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function KFe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function JFe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function l9(s){s=s|0,ZFe(s)}function zFe(s){s=s|0,XFe(s+24|0)}function XFe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function ZFe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,9,l,$Fe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function $Fe(){return 1372}function eTe(s,l,c){s=s|0,l=l|0,c=+c;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,d=f+8|0,m=f,B=tTe(s)|0,s=n[B+4>>2]|0,n[m>>2]=n[B>>2],n[m+4>>2]=s,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],rTe(l,d,c),C=f}function tTe(s){return s=s|0,(n[(aT()|0)+24>>2]|0)+(s*12|0)|0}function rTe(s,l,c){s=s|0,l=l|0,c=+c;var f=0,d=0,m=0,B=Ze;m=C,C=C+16|0,d=m,f=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(f=n[(n[s>>2]|0)+f>>2]|0),nTe(d,c),B=y(iTe(d,c)),I7[f&1](s,B),C=m}function nTe(s,l){s=s|0,l=+l}function iTe(s,l){return s=s|0,l=+l,y(sTe(l))}function sTe(s){return s=+s,y(s)}function oTe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,d=f+8|0,m=f,k=n[c>>2]|0,B=n[c+4>>2]|0,c=pn(l)|0,n[m>>2]=k,n[m+4>>2]=B,n[d>>2]=n[m>>2],n[d+4>>2]=n[m+4>>2],aTe(s,c,d,0),C=f}function aTe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0,Q=0,O=0,M=0;d=C,C=C+32|0,m=d+16|0,M=d+8|0,k=d,O=n[c>>2]|0,Q=n[c+4>>2]|0,B=n[s>>2]|0,s=lT()|0,n[M>>2]=O,n[M+4>>2]=Q,n[m>>2]=n[M>>2],n[m+4>>2]=n[M+4>>2],c=lTe(m)|0,n[k>>2]=O,n[k+4>>2]=Q,n[m>>2]=n[k>>2],n[m+4>>2]=n[k+4>>2],hn(B,l,s,c,cTe(m,f)|0,f),C=d}function lT(){var s=0,l=0;if(o[7856]|0||(u9(10172),tr(50,10172,U|0)|0,l=7856,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10172)|0)){s=10172,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));u9(10172)}return 10172}function lTe(s){return s=s|0,0}function cTe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0;return M=C,C=C+32|0,d=M+24|0,B=M+16|0,k=M,Q=M+8|0,m=n[s>>2]|0,f=n[s+4>>2]|0,n[k>>2]=m,n[k+4>>2]=f,q=lT()|0,O=q+24|0,s=gr(l,4)|0,n[Q>>2]=s,l=q+28|0,c=n[l>>2]|0,c>>>0<(n[q+32>>2]|0)>>>0?(n[B>>2]=m,n[B+4>>2]=f,n[d>>2]=n[B>>2],n[d+4>>2]=n[B+4>>2],c9(c,d,s),s=(n[l>>2]|0)+12|0,n[l>>2]=s):(uTe(O,k,Q),s=n[l>>2]|0),C=M,((s-(n[O>>2]|0)|0)/12|0)+-1|0}function c9(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=n[l+4>>2]|0,n[s>>2]=n[l>>2],n[s+4>>2]=f,n[s+8>>2]=c}function uTe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;if(O=C,C=C+48|0,f=O+32|0,B=O+24|0,k=O,Q=s+4|0,d=(((n[Q>>2]|0)-(n[s>>2]|0)|0)/12|0)+1|0,m=ATe(s)|0,m>>>0<d>>>0)zr(s);else{M=n[s>>2]|0,se=((n[s+8>>2]|0)-M|0)/12|0,q=se<<1,fTe(k,se>>>0<m>>>1>>>0?q>>>0<d>>>0?d:q:m,((n[Q>>2]|0)-M|0)/12|0,s+8|0),Q=k+8|0,m=n[Q>>2]|0,d=n[l+4>>2]|0,c=n[c>>2]|0,n[B>>2]=n[l>>2],n[B+4>>2]=d,n[f>>2]=n[B>>2],n[f+4>>2]=n[B+4>>2],c9(m,f,c),n[Q>>2]=(n[Q>>2]|0)+12,pTe(s,k),hTe(k),C=O;return}}function ATe(s){return s=s|0,357913941}function fTe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>357913941)Tt();else{d=Vt(l*12|0)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c*12|0)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l*12|0)}function pTe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(((d|0)/-12|0)*12|0)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function hTe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~(((f+-12-l|0)>>>0)/12|0)*12|0)),s=n[s>>2]|0,s|0&>(s)}function u9(s){s=s|0,mTe(s)}function gTe(s){s=s|0,dTe(s+24|0)}function dTe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~(((l+-12-f|0)>>>0)/12|0)*12|0)),gt(c))}function mTe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,2,3,l,yTe()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function yTe(){return 1380}function ETe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;d=C,C=C+16|0,m=d+8|0,B=d,k=CTe(s)|0,s=n[k+4>>2]|0,n[B>>2]=n[k>>2],n[B+4>>2]=s,n[m>>2]=n[B>>2],n[m+4>>2]=n[B+4>>2],wTe(l,m,c,f),C=d}function CTe(s){return s=s|0,(n[(lT()|0)+24>>2]|0)+(s*12|0)|0}function wTe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;k=C,C=C+16|0,m=k+1|0,B=k,d=n[l>>2]|0,l=n[l+4>>2]|0,s=s+(l>>1)|0,l&1&&(d=n[(n[s>>2]|0)+d>>2]|0),XA(m,c),m=ZA(m,c)|0,ITe(B,f),B=BTe(B,f)|0,_w[d&15](s,m,B),C=k}function ITe(s,l){s=s|0,l=l|0}function BTe(s,l){return s=s|0,l=l|0,vTe(l)|0}function vTe(s){return s=s|0,(s|0)!=0|0}function DTe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=cT()|0,s=PTe(c)|0,hn(m,l,d,s,STe(c,f)|0,f)}function cT(){var s=0,l=0;if(o[7864]|0||(f9(10208),tr(51,10208,U|0)|0,l=7864,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10208)|0)){s=10208,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));f9(10208)}return 10208}function PTe(s){return s=s|0,s|0}function STe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=cT()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(A9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(xTe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function A9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function xTe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=bTe(s)|0,f>>>0<B>>>0)zr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,kTe(d,M>>3>>>0<f>>>1>>>0?O>>>0<B>>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,A9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,QTe(s,d),FTe(d),C=k;return}}function bTe(s){return s=s|0,536870911}function kTe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Vt(l<<3)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function QTe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function FTe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function f9(s){s=s|0,NTe(s)}function TTe(s){s=s|0,RTe(s+24|0)}function RTe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function NTe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,1,24,l,LTe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function LTe(){return 1392}function MTe(s,l){s=s|0,l=l|0,UTe(n[(OTe(s)|0)>>2]|0,l)}function OTe(s){return s=s|0,(n[(cT()|0)+24>>2]|0)+(s<<3)|0}function UTe(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,t9(f,l),l=r9(f,l)|0,ef[s&127](l),C=c}function _Te(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=uT()|0,s=HTe(c)|0,hn(m,l,d,s,jTe(c,f)|0,f)}function uT(){var s=0,l=0;if(o[7872]|0||(h9(10244),tr(52,10244,U|0)|0,l=7872,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10244)|0)){s=10244,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));h9(10244)}return 10244}function HTe(s){return s=s|0,s|0}function jTe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=uT()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(p9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(qTe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function p9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function qTe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=GTe(s)|0,f>>>0<B>>>0)zr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,YTe(d,M>>3>>>0<f>>>1>>>0?O>>>0<B>>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,p9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,WTe(s,d),VTe(d),C=k;return}}function GTe(s){return s=s|0,536870911}function YTe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Vt(l<<3)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function WTe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function VTe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function h9(s){s=s|0,zTe(s)}function KTe(s){s=s|0,JTe(s+24|0)}function JTe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function zTe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,1,16,l,XTe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function XTe(){return 1400}function ZTe(s){return s=s|0,eRe(n[($Te(s)|0)>>2]|0)|0}function $Te(s){return s=s|0,(n[(uT()|0)+24>>2]|0)+(s<<3)|0}function eRe(s){return s=s|0,tRe(CD[s&7]()|0)|0}function tRe(s){return s=s|0,s|0}function rRe(){var s=0;return o[7880]|0||(cRe(10280),tr(25,10280,U|0)|0,s=7880,n[s>>2]=1,n[s+4>>2]=0),10280}function nRe(s,l){s=s|0,l=l|0,n[s>>2]=iRe()|0,n[s+4>>2]=sRe()|0,n[s+12>>2]=l,n[s+8>>2]=oRe()|0,n[s+32>>2]=4}function iRe(){return 11711}function sRe(){return 1356}function oRe(){return aD()|0}function aRe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Sp(f,896)|0)==512?c|0&&(lRe(c),gt(c)):l|0&&(vg(l),gt(l))}function lRe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function cRe(s){s=s|0,Bp(s)}function uRe(s){s=s|0,ARe(s,4920),fRe(s)|0,pRe(s)|0}function ARe(s,l){s=s|0,l=l|0;var c=0;c=L5()|0,n[s>>2]=c,RRe(c,l),xp(n[s>>2]|0)}function fRe(s){s=s|0;var l=0;return l=n[s>>2]|0,bg(l,vRe()|0),s|0}function pRe(s){s=s|0;var l=0;return l=n[s>>2]|0,bg(l,hRe()|0),s|0}function hRe(){var s=0;return o[7888]|0||(g9(10328),tr(53,10328,U|0)|0,s=7888,n[s>>2]=1,n[s+4>>2]=0),Rr(10328)|0||g9(10328),10328}function bg(s,l){s=s|0,l=l|0,hn(s,0,l,0,0,0)}function g9(s){s=s|0,mRe(s),kg(s,10)}function gRe(s){s=s|0,dRe(s+24|0)}function dRe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function mRe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,5,1,l,wRe()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function yRe(s,l,c){s=s|0,l=l|0,c=+c,ERe(s,l,c)}function kg(s,l){s=s|0,l=l|0,n[s+20>>2]=l}function ERe(s,l,c){s=s|0,l=l|0,c=+c;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+16|0,m=f+8|0,k=f+13|0,d=f,B=f+12|0,XA(k,l),n[m>>2]=ZA(k,l)|0,ku(B,c),E[d>>3]=+Qu(B,c),CRe(s,m,d),C=f}function CRe(s,l,c){s=s|0,l=l|0,c=c|0,Y(s+8|0,n[l>>2]|0,+E[c>>3]),o[s+24>>0]=1}function wRe(){return 1404}function IRe(s,l){return s=s|0,l=+l,BRe(s,l)|0}function BRe(s,l){s=s|0,l=+l;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return f=C,C=C+16|0,m=f+4|0,B=f+8|0,k=f,d=Wa(8)|0,c=d,Q=Vt(16)|0,XA(m,s),s=ZA(m,s)|0,ku(B,l),Y(Q,s,+Qu(B,l)),B=c+4|0,n[B>>2]=Q,s=Vt(8)|0,B=n[B>>2]|0,n[k>>2]=0,n[m>>2]=n[k>>2],JF(s,B,m),n[d>>2]=s,C=f,c|0}function vRe(){var s=0;return o[7896]|0||(d9(10364),tr(54,10364,U|0)|0,s=7896,n[s>>2]=1,n[s+4>>2]=0),Rr(10364)|0||d9(10364),10364}function d9(s){s=s|0,SRe(s),kg(s,55)}function DRe(s){s=s|0,PRe(s+24|0)}function PRe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function SRe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,5,4,l,QRe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function xRe(s){s=s|0,bRe(s)}function bRe(s){s=s|0,kRe(s)}function kRe(s){s=s|0,m9(s+8|0),o[s+24>>0]=1}function m9(s){s=s|0,n[s>>2]=0,E[s+8>>3]=0}function QRe(){return 1424}function FRe(){return TRe()|0}function TRe(){var s=0,l=0,c=0,f=0,d=0,m=0,B=0;return l=C,C=C+16|0,d=l+4|0,B=l,c=Wa(8)|0,s=c,f=Vt(16)|0,m9(f),m=s+4|0,n[m>>2]=f,f=Vt(8)|0,m=n[m>>2]|0,n[B>>2]=0,n[d>>2]=n[B>>2],JF(f,m,d),n[c>>2]=f,C=l,s|0}function RRe(s,l){s=s|0,l=l|0,n[s>>2]=NRe()|0,n[s+4>>2]=LRe()|0,n[s+12>>2]=l,n[s+8>>2]=MRe()|0,n[s+32>>2]=5}function NRe(){return 11710}function LRe(){return 1416}function MRe(){return lD()|0}function ORe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Sp(f,896)|0)==512?c|0&&(URe(c),gt(c)):l|0&>(l)}function URe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function lD(){var s=0;return o[7904]|0||(n[2600]=_Re()|0,n[2601]=0,s=7904,n[s>>2]=1,n[s+4>>2]=0),10400}function _Re(){return n[357]|0}function HRe(s){s=s|0,jRe(s,4926),qRe(s)|0}function jRe(s,l){s=s|0,l=l|0;var c=0;c=s5()|0,n[s>>2]=c,eNe(c,l),xp(n[s>>2]|0)}function qRe(s){s=s|0;var l=0;return l=n[s>>2]|0,bg(l,GRe()|0),s|0}function GRe(){var s=0;return o[7912]|0||(y9(10412),tr(56,10412,U|0)|0,s=7912,n[s>>2]=1,n[s+4>>2]=0),Rr(10412)|0||y9(10412),10412}function y9(s){s=s|0,VRe(s),kg(s,57)}function YRe(s){s=s|0,WRe(s+24|0)}function WRe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function VRe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,5,5,l,XRe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function KRe(s){s=s|0,JRe(s)}function JRe(s){s=s|0,zRe(s)}function zRe(s){s=s|0;var l=0,c=0;l=s+8|0,c=l+48|0;do n[l>>2]=0,l=l+4|0;while((l|0)<(c|0));o[s+56>>0]=1}function XRe(){return 1432}function ZRe(){return $Re()|0}function $Re(){var s=0,l=0,c=0,f=0,d=0,m=0,B=0,k=0;B=C,C=C+16|0,s=B+4|0,l=B,c=Wa(8)|0,f=c,d=Vt(48)|0,m=d,k=m+48|0;do n[m>>2]=0,m=m+4|0;while((m|0)<(k|0));return m=f+4|0,n[m>>2]=d,k=Vt(8)|0,m=n[m>>2]|0,n[l>>2]=0,n[s>>2]=n[l>>2],o5(k,m,s),n[c>>2]=k,C=B,f|0}function eNe(s,l){s=s|0,l=l|0,n[s>>2]=tNe()|0,n[s+4>>2]=rNe()|0,n[s+12>>2]=l,n[s+8>>2]=nNe()|0,n[s+32>>2]=6}function tNe(){return 11704}function rNe(){return 1436}function nNe(){return lD()|0}function iNe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Sp(f,896)|0)==512?c|0&&(sNe(c),gt(c)):l|0&>(l)}function sNe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function oNe(s){s=s|0,aNe(s,4933),lNe(s)|0,cNe(s)|0}function aNe(s,l){s=s|0,l=l|0;var c=0;c=TNe()|0,n[s>>2]=c,RNe(c,l),xp(n[s>>2]|0)}function lNe(s){s=s|0;var l=0;return l=n[s>>2]|0,bg(l,BNe()|0),s|0}function cNe(s){s=s|0;var l=0;return l=n[s>>2]|0,bg(l,uNe()|0),s|0}function uNe(){var s=0;return o[7920]|0||(E9(10452),tr(58,10452,U|0)|0,s=7920,n[s>>2]=1,n[s+4>>2]=0),Rr(10452)|0||E9(10452),10452}function E9(s){s=s|0,pNe(s),kg(s,1)}function ANe(s){s=s|0,fNe(s+24|0)}function fNe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function pNe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,5,1,l,mNe()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function hNe(s,l,c){s=s|0,l=+l,c=+c,gNe(s,l,c)}function gNe(s,l,c){s=s|0,l=+l,c=+c;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+32|0,m=f+8|0,k=f+17|0,d=f,B=f+16|0,ku(k,l),E[m>>3]=+Qu(k,l),ku(B,c),E[d>>3]=+Qu(B,c),dNe(s,m,d),C=f}function dNe(s,l,c){s=s|0,l=l|0,c=c|0,C9(s+8|0,+E[l>>3],+E[c>>3]),o[s+24>>0]=1}function C9(s,l,c){s=s|0,l=+l,c=+c,E[s>>3]=l,E[s+8>>3]=c}function mNe(){return 1472}function yNe(s,l){return s=+s,l=+l,ENe(s,l)|0}function ENe(s,l){s=+s,l=+l;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return f=C,C=C+16|0,B=f+4|0,k=f+8|0,Q=f,d=Wa(8)|0,c=d,m=Vt(16)|0,ku(B,s),s=+Qu(B,s),ku(k,l),C9(m,s,+Qu(k,l)),k=c+4|0,n[k>>2]=m,m=Vt(8)|0,k=n[k>>2]|0,n[Q>>2]=0,n[B>>2]=n[Q>>2],w9(m,k,B),n[d>>2]=m,C=f,c|0}function w9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,c=Vt(16)|0,n[c+4>>2]=0,n[c+8>>2]=0,n[c>>2]=1452,n[c+12>>2]=l,n[s+4>>2]=c}function CNe(s){s=s|0,Jm(s),gt(s)}function wNe(s){s=s|0,s=n[s+12>>2]|0,s|0&>(s)}function INe(s){s=s|0,gt(s)}function BNe(){var s=0;return o[7928]|0||(I9(10488),tr(59,10488,U|0)|0,s=7928,n[s>>2]=1,n[s+4>>2]=0),Rr(10488)|0||I9(10488),10488}function I9(s){s=s|0,PNe(s),kg(s,60)}function vNe(s){s=s|0,DNe(s+24|0)}function DNe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function PNe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,5,6,l,kNe()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function SNe(s){s=s|0,xNe(s)}function xNe(s){s=s|0,bNe(s)}function bNe(s){s=s|0,B9(s+8|0),o[s+24>>0]=1}function B9(s){s=s|0,n[s>>2]=0,n[s+4>>2]=0,n[s+8>>2]=0,n[s+12>>2]=0}function kNe(){return 1492}function QNe(){return FNe()|0}function FNe(){var s=0,l=0,c=0,f=0,d=0,m=0,B=0;return l=C,C=C+16|0,d=l+4|0,B=l,c=Wa(8)|0,s=c,f=Vt(16)|0,B9(f),m=s+4|0,n[m>>2]=f,f=Vt(8)|0,m=n[m>>2]|0,n[B>>2]=0,n[d>>2]=n[B>>2],w9(f,m,d),n[c>>2]=f,C=l,s|0}function TNe(){var s=0;return o[7936]|0||(_Ne(10524),tr(25,10524,U|0)|0,s=7936,n[s>>2]=1,n[s+4>>2]=0),10524}function RNe(s,l){s=s|0,l=l|0,n[s>>2]=NNe()|0,n[s+4>>2]=LNe()|0,n[s+12>>2]=l,n[s+8>>2]=MNe()|0,n[s+32>>2]=7}function NNe(){return 11700}function LNe(){return 1484}function MNe(){return lD()|0}function ONe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Sp(f,896)|0)==512?c|0&&(UNe(c),gt(c)):l|0&>(l)}function UNe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function _Ne(s){s=s|0,Bp(s)}function HNe(s,l,c){s=s|0,l=l|0,c=c|0,s=pn(l)|0,l=jNe(c)|0,c=qNe(c,0)|0,ELe(s,l,c,AT()|0,0)}function jNe(s){return s=s|0,s|0}function qNe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=AT()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(D9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(zNe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function AT(){var s=0,l=0;if(o[7944]|0||(v9(10568),tr(61,10568,U|0)|0,l=7944,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10568)|0)){s=10568,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));v9(10568)}return 10568}function v9(s){s=s|0,WNe(s)}function GNe(s){s=s|0,YNe(s+24|0)}function YNe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function WNe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,1,17,l,B5()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function VNe(s){return s=s|0,JNe(n[(KNe(s)|0)>>2]|0)|0}function KNe(s){return s=s|0,(n[(AT()|0)+24>>2]|0)+(s<<3)|0}function JNe(s){return s=s|0,oD(CD[s&7]()|0)|0}function D9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function zNe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=XNe(s)|0,f>>>0<B>>>0)zr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,ZNe(d,M>>3>>>0<f>>>1>>>0?O>>>0<B>>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,D9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,$Ne(s,d),eLe(d),C=k;return}}function XNe(s){return s=s|0,536870911}function ZNe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Vt(l<<3)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function $Ne(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function eLe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function tLe(){rLe()}function rLe(){nLe(10604)}function nLe(s){s=s|0,iLe(s,4955)}function iLe(s,l){s=s|0,l=l|0;var c=0;c=sLe()|0,n[s>>2]=c,oLe(c,l),xp(n[s>>2]|0)}function sLe(){var s=0;return o[7952]|0||(gLe(10612),tr(25,10612,U|0)|0,s=7952,n[s>>2]=1,n[s+4>>2]=0),10612}function oLe(s,l){s=s|0,l=l|0,n[s>>2]=uLe()|0,n[s+4>>2]=ALe()|0,n[s+12>>2]=l,n[s+8>>2]=fLe()|0,n[s+32>>2]=8}function xp(s){s=s|0;var l=0,c=0;l=C,C=C+16|0,c=l,Gm()|0,n[c>>2]=s,aLe(10608,c),C=l}function Gm(){return o[11714]|0||(n[2652]=0,tr(62,10608,U|0)|0,o[11714]=1),10608}function aLe(s,l){s=s|0,l=l|0;var c=0;c=Vt(8)|0,n[c+4>>2]=n[l>>2],n[c>>2]=n[s>>2],n[s>>2]=c}function lLe(s){s=s|0,cLe(s)}function cLe(s){s=s|0;var l=0,c=0;if(l=n[s>>2]|0,l|0)do c=l,l=n[l>>2]|0,gt(c);while((l|0)!=0);n[s>>2]=0}function uLe(){return 11715}function ALe(){return 1496}function fLe(){return aD()|0}function pLe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Sp(f,896)|0)==512?c|0&&(hLe(c),gt(c)):l|0&>(l)}function hLe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function gLe(s){s=s|0,Bp(s)}function dLe(s,l){s=s|0,l=l|0;var c=0,f=0;Gm()|0,c=n[2652]|0;e:do if(c|0){for(;f=n[c+4>>2]|0,!(f|0&&(o7(fT(f)|0,s)|0)==0);)if(c=n[c>>2]|0,!c)break e;mLe(f,l)}while(0)}function fT(s){return s=s|0,n[s+12>>2]|0}function mLe(s,l){s=s|0,l=l|0;var c=0;s=s+36|0,c=n[s>>2]|0,c|0&&(jA(c),gt(c)),c=Vt(4)|0,$G(c,l),n[s>>2]=c}function pT(){return o[11716]|0||(n[2664]=0,tr(63,10656,U|0)|0,o[11716]=1),10656}function P9(){var s=0;return o[11717]|0?s=n[2665]|0:(yLe(),n[2665]=1504,o[11717]=1,s=1504),s|0}function yLe(){o[11740]|0||(o[11718]=gr(gr(8,0)|0,0)|0,o[11719]=gr(gr(0,0)|0,0)|0,o[11720]=gr(gr(0,16)|0,0)|0,o[11721]=gr(gr(8,0)|0,0)|0,o[11722]=gr(gr(0,0)|0,0)|0,o[11723]=gr(gr(8,0)|0,0)|0,o[11724]=gr(gr(0,0)|0,0)|0,o[11725]=gr(gr(8,0)|0,0)|0,o[11726]=gr(gr(0,0)|0,0)|0,o[11727]=gr(gr(8,0)|0,0)|0,o[11728]=gr(gr(0,0)|0,0)|0,o[11729]=gr(gr(0,0)|0,32)|0,o[11730]=gr(gr(0,0)|0,32)|0,o[11740]=1)}function S9(){return 1572}function ELe(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0,O=0,M=0;m=C,C=C+32|0,M=m+16|0,O=m+12|0,Q=m+8|0,k=m+4|0,B=m,n[M>>2]=s,n[O>>2]=l,n[Q>>2]=c,n[k>>2]=f,n[B>>2]=d,pT()|0,CLe(10656,M,O,Q,k,B),C=m}function CLe(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0;var B=0;B=Vt(24)|0,r5(B+4|0,n[l>>2]|0,n[c>>2]|0,n[f>>2]|0,n[d>>2]|0,n[m>>2]|0),n[B>>2]=n[s>>2],n[s>>2]=B}function x9(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0,Ge=0,Oe=0,Fe=0,et=0,Xe=0,at=0;if(at=C,C=C+32|0,Oe=at+20|0,Fe=at+8|0,et=at+4|0,Xe=at,l=n[l>>2]|0,l|0){Ge=Oe+4|0,Q=Oe+8|0,O=Fe+4|0,M=Fe+8|0,q=Fe+8|0,se=Oe+8|0;do{if(B=l+4|0,k=hT(B)|0,k|0){if(d=Rw(k)|0,n[Oe>>2]=0,n[Ge>>2]=0,n[Q>>2]=0,f=(Nw(k)|0)+1|0,wLe(Oe,f),f|0)for(;f=f+-1|0,xc(Fe,n[d>>2]|0),m=n[Ge>>2]|0,m>>>0<(n[se>>2]|0)>>>0?(n[m>>2]=n[Fe>>2],n[Ge>>2]=(n[Ge>>2]|0)+4):gT(Oe,Fe),f;)d=d+4|0;f=Lw(k)|0,n[Fe>>2]=0,n[O>>2]=0,n[M>>2]=0;e:do if(n[f>>2]|0)for(d=0,m=0;;){if((d|0)==(m|0)?ILe(Fe,f):(n[d>>2]=n[f>>2],n[O>>2]=(n[O>>2]|0)+4),f=f+4|0,!(n[f>>2]|0))break e;d=n[O>>2]|0,m=n[q>>2]|0}while(0);n[et>>2]=cD(B)|0,n[Xe>>2]=Rr(k)|0,BLe(c,s,et,Xe,Oe,Fe),dT(Fe),$A(Oe)}l=n[l>>2]|0}while((l|0)!=0)}C=at}function hT(s){return s=s|0,n[s+12>>2]|0}function Rw(s){return s=s|0,n[s+12>>2]|0}function Nw(s){return s=s|0,n[s+16>>2]|0}function wLe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;d=C,C=C+32|0,c=d,f=n[s>>2]|0,(n[s+8>>2]|0)-f>>2>>>0<l>>>0&&(L9(c,l,(n[s+4>>2]|0)-f>>2,s+8|0),M9(s,c),O9(c)),C=d}function gT(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0;if(B=C,C=C+32|0,c=B,f=s+4|0,d=((n[f>>2]|0)-(n[s>>2]|0)>>2)+1|0,m=N9(s)|0,m>>>0<d>>>0)zr(s);else{k=n[s>>2]|0,O=(n[s+8>>2]|0)-k|0,Q=O>>1,L9(c,O>>2>>>0<m>>>1>>>0?Q>>>0<d>>>0?d:Q:m,(n[f>>2]|0)-k>>2,s+8|0),m=c+8|0,n[n[m>>2]>>2]=n[l>>2],n[m>>2]=(n[m>>2]|0)+4,M9(s,c),O9(c),C=B;return}}function Lw(s){return s=s|0,n[s+8>>2]|0}function ILe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0;if(B=C,C=C+32|0,c=B,f=s+4|0,d=((n[f>>2]|0)-(n[s>>2]|0)>>2)+1|0,m=R9(s)|0,m>>>0<d>>>0)zr(s);else{k=n[s>>2]|0,O=(n[s+8>>2]|0)-k|0,Q=O>>1,jLe(c,O>>2>>>0<m>>>1>>>0?Q>>>0<d>>>0?d:Q:m,(n[f>>2]|0)-k>>2,s+8|0),m=c+8|0,n[n[m>>2]>>2]=n[l>>2],n[m>>2]=(n[m>>2]|0)+4,qLe(s,c),GLe(c),C=B;return}}function cD(s){return s=s|0,n[s>>2]|0}function BLe(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,vLe(s,l,c,f,d,m)}function dT(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-4-f|0)>>>2)<<2)),gt(c))}function $A(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-4-f|0)>>>2)<<2)),gt(c))}function vLe(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0;var B=0,k=0,Q=0,O=0,M=0,q=0;B=C,C=C+48|0,M=B+40|0,k=B+32|0,q=B+24|0,Q=B+12|0,O=B,Va(k),s=da(s)|0,n[q>>2]=n[l>>2],c=n[c>>2]|0,f=n[f>>2]|0,mT(Q,d),DLe(O,m),n[M>>2]=n[q>>2],PLe(s,M,c,f,Q,O),dT(O),$A(Q),Ka(k),C=B}function mT(s,l){s=s|0,l=l|0;var c=0,f=0;n[s>>2]=0,n[s+4>>2]=0,n[s+8>>2]=0,c=l+4|0,f=(n[c>>2]|0)-(n[l>>2]|0)>>2,f|0&&(_Le(s,f),HLe(s,n[l>>2]|0,n[c>>2]|0,f))}function DLe(s,l){s=s|0,l=l|0;var c=0,f=0;n[s>>2]=0,n[s+4>>2]=0,n[s+8>>2]=0,c=l+4|0,f=(n[c>>2]|0)-(n[l>>2]|0)>>2,f|0&&(OLe(s,f),ULe(s,n[l>>2]|0,n[c>>2]|0,f))}function PLe(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0;var B=0,k=0,Q=0,O=0,M=0,q=0;B=C,C=C+32|0,M=B+28|0,q=B+24|0,k=B+12|0,Q=B,O=Pl(SLe()|0)|0,n[q>>2]=n[l>>2],n[M>>2]=n[q>>2],l=Qg(M)|0,c=b9(c)|0,f=yT(f)|0,n[k>>2]=n[d>>2],M=d+4|0,n[k+4>>2]=n[M>>2],q=d+8|0,n[k+8>>2]=n[q>>2],n[q>>2]=0,n[M>>2]=0,n[d>>2]=0,d=ET(k)|0,n[Q>>2]=n[m>>2],M=m+4|0,n[Q+4>>2]=n[M>>2],q=m+8|0,n[Q+8>>2]=n[q>>2],n[q>>2]=0,n[M>>2]=0,n[m>>2]=0,ao(0,O|0,s|0,l|0,c|0,f|0,d|0,xLe(Q)|0)|0,dT(Q),$A(k),C=B}function SLe(){var s=0;return o[7968]|0||(LLe(10708),s=7968,n[s>>2]=1,n[s+4>>2]=0),10708}function Qg(s){return s=s|0,Q9(s)|0}function b9(s){return s=s|0,k9(s)|0}function yT(s){return s=s|0,oD(s)|0}function ET(s){return s=s|0,kLe(s)|0}function xLe(s){return s=s|0,bLe(s)|0}function bLe(s){s=s|0;var l=0,c=0,f=0;if(f=(n[s+4>>2]|0)-(n[s>>2]|0)|0,c=f>>2,f=Wa(f+4|0)|0,n[f>>2]=c,c|0){l=0;do n[f+4+(l<<2)>>2]=k9(n[(n[s>>2]|0)+(l<<2)>>2]|0)|0,l=l+1|0;while((l|0)!=(c|0))}return f|0}function k9(s){return s=s|0,s|0}function kLe(s){s=s|0;var l=0,c=0,f=0;if(f=(n[s+4>>2]|0)-(n[s>>2]|0)|0,c=f>>2,f=Wa(f+4|0)|0,n[f>>2]=c,c|0){l=0;do n[f+4+(l<<2)>>2]=Q9((n[s>>2]|0)+(l<<2)|0)|0,l=l+1|0;while((l|0)!=(c|0))}return f|0}function Q9(s){s=s|0;var l=0,c=0,f=0,d=0;return d=C,C=C+32|0,l=d+12|0,c=d,f=QF(F9()|0)|0,f?(FF(l,f),TF(c,l),fUe(s,c),s=RF(l)|0):s=QLe(s)|0,C=d,s|0}function F9(){var s=0;return o[7960]|0||(NLe(10664),tr(25,10664,U|0)|0,s=7960,n[s>>2]=1,n[s+4>>2]=0),10664}function QLe(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0;return c=C,C=C+16|0,d=c+4|0,B=c,f=Wa(8)|0,l=f,k=Vt(4)|0,n[k>>2]=n[s>>2],m=l+4|0,n[m>>2]=k,s=Vt(8)|0,m=n[m>>2]|0,n[B>>2]=0,n[d>>2]=n[B>>2],T9(s,m,d),n[f>>2]=s,C=c,l|0}function T9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,c=Vt(16)|0,n[c+4>>2]=0,n[c+8>>2]=0,n[c>>2]=1656,n[c+12>>2]=l,n[s+4>>2]=c}function FLe(s){s=s|0,Jm(s),gt(s)}function TLe(s){s=s|0,s=n[s+12>>2]|0,s|0&>(s)}function RLe(s){s=s|0,gt(s)}function NLe(s){s=s|0,Bp(s)}function LLe(s){s=s|0,Sl(s,MLe()|0,5)}function MLe(){return 1676}function OLe(s,l){s=s|0,l=l|0;var c=0;if((R9(s)|0)>>>0<l>>>0&&zr(s),l>>>0>1073741823)Tt();else{c=Vt(l<<2)|0,n[s+4>>2]=c,n[s>>2]=c,n[s+8>>2]=c+(l<<2);return}}function ULe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,f=s+4|0,s=c-l|0,(s|0)>0&&(Dr(n[f>>2]|0,l|0,s|0)|0,n[f>>2]=(n[f>>2]|0)+(s>>>2<<2))}function R9(s){return s=s|0,1073741823}function _Le(s,l){s=s|0,l=l|0;var c=0;if((N9(s)|0)>>>0<l>>>0&&zr(s),l>>>0>1073741823)Tt();else{c=Vt(l<<2)|0,n[s+4>>2]=c,n[s>>2]=c,n[s+8>>2]=c+(l<<2);return}}function HLe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,f=s+4|0,s=c-l|0,(s|0)>0&&(Dr(n[f>>2]|0,l|0,s|0)|0,n[f>>2]=(n[f>>2]|0)+(s>>>2<<2))}function N9(s){return s=s|0,1073741823}function jLe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>1073741823)Tt();else{d=Vt(l<<2)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<2)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<2)}function qLe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>2)<<2)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function GLe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-4-l|0)>>>2)<<2)),s=n[s>>2]|0,s|0&>(s)}function L9(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>1073741823)Tt();else{d=Vt(l<<2)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<2)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<2)}function M9(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>2)<<2)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function O9(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-4-l|0)>>>2)<<2)),s=n[s>>2]|0,s|0&>(s)}function YLe(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0,Ge=0,Oe=0,Fe=0;if(Fe=C,C=C+32|0,M=Fe+20|0,q=Fe+12|0,O=Fe+16|0,se=Fe+4|0,Ge=Fe,Oe=Fe+8|0,k=P9()|0,m=n[k>>2]|0,B=n[m>>2]|0,B|0)for(Q=n[k+8>>2]|0,k=n[k+4>>2]|0;xc(M,B),WLe(s,M,k,Q),m=m+4|0,B=n[m>>2]|0,B;)Q=Q+1|0,k=k+1|0;if(m=S9()|0,B=n[m>>2]|0,B|0)do xc(M,B),n[q>>2]=n[m+4>>2],VLe(l,M,q),m=m+8|0,B=n[m>>2]|0;while((B|0)!=0);if(m=n[(Gm()|0)>>2]|0,m|0)do l=n[m+4>>2]|0,xc(M,n[(Ym(l)|0)>>2]|0),n[q>>2]=fT(l)|0,KLe(c,M,q),m=n[m>>2]|0;while((m|0)!=0);if(xc(O,0),m=pT()|0,n[M>>2]=n[O>>2],x9(M,m,d),m=n[(Gm()|0)>>2]|0,m|0){s=M+4|0,l=M+8|0,c=M+8|0;do{if(Q=n[m+4>>2]|0,xc(q,n[(Ym(Q)|0)>>2]|0),JLe(se,U9(Q)|0),B=n[se>>2]|0,B|0){n[M>>2]=0,n[s>>2]=0,n[l>>2]=0;do xc(Ge,n[(Ym(n[B+4>>2]|0)|0)>>2]|0),k=n[s>>2]|0,k>>>0<(n[c>>2]|0)>>>0?(n[k>>2]=n[Ge>>2],n[s>>2]=(n[s>>2]|0)+4):gT(M,Ge),B=n[B>>2]|0;while((B|0)!=0);zLe(f,q,M),$A(M)}n[Oe>>2]=n[q>>2],O=_9(Q)|0,n[M>>2]=n[Oe>>2],x9(M,O,d),l5(se),m=n[m>>2]|0}while((m|0)!=0)}C=Fe}function WLe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,lMe(s,l,c,f)}function VLe(s,l,c){s=s|0,l=l|0,c=c|0,aMe(s,l,c)}function Ym(s){return s=s|0,s|0}function KLe(s,l,c){s=s|0,l=l|0,c=c|0,nMe(s,l,c)}function U9(s){return s=s|0,s+16|0}function JLe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;if(m=C,C=C+16|0,d=m+8|0,c=m,n[s>>2]=0,f=n[l>>2]|0,n[d>>2]=f,n[c>>2]=s,c=rMe(c)|0,f|0){if(f=Vt(12)|0,B=(H9(d)|0)+4|0,s=n[B+4>>2]|0,l=f+4|0,n[l>>2]=n[B>>2],n[l+4>>2]=s,l=n[n[d>>2]>>2]|0,n[d>>2]=l,!l)s=f;else for(l=f;s=Vt(12)|0,Q=(H9(d)|0)+4|0,k=n[Q+4>>2]|0,B=s+4|0,n[B>>2]=n[Q>>2],n[B+4>>2]=k,n[l>>2]=s,B=n[n[d>>2]>>2]|0,n[d>>2]=B,B;)l=s;n[s>>2]=n[c>>2],n[c>>2]=f}C=m}function zLe(s,l,c){s=s|0,l=l|0,c=c|0,XLe(s,l,c)}function _9(s){return s=s|0,s+24|0}function XLe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+32|0,B=f+24|0,d=f+16|0,k=f+12|0,m=f,Va(d),s=da(s)|0,n[k>>2]=n[l>>2],mT(m,c),n[B>>2]=n[k>>2],ZLe(s,B,m),$A(m),Ka(d),C=f}function ZLe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=C,C=C+32|0,B=f+16|0,k=f+12|0,d=f,m=Pl($Le()|0)|0,n[k>>2]=n[l>>2],n[B>>2]=n[k>>2],l=Qg(B)|0,n[d>>2]=n[c>>2],B=c+4|0,n[d+4>>2]=n[B>>2],k=c+8|0,n[d+8>>2]=n[k>>2],n[k>>2]=0,n[B>>2]=0,n[c>>2]=0,oo(0,m|0,s|0,l|0,ET(d)|0)|0,$A(d),C=f}function $Le(){var s=0;return o[7976]|0||(eMe(10720),s=7976,n[s>>2]=1,n[s+4>>2]=0),10720}function eMe(s){s=s|0,Sl(s,tMe()|0,2)}function tMe(){return 1732}function rMe(s){return s=s|0,n[s>>2]|0}function H9(s){return s=s|0,n[s>>2]|0}function nMe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+32|0,m=f+16|0,d=f+8|0,B=f,Va(d),s=da(s)|0,n[B>>2]=n[l>>2],c=n[c>>2]|0,n[m>>2]=n[B>>2],j9(s,m,c),Ka(d),C=f}function j9(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+16|0,m=f+4|0,B=f,d=Pl(iMe()|0)|0,n[B>>2]=n[l>>2],n[m>>2]=n[B>>2],l=Qg(m)|0,oo(0,d|0,s|0,l|0,b9(c)|0)|0,C=f}function iMe(){var s=0;return o[7984]|0||(sMe(10732),s=7984,n[s>>2]=1,n[s+4>>2]=0),10732}function sMe(s){s=s|0,Sl(s,oMe()|0,2)}function oMe(){return 1744}function aMe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;f=C,C=C+32|0,m=f+16|0,d=f+8|0,B=f,Va(d),s=da(s)|0,n[B>>2]=n[l>>2],c=n[c>>2]|0,n[m>>2]=n[B>>2],j9(s,m,c),Ka(d),C=f}function lMe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;d=C,C=C+32|0,B=d+16|0,m=d+8|0,k=d,Va(m),s=da(s)|0,n[k>>2]=n[l>>2],c=o[c>>0]|0,f=o[f>>0]|0,n[B>>2]=n[k>>2],cMe(s,B,c,f),Ka(m),C=d}function cMe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;d=C,C=C+16|0,B=d+4|0,k=d,m=Pl(uMe()|0)|0,n[k>>2]=n[l>>2],n[B>>2]=n[k>>2],l=Qg(B)|0,c=Wm(c)|0,pc(0,m|0,s|0,l|0,c|0,Wm(f)|0)|0,C=d}function uMe(){var s=0;return o[7992]|0||(fMe(10744),s=7992,n[s>>2]=1,n[s+4>>2]=0),10744}function Wm(s){return s=s|0,AMe(s)|0}function AMe(s){return s=s|0,s&255|0}function fMe(s){s=s|0,Sl(s,pMe()|0,3)}function pMe(){return 1756}function hMe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;switch(se=C,C=C+32|0,k=se+8|0,Q=se+4|0,O=se+20|0,M=se,OF(s,0),f=AUe(l)|0,n[k>>2]=0,q=k+4|0,n[q>>2]=0,n[k+8>>2]=0,f<<24>>24){case 0:{o[O>>0]=0,gMe(Q,c,O),uD(s,Q)|0,qA(Q);break}case 8:{q=DT(l)|0,o[O>>0]=8,xc(M,n[q+4>>2]|0),dMe(Q,c,O,M,q+8|0),uD(s,Q)|0,qA(Q);break}case 9:{if(m=DT(l)|0,l=n[m+4>>2]|0,l|0)for(B=k+8|0,d=m+12|0;l=l+-1|0,xc(Q,n[d>>2]|0),f=n[q>>2]|0,f>>>0<(n[B>>2]|0)>>>0?(n[f>>2]=n[Q>>2],n[q>>2]=(n[q>>2]|0)+4):gT(k,Q),l;)d=d+4|0;o[O>>0]=9,xc(M,n[m+8>>2]|0),mMe(Q,c,O,M,k),uD(s,Q)|0,qA(Q);break}default:q=DT(l)|0,o[O>>0]=f,xc(M,n[q+4>>2]|0),yMe(Q,c,O,M),uD(s,Q)|0,qA(Q)}$A(k),C=se}function gMe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;f=C,C=C+16|0,d=f,Va(d),l=da(l)|0,QMe(s,l,o[c>>0]|0),Ka(d),C=f}function uD(s,l){s=s|0,l=l|0;var c=0;return c=n[s>>2]|0,c|0&&PA(c|0),n[s>>2]=n[l>>2],n[l>>2]=0,s|0}function dMe(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0;m=C,C=C+32|0,k=m+16|0,B=m+8|0,Q=m,Va(B),l=da(l)|0,c=o[c>>0]|0,n[Q>>2]=n[f>>2],d=n[d>>2]|0,n[k>>2]=n[Q>>2],SMe(s,l,c,k,d),Ka(B),C=m}function mMe(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0,O=0;m=C,C=C+32|0,Q=m+24|0,B=m+16|0,O=m+12|0,k=m,Va(B),l=da(l)|0,c=o[c>>0]|0,n[O>>2]=n[f>>2],mT(k,d),n[Q>>2]=n[O>>2],BMe(s,l,c,Q,k),$A(k),Ka(B),C=m}function yMe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;d=C,C=C+32|0,B=d+16|0,m=d+8|0,k=d,Va(m),l=da(l)|0,c=o[c>>0]|0,n[k>>2]=n[f>>2],n[B>>2]=n[k>>2],EMe(s,l,c,B),Ka(m),C=d}function EMe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0,B=0,k=0;d=C,C=C+16|0,m=d+4|0,k=d,B=Pl(CMe()|0)|0,c=Wm(c)|0,n[k>>2]=n[f>>2],n[m>>2]=n[k>>2],AD(s,oo(0,B|0,l|0,c|0,Qg(m)|0)|0),C=d}function CMe(){var s=0;return o[8e3]|0||(wMe(10756),s=8e3,n[s>>2]=1,n[s+4>>2]=0),10756}function AD(s,l){s=s|0,l=l|0,OF(s,l)}function wMe(s){s=s|0,Sl(s,IMe()|0,2)}function IMe(){return 1772}function BMe(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0,O=0;m=C,C=C+32|0,Q=m+16|0,O=m+12|0,B=m,k=Pl(vMe()|0)|0,c=Wm(c)|0,n[O>>2]=n[f>>2],n[Q>>2]=n[O>>2],f=Qg(Q)|0,n[B>>2]=n[d>>2],Q=d+4|0,n[B+4>>2]=n[Q>>2],O=d+8|0,n[B+8>>2]=n[O>>2],n[O>>2]=0,n[Q>>2]=0,n[d>>2]=0,AD(s,pc(0,k|0,l|0,c|0,f|0,ET(B)|0)|0),$A(B),C=m}function vMe(){var s=0;return o[8008]|0||(DMe(10768),s=8008,n[s>>2]=1,n[s+4>>2]=0),10768}function DMe(s){s=s|0,Sl(s,PMe()|0,3)}function PMe(){return 1784}function SMe(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0;m=C,C=C+16|0,k=m+4|0,Q=m,B=Pl(xMe()|0)|0,c=Wm(c)|0,n[Q>>2]=n[f>>2],n[k>>2]=n[Q>>2],f=Qg(k)|0,AD(s,pc(0,B|0,l|0,c|0,f|0,yT(d)|0)|0),C=m}function xMe(){var s=0;return o[8016]|0||(bMe(10780),s=8016,n[s>>2]=1,n[s+4>>2]=0),10780}function bMe(s){s=s|0,Sl(s,kMe()|0,3)}function kMe(){return 1800}function QMe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;f=Pl(FMe()|0)|0,AD(s,Qn(0,f|0,l|0,Wm(c)|0)|0)}function FMe(){var s=0;return o[8024]|0||(TMe(10792),s=8024,n[s>>2]=1,n[s+4>>2]=0),10792}function TMe(s){s=s|0,Sl(s,RMe()|0,1)}function RMe(){return 1816}function NMe(){LMe(),MMe(),OMe()}function LMe(){n[2702]=d7(65536)|0}function MMe(){iOe(10856)}function OMe(){UMe(10816)}function UMe(s){s=s|0,_Me(s,5044),HMe(s)|0}function _Me(s,l){s=s|0,l=l|0;var c=0;c=F9()|0,n[s>>2]=c,ZMe(c,l),xp(n[s>>2]|0)}function HMe(s){s=s|0;var l=0;return l=n[s>>2]|0,bg(l,jMe()|0),s|0}function jMe(){var s=0;return o[8032]|0||(q9(10820),tr(64,10820,U|0)|0,s=8032,n[s>>2]=1,n[s+4>>2]=0),Rr(10820)|0||q9(10820),10820}function q9(s){s=s|0,YMe(s),kg(s,25)}function qMe(s){s=s|0,GMe(s+24|0)}function GMe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function YMe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,5,18,l,JMe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function WMe(s,l){s=s|0,l=l|0,VMe(s,l)}function VMe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;c=C,C=C+16|0,f=c,d=c+4|0,Sg(d,l),n[f>>2]=xg(d,l)|0,KMe(s,f),C=c}function KMe(s,l){s=s|0,l=l|0,G9(s+4|0,n[l>>2]|0),o[s+8>>0]=1}function G9(s,l){s=s|0,l=l|0,n[s>>2]=l}function JMe(){return 1824}function zMe(s){return s=s|0,XMe(s)|0}function XMe(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0;return c=C,C=C+16|0,d=c+4|0,B=c,f=Wa(8)|0,l=f,k=Vt(4)|0,Sg(d,s),G9(k,xg(d,s)|0),m=l+4|0,n[m>>2]=k,s=Vt(8)|0,m=n[m>>2]|0,n[B>>2]=0,n[d>>2]=n[B>>2],T9(s,m,d),n[f>>2]=s,C=c,l|0}function Wa(s){s=s|0;var l=0,c=0;return s=s+7&-8,s>>>0<=32768&&(l=n[2701]|0,s>>>0<=(65536-l|0)>>>0)?(c=(n[2702]|0)+l|0,n[2701]=l+s,s=c):(s=d7(s+8|0)|0,n[s>>2]=n[2703],n[2703]=s,s=s+8|0),s|0}function ZMe(s,l){s=s|0,l=l|0,n[s>>2]=$Me()|0,n[s+4>>2]=eOe()|0,n[s+12>>2]=l,n[s+8>>2]=tOe()|0,n[s+32>>2]=9}function $Me(){return 11744}function eOe(){return 1832}function tOe(){return lD()|0}function rOe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Sp(f,896)|0)==512?c|0&&(nOe(c),gt(c)):l|0&>(l)}function nOe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function iOe(s){s=s|0,sOe(s,5052),oOe(s)|0,aOe(s,5058,26)|0,lOe(s,5069,1)|0,cOe(s,5077,10)|0,uOe(s,5087,19)|0,AOe(s,5094,27)|0}function sOe(s,l){s=s|0,l=l|0;var c=0;c=nUe()|0,n[s>>2]=c,iUe(c,l),xp(n[s>>2]|0)}function oOe(s){s=s|0;var l=0;return l=n[s>>2]|0,bg(l,q4e()|0),s|0}function aOe(s,l,c){return s=s|0,l=l|0,c=c|0,D4e(s,pn(l)|0,c,0),s|0}function lOe(s,l,c){return s=s|0,l=l|0,c=c|0,u4e(s,pn(l)|0,c,0),s|0}function cOe(s,l,c){return s=s|0,l=l|0,c=c|0,jOe(s,pn(l)|0,c,0),s|0}function uOe(s,l,c){return s=s|0,l=l|0,c=c|0,SOe(s,pn(l)|0,c,0),s|0}function Y9(s,l){s=s|0,l=l|0;var c=0,f=0;e:for(;;){for(c=n[2703]|0;;){if((c|0)==(l|0))break e;if(f=n[c>>2]|0,n[2703]=f,!c)c=f;else break}gt(c)}n[2701]=s}function AOe(s,l,c){return s=s|0,l=l|0,c=c|0,fOe(s,pn(l)|0,c,0),s|0}function fOe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=CT()|0,s=pOe(c)|0,hn(m,l,d,s,hOe(c,f)|0,f)}function CT(){var s=0,l=0;if(o[8040]|0||(V9(10860),tr(65,10860,U|0)|0,l=8040,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10860)|0)){s=10860,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));V9(10860)}return 10860}function pOe(s){return s=s|0,s|0}function hOe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=CT()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(W9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(gOe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function W9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function gOe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=dOe(s)|0,f>>>0<B>>>0)zr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,mOe(d,M>>3>>>0<f>>>1>>>0?O>>>0<B>>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,W9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,yOe(s,d),EOe(d),C=k;return}}function dOe(s){return s=s|0,536870911}function mOe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Vt(l<<3)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function yOe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function EOe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function V9(s){s=s|0,IOe(s)}function COe(s){s=s|0,wOe(s+24|0)}function wOe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function IOe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,1,11,l,BOe()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function BOe(){return 1840}function vOe(s,l,c){s=s|0,l=l|0,c=c|0,POe(n[(DOe(s)|0)>>2]|0,l,c)}function DOe(s){return s=s|0,(n[(CT()|0)+24>>2]|0)+(s<<3)|0}function POe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;f=C,C=C+16|0,m=f+1|0,d=f,Sg(m,l),l=xg(m,l)|0,Sg(d,c),c=xg(d,c)|0,tf[s&31](l,c),C=f}function SOe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=wT()|0,s=xOe(c)|0,hn(m,l,d,s,bOe(c,f)|0,f)}function wT(){var s=0,l=0;if(o[8048]|0||(J9(10896),tr(66,10896,U|0)|0,l=8048,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10896)|0)){s=10896,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));J9(10896)}return 10896}function xOe(s){return s=s|0,s|0}function bOe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=wT()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(K9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(kOe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function K9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function kOe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=QOe(s)|0,f>>>0<B>>>0)zr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,FOe(d,M>>3>>>0<f>>>1>>>0?O>>>0<B>>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,K9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,TOe(s,d),ROe(d),C=k;return}}function QOe(s){return s=s|0,536870911}function FOe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Vt(l<<3)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function TOe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function ROe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function J9(s){s=s|0,MOe(s)}function NOe(s){s=s|0,LOe(s+24|0)}function LOe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function MOe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,1,11,l,OOe()|0,1),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function OOe(){return 1852}function UOe(s,l){return s=s|0,l=l|0,HOe(n[(_Oe(s)|0)>>2]|0,l)|0}function _Oe(s){return s=s|0,(n[(wT()|0)+24>>2]|0)+(s<<3)|0}function HOe(s,l){s=s|0,l=l|0;var c=0,f=0;return c=C,C=C+16|0,f=c,Sg(f,l),l=xg(f,l)|0,l=oD(Ng[s&31](l)|0)|0,C=c,l|0}function jOe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=IT()|0,s=qOe(c)|0,hn(m,l,d,s,GOe(c,f)|0,f)}function IT(){var s=0,l=0;if(o[8056]|0||(X9(10932),tr(67,10932,U|0)|0,l=8056,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10932)|0)){s=10932,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));X9(10932)}return 10932}function qOe(s){return s=s|0,s|0}function GOe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=IT()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(z9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(YOe(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function z9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function YOe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=WOe(s)|0,f>>>0<B>>>0)zr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,VOe(d,M>>3>>>0<f>>>1>>>0?O>>>0<B>>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,z9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,KOe(s,d),JOe(d),C=k;return}}function WOe(s){return s=s|0,536870911}function VOe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Vt(l<<3)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function KOe(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function JOe(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function X9(s){s=s|0,ZOe(s)}function zOe(s){s=s|0,XOe(s+24|0)}function XOe(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function ZOe(s){s=s|0;var l=0;l=Vr()|0,Kr(s,1,7,l,$Oe()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function $Oe(){return 1860}function e4e(s,l,c){return s=s|0,l=l|0,c=c|0,r4e(n[(t4e(s)|0)>>2]|0,l,c)|0}function t4e(s){return s=s|0,(n[(IT()|0)+24>>2]|0)+(s<<3)|0}function r4e(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0;return f=C,C=C+32|0,B=f+12|0,m=f+8|0,k=f,Q=f+16|0,d=f+4|0,n4e(Q,l),i4e(k,Q,l),vp(d,c),c=Dp(d,c)|0,n[B>>2]=n[k>>2],_w[s&15](m,B,c),c=s4e(m)|0,qA(m),Pp(d),C=f,c|0}function n4e(s,l){s=s|0,l=l|0}function i4e(s,l,c){s=s|0,l=l|0,c=c|0,o4e(s,c)}function s4e(s){return s=s|0,da(s)|0}function o4e(s,l){s=s|0,l=l|0;var c=0,f=0,d=0;d=C,C=C+16|0,c=d,f=l,f&1?(a4e(c,0),ii(f|0,c|0)|0,l4e(s,c),c4e(c)):n[s>>2]=n[l>>2],C=d}function a4e(s,l){s=s|0,l=l|0,e5(s,l),n[s+4>>2]=0,o[s+8>>0]=0}function l4e(s,l){s=s|0,l=l|0,n[s>>2]=n[l+4>>2]}function c4e(s){s=s|0,o[s+8>>0]=0}function u4e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=BT()|0,s=A4e(c)|0,hn(m,l,d,s,f4e(c,f)|0,f)}function BT(){var s=0,l=0;if(o[8064]|0||($9(10968),tr(68,10968,U|0)|0,l=8064,n[l>>2]=1,n[l+4>>2]=0),!(Rr(10968)|0)){s=10968,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));$9(10968)}return 10968}function A4e(s){return s=s|0,s|0}function f4e(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=BT()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(Z9(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(p4e(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function Z9(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function p4e(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=h4e(s)|0,f>>>0<B>>>0)zr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,g4e(d,M>>3>>>0<f>>>1>>>0?O>>>0<B>>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,Z9(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,d4e(s,d),m4e(d),C=k;return}}function h4e(s){return s=s|0,536870911}function g4e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Vt(l<<3)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function d4e(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function m4e(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function $9(s){s=s|0,C4e(s)}function y4e(s){s=s|0,E4e(s+24|0)}function E4e(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function C4e(s){s=s|0;var l=0;l=Vr()|0,Kr(s,1,1,l,w4e()|0,5),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function w4e(){return 1872}function I4e(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,v4e(n[(B4e(s)|0)>>2]|0,l,c,f,d,m)}function B4e(s){return s=s|0,(n[(BT()|0)+24>>2]|0)+(s<<3)|0}function v4e(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0;var B=0,k=0,Q=0,O=0,M=0,q=0;B=C,C=C+32|0,k=B+16|0,Q=B+12|0,O=B+8|0,M=B+4|0,q=B,vp(k,l),l=Dp(k,l)|0,vp(Q,c),c=Dp(Q,c)|0,vp(O,f),f=Dp(O,f)|0,vp(M,d),d=Dp(M,d)|0,vp(q,m),m=Dp(q,m)|0,w7[s&1](l,c,f,d,m),Pp(q),Pp(M),Pp(O),Pp(Q),Pp(k),C=B}function D4e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;m=n[s>>2]|0,d=vT()|0,s=P4e(c)|0,hn(m,l,d,s,S4e(c,f)|0,f)}function vT(){var s=0,l=0;if(o[8072]|0||(t7(11004),tr(69,11004,U|0)|0,l=8072,n[l>>2]=1,n[l+4>>2]=0),!(Rr(11004)|0)){s=11004,l=s+36|0;do n[s>>2]=0,s=s+4|0;while((s|0)<(l|0));t7(11004)}return 11004}function P4e(s){return s=s|0,s|0}function S4e(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0,k=0,Q=0;return k=C,C=C+16|0,d=k,m=k+4|0,n[d>>2]=s,Q=vT()|0,B=Q+24|0,l=gr(l,4)|0,n[m>>2]=l,c=Q+28|0,f=n[c>>2]|0,f>>>0<(n[Q+32>>2]|0)>>>0?(e7(f,s,l),l=(n[c>>2]|0)+8|0,n[c>>2]=l):(x4e(B,d,m),l=n[c>>2]|0),C=k,(l-(n[B>>2]|0)>>3)+-1|0}function e7(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,n[s+4>>2]=c}function x4e(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0;if(k=C,C=C+32|0,d=k,m=s+4|0,B=((n[m>>2]|0)-(n[s>>2]|0)>>3)+1|0,f=b4e(s)|0,f>>>0<B>>>0)zr(s);else{Q=n[s>>2]|0,M=(n[s+8>>2]|0)-Q|0,O=M>>2,k4e(d,M>>3>>>0<f>>>1>>>0?O>>>0<B>>>0?B:O:f,(n[m>>2]|0)-Q>>3,s+8|0),B=d+8|0,e7(n[B>>2]|0,n[l>>2]|0,n[c>>2]|0),n[B>>2]=(n[B>>2]|0)+8,Q4e(s,d),F4e(d),C=k;return}}function b4e(s){return s=s|0,536870911}function k4e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0;n[s+12>>2]=0,n[s+16>>2]=f;do if(l)if(l>>>0>536870911)Tt();else{d=Vt(l<<3)|0;break}else d=0;while(0);n[s>>2]=d,f=d+(c<<3)|0,n[s+8>>2]=f,n[s+4>>2]=f,n[s+12>>2]=d+(l<<3)}function Q4e(s,l){s=s|0,l=l|0;var c=0,f=0,d=0,m=0,B=0;f=n[s>>2]|0,B=s+4|0,m=l+4|0,d=(n[B>>2]|0)-f|0,c=(n[m>>2]|0)+(0-(d>>3)<<3)|0,n[m>>2]=c,(d|0)>0?(Dr(c|0,f|0,d|0)|0,f=m,c=n[m>>2]|0):f=m,m=n[s>>2]|0,n[s>>2]=c,n[f>>2]=m,m=l+8|0,d=n[B>>2]|0,n[B>>2]=n[m>>2],n[m>>2]=d,m=s+8|0,B=l+12|0,s=n[m>>2]|0,n[m>>2]=n[B>>2],n[B>>2]=s,n[l>>2]=n[f>>2]}function F4e(s){s=s|0;var l=0,c=0,f=0;l=n[s+4>>2]|0,c=s+8|0,f=n[c>>2]|0,(f|0)!=(l|0)&&(n[c>>2]=f+(~((f+-8-l|0)>>>3)<<3)),s=n[s>>2]|0,s|0&>(s)}function t7(s){s=s|0,N4e(s)}function T4e(s){s=s|0,R4e(s+24|0)}function R4e(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function N4e(s){s=s|0;var l=0;l=Vr()|0,Kr(s,1,12,l,L4e()|0,2),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function L4e(){return 1896}function M4e(s,l,c){s=s|0,l=l|0,c=c|0,U4e(n[(O4e(s)|0)>>2]|0,l,c)}function O4e(s){return s=s|0,(n[(vT()|0)+24>>2]|0)+(s<<3)|0}function U4e(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;f=C,C=C+16|0,m=f+4|0,d=f,_4e(m,l),l=H4e(m,l)|0,vp(d,c),c=Dp(d,c)|0,tf[s&31](l,c),Pp(d),C=f}function _4e(s,l){s=s|0,l=l|0}function H4e(s,l){return s=s|0,l=l|0,j4e(l)|0}function j4e(s){return s=s|0,s|0}function q4e(){var s=0;return o[8080]|0||(r7(11040),tr(70,11040,U|0)|0,s=8080,n[s>>2]=1,n[s+4>>2]=0),Rr(11040)|0||r7(11040),11040}function r7(s){s=s|0,W4e(s),kg(s,71)}function G4e(s){s=s|0,Y4e(s+24|0)}function Y4e(s){s=s|0;var l=0,c=0,f=0;c=n[s>>2]|0,f=c,c|0&&(s=s+4|0,l=n[s>>2]|0,(l|0)!=(c|0)&&(n[s>>2]=l+(~((l+-8-f|0)>>>3)<<3)),gt(c))}function W4e(s){s=s|0;var l=0;l=Vr()|0,Kr(s,5,7,l,z4e()|0,0),n[s+24>>2]=0,n[s+28>>2]=0,n[s+32>>2]=0}function V4e(s){s=s|0,K4e(s)}function K4e(s){s=s|0,J4e(s)}function J4e(s){s=s|0,o[s+8>>0]=1}function z4e(){return 1936}function X4e(){return Z4e()|0}function Z4e(){var s=0,l=0,c=0,f=0,d=0,m=0,B=0;return l=C,C=C+16|0,d=l+4|0,B=l,c=Wa(8)|0,s=c,m=s+4|0,n[m>>2]=Vt(1)|0,f=Vt(8)|0,m=n[m>>2]|0,n[B>>2]=0,n[d>>2]=n[B>>2],$4e(f,m,d),n[c>>2]=f,C=l,s|0}function $4e(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]=l,c=Vt(16)|0,n[c+4>>2]=0,n[c+8>>2]=0,n[c>>2]=1916,n[c+12>>2]=l,n[s+4>>2]=c}function eUe(s){s=s|0,Jm(s),gt(s)}function tUe(s){s=s|0,s=n[s+12>>2]|0,s|0&>(s)}function rUe(s){s=s|0,gt(s)}function nUe(){var s=0;return o[8088]|0||(uUe(11076),tr(25,11076,U|0)|0,s=8088,n[s>>2]=1,n[s+4>>2]=0),11076}function iUe(s,l){s=s|0,l=l|0,n[s>>2]=sUe()|0,n[s+4>>2]=oUe()|0,n[s+12>>2]=l,n[s+8>>2]=aUe()|0,n[s+32>>2]=10}function sUe(){return 11745}function oUe(){return 1940}function aUe(){return aD()|0}function lUe(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,(Sp(f,896)|0)==512?c|0&&(cUe(c),gt(c)):l|0&>(l)}function cUe(s){s=s|0,s=n[s+4>>2]|0,s|0&&bp(s)}function uUe(s){s=s|0,Bp(s)}function xc(s,l){s=s|0,l=l|0,n[s>>2]=l}function DT(s){return s=s|0,n[s>>2]|0}function AUe(s){return s=s|0,o[n[s>>2]>>0]|0}function fUe(s,l){s=s|0,l=l|0;var c=0,f=0;c=C,C=C+16|0,f=c,n[f>>2]=n[s>>2],pUe(l,f)|0,C=c}function pUe(s,l){s=s|0,l=l|0;var c=0;return c=hUe(n[s>>2]|0,l)|0,l=s+4|0,n[(n[l>>2]|0)+8>>2]=c,n[(n[l>>2]|0)+8>>2]|0}function hUe(s,l){s=s|0,l=l|0;var c=0,f=0;return c=C,C=C+16|0,f=c,Va(f),s=da(s)|0,l=gUe(s,n[l>>2]|0)|0,Ka(f),C=c,l|0}function Va(s){s=s|0,n[s>>2]=n[2701],n[s+4>>2]=n[2703]}function gUe(s,l){s=s|0,l=l|0;var c=0;return c=Pl(dUe()|0)|0,Qn(0,c|0,s|0,yT(l)|0)|0}function Ka(s){s=s|0,Y9(n[s>>2]|0,n[s+4>>2]|0)}function dUe(){var s=0;return o[8096]|0||(mUe(11120),s=8096,n[s>>2]=1,n[s+4>>2]=0),11120}function mUe(s){s=s|0,Sl(s,yUe()|0,1)}function yUe(){return 1948}function EUe(){CUe()}function CUe(){var s=0,l=0,c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0,Ge=0,Oe=0,Fe=0;if(Oe=C,C=C+16|0,M=Oe+4|0,q=Oe,Ni(65536,10804,n[2702]|0,10812),c=P9()|0,l=n[c>>2]|0,s=n[l>>2]|0,s|0)for(f=n[c+8>>2]|0,c=n[c+4>>2]|0;uc(s|0,u[c>>0]|0|0,o[f>>0]|0),l=l+4|0,s=n[l>>2]|0,s;)f=f+1|0,c=c+1|0;if(s=S9()|0,l=n[s>>2]|0,l|0)do uu(l|0,n[s+4>>2]|0),s=s+8|0,l=n[s>>2]|0;while((l|0)!=0);uu(wUe()|0,5167),O=Gm()|0,s=n[O>>2]|0;e:do if(s|0){do IUe(n[s+4>>2]|0),s=n[s>>2]|0;while((s|0)!=0);if(s=n[O>>2]|0,s|0){Q=O;do{for(;d=s,s=n[s>>2]|0,d=n[d+4>>2]|0,!!(BUe(d)|0);)if(n[q>>2]=Q,n[M>>2]=n[q>>2],vUe(O,M)|0,!s)break e;if(DUe(d),Q=n[Q>>2]|0,l=n7(d)|0,m=Hi()|0,B=C,C=C+((1*(l<<2)|0)+15&-16)|0,k=C,C=C+((1*(l<<2)|0)+15&-16)|0,l=n[(U9(d)|0)>>2]|0,l|0)for(c=B,f=k;n[c>>2]=n[(Ym(n[l+4>>2]|0)|0)>>2],n[f>>2]=n[l+8>>2],l=n[l>>2]|0,l;)c=c+4|0,f=f+4|0;Fe=Ym(d)|0,l=PUe(d)|0,c=n7(d)|0,f=SUe(d)|0,Au(Fe|0,l|0,B|0,k|0,c|0,f|0,fT(d)|0),_i(m|0)}while((s|0)!=0)}}while(0);if(s=n[(pT()|0)>>2]|0,s|0)do Fe=s+4|0,O=hT(Fe)|0,d=Lw(O)|0,m=Rw(O)|0,B=(Nw(O)|0)+1|0,k=fD(O)|0,Q=i7(Fe)|0,O=Rr(O)|0,M=cD(Fe)|0,q=PT(Fe)|0,El(0,d|0,m|0,B|0,k|0,Q|0,O|0,M|0,q|0,ST(Fe)|0),s=n[s>>2]|0;while((s|0)!=0);s=n[(Gm()|0)>>2]|0;e:do if(s|0){t:for(;;){if(l=n[s+4>>2]|0,l|0&&(se=n[(Ym(l)|0)>>2]|0,Ge=n[(_9(l)|0)>>2]|0,Ge|0)){c=Ge;do{l=c+4|0,f=hT(l)|0;r:do if(f|0)switch(Rr(f)|0){case 0:break t;case 4:case 3:case 2:{k=Lw(f)|0,Q=Rw(f)|0,O=(Nw(f)|0)+1|0,M=fD(f)|0,q=Rr(f)|0,Fe=cD(l)|0,El(se|0,k|0,Q|0,O|0,M|0,0,q|0,Fe|0,PT(l)|0,ST(l)|0);break r}case 1:{B=Lw(f)|0,k=Rw(f)|0,Q=(Nw(f)|0)+1|0,O=fD(f)|0,M=i7(l)|0,q=Rr(f)|0,Fe=cD(l)|0,El(se|0,B|0,k|0,Q|0,O|0,M|0,q|0,Fe|0,PT(l)|0,ST(l)|0);break r}case 5:{O=Lw(f)|0,M=Rw(f)|0,q=(Nw(f)|0)+1|0,Fe=fD(f)|0,El(se|0,O|0,M|0,q|0,Fe|0,xUe(f)|0,Rr(f)|0,0,0,0);break r}default:break r}while(0);c=n[c>>2]|0}while((c|0)!=0)}if(s=n[s>>2]|0,!s)break e}Tt()}while(0);Ce(),C=Oe}function wUe(){return 11703}function IUe(s){s=s|0,o[s+40>>0]=0}function BUe(s){return s=s|0,(o[s+40>>0]|0)!=0|0}function vUe(s,l){return s=s|0,l=l|0,l=bUe(l)|0,s=n[l>>2]|0,n[l>>2]=n[s>>2],gt(s),n[l>>2]|0}function DUe(s){s=s|0,o[s+40>>0]=1}function n7(s){return s=s|0,n[s+20>>2]|0}function PUe(s){return s=s|0,n[s+8>>2]|0}function SUe(s){return s=s|0,n[s+32>>2]|0}function fD(s){return s=s|0,n[s+4>>2]|0}function i7(s){return s=s|0,n[s+4>>2]|0}function PT(s){return s=s|0,n[s+8>>2]|0}function ST(s){return s=s|0,n[s+16>>2]|0}function xUe(s){return s=s|0,n[s+20>>2]|0}function bUe(s){return s=s|0,n[s>>2]|0}function pD(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0,Ge=0,Oe=0,Fe=0,et=0,Xe=0,at=0,Ue=0,qe=0,Lt=0;Lt=C,C=C+16|0,se=Lt;do if(s>>>0<245){if(O=s>>>0<11?16:s+11&-8,s=O>>>3,q=n[2783]|0,c=q>>>s,c&3|0)return l=(c&1^1)+s|0,s=11172+(l<<1<<2)|0,c=s+8|0,f=n[c>>2]|0,d=f+8|0,m=n[d>>2]|0,(s|0)==(m|0)?n[2783]=q&~(1<<l):(n[m+12>>2]=s,n[c>>2]=m),qe=l<<3,n[f+4>>2]=qe|3,qe=f+qe+4|0,n[qe>>2]=n[qe>>2]|1,qe=d,C=Lt,qe|0;if(M=n[2785]|0,O>>>0>M>>>0){if(c|0)return l=2<<s,l=c<<s&(l|0-l),l=(l&0-l)+-1|0,B=l>>>12&16,l=l>>>B,c=l>>>5&8,l=l>>>c,d=l>>>2&4,l=l>>>d,s=l>>>1&2,l=l>>>s,f=l>>>1&1,f=(c|B|d|s|f)+(l>>>f)|0,l=11172+(f<<1<<2)|0,s=l+8|0,d=n[s>>2]|0,B=d+8|0,c=n[B>>2]|0,(l|0)==(c|0)?(s=q&~(1<<f),n[2783]=s):(n[c+12>>2]=l,n[s>>2]=c,s=q),m=(f<<3)-O|0,n[d+4>>2]=O|3,f=d+O|0,n[f+4>>2]=m|1,n[f+m>>2]=m,M|0&&(d=n[2788]|0,l=M>>>3,c=11172+(l<<1<<2)|0,l=1<<l,s&l?(s=c+8|0,l=n[s>>2]|0):(n[2783]=s|l,l=c,s=c+8|0),n[s>>2]=d,n[l+12>>2]=d,n[d+8>>2]=l,n[d+12>>2]=c),n[2785]=m,n[2788]=f,qe=B,C=Lt,qe|0;if(k=n[2784]|0,k){if(c=(k&0-k)+-1|0,B=c>>>12&16,c=c>>>B,m=c>>>5&8,c=c>>>m,Q=c>>>2&4,c=c>>>Q,f=c>>>1&2,c=c>>>f,s=c>>>1&1,s=n[11436+((m|B|Q|f|s)+(c>>>s)<<2)>>2]|0,c=(n[s+4>>2]&-8)-O|0,f=n[s+16+(((n[s+16>>2]|0)==0&1)<<2)>>2]|0,!f)Q=s,m=c;else{do B=(n[f+4>>2]&-8)-O|0,Q=B>>>0<c>>>0,c=Q?B:c,s=Q?f:s,f=n[f+16+(((n[f+16>>2]|0)==0&1)<<2)>>2]|0;while((f|0)!=0);Q=s,m=c}if(B=Q+O|0,Q>>>0<B>>>0){d=n[Q+24>>2]|0,l=n[Q+12>>2]|0;do if((l|0)==(Q|0)){if(s=Q+20|0,l=n[s>>2]|0,!l&&(s=Q+16|0,l=n[s>>2]|0,!l)){c=0;break}for(;;){if(c=l+20|0,f=n[c>>2]|0,f|0){l=f,s=c;continue}if(c=l+16|0,f=n[c>>2]|0,f)l=f,s=c;else break}n[s>>2]=0,c=l}else c=n[Q+8>>2]|0,n[c+12>>2]=l,n[l+8>>2]=c,c=l;while(0);do if(d|0){if(l=n[Q+28>>2]|0,s=11436+(l<<2)|0,(Q|0)==(n[s>>2]|0)){if(n[s>>2]=c,!c){n[2784]=k&~(1<<l);break}}else if(n[d+16+(((n[d+16>>2]|0)!=(Q|0)&1)<<2)>>2]=c,!c)break;n[c+24>>2]=d,l=n[Q+16>>2]|0,l|0&&(n[c+16>>2]=l,n[l+24>>2]=c),l=n[Q+20>>2]|0,l|0&&(n[c+20>>2]=l,n[l+24>>2]=c)}while(0);return m>>>0<16?(qe=m+O|0,n[Q+4>>2]=qe|3,qe=Q+qe+4|0,n[qe>>2]=n[qe>>2]|1):(n[Q+4>>2]=O|3,n[B+4>>2]=m|1,n[B+m>>2]=m,M|0&&(f=n[2788]|0,l=M>>>3,c=11172+(l<<1<<2)|0,l=1<<l,q&l?(s=c+8|0,l=n[s>>2]|0):(n[2783]=q|l,l=c,s=c+8|0),n[s>>2]=f,n[l+12>>2]=f,n[f+8>>2]=l,n[f+12>>2]=c),n[2785]=m,n[2788]=B),qe=Q+8|0,C=Lt,qe|0}else q=O}else q=O}else q=O}else if(s>>>0<=4294967231)if(s=s+11|0,O=s&-8,Q=n[2784]|0,Q){f=0-O|0,s=s>>>8,s?O>>>0>16777215?k=31:(q=(s+1048320|0)>>>16&8,Ue=s<<q,M=(Ue+520192|0)>>>16&4,Ue=Ue<<M,k=(Ue+245760|0)>>>16&2,k=14-(M|q|k)+(Ue<<k>>>15)|0,k=O>>>(k+7|0)&1|k<<1):k=0,c=n[11436+(k<<2)>>2]|0;e:do if(!c)c=0,s=0,Ue=57;else for(s=0,B=O<<((k|0)==31?0:25-(k>>>1)|0),m=0;;){if(d=(n[c+4>>2]&-8)-O|0,d>>>0<f>>>0)if(d)s=c,f=d;else{s=c,f=0,d=c,Ue=61;break e}if(d=n[c+20>>2]|0,c=n[c+16+(B>>>31<<2)>>2]|0,m=(d|0)==0|(d|0)==(c|0)?m:d,d=(c|0)==0,d){c=m,Ue=57;break}else B=B<<((d^1)&1)}while(0);if((Ue|0)==57){if((c|0)==0&(s|0)==0){if(s=2<<k,s=Q&(s|0-s),!s){q=O;break}q=(s&0-s)+-1|0,B=q>>>12&16,q=q>>>B,m=q>>>5&8,q=q>>>m,k=q>>>2&4,q=q>>>k,M=q>>>1&2,q=q>>>M,c=q>>>1&1,s=0,c=n[11436+((m|B|k|M|c)+(q>>>c)<<2)>>2]|0}c?(d=c,Ue=61):(k=s,B=f)}if((Ue|0)==61)for(;;)if(Ue=0,c=(n[d+4>>2]&-8)-O|0,q=c>>>0<f>>>0,c=q?c:f,s=q?d:s,d=n[d+16+(((n[d+16>>2]|0)==0&1)<<2)>>2]|0,d)f=c,Ue=61;else{k=s,B=c;break}if((k|0)!=0&&B>>>0<((n[2785]|0)-O|0)>>>0){if(m=k+O|0,k>>>0>=m>>>0)return qe=0,C=Lt,qe|0;d=n[k+24>>2]|0,l=n[k+12>>2]|0;do if((l|0)==(k|0)){if(s=k+20|0,l=n[s>>2]|0,!l&&(s=k+16|0,l=n[s>>2]|0,!l)){l=0;break}for(;;){if(c=l+20|0,f=n[c>>2]|0,f|0){l=f,s=c;continue}if(c=l+16|0,f=n[c>>2]|0,f)l=f,s=c;else break}n[s>>2]=0}else qe=n[k+8>>2]|0,n[qe+12>>2]=l,n[l+8>>2]=qe;while(0);do if(d){if(s=n[k+28>>2]|0,c=11436+(s<<2)|0,(k|0)==(n[c>>2]|0)){if(n[c>>2]=l,!l){f=Q&~(1<<s),n[2784]=f;break}}else if(n[d+16+(((n[d+16>>2]|0)!=(k|0)&1)<<2)>>2]=l,!l){f=Q;break}n[l+24>>2]=d,s=n[k+16>>2]|0,s|0&&(n[l+16>>2]=s,n[s+24>>2]=l),s=n[k+20>>2]|0,s&&(n[l+20>>2]=s,n[s+24>>2]=l),f=Q}else f=Q;while(0);do if(B>>>0>=16){if(n[k+4>>2]=O|3,n[m+4>>2]=B|1,n[m+B>>2]=B,l=B>>>3,B>>>0<256){c=11172+(l<<1<<2)|0,s=n[2783]|0,l=1<<l,s&l?(s=c+8|0,l=n[s>>2]|0):(n[2783]=s|l,l=c,s=c+8|0),n[s>>2]=m,n[l+12>>2]=m,n[m+8>>2]=l,n[m+12>>2]=c;break}if(l=B>>>8,l?B>>>0>16777215?l=31:(Ue=(l+1048320|0)>>>16&8,qe=l<<Ue,at=(qe+520192|0)>>>16&4,qe=qe<<at,l=(qe+245760|0)>>>16&2,l=14-(at|Ue|l)+(qe<<l>>>15)|0,l=B>>>(l+7|0)&1|l<<1):l=0,c=11436+(l<<2)|0,n[m+28>>2]=l,s=m+16|0,n[s+4>>2]=0,n[s>>2]=0,s=1<<l,!(f&s)){n[2784]=f|s,n[c>>2]=m,n[m+24>>2]=c,n[m+12>>2]=m,n[m+8>>2]=m;break}for(s=B<<((l|0)==31?0:25-(l>>>1)|0),c=n[c>>2]|0;;){if((n[c+4>>2]&-8|0)==(B|0)){Ue=97;break}if(f=c+16+(s>>>31<<2)|0,l=n[f>>2]|0,l)s=s<<1,c=l;else{Ue=96;break}}if((Ue|0)==96){n[f>>2]=m,n[m+24>>2]=c,n[m+12>>2]=m,n[m+8>>2]=m;break}else if((Ue|0)==97){Ue=c+8|0,qe=n[Ue>>2]|0,n[qe+12>>2]=m,n[Ue>>2]=m,n[m+8>>2]=qe,n[m+12>>2]=c,n[m+24>>2]=0;break}}else qe=B+O|0,n[k+4>>2]=qe|3,qe=k+qe+4|0,n[qe>>2]=n[qe>>2]|1;while(0);return qe=k+8|0,C=Lt,qe|0}else q=O}else q=O;else q=-1;while(0);if(c=n[2785]|0,c>>>0>=q>>>0)return l=c-q|0,s=n[2788]|0,l>>>0>15?(qe=s+q|0,n[2788]=qe,n[2785]=l,n[qe+4>>2]=l|1,n[qe+l>>2]=l,n[s+4>>2]=q|3):(n[2785]=0,n[2788]=0,n[s+4>>2]=c|3,qe=s+c+4|0,n[qe>>2]=n[qe>>2]|1),qe=s+8|0,C=Lt,qe|0;if(B=n[2786]|0,B>>>0>q>>>0)return at=B-q|0,n[2786]=at,qe=n[2789]|0,Ue=qe+q|0,n[2789]=Ue,n[Ue+4>>2]=at|1,n[qe+4>>2]=q|3,qe=qe+8|0,C=Lt,qe|0;if(n[2901]|0?s=n[2903]|0:(n[2903]=4096,n[2902]=4096,n[2904]=-1,n[2905]=-1,n[2906]=0,n[2894]=0,s=se&-16^1431655768,n[se>>2]=s,n[2901]=s,s=4096),k=q+48|0,Q=q+47|0,m=s+Q|0,d=0-s|0,O=m&d,O>>>0<=q>>>0||(s=n[2893]|0,s|0&&(M=n[2891]|0,se=M+O|0,se>>>0<=M>>>0|se>>>0>s>>>0)))return qe=0,C=Lt,qe|0;e:do if(n[2894]&4)l=0,Ue=133;else{c=n[2789]|0;t:do if(c){for(f=11580;s=n[f>>2]|0,!(s>>>0<=c>>>0&&(Fe=f+4|0,(s+(n[Fe>>2]|0)|0)>>>0>c>>>0));)if(s=n[f+8>>2]|0,s)f=s;else{Ue=118;break t}if(l=m-B&d,l>>>0<2147483647)if(s=kp(l|0)|0,(s|0)==((n[f>>2]|0)+(n[Fe>>2]|0)|0)){if((s|0)!=-1){B=l,m=s,Ue=135;break e}}else f=s,Ue=126;else l=0}else Ue=118;while(0);do if((Ue|0)==118)if(c=kp(0)|0,(c|0)!=-1&&(l=c,Ge=n[2902]|0,Oe=Ge+-1|0,l=((Oe&l|0)==0?0:(Oe+l&0-Ge)-l|0)+O|0,Ge=n[2891]|0,Oe=l+Ge|0,l>>>0>q>>>0&l>>>0<2147483647)){if(Fe=n[2893]|0,Fe|0&&Oe>>>0<=Ge>>>0|Oe>>>0>Fe>>>0){l=0;break}if(s=kp(l|0)|0,(s|0)==(c|0)){B=l,m=c,Ue=135;break e}else f=s,Ue=126}else l=0;while(0);do if((Ue|0)==126){if(c=0-l|0,!(k>>>0>l>>>0&(l>>>0<2147483647&(f|0)!=-1)))if((f|0)==-1){l=0;break}else{B=l,m=f,Ue=135;break e}if(s=n[2903]|0,s=Q-l+s&0-s,s>>>0>=2147483647){B=l,m=f,Ue=135;break e}if((kp(s|0)|0)==-1){kp(c|0)|0,l=0;break}else{B=s+l|0,m=f,Ue=135;break e}}while(0);n[2894]=n[2894]|4,Ue=133}while(0);if((Ue|0)==133&&O>>>0<2147483647&&(at=kp(O|0)|0,Fe=kp(0)|0,et=Fe-at|0,Xe=et>>>0>(q+40|0)>>>0,!((at|0)==-1|Xe^1|at>>>0<Fe>>>0&((at|0)!=-1&(Fe|0)!=-1)^1))&&(B=Xe?et:l,m=at,Ue=135),(Ue|0)==135){l=(n[2891]|0)+B|0,n[2891]=l,l>>>0>(n[2892]|0)>>>0&&(n[2892]=l),Q=n[2789]|0;do if(Q){for(l=11580;;){if(s=n[l>>2]|0,c=l+4|0,f=n[c>>2]|0,(m|0)==(s+f|0)){Ue=145;break}if(d=n[l+8>>2]|0,d)l=d;else break}if((Ue|0)==145&&(n[l+12>>2]&8|0)==0&&Q>>>0<m>>>0&Q>>>0>=s>>>0){n[c>>2]=f+B,qe=Q+8|0,qe=(qe&7|0)==0?0:0-qe&7,Ue=Q+qe|0,qe=(n[2786]|0)+(B-qe)|0,n[2789]=Ue,n[2786]=qe,n[Ue+4>>2]=qe|1,n[Ue+qe+4>>2]=40,n[2790]=n[2905];break}for(m>>>0<(n[2787]|0)>>>0&&(n[2787]=m),c=m+B|0,l=11580;;){if((n[l>>2]|0)==(c|0)){Ue=153;break}if(s=n[l+8>>2]|0,s)l=s;else break}if((Ue|0)==153&&(n[l+12>>2]&8|0)==0){n[l>>2]=m,M=l+4|0,n[M>>2]=(n[M>>2]|0)+B,M=m+8|0,M=m+((M&7|0)==0?0:0-M&7)|0,l=c+8|0,l=c+((l&7|0)==0?0:0-l&7)|0,O=M+q|0,k=l-M-q|0,n[M+4>>2]=q|3;do if((l|0)!=(Q|0)){if((l|0)==(n[2788]|0)){qe=(n[2785]|0)+k|0,n[2785]=qe,n[2788]=O,n[O+4>>2]=qe|1,n[O+qe>>2]=qe;break}if(s=n[l+4>>2]|0,(s&3|0)==1){B=s&-8,f=s>>>3;e:do if(s>>>0<256)if(s=n[l+8>>2]|0,c=n[l+12>>2]|0,(c|0)==(s|0)){n[2783]=n[2783]&~(1<<f);break}else{n[s+12>>2]=c,n[c+8>>2]=s;break}else{m=n[l+24>>2]|0,s=n[l+12>>2]|0;do if((s|0)==(l|0)){if(f=l+16|0,c=f+4|0,s=n[c>>2]|0,!s)if(s=n[f>>2]|0,s)c=f;else{s=0;break}for(;;){if(f=s+20|0,d=n[f>>2]|0,d|0){s=d,c=f;continue}if(f=s+16|0,d=n[f>>2]|0,d)s=d,c=f;else break}n[c>>2]=0}else qe=n[l+8>>2]|0,n[qe+12>>2]=s,n[s+8>>2]=qe;while(0);if(!m)break;c=n[l+28>>2]|0,f=11436+(c<<2)|0;do if((l|0)!=(n[f>>2]|0)){if(n[m+16+(((n[m+16>>2]|0)!=(l|0)&1)<<2)>>2]=s,!s)break e}else{if(n[f>>2]=s,s|0)break;n[2784]=n[2784]&~(1<<c);break e}while(0);if(n[s+24>>2]=m,c=l+16|0,f=n[c>>2]|0,f|0&&(n[s+16>>2]=f,n[f+24>>2]=s),c=n[c+4>>2]|0,!c)break;n[s+20>>2]=c,n[c+24>>2]=s}while(0);l=l+B|0,d=B+k|0}else d=k;if(l=l+4|0,n[l>>2]=n[l>>2]&-2,n[O+4>>2]=d|1,n[O+d>>2]=d,l=d>>>3,d>>>0<256){c=11172+(l<<1<<2)|0,s=n[2783]|0,l=1<<l,s&l?(s=c+8|0,l=n[s>>2]|0):(n[2783]=s|l,l=c,s=c+8|0),n[s>>2]=O,n[l+12>>2]=O,n[O+8>>2]=l,n[O+12>>2]=c;break}l=d>>>8;do if(!l)l=0;else{if(d>>>0>16777215){l=31;break}Ue=(l+1048320|0)>>>16&8,qe=l<<Ue,at=(qe+520192|0)>>>16&4,qe=qe<<at,l=(qe+245760|0)>>>16&2,l=14-(at|Ue|l)+(qe<<l>>>15)|0,l=d>>>(l+7|0)&1|l<<1}while(0);if(f=11436+(l<<2)|0,n[O+28>>2]=l,s=O+16|0,n[s+4>>2]=0,n[s>>2]=0,s=n[2784]|0,c=1<<l,!(s&c)){n[2784]=s|c,n[f>>2]=O,n[O+24>>2]=f,n[O+12>>2]=O,n[O+8>>2]=O;break}for(s=d<<((l|0)==31?0:25-(l>>>1)|0),c=n[f>>2]|0;;){if((n[c+4>>2]&-8|0)==(d|0)){Ue=194;break}if(f=c+16+(s>>>31<<2)|0,l=n[f>>2]|0,l)s=s<<1,c=l;else{Ue=193;break}}if((Ue|0)==193){n[f>>2]=O,n[O+24>>2]=c,n[O+12>>2]=O,n[O+8>>2]=O;break}else if((Ue|0)==194){Ue=c+8|0,qe=n[Ue>>2]|0,n[qe+12>>2]=O,n[Ue>>2]=O,n[O+8>>2]=qe,n[O+12>>2]=c,n[O+24>>2]=0;break}}else qe=(n[2786]|0)+k|0,n[2786]=qe,n[2789]=O,n[O+4>>2]=qe|1;while(0);return qe=M+8|0,C=Lt,qe|0}for(l=11580;s=n[l>>2]|0,!(s>>>0<=Q>>>0&&(qe=s+(n[l+4>>2]|0)|0,qe>>>0>Q>>>0));)l=n[l+8>>2]|0;d=qe+-47|0,s=d+8|0,s=d+((s&7|0)==0?0:0-s&7)|0,d=Q+16|0,s=s>>>0<d>>>0?Q:s,l=s+8|0,c=m+8|0,c=(c&7|0)==0?0:0-c&7,Ue=m+c|0,c=B+-40-c|0,n[2789]=Ue,n[2786]=c,n[Ue+4>>2]=c|1,n[Ue+c+4>>2]=40,n[2790]=n[2905],c=s+4|0,n[c>>2]=27,n[l>>2]=n[2895],n[l+4>>2]=n[2896],n[l+8>>2]=n[2897],n[l+12>>2]=n[2898],n[2895]=m,n[2896]=B,n[2898]=0,n[2897]=l,l=s+24|0;do Ue=l,l=l+4|0,n[l>>2]=7;while((Ue+8|0)>>>0<qe>>>0);if((s|0)!=(Q|0)){if(m=s-Q|0,n[c>>2]=n[c>>2]&-2,n[Q+4>>2]=m|1,n[s>>2]=m,l=m>>>3,m>>>0<256){c=11172+(l<<1<<2)|0,s=n[2783]|0,l=1<<l,s&l?(s=c+8|0,l=n[s>>2]|0):(n[2783]=s|l,l=c,s=c+8|0),n[s>>2]=Q,n[l+12>>2]=Q,n[Q+8>>2]=l,n[Q+12>>2]=c;break}if(l=m>>>8,l?m>>>0>16777215?c=31:(Ue=(l+1048320|0)>>>16&8,qe=l<<Ue,at=(qe+520192|0)>>>16&4,qe=qe<<at,c=(qe+245760|0)>>>16&2,c=14-(at|Ue|c)+(qe<<c>>>15)|0,c=m>>>(c+7|0)&1|c<<1):c=0,f=11436+(c<<2)|0,n[Q+28>>2]=c,n[Q+20>>2]=0,n[d>>2]=0,l=n[2784]|0,s=1<<c,!(l&s)){n[2784]=l|s,n[f>>2]=Q,n[Q+24>>2]=f,n[Q+12>>2]=Q,n[Q+8>>2]=Q;break}for(s=m<<((c|0)==31?0:25-(c>>>1)|0),c=n[f>>2]|0;;){if((n[c+4>>2]&-8|0)==(m|0)){Ue=216;break}if(f=c+16+(s>>>31<<2)|0,l=n[f>>2]|0,l)s=s<<1,c=l;else{Ue=215;break}}if((Ue|0)==215){n[f>>2]=Q,n[Q+24>>2]=c,n[Q+12>>2]=Q,n[Q+8>>2]=Q;break}else if((Ue|0)==216){Ue=c+8|0,qe=n[Ue>>2]|0,n[qe+12>>2]=Q,n[Ue>>2]=Q,n[Q+8>>2]=qe,n[Q+12>>2]=c,n[Q+24>>2]=0;break}}}else{qe=n[2787]|0,(qe|0)==0|m>>>0<qe>>>0&&(n[2787]=m),n[2895]=m,n[2896]=B,n[2898]=0,n[2792]=n[2901],n[2791]=-1,l=0;do qe=11172+(l<<1<<2)|0,n[qe+12>>2]=qe,n[qe+8>>2]=qe,l=l+1|0;while((l|0)!=32);qe=m+8|0,qe=(qe&7|0)==0?0:0-qe&7,Ue=m+qe|0,qe=B+-40-qe|0,n[2789]=Ue,n[2786]=qe,n[Ue+4>>2]=qe|1,n[Ue+qe+4>>2]=40,n[2790]=n[2905]}while(0);if(l=n[2786]|0,l>>>0>q>>>0)return at=l-q|0,n[2786]=at,qe=n[2789]|0,Ue=qe+q|0,n[2789]=Ue,n[Ue+4>>2]=at|1,n[qe+4>>2]=q|3,qe=qe+8|0,C=Lt,qe|0}return n[(Vm()|0)>>2]=12,qe=0,C=Lt,qe|0}function hD(s){s=s|0;var l=0,c=0,f=0,d=0,m=0,B=0,k=0,Q=0;if(!!s){c=s+-8|0,d=n[2787]|0,s=n[s+-4>>2]|0,l=s&-8,Q=c+l|0;do if(s&1)k=c,B=c;else{if(f=n[c>>2]|0,!(s&3)||(B=c+(0-f)|0,m=f+l|0,B>>>0<d>>>0))return;if((B|0)==(n[2788]|0)){if(s=Q+4|0,l=n[s>>2]|0,(l&3|0)!=3){k=B,l=m;break}n[2785]=m,n[s>>2]=l&-2,n[B+4>>2]=m|1,n[B+m>>2]=m;return}if(c=f>>>3,f>>>0<256)if(s=n[B+8>>2]|0,l=n[B+12>>2]|0,(l|0)==(s|0)){n[2783]=n[2783]&~(1<<c),k=B,l=m;break}else{n[s+12>>2]=l,n[l+8>>2]=s,k=B,l=m;break}d=n[B+24>>2]|0,s=n[B+12>>2]|0;do if((s|0)==(B|0)){if(c=B+16|0,l=c+4|0,s=n[l>>2]|0,!s)if(s=n[c>>2]|0,s)l=c;else{s=0;break}for(;;){if(c=s+20|0,f=n[c>>2]|0,f|0){s=f,l=c;continue}if(c=s+16|0,f=n[c>>2]|0,f)s=f,l=c;else break}n[l>>2]=0}else k=n[B+8>>2]|0,n[k+12>>2]=s,n[s+8>>2]=k;while(0);if(d){if(l=n[B+28>>2]|0,c=11436+(l<<2)|0,(B|0)==(n[c>>2]|0)){if(n[c>>2]=s,!s){n[2784]=n[2784]&~(1<<l),k=B,l=m;break}}else if(n[d+16+(((n[d+16>>2]|0)!=(B|0)&1)<<2)>>2]=s,!s){k=B,l=m;break}n[s+24>>2]=d,l=B+16|0,c=n[l>>2]|0,c|0&&(n[s+16>>2]=c,n[c+24>>2]=s),l=n[l+4>>2]|0,l?(n[s+20>>2]=l,n[l+24>>2]=s,k=B,l=m):(k=B,l=m)}else k=B,l=m}while(0);if(!(B>>>0>=Q>>>0)&&(s=Q+4|0,f=n[s>>2]|0,!!(f&1))){if(f&2)n[s>>2]=f&-2,n[k+4>>2]=l|1,n[B+l>>2]=l,d=l;else{if(s=n[2788]|0,(Q|0)==(n[2789]|0)){if(Q=(n[2786]|0)+l|0,n[2786]=Q,n[2789]=k,n[k+4>>2]=Q|1,(k|0)!=(s|0))return;n[2788]=0,n[2785]=0;return}if((Q|0)==(s|0)){Q=(n[2785]|0)+l|0,n[2785]=Q,n[2788]=B,n[k+4>>2]=Q|1,n[B+Q>>2]=Q;return}d=(f&-8)+l|0,c=f>>>3;do if(f>>>0<256)if(l=n[Q+8>>2]|0,s=n[Q+12>>2]|0,(s|0)==(l|0)){n[2783]=n[2783]&~(1<<c);break}else{n[l+12>>2]=s,n[s+8>>2]=l;break}else{m=n[Q+24>>2]|0,s=n[Q+12>>2]|0;do if((s|0)==(Q|0)){if(c=Q+16|0,l=c+4|0,s=n[l>>2]|0,!s)if(s=n[c>>2]|0,s)l=c;else{c=0;break}for(;;){if(c=s+20|0,f=n[c>>2]|0,f|0){s=f,l=c;continue}if(c=s+16|0,f=n[c>>2]|0,f)s=f,l=c;else break}n[l>>2]=0,c=s}else c=n[Q+8>>2]|0,n[c+12>>2]=s,n[s+8>>2]=c,c=s;while(0);if(m|0){if(s=n[Q+28>>2]|0,l=11436+(s<<2)|0,(Q|0)==(n[l>>2]|0)){if(n[l>>2]=c,!c){n[2784]=n[2784]&~(1<<s);break}}else if(n[m+16+(((n[m+16>>2]|0)!=(Q|0)&1)<<2)>>2]=c,!c)break;n[c+24>>2]=m,s=Q+16|0,l=n[s>>2]|0,l|0&&(n[c+16>>2]=l,n[l+24>>2]=c),s=n[s+4>>2]|0,s|0&&(n[c+20>>2]=s,n[s+24>>2]=c)}}while(0);if(n[k+4>>2]=d|1,n[B+d>>2]=d,(k|0)==(n[2788]|0)){n[2785]=d;return}}if(s=d>>>3,d>>>0<256){c=11172+(s<<1<<2)|0,l=n[2783]|0,s=1<<s,l&s?(l=c+8|0,s=n[l>>2]|0):(n[2783]=l|s,s=c,l=c+8|0),n[l>>2]=k,n[s+12>>2]=k,n[k+8>>2]=s,n[k+12>>2]=c;return}s=d>>>8,s?d>>>0>16777215?s=31:(B=(s+1048320|0)>>>16&8,Q=s<<B,m=(Q+520192|0)>>>16&4,Q=Q<<m,s=(Q+245760|0)>>>16&2,s=14-(m|B|s)+(Q<<s>>>15)|0,s=d>>>(s+7|0)&1|s<<1):s=0,f=11436+(s<<2)|0,n[k+28>>2]=s,n[k+20>>2]=0,n[k+16>>2]=0,l=n[2784]|0,c=1<<s;do if(l&c){for(l=d<<((s|0)==31?0:25-(s>>>1)|0),c=n[f>>2]|0;;){if((n[c+4>>2]&-8|0)==(d|0)){s=73;break}if(f=c+16+(l>>>31<<2)|0,s=n[f>>2]|0,s)l=l<<1,c=s;else{s=72;break}}if((s|0)==72){n[f>>2]=k,n[k+24>>2]=c,n[k+12>>2]=k,n[k+8>>2]=k;break}else if((s|0)==73){B=c+8|0,Q=n[B>>2]|0,n[Q+12>>2]=k,n[B>>2]=k,n[k+8>>2]=Q,n[k+12>>2]=c,n[k+24>>2]=0;break}}else n[2784]=l|c,n[f>>2]=k,n[k+24>>2]=f,n[k+12>>2]=k,n[k+8>>2]=k;while(0);if(Q=(n[2791]|0)+-1|0,n[2791]=Q,!Q)s=11588;else return;for(;s=n[s>>2]|0,s;)s=s+8|0;n[2791]=-1}}}function kUe(){return 11628}function QUe(s){s=s|0;var l=0,c=0;return l=C,C=C+16|0,c=l,n[c>>2]=RUe(n[s+60>>2]|0)|0,s=gD(hc(6,c|0)|0)|0,C=l,s|0}function s7(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0,Ge=0;q=C,C=C+48|0,O=q+16|0,m=q,d=q+32|0,k=s+28|0,f=n[k>>2]|0,n[d>>2]=f,Q=s+20|0,f=(n[Q>>2]|0)-f|0,n[d+4>>2]=f,n[d+8>>2]=l,n[d+12>>2]=c,f=f+c|0,B=s+60|0,n[m>>2]=n[B>>2],n[m+4>>2]=d,n[m+8>>2]=2,m=gD(Li(146,m|0)|0)|0;e:do if((f|0)!=(m|0)){for(l=2;!((m|0)<0);)if(f=f-m|0,Ge=n[d+4>>2]|0,se=m>>>0>Ge>>>0,d=se?d+8|0:d,l=(se<<31>>31)+l|0,Ge=m-(se?Ge:0)|0,n[d>>2]=(n[d>>2]|0)+Ge,se=d+4|0,n[se>>2]=(n[se>>2]|0)-Ge,n[O>>2]=n[B>>2],n[O+4>>2]=d,n[O+8>>2]=l,m=gD(Li(146,O|0)|0)|0,(f|0)==(m|0)){M=3;break e}n[s+16>>2]=0,n[k>>2]=0,n[Q>>2]=0,n[s>>2]=n[s>>2]|32,(l|0)==2?c=0:c=c-(n[d+4>>2]|0)|0}else M=3;while(0);return(M|0)==3&&(Ge=n[s+44>>2]|0,n[s+16>>2]=Ge+(n[s+48>>2]|0),n[k>>2]=Ge,n[Q>>2]=Ge),C=q,c|0}function FUe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;return d=C,C=C+32|0,m=d,f=d+20|0,n[m>>2]=n[s+60>>2],n[m+4>>2]=0,n[m+8>>2]=l,n[m+12>>2]=f,n[m+16>>2]=c,(gD(sa(140,m|0)|0)|0)<0?(n[f>>2]=-1,s=-1):s=n[f>>2]|0,C=d,s|0}function gD(s){return s=s|0,s>>>0>4294963200&&(n[(Vm()|0)>>2]=0-s,s=-1),s|0}function Vm(){return(TUe()|0)+64|0}function TUe(){return xT()|0}function xT(){return 2084}function RUe(s){return s=s|0,s|0}function NUe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;return d=C,C=C+32|0,f=d,n[s+36>>2]=1,(n[s>>2]&64|0)==0&&(n[f>>2]=n[s+60>>2],n[f+4>>2]=21523,n[f+8>>2]=d+16,fu(54,f|0)|0)&&(o[s+75>>0]=-1),f=s7(s,l,c)|0,C=d,f|0}function o7(s,l){s=s|0,l=l|0;var c=0,f=0;if(c=o[s>>0]|0,f=o[l>>0]|0,c<<24>>24==0||c<<24>>24!=f<<24>>24)s=f;else{do s=s+1|0,l=l+1|0,c=o[s>>0]|0,f=o[l>>0]|0;while(!(c<<24>>24==0||c<<24>>24!=f<<24>>24));s=f}return(c&255)-(s&255)|0}function LUe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0;e:do if(!c)s=0;else{for(;f=o[s>>0]|0,d=o[l>>0]|0,f<<24>>24==d<<24>>24;)if(c=c+-1|0,c)s=s+1|0,l=l+1|0;else{s=0;break e}s=(f&255)-(d&255)|0}while(0);return s|0}function a7(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0,Ge=0,Oe=0,Fe=0;Fe=C,C=C+224|0,M=Fe+120|0,q=Fe+80|0,Ge=Fe,Oe=Fe+136|0,f=q,d=f+40|0;do n[f>>2]=0,f=f+4|0;while((f|0)<(d|0));return n[M>>2]=n[c>>2],(bT(0,l,M,Ge,q)|0)<0?c=-1:((n[s+76>>2]|0)>-1?se=MUe(s)|0:se=0,c=n[s>>2]|0,O=c&32,(o[s+74>>0]|0)<1&&(n[s>>2]=c&-33),f=s+48|0,n[f>>2]|0?c=bT(s,l,M,Ge,q)|0:(d=s+44|0,m=n[d>>2]|0,n[d>>2]=Oe,B=s+28|0,n[B>>2]=Oe,k=s+20|0,n[k>>2]=Oe,n[f>>2]=80,Q=s+16|0,n[Q>>2]=Oe+80,c=bT(s,l,M,Ge,q)|0,m&&(ED[n[s+36>>2]&7](s,0,0)|0,c=(n[k>>2]|0)==0?-1:c,n[d>>2]=m,n[f>>2]=0,n[Q>>2]=0,n[B>>2]=0,n[k>>2]=0)),f=n[s>>2]|0,n[s>>2]=f|O,se|0&&OUe(s),c=(f&32|0)==0?c:-1),C=Fe,c|0}function bT(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0,Ge=0,Oe=0,Fe=0,et=0,Xe=0,at=0,Ue=0,qe=0,Lt=0,Or=0,or=0,Xt=0,Pr=0,Nr=0,ir=0;ir=C,C=C+64|0,or=ir+16|0,Xt=ir,Lt=ir+24|0,Pr=ir+8|0,Nr=ir+20|0,n[or>>2]=l,at=(s|0)!=0,Ue=Lt+40|0,qe=Ue,Lt=Lt+39|0,Or=Pr+4|0,B=0,m=0,M=0;e:for(;;){do if((m|0)>-1)if((B|0)>(2147483647-m|0)){n[(Vm()|0)>>2]=75,m=-1;break}else{m=B+m|0;break}while(0);if(B=o[l>>0]|0,B<<24>>24)k=l;else{Xe=87;break}t:for(;;){switch(B<<24>>24){case 37:{B=k,Xe=9;break t}case 0:{B=k;break t}default:}et=k+1|0,n[or>>2]=et,B=o[et>>0]|0,k=et}t:do if((Xe|0)==9)for(;;){if(Xe=0,(o[k+1>>0]|0)!=37)break t;if(B=B+1|0,k=k+2|0,n[or>>2]=k,(o[k>>0]|0)==37)Xe=9;else break}while(0);if(B=B-l|0,at&&ss(s,l,B),B|0){l=k;continue}Q=k+1|0,B=(o[Q>>0]|0)+-48|0,B>>>0<10?(et=(o[k+2>>0]|0)==36,Fe=et?B:-1,M=et?1:M,Q=et?k+3|0:Q):Fe=-1,n[or>>2]=Q,B=o[Q>>0]|0,k=(B<<24>>24)+-32|0;t:do if(k>>>0<32)for(O=0,q=B;;){if(B=1<<k,!(B&75913)){B=q;break t}if(O=B|O,Q=Q+1|0,n[or>>2]=Q,B=o[Q>>0]|0,k=(B<<24>>24)+-32|0,k>>>0>=32)break;q=B}else O=0;while(0);if(B<<24>>24==42){if(k=Q+1|0,B=(o[k>>0]|0)+-48|0,B>>>0<10&&(o[Q+2>>0]|0)==36)n[d+(B<<2)>>2]=10,B=n[f+((o[k>>0]|0)+-48<<3)>>2]|0,M=1,Q=Q+3|0;else{if(M|0){m=-1;break}at?(M=(n[c>>2]|0)+(4-1)&~(4-1),B=n[M>>2]|0,n[c>>2]=M+4,M=0,Q=k):(B=0,M=0,Q=k)}n[or>>2]=Q,et=(B|0)<0,B=et?0-B|0:B,O=et?O|8192:O}else{if(B=l7(or)|0,(B|0)<0){m=-1;break}Q=n[or>>2]|0}do if((o[Q>>0]|0)==46){if((o[Q+1>>0]|0)!=42){n[or>>2]=Q+1,k=l7(or)|0,Q=n[or>>2]|0;break}if(q=Q+2|0,k=(o[q>>0]|0)+-48|0,k>>>0<10&&(o[Q+3>>0]|0)==36){n[d+(k<<2)>>2]=10,k=n[f+((o[q>>0]|0)+-48<<3)>>2]|0,Q=Q+4|0,n[or>>2]=Q;break}if(M|0){m=-1;break e}at?(et=(n[c>>2]|0)+(4-1)&~(4-1),k=n[et>>2]|0,n[c>>2]=et+4):k=0,n[or>>2]=q,Q=q}else k=-1;while(0);for(Oe=0;;){if(((o[Q>>0]|0)+-65|0)>>>0>57){m=-1;break e}if(et=Q+1|0,n[or>>2]=et,q=o[(o[Q>>0]|0)+-65+(5178+(Oe*58|0))>>0]|0,se=q&255,(se+-1|0)>>>0<8)Oe=se,Q=et;else break}if(!(q<<24>>24)){m=-1;break}Ge=(Fe|0)>-1;do if(q<<24>>24==19)if(Ge){m=-1;break e}else Xe=49;else{if(Ge){n[d+(Fe<<2)>>2]=se,Ge=f+(Fe<<3)|0,Fe=n[Ge+4>>2]|0,Xe=Xt,n[Xe>>2]=n[Ge>>2],n[Xe+4>>2]=Fe,Xe=49;break}if(!at){m=0;break e}c7(Xt,se,c)}while(0);if((Xe|0)==49&&(Xe=0,!at)){B=0,l=et;continue}Q=o[Q>>0]|0,Q=(Oe|0)!=0&(Q&15|0)==3?Q&-33:Q,Ge=O&-65537,Fe=(O&8192|0)==0?O:Ge;t:do switch(Q|0){case 110:switch((Oe&255)<<24>>24){case 0:{n[n[Xt>>2]>>2]=m,B=0,l=et;continue e}case 1:{n[n[Xt>>2]>>2]=m,B=0,l=et;continue e}case 2:{B=n[Xt>>2]|0,n[B>>2]=m,n[B+4>>2]=((m|0)<0)<<31>>31,B=0,l=et;continue e}case 3:{a[n[Xt>>2]>>1]=m,B=0,l=et;continue e}case 4:{o[n[Xt>>2]>>0]=m,B=0,l=et;continue e}case 6:{n[n[Xt>>2]>>2]=m,B=0,l=et;continue e}case 7:{B=n[Xt>>2]|0,n[B>>2]=m,n[B+4>>2]=((m|0)<0)<<31>>31,B=0,l=et;continue e}default:{B=0,l=et;continue e}}case 112:{Q=120,k=k>>>0>8?k:8,l=Fe|8,Xe=61;break}case 88:case 120:{l=Fe,Xe=61;break}case 111:{Q=Xt,l=n[Q>>2]|0,Q=n[Q+4>>2]|0,se=_Ue(l,Q,Ue)|0,Ge=qe-se|0,O=0,q=5642,k=(Fe&8|0)==0|(k|0)>(Ge|0)?k:Ge+1|0,Ge=Fe,Xe=67;break}case 105:case 100:if(Q=Xt,l=n[Q>>2]|0,Q=n[Q+4>>2]|0,(Q|0)<0){l=dD(0,0,l|0,Q|0)|0,Q=De,O=Xt,n[O>>2]=l,n[O+4>>2]=Q,O=1,q=5642,Xe=66;break t}else{O=(Fe&2049|0)!=0&1,q=(Fe&2048|0)==0?(Fe&1|0)==0?5642:5644:5643,Xe=66;break t}case 117:{Q=Xt,O=0,q=5642,l=n[Q>>2]|0,Q=n[Q+4>>2]|0,Xe=66;break}case 99:{o[Lt>>0]=n[Xt>>2],l=Lt,O=0,q=5642,se=Ue,Q=1,k=Ge;break}case 109:{Q=HUe(n[(Vm()|0)>>2]|0)|0,Xe=71;break}case 115:{Q=n[Xt>>2]|0,Q=Q|0?Q:5652,Xe=71;break}case 67:{n[Pr>>2]=n[Xt>>2],n[Or>>2]=0,n[Xt>>2]=Pr,se=-1,Q=Pr,Xe=75;break}case 83:{l=n[Xt>>2]|0,k?(se=k,Q=l,Xe=75):(Bs(s,32,B,0,Fe),l=0,Xe=84);break}case 65:case 71:case 70:case 69:case 97:case 103:case 102:case 101:{B=qUe(s,+E[Xt>>3],B,k,Fe,Q)|0,l=et;continue e}default:O=0,q=5642,se=Ue,Q=k,k=Fe}while(0);t:do if((Xe|0)==61)Fe=Xt,Oe=n[Fe>>2]|0,Fe=n[Fe+4>>2]|0,se=UUe(Oe,Fe,Ue,Q&32)|0,q=(l&8|0)==0|(Oe|0)==0&(Fe|0)==0,O=q?0:2,q=q?5642:5642+(Q>>4)|0,Ge=l,l=Oe,Q=Fe,Xe=67;else if((Xe|0)==66)se=Km(l,Q,Ue)|0,Ge=Fe,Xe=67;else if((Xe|0)==71)Xe=0,Fe=jUe(Q,0,k)|0,Oe=(Fe|0)==0,l=Q,O=0,q=5642,se=Oe?Q+k|0:Fe,Q=Oe?k:Fe-Q|0,k=Ge;else if((Xe|0)==75){for(Xe=0,q=Q,l=0,k=0;O=n[q>>2]|0,!(!O||(k=u7(Nr,O)|0,(k|0)<0|k>>>0>(se-l|0)>>>0));)if(l=k+l|0,se>>>0>l>>>0)q=q+4|0;else break;if((k|0)<0){m=-1;break e}if(Bs(s,32,B,l,Fe),!l)l=0,Xe=84;else for(O=0;;){if(k=n[Q>>2]|0,!k){Xe=84;break t}if(k=u7(Nr,k)|0,O=k+O|0,(O|0)>(l|0)){Xe=84;break t}if(ss(s,Nr,k),O>>>0>=l>>>0){Xe=84;break}else Q=Q+4|0}}while(0);if((Xe|0)==67)Xe=0,Q=(l|0)!=0|(Q|0)!=0,Fe=(k|0)!=0|Q,Q=((Q^1)&1)+(qe-se)|0,l=Fe?se:Ue,se=Ue,Q=Fe?(k|0)>(Q|0)?k:Q:k,k=(k|0)>-1?Ge&-65537:Ge;else if((Xe|0)==84){Xe=0,Bs(s,32,B,l,Fe^8192),B=(B|0)>(l|0)?B:l,l=et;continue}Oe=se-l|0,Ge=(Q|0)<(Oe|0)?Oe:Q,Fe=Ge+O|0,B=(B|0)<(Fe|0)?Fe:B,Bs(s,32,B,Fe,k),ss(s,q,O),Bs(s,48,B,Fe,k^65536),Bs(s,48,Ge,Oe,0),ss(s,l,Oe),Bs(s,32,B,Fe,k^8192),l=et}e:do if((Xe|0)==87&&!s)if(!M)m=0;else{for(m=1;l=n[d+(m<<2)>>2]|0,!!l;)if(c7(f+(m<<3)|0,l,c),m=m+1|0,(m|0)>=10){m=1;break e}for(;;){if(n[d+(m<<2)>>2]|0){m=-1;break e}if(m=m+1|0,(m|0)>=10){m=1;break}}}while(0);return C=ir,m|0}function MUe(s){return s=s|0,0}function OUe(s){s=s|0}function ss(s,l,c){s=s|0,l=l|0,c=c|0,n[s>>2]&32||ZUe(l,c,s)|0}function l7(s){s=s|0;var l=0,c=0,f=0;if(c=n[s>>2]|0,f=(o[c>>0]|0)+-48|0,f>>>0<10){l=0;do l=f+(l*10|0)|0,c=c+1|0,n[s>>2]=c,f=(o[c>>0]|0)+-48|0;while(f>>>0<10)}else l=0;return l|0}function c7(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;e:do if(l>>>0<=20)do switch(l|0){case 9:{f=(n[c>>2]|0)+(4-1)&~(4-1),l=n[f>>2]|0,n[c>>2]=f+4,n[s>>2]=l;break e}case 10:{f=(n[c>>2]|0)+(4-1)&~(4-1),l=n[f>>2]|0,n[c>>2]=f+4,f=s,n[f>>2]=l,n[f+4>>2]=((l|0)<0)<<31>>31;break e}case 11:{f=(n[c>>2]|0)+(4-1)&~(4-1),l=n[f>>2]|0,n[c>>2]=f+4,f=s,n[f>>2]=l,n[f+4>>2]=0;break e}case 12:{f=(n[c>>2]|0)+(8-1)&~(8-1),l=f,d=n[l>>2]|0,l=n[l+4>>2]|0,n[c>>2]=f+8,f=s,n[f>>2]=d,n[f+4>>2]=l;break e}case 13:{d=(n[c>>2]|0)+(4-1)&~(4-1),f=n[d>>2]|0,n[c>>2]=d+4,f=(f&65535)<<16>>16,d=s,n[d>>2]=f,n[d+4>>2]=((f|0)<0)<<31>>31;break e}case 14:{d=(n[c>>2]|0)+(4-1)&~(4-1),f=n[d>>2]|0,n[c>>2]=d+4,d=s,n[d>>2]=f&65535,n[d+4>>2]=0;break e}case 15:{d=(n[c>>2]|0)+(4-1)&~(4-1),f=n[d>>2]|0,n[c>>2]=d+4,f=(f&255)<<24>>24,d=s,n[d>>2]=f,n[d+4>>2]=((f|0)<0)<<31>>31;break e}case 16:{d=(n[c>>2]|0)+(4-1)&~(4-1),f=n[d>>2]|0,n[c>>2]=d+4,d=s,n[d>>2]=f&255,n[d+4>>2]=0;break e}case 17:{d=(n[c>>2]|0)+(8-1)&~(8-1),m=+E[d>>3],n[c>>2]=d+8,E[s>>3]=m;break e}case 18:{d=(n[c>>2]|0)+(8-1)&~(8-1),m=+E[d>>3],n[c>>2]=d+8,E[s>>3]=m;break e}default:break e}while(0);while(0)}function UUe(s,l,c,f){if(s=s|0,l=l|0,c=c|0,f=f|0,!((s|0)==0&(l|0)==0))do c=c+-1|0,o[c>>0]=u[5694+(s&15)>>0]|0|f,s=mD(s|0,l|0,4)|0,l=De;while(!((s|0)==0&(l|0)==0));return c|0}function _Ue(s,l,c){if(s=s|0,l=l|0,c=c|0,!((s|0)==0&(l|0)==0))do c=c+-1|0,o[c>>0]=s&7|48,s=mD(s|0,l|0,3)|0,l=De;while(!((s|0)==0&(l|0)==0));return c|0}function Km(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;if(l>>>0>0|(l|0)==0&s>>>0>4294967295){for(;f=TT(s|0,l|0,10,0)|0,c=c+-1|0,o[c>>0]=f&255|48,f=s,s=FT(s|0,l|0,10,0)|0,l>>>0>9|(l|0)==9&f>>>0>4294967295;)l=De;l=s}else l=s;if(l)for(;c=c+-1|0,o[c>>0]=(l>>>0)%10|0|48,!(l>>>0<10);)l=(l>>>0)/10|0;return c|0}function HUe(s){return s=s|0,KUe(s,n[(VUe()|0)+188>>2]|0)|0}function jUe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;m=l&255,f=(c|0)!=0;e:do if(f&(s&3|0)!=0)for(d=l&255;;){if((o[s>>0]|0)==d<<24>>24){B=6;break e}if(s=s+1|0,c=c+-1|0,f=(c|0)!=0,!(f&(s&3|0)!=0)){B=5;break}}else B=5;while(0);(B|0)==5&&(f?B=6:c=0);e:do if((B|0)==6&&(d=l&255,(o[s>>0]|0)!=d<<24>>24)){f=He(m,16843009)|0;t:do if(c>>>0>3){for(;m=n[s>>2]^f,!((m&-2139062144^-2139062144)&m+-16843009|0);)if(s=s+4|0,c=c+-4|0,c>>>0<=3){B=11;break t}}else B=11;while(0);if((B|0)==11&&!c){c=0;break}for(;;){if((o[s>>0]|0)==d<<24>>24)break e;if(s=s+1|0,c=c+-1|0,!c){c=0;break}}}while(0);return(c|0?s:0)|0}function Bs(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0;if(B=C,C=C+256|0,m=B,(c|0)>(f|0)&(d&73728|0)==0){if(d=c-f|0,zm(m|0,l|0,(d>>>0<256?d:256)|0)|0,d>>>0>255){l=c-f|0;do ss(s,m,256),d=d+-256|0;while(d>>>0>255);d=l&255}ss(s,m,d)}C=B}function u7(s,l){return s=s|0,l=l|0,s?s=YUe(s,l,0)|0:s=0,s|0}function qUe(s,l,c,f,d,m){s=s|0,l=+l,c=c|0,f=f|0,d=d|0,m=m|0;var B=0,k=0,Q=0,O=0,M=0,q=0,se=0,Ge=0,Oe=0,Fe=0,et=0,Xe=0,at=0,Ue=0,qe=0,Lt=0,Or=0,or=0,Xt=0,Pr=0,Nr=0,ir=0,bn=0;bn=C,C=C+560|0,Q=bn+8|0,et=bn,ir=bn+524|0,Nr=ir,O=bn+512|0,n[et>>2]=0,Pr=O+12|0,A7(l)|0,(De|0)<0?(l=-l,or=1,Or=5659):(or=(d&2049|0)!=0&1,Or=(d&2048|0)==0?(d&1|0)==0?5660:5665:5662),A7(l)|0,Xt=De&2146435072;do if(Xt>>>0<2146435072|(Xt|0)==2146435072&0<0){if(Ge=+GUe(l,et)*2,B=Ge!=0,B&&(n[et>>2]=(n[et>>2]|0)+-1),at=m|32,(at|0)==97){Oe=m&32,se=(Oe|0)==0?Or:Or+9|0,q=or|2,B=12-f|0;do if(f>>>0>11|(B|0)==0)l=Ge;else{l=8;do B=B+-1|0,l=l*16;while((B|0)!=0);if((o[se>>0]|0)==45){l=-(l+(-Ge-l));break}else{l=Ge+l-l;break}}while(0);k=n[et>>2]|0,B=(k|0)<0?0-k|0:k,B=Km(B,((B|0)<0)<<31>>31,Pr)|0,(B|0)==(Pr|0)&&(B=O+11|0,o[B>>0]=48),o[B+-1>>0]=(k>>31&2)+43,M=B+-2|0,o[M>>0]=m+15,O=(f|0)<1,Q=(d&8|0)==0,B=ir;do Xt=~~l,k=B+1|0,o[B>>0]=u[5694+Xt>>0]|Oe,l=(l-+(Xt|0))*16,(k-Nr|0)==1&&!(Q&(O&l==0))?(o[k>>0]=46,B=B+2|0):B=k;while(l!=0);Xt=B-Nr|0,Nr=Pr-M|0,Pr=(f|0)!=0&(Xt+-2|0)<(f|0)?f+2|0:Xt,B=Nr+q+Pr|0,Bs(s,32,c,B,d),ss(s,se,q),Bs(s,48,c,B,d^65536),ss(s,ir,Xt),Bs(s,48,Pr-Xt|0,0,0),ss(s,M,Nr),Bs(s,32,c,B,d^8192);break}k=(f|0)<0?6:f,B?(B=(n[et>>2]|0)+-28|0,n[et>>2]=B,l=Ge*268435456):(l=Ge,B=n[et>>2]|0),Xt=(B|0)<0?Q:Q+288|0,Q=Xt;do qe=~~l>>>0,n[Q>>2]=qe,Q=Q+4|0,l=(l-+(qe>>>0))*1e9;while(l!=0);if((B|0)>0)for(O=Xt,q=Q;;){if(M=(B|0)<29?B:29,B=q+-4|0,B>>>0>=O>>>0){Q=0;do Ue=m7(n[B>>2]|0,0,M|0)|0,Ue=QT(Ue|0,De|0,Q|0,0)|0,qe=De,Xe=TT(Ue|0,qe|0,1e9,0)|0,n[B>>2]=Xe,Q=FT(Ue|0,qe|0,1e9,0)|0,B=B+-4|0;while(B>>>0>=O>>>0);Q&&(O=O+-4|0,n[O>>2]=Q)}for(Q=q;!(Q>>>0<=O>>>0);)if(B=Q+-4|0,!(n[B>>2]|0))Q=B;else break;if(B=(n[et>>2]|0)-M|0,n[et>>2]=B,(B|0)>0)q=Q;else break}else O=Xt;if((B|0)<0){f=((k+25|0)/9|0)+1|0,Fe=(at|0)==102;do{if(Oe=0-B|0,Oe=(Oe|0)<9?Oe:9,O>>>0<Q>>>0){M=(1<<Oe)+-1|0,q=1e9>>>Oe,se=0,B=O;do qe=n[B>>2]|0,n[B>>2]=(qe>>>Oe)+se,se=He(qe&M,q)|0,B=B+4|0;while(B>>>0<Q>>>0);B=(n[O>>2]|0)==0?O+4|0:O,se?(n[Q>>2]=se,O=B,B=Q+4|0):(O=B,B=Q)}else O=(n[O>>2]|0)==0?O+4|0:O,B=Q;Q=Fe?Xt:O,Q=(B-Q>>2|0)>(f|0)?Q+(f<<2)|0:B,B=(n[et>>2]|0)+Oe|0,n[et>>2]=B}while((B|0)<0);B=O,f=Q}else B=O,f=Q;if(qe=Xt,B>>>0<f>>>0){if(Q=(qe-B>>2)*9|0,M=n[B>>2]|0,M>>>0>=10){O=10;do O=O*10|0,Q=Q+1|0;while(M>>>0>=O>>>0)}}else Q=0;if(Fe=(at|0)==103,Xe=(k|0)!=0,O=k-((at|0)!=102?Q:0)+((Xe&Fe)<<31>>31)|0,(O|0)<(((f-qe>>2)*9|0)+-9|0)){if(O=O+9216|0,Oe=Xt+4+(((O|0)/9|0)+-1024<<2)|0,O=((O|0)%9|0)+1|0,(O|0)<9){M=10;do M=M*10|0,O=O+1|0;while((O|0)!=9)}else M=10;if(q=n[Oe>>2]|0,se=(q>>>0)%(M>>>0)|0,O=(Oe+4|0)==(f|0),O&(se|0)==0)O=Oe;else if(Ge=(((q>>>0)/(M>>>0)|0)&1|0)==0?9007199254740992:9007199254740994,Ue=(M|0)/2|0,l=se>>>0<Ue>>>0?.5:O&(se|0)==(Ue|0)?1:1.5,or&&(Ue=(o[Or>>0]|0)==45,l=Ue?-l:l,Ge=Ue?-Ge:Ge),O=q-se|0,n[Oe>>2]=O,Ge+l!=Ge){if(Ue=O+M|0,n[Oe>>2]=Ue,Ue>>>0>999999999)for(Q=Oe;O=Q+-4|0,n[Q>>2]=0,O>>>0<B>>>0&&(B=B+-4|0,n[B>>2]=0),Ue=(n[O>>2]|0)+1|0,n[O>>2]=Ue,Ue>>>0>999999999;)Q=O;else O=Oe;if(Q=(qe-B>>2)*9|0,q=n[B>>2]|0,q>>>0>=10){M=10;do M=M*10|0,Q=Q+1|0;while(q>>>0>=M>>>0)}}else O=Oe;O=O+4|0,O=f>>>0>O>>>0?O:f,Ue=B}else O=f,Ue=B;for(at=O;;){if(at>>>0<=Ue>>>0){et=0;break}if(B=at+-4|0,!(n[B>>2]|0))at=B;else{et=1;break}}f=0-Q|0;do if(Fe)if(B=((Xe^1)&1)+k|0,(B|0)>(Q|0)&(Q|0)>-5?(M=m+-1|0,k=B+-1-Q|0):(M=m+-2|0,k=B+-1|0),B=d&8,B)Oe=B;else{if(et&&(Lt=n[at+-4>>2]|0,(Lt|0)!=0))if((Lt>>>0)%10|0)O=0;else{O=0,B=10;do B=B*10|0,O=O+1|0;while(!((Lt>>>0)%(B>>>0)|0|0))}else O=9;if(B=((at-qe>>2)*9|0)+-9|0,(M|32|0)==102){Oe=B-O|0,Oe=(Oe|0)>0?Oe:0,k=(k|0)<(Oe|0)?k:Oe,Oe=0;break}else{Oe=B+Q-O|0,Oe=(Oe|0)>0?Oe:0,k=(k|0)<(Oe|0)?k:Oe,Oe=0;break}}else M=m,Oe=d&8;while(0);if(Fe=k|Oe,q=(Fe|0)!=0&1,se=(M|32|0)==102,se)Xe=0,B=(Q|0)>0?Q:0;else{if(B=(Q|0)<0?f:Q,B=Km(B,((B|0)<0)<<31>>31,Pr)|0,O=Pr,(O-B|0)<2)do B=B+-1|0,o[B>>0]=48;while((O-B|0)<2);o[B+-1>>0]=(Q>>31&2)+43,B=B+-2|0,o[B>>0]=M,Xe=B,B=O-B|0}if(B=or+1+k+q+B|0,Bs(s,32,c,B,d),ss(s,Or,or),Bs(s,48,c,B,d^65536),se){M=Ue>>>0>Xt>>>0?Xt:Ue,Oe=ir+9|0,q=Oe,se=ir+8|0,O=M;do{if(Q=Km(n[O>>2]|0,0,Oe)|0,(O|0)==(M|0))(Q|0)==(Oe|0)&&(o[se>>0]=48,Q=se);else if(Q>>>0>ir>>>0){zm(ir|0,48,Q-Nr|0)|0;do Q=Q+-1|0;while(Q>>>0>ir>>>0)}ss(s,Q,q-Q|0),O=O+4|0}while(O>>>0<=Xt>>>0);if(Fe|0&&ss(s,5710,1),O>>>0<at>>>0&(k|0)>0)for(;;){if(Q=Km(n[O>>2]|0,0,Oe)|0,Q>>>0>ir>>>0){zm(ir|0,48,Q-Nr|0)|0;do Q=Q+-1|0;while(Q>>>0>ir>>>0)}if(ss(s,Q,(k|0)<9?k:9),O=O+4|0,Q=k+-9|0,O>>>0<at>>>0&(k|0)>9)k=Q;else{k=Q;break}}Bs(s,48,k+9|0,9,0)}else{if(Fe=et?at:Ue+4|0,(k|0)>-1){et=ir+9|0,Oe=(Oe|0)==0,f=et,q=0-Nr|0,se=ir+8|0,M=Ue;do{Q=Km(n[M>>2]|0,0,et)|0,(Q|0)==(et|0)&&(o[se>>0]=48,Q=se);do if((M|0)==(Ue|0)){if(O=Q+1|0,ss(s,Q,1),Oe&(k|0)<1){Q=O;break}ss(s,5710,1),Q=O}else{if(Q>>>0<=ir>>>0)break;zm(ir|0,48,Q+q|0)|0;do Q=Q+-1|0;while(Q>>>0>ir>>>0)}while(0);Nr=f-Q|0,ss(s,Q,(k|0)>(Nr|0)?Nr:k),k=k-Nr|0,M=M+4|0}while(M>>>0<Fe>>>0&(k|0)>-1)}Bs(s,48,k+18|0,18,0),ss(s,Xe,Pr-Xe|0)}Bs(s,32,c,B,d^8192)}else ir=(m&32|0)!=0,B=or+3|0,Bs(s,32,c,B,d&-65537),ss(s,Or,or),ss(s,l!=l|!1?ir?5686:5690:ir?5678:5682,3),Bs(s,32,c,B,d^8192);while(0);return C=bn,((B|0)<(c|0)?c:B)|0}function A7(s){s=+s;var l=0;return E[v>>3]=s,l=n[v>>2]|0,De=n[v+4>>2]|0,l|0}function GUe(s,l){return s=+s,l=l|0,+ +f7(s,l)}function f7(s,l){s=+s,l=l|0;var c=0,f=0,d=0;switch(E[v>>3]=s,c=n[v>>2]|0,f=n[v+4>>2]|0,d=mD(c|0,f|0,52)|0,d&2047){case 0:{s!=0?(s=+f7(s*18446744073709552e3,l),c=(n[l>>2]|0)+-64|0):c=0,n[l>>2]=c;break}case 2047:break;default:n[l>>2]=(d&2047)+-1022,n[v>>2]=c,n[v+4>>2]=f&-2146435073|1071644672,s=+E[v>>3]}return+s}function YUe(s,l,c){s=s|0,l=l|0,c=c|0;do if(s){if(l>>>0<128){o[s>>0]=l,s=1;break}if(!(n[n[(WUe()|0)+188>>2]>>2]|0))if((l&-128|0)==57216){o[s>>0]=l,s=1;break}else{n[(Vm()|0)>>2]=84,s=-1;break}if(l>>>0<2048){o[s>>0]=l>>>6|192,o[s+1>>0]=l&63|128,s=2;break}if(l>>>0<55296|(l&-8192|0)==57344){o[s>>0]=l>>>12|224,o[s+1>>0]=l>>>6&63|128,o[s+2>>0]=l&63|128,s=3;break}if((l+-65536|0)>>>0<1048576){o[s>>0]=l>>>18|240,o[s+1>>0]=l>>>12&63|128,o[s+2>>0]=l>>>6&63|128,o[s+3>>0]=l&63|128,s=4;break}else{n[(Vm()|0)>>2]=84,s=-1;break}}else s=1;while(0);return s|0}function WUe(){return xT()|0}function VUe(){return xT()|0}function KUe(s,l){s=s|0,l=l|0;var c=0,f=0;for(f=0;;){if((u[5712+f>>0]|0)==(s|0)){s=2;break}if(c=f+1|0,(c|0)==87){c=5800,f=87,s=5;break}else f=c}if((s|0)==2&&(f?(c=5800,s=5):c=5800),(s|0)==5)for(;;){do s=c,c=c+1|0;while((o[s>>0]|0)!=0);if(f=f+-1|0,f)s=5;else break}return JUe(c,n[l+20>>2]|0)|0}function JUe(s,l){return s=s|0,l=l|0,zUe(s,l)|0}function zUe(s,l){return s=s|0,l=l|0,l?l=XUe(n[l>>2]|0,n[l+4>>2]|0,s)|0:l=0,(l|0?l:s)|0}function XUe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0;se=(n[s>>2]|0)+1794895138|0,m=Fg(n[s+8>>2]|0,se)|0,f=Fg(n[s+12>>2]|0,se)|0,d=Fg(n[s+16>>2]|0,se)|0;e:do if(m>>>0<l>>>2>>>0&&(q=l-(m<<2)|0,f>>>0<q>>>0&d>>>0<q>>>0)&&((d|f)&3|0)==0){for(q=f>>>2,M=d>>>2,O=0;;){if(k=m>>>1,Q=O+k|0,B=Q<<1,d=B+q|0,f=Fg(n[s+(d<<2)>>2]|0,se)|0,d=Fg(n[s+(d+1<<2)>>2]|0,se)|0,!(d>>>0<l>>>0&f>>>0<(l-d|0)>>>0)){f=0;break e}if(o[s+(d+f)>>0]|0){f=0;break e}if(f=o7(c,s+d|0)|0,!f)break;if(f=(f|0)<0,(m|0)==1){f=0;break e}else O=f?O:Q,m=f?k:m-k|0}f=B+M|0,d=Fg(n[s+(f<<2)>>2]|0,se)|0,f=Fg(n[s+(f+1<<2)>>2]|0,se)|0,f>>>0<l>>>0&d>>>0<(l-f|0)>>>0?f=(o[s+(f+d)>>0]|0)==0?s+f|0:0:f=0}else f=0;while(0);return f|0}function Fg(s,l){s=s|0,l=l|0;var c=0;return c=C7(s|0)|0,((l|0)==0?s:c)|0}function ZUe(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0,k=0;f=c+16|0,d=n[f>>2]|0,d?m=5:$Ue(c)|0?f=0:(d=n[f>>2]|0,m=5);e:do if((m|0)==5){if(k=c+20|0,B=n[k>>2]|0,f=B,(d-B|0)>>>0<l>>>0){f=ED[n[c+36>>2]&7](c,s,l)|0;break}t:do if((o[c+75>>0]|0)>-1){for(B=l;;){if(!B){m=0,d=s;break t}if(d=B+-1|0,(o[s+d>>0]|0)==10)break;B=d}if(f=ED[n[c+36>>2]&7](c,s,B)|0,f>>>0<B>>>0)break e;m=B,d=s+B|0,l=l-B|0,f=n[k>>2]|0}else m=0,d=s;while(0);Dr(f|0,d|0,l|0)|0,n[k>>2]=(n[k>>2]|0)+l,f=m+l|0}while(0);return f|0}function $Ue(s){s=s|0;var l=0,c=0;return l=s+74|0,c=o[l>>0]|0,o[l>>0]=c+255|c,l=n[s>>2]|0,l&8?(n[s>>2]=l|32,s=-1):(n[s+8>>2]=0,n[s+4>>2]=0,c=n[s+44>>2]|0,n[s+28>>2]=c,n[s+20>>2]=c,n[s+16>>2]=c+(n[s+48>>2]|0),s=0),s|0}function _n(s,l){s=y(s),l=y(l);var c=0,f=0;c=p7(s)|0;do if((c&2147483647)>>>0<=2139095040){if(f=p7(l)|0,(f&2147483647)>>>0<=2139095040)if((f^c|0)<0){s=(c|0)<0?l:s;break}else{s=s<l?l:s;break}}else s=l;while(0);return y(s)}function p7(s){return s=y(s),h[v>>2]=s,n[v>>2]|0|0}function Tg(s,l){s=y(s),l=y(l);var c=0,f=0;c=h7(s)|0;do if((c&2147483647)>>>0<=2139095040){if(f=h7(l)|0,(f&2147483647)>>>0<=2139095040)if((f^c|0)<0){s=(c|0)<0?s:l;break}else{s=s<l?s:l;break}}else s=l;while(0);return y(s)}function h7(s){return s=y(s),h[v>>2]=s,n[v>>2]|0|0}function kT(s,l){s=y(s),l=y(l);var c=0,f=0,d=0,m=0,B=0,k=0,Q=0,O=0;m=(h[v>>2]=s,n[v>>2]|0),k=(h[v>>2]=l,n[v>>2]|0),c=m>>>23&255,B=k>>>23&255,Q=m&-2147483648,d=k<<1;e:do if((d|0)!=0&&!((c|0)==255|((e3e(l)|0)&2147483647)>>>0>2139095040)){if(f=m<<1,f>>>0<=d>>>0)return l=y(s*y(0)),y((f|0)==(d|0)?l:s);if(c)f=m&8388607|8388608;else{if(c=m<<9,(c|0)>-1){f=c,c=0;do c=c+-1|0,f=f<<1;while((f|0)>-1)}else c=0;f=m<<1-c}if(B)k=k&8388607|8388608;else{if(m=k<<9,(m|0)>-1){d=0;do d=d+-1|0,m=m<<1;while((m|0)>-1)}else d=0;B=d,k=k<<1-d}d=f-k|0,m=(d|0)>-1;t:do if((c|0)>(B|0)){for(;;){if(m)if(d)f=d;else break;if(f=f<<1,c=c+-1|0,d=f-k|0,m=(d|0)>-1,(c|0)<=(B|0))break t}l=y(s*y(0));break e}while(0);if(m)if(d)f=d;else{l=y(s*y(0));break}if(f>>>0<8388608)do f=f<<1,c=c+-1|0;while(f>>>0<8388608);(c|0)>0?c=f+-8388608|c<<23:c=f>>>(1-c|0),l=(n[v>>2]=c|Q,y(h[v>>2]))}else O=3;while(0);return(O|0)==3&&(l=y(s*l),l=y(l/l)),y(l)}function e3e(s){return s=y(s),h[v>>2]=s,n[v>>2]|0|0}function t3e(s,l){return s=s|0,l=l|0,a7(n[582]|0,s,l)|0}function zr(s){s=s|0,Tt()}function Jm(s){s=s|0}function r3e(s,l){return s=s|0,l=l|0,0}function n3e(s){return s=s|0,(g7(s+4|0)|0)==-1?(ef[n[(n[s>>2]|0)+8>>2]&127](s),s=1):s=0,s|0}function g7(s){s=s|0;var l=0;return l=n[s>>2]|0,n[s>>2]=l+-1,l+-1|0}function bp(s){s=s|0,n3e(s)|0&&i3e(s)}function i3e(s){s=s|0;var l=0;l=s+8|0,(n[l>>2]|0)!=0&&(g7(l)|0)!=-1||ef[n[(n[s>>2]|0)+16>>2]&127](s)}function Vt(s){s=s|0;var l=0;for(l=(s|0)==0?1:s;s=pD(l)|0,!(s|0);){if(s=o3e()|0,!s){s=0;break}k7[s&0]()}return s|0}function d7(s){return s=s|0,Vt(s)|0}function gt(s){s=s|0,hD(s)}function s3e(s){s=s|0,(o[s+11>>0]|0)<0&>(n[s>>2]|0)}function o3e(){var s=0;return s=n[2923]|0,n[2923]=s+0,s|0}function a3e(){}function dD(s,l,c,f){return s=s|0,l=l|0,c=c|0,f=f|0,f=l-f-(c>>>0>s>>>0|0)>>>0,De=f,s-c>>>0|0|0}function QT(s,l,c,f){return s=s|0,l=l|0,c=c|0,f=f|0,c=s+c>>>0,De=l+f+(c>>>0<s>>>0|0)>>>0,c|0|0}function zm(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0,B=0;if(m=s+c|0,l=l&255,(c|0)>=67){for(;s&3;)o[s>>0]=l,s=s+1|0;for(f=m&-4|0,d=f-64|0,B=l|l<<8|l<<16|l<<24;(s|0)<=(d|0);)n[s>>2]=B,n[s+4>>2]=B,n[s+8>>2]=B,n[s+12>>2]=B,n[s+16>>2]=B,n[s+20>>2]=B,n[s+24>>2]=B,n[s+28>>2]=B,n[s+32>>2]=B,n[s+36>>2]=B,n[s+40>>2]=B,n[s+44>>2]=B,n[s+48>>2]=B,n[s+52>>2]=B,n[s+56>>2]=B,n[s+60>>2]=B,s=s+64|0;for(;(s|0)<(f|0);)n[s>>2]=B,s=s+4|0}for(;(s|0)<(m|0);)o[s>>0]=l,s=s+1|0;return m-c|0}function m7(s,l,c){return s=s|0,l=l|0,c=c|0,(c|0)<32?(De=l<<c|(s&(1<<c)-1<<32-c)>>>32-c,s<<c):(De=s<<c-32,0)}function mD(s,l,c){return s=s|0,l=l|0,c=c|0,(c|0)<32?(De=l>>>c,s>>>c|(l&(1<<c)-1)<<32-c):(De=0,l>>>c-32|0)}function Dr(s,l,c){s=s|0,l=l|0,c=c|0;var f=0,d=0,m=0;if((c|0)>=8192)return Ac(s|0,l|0,c|0)|0;if(m=s|0,d=s+c|0,(s&3)==(l&3)){for(;s&3;){if(!c)return m|0;o[s>>0]=o[l>>0]|0,s=s+1|0,l=l+1|0,c=c-1|0}for(c=d&-4|0,f=c-64|0;(s|0)<=(f|0);)n[s>>2]=n[l>>2],n[s+4>>2]=n[l+4>>2],n[s+8>>2]=n[l+8>>2],n[s+12>>2]=n[l+12>>2],n[s+16>>2]=n[l+16>>2],n[s+20>>2]=n[l+20>>2],n[s+24>>2]=n[l+24>>2],n[s+28>>2]=n[l+28>>2],n[s+32>>2]=n[l+32>>2],n[s+36>>2]=n[l+36>>2],n[s+40>>2]=n[l+40>>2],n[s+44>>2]=n[l+44>>2],n[s+48>>2]=n[l+48>>2],n[s+52>>2]=n[l+52>>2],n[s+56>>2]=n[l+56>>2],n[s+60>>2]=n[l+60>>2],s=s+64|0,l=l+64|0;for(;(s|0)<(c|0);)n[s>>2]=n[l>>2],s=s+4|0,l=l+4|0}else for(c=d-4|0;(s|0)<(c|0);)o[s>>0]=o[l>>0]|0,o[s+1>>0]=o[l+1>>0]|0,o[s+2>>0]=o[l+2>>0]|0,o[s+3>>0]=o[l+3>>0]|0,s=s+4|0,l=l+4|0;for(;(s|0)<(d|0);)o[s>>0]=o[l>>0]|0,s=s+1|0,l=l+1|0;return m|0}function y7(s){s=s|0;var l=0;return l=o[L+(s&255)>>0]|0,(l|0)<8?l|0:(l=o[L+(s>>8&255)>>0]|0,(l|0)<8?l+8|0:(l=o[L+(s>>16&255)>>0]|0,(l|0)<8?l+16|0:(o[L+(s>>>24)>>0]|0)+24|0))}function E7(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0;var m=0,B=0,k=0,Q=0,O=0,M=0,q=0,se=0,Ge=0,Oe=0;if(M=s,Q=l,O=Q,B=c,se=f,k=se,!O)return m=(d|0)!=0,k?m?(n[d>>2]=s|0,n[d+4>>2]=l&0,se=0,d=0,De=se,d|0):(se=0,d=0,De=se,d|0):(m&&(n[d>>2]=(M>>>0)%(B>>>0),n[d+4>>2]=0),se=0,d=(M>>>0)/(B>>>0)>>>0,De=se,d|0);m=(k|0)==0;do if(B){if(!m){if(m=(S(k|0)|0)-(S(O|0)|0)|0,m>>>0<=31){q=m+1|0,k=31-m|0,l=m-31>>31,B=q,s=M>>>(q>>>0)&l|O<<k,l=O>>>(q>>>0)&l,m=0,k=M<<k;break}return d?(n[d>>2]=s|0,n[d+4>>2]=Q|l&0,se=0,d=0,De=se,d|0):(se=0,d=0,De=se,d|0)}if(m=B-1|0,m&B|0){k=(S(B|0)|0)+33-(S(O|0)|0)|0,Oe=64-k|0,q=32-k|0,Q=q>>31,Ge=k-32|0,l=Ge>>31,B=k,s=q-1>>31&O>>>(Ge>>>0)|(O<<q|M>>>(k>>>0))&l,l=l&O>>>(k>>>0),m=M<<Oe&Q,k=(O<<Oe|M>>>(Ge>>>0))&Q|M<<q&k-33>>31;break}return d|0&&(n[d>>2]=m&M,n[d+4>>2]=0),(B|0)==1?(Ge=Q|l&0,Oe=s|0|0,De=Ge,Oe|0):(Oe=y7(B|0)|0,Ge=O>>>(Oe>>>0)|0,Oe=O<<32-Oe|M>>>(Oe>>>0)|0,De=Ge,Oe|0)}else{if(m)return d|0&&(n[d>>2]=(O>>>0)%(B>>>0),n[d+4>>2]=0),Ge=0,Oe=(O>>>0)/(B>>>0)>>>0,De=Ge,Oe|0;if(!M)return d|0&&(n[d>>2]=0,n[d+4>>2]=(O>>>0)%(k>>>0)),Ge=0,Oe=(O>>>0)/(k>>>0)>>>0,De=Ge,Oe|0;if(m=k-1|0,!(m&k))return d|0&&(n[d>>2]=s|0,n[d+4>>2]=m&O|l&0),Ge=0,Oe=O>>>((y7(k|0)|0)>>>0),De=Ge,Oe|0;if(m=(S(k|0)|0)-(S(O|0)|0)|0,m>>>0<=30){l=m+1|0,k=31-m|0,B=l,s=O<<k|M>>>(l>>>0),l=O>>>(l>>>0),m=0,k=M<<k;break}return d?(n[d>>2]=s|0,n[d+4>>2]=Q|l&0,Ge=0,Oe=0,De=Ge,Oe|0):(Ge=0,Oe=0,De=Ge,Oe|0)}while(0);if(!B)O=k,Q=0,k=0;else{q=c|0|0,M=se|f&0,O=QT(q|0,M|0,-1,-1)|0,c=De,Q=k,k=0;do f=Q,Q=m>>>31|Q<<1,m=k|m<<1,f=s<<1|f>>>31|0,se=s>>>31|l<<1|0,dD(O|0,c|0,f|0,se|0)|0,Oe=De,Ge=Oe>>31|((Oe|0)<0?-1:0)<<1,k=Ge&1,s=dD(f|0,se|0,Ge&q|0,(((Oe|0)<0?-1:0)>>31|((Oe|0)<0?-1:0)<<1)&M|0)|0,l=De,B=B-1|0;while((B|0)!=0);O=Q,Q=0}return B=0,d|0&&(n[d>>2]=s,n[d+4>>2]=l),Ge=(m|0)>>>31|(O|B)<<1|(B<<1|m>>>31)&0|Q,Oe=(m<<1|0>>>31)&-2|k,De=Ge,Oe|0}function FT(s,l,c,f){return s=s|0,l=l|0,c=c|0,f=f|0,E7(s,l,c,f,0)|0}function kp(s){s=s|0;var l=0,c=0;return c=s+15&-16|0,l=n[I>>2]|0,s=l+c|0,(c|0)>0&(s|0)<(l|0)|(s|0)<0?(ie()|0,vA(12),-1):(n[I>>2]=s,(s|0)>(Z()|0)&&(X()|0)==0?(n[I>>2]=l,vA(12),-1):l|0)}function Mw(s,l,c){s=s|0,l=l|0,c=c|0;var f=0;if((l|0)<(s|0)&(s|0)<(l+c|0)){for(f=s,l=l+c|0,s=s+c|0;(c|0)>0;)s=s-1|0,l=l-1|0,c=c-1|0,o[s>>0]=o[l>>0]|0;s=f}else Dr(s,l,c)|0;return s|0}function TT(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0;var d=0,m=0;return m=C,C=C+16|0,d=m|0,E7(s,l,c,f,d)|0,C=m,De=n[d+4>>2]|0,n[d>>2]|0|0}function C7(s){return s=s|0,(s&255)<<24|(s>>8&255)<<16|(s>>16&255)<<8|s>>>24|0}function l3e(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,w7[s&1](l|0,c|0,f|0,d|0,m|0)}function c3e(s,l,c){s=s|0,l=l|0,c=y(c),I7[s&1](l|0,y(c))}function u3e(s,l,c){s=s|0,l=l|0,c=+c,B7[s&31](l|0,+c)}function A3e(s,l,c,f){return s=s|0,l=l|0,c=y(c),f=y(f),y(v7[s&0](l|0,y(c),y(f)))}function f3e(s,l){s=s|0,l=l|0,ef[s&127](l|0)}function p3e(s,l,c){s=s|0,l=l|0,c=c|0,tf[s&31](l|0,c|0)}function h3e(s,l){return s=s|0,l=l|0,Ng[s&31](l|0)|0}function g3e(s,l,c,f,d){s=s|0,l=l|0,c=+c,f=+f,d=d|0,D7[s&1](l|0,+c,+f,d|0)}function d3e(s,l,c,f){s=s|0,l=l|0,c=+c,f=+f,z3e[s&1](l|0,+c,+f)}function m3e(s,l,c,f){return s=s|0,l=l|0,c=c|0,f=f|0,ED[s&7](l|0,c|0,f|0)|0}function y3e(s,l,c,f){return s=s|0,l=l|0,c=c|0,f=f|0,+X3e[s&1](l|0,c|0,f|0)}function E3e(s,l){return s=s|0,l=l|0,+P7[s&15](l|0)}function C3e(s,l,c){return s=s|0,l=l|0,c=+c,Z3e[s&1](l|0,+c)|0}function w3e(s,l,c){return s=s|0,l=l|0,c=c|0,NT[s&15](l|0,c|0)|0}function I3e(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=+f,d=+d,m=m|0,$3e[s&1](l|0,c|0,+f,+d,m|0)}function B3e(s,l,c,f,d,m,B){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,B=B|0,e_e[s&1](l|0,c|0,f|0,d|0,m|0,B|0)}function v3e(s,l,c){return s=s|0,l=l|0,c=c|0,+S7[s&7](l|0,c|0)}function D3e(s){return s=s|0,CD[s&7]()|0}function P3e(s,l,c,f,d,m){return s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,x7[s&1](l|0,c|0,f|0,d|0,m|0)|0}function S3e(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=+d,t_e[s&1](l|0,c|0,f|0,+d)}function x3e(s,l,c,f,d,m,B){s=s|0,l=l|0,c=c|0,f=y(f),d=d|0,m=y(m),B=B|0,b7[s&1](l|0,c|0,y(f),d|0,y(m),B|0)}function b3e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,_w[s&15](l|0,c|0,f|0)}function k3e(s){s=s|0,k7[s&0]()}function Q3e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=+f,Q7[s&15](l|0,c|0,+f)}function F3e(s,l,c){return s=s|0,l=+l,c=+c,r_e[s&1](+l,+c)|0}function T3e(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,LT[s&15](l|0,c|0,f|0,d|0)}function R3e(s,l,c,f,d){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,F(0)}function N3e(s,l){s=s|0,l=y(l),F(1)}function ma(s,l){s=s|0,l=+l,F(2)}function L3e(s,l,c){return s=s|0,l=y(l),c=y(c),F(3),Ze}function Er(s){s=s|0,F(4)}function Ow(s,l){s=s|0,l=l|0,F(5)}function Ja(s){return s=s|0,F(6),0}function M3e(s,l,c,f){s=s|0,l=+l,c=+c,f=f|0,F(7)}function O3e(s,l,c){s=s|0,l=+l,c=+c,F(8)}function U3e(s,l,c){return s=s|0,l=l|0,c=c|0,F(9),0}function _3e(s,l,c){return s=s|0,l=l|0,c=c|0,F(10),0}function Rg(s){return s=s|0,F(11),0}function H3e(s,l){return s=s|0,l=+l,F(12),0}function Uw(s,l){return s=s|0,l=l|0,F(13),0}function j3e(s,l,c,f,d){s=s|0,l=l|0,c=+c,f=+f,d=d|0,F(14)}function q3e(s,l,c,f,d,m){s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,m=m|0,F(15)}function RT(s,l){return s=s|0,l=l|0,F(16),0}function G3e(){return F(17),0}function Y3e(s,l,c,f,d){return s=s|0,l=l|0,c=c|0,f=f|0,d=d|0,F(18),0}function W3e(s,l,c,f){s=s|0,l=l|0,c=c|0,f=+f,F(19)}function V3e(s,l,c,f,d,m){s=s|0,l=l|0,c=y(c),f=f|0,d=y(d),m=m|0,F(20)}function yD(s,l,c){s=s|0,l=l|0,c=c|0,F(21)}function K3e(){F(22)}function Xm(s,l,c){s=s|0,l=l|0,c=+c,F(23)}function J3e(s,l){return s=+s,l=+l,F(24),0}function Zm(s,l,c,f){s=s|0,l=l|0,c=c|0,f=f|0,F(25)}var w7=[R3e,YLe],I7=[N3e,fo],B7=[ma,xw,bw,wF,IF,Dl,kw,BF,Hm,xu,Fw,vF,$v,WA,eD,jm,tD,rD,qm,ma,ma,ma,ma,ma,ma,ma,ma,ma,ma,ma,ma,ma],v7=[L3e],ef=[Er,Jm,DDe,PDe,SDe,rbe,nbe,ibe,CNe,wNe,INe,FLe,TLe,RLe,eUe,tUe,rUe,hs,Kv,_m,YA,Qw,wve,Ive,gDe,NDe,VDe,APe,SPe,GPe,aSe,ISe,MSe,$Se,gxe,Qxe,Vxe,wbe,Mbe,$be,gke,Qke,Vke,fQe,SQe,HQe,nFe,Sc,RFe,zFe,gTe,TTe,KTe,gRe,DRe,xRe,YRe,KRe,ANe,vNe,SNe,GNe,lLe,a5,qMe,COe,NOe,zOe,y4e,T4e,G4e,V4e,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er,Er],tf=[Ow,hF,gF,Sw,Su,dF,mF,Ip,yF,EF,CF,Zv,VA,Ke,At,Wt,vr,Sn,Fr,PF,lve,Qve,dQe,kQe,MTe,WMe,dLe,Y9,Ow,Ow,Ow,Ow],Ng=[Ja,QUe,pF,D,fe,ve,vt,wt,bt,_r,di,po,sve,ove,Bve,oFe,ZTe,VNe,zMe,Wa,Ja,Ja,Ja,Ja,Ja,Ja,Ja,Ja,Ja,Ja,Ja,Ja],D7=[M3e,vve],z3e=[O3e,hNe],ED=[U3e,s7,FUe,NUe,KPe,Dbe,OFe,e4e],X3e=[_3e,Exe],P7=[Rg,Yo,rt,xn,Dve,Pve,Sve,xve,bve,kve,Rg,Rg,Rg,Rg,Rg,Rg],Z3e=[H3e,IRe],NT=[Uw,r3e,ave,EDe,gPe,uSe,DSe,Xxe,Hbe,YQe,Wv,UOe,Uw,Uw,Uw,Uw],$3e=[j3e,XDe],e_e=[q3e,I4e],S7=[RT,ai,Fve,Tve,Rve,Nxe,RT,RT],CD=[G3e,Nve,Dw,ga,FRe,ZRe,QNe,X4e],x7=[Y3e,Ew],t_e=[W3e,Eke],b7=[V3e,cve],_w=[yD,R,is,en,ho,QPe,_Se,Nke,Xke,Um,hMe,vOe,M4e,yD,yD,yD],k7=[K3e],Q7=[Xm,Jv,zv,Xv,GA,nD,DF,P,nke,eTe,yRe,Xm,Xm,Xm,Xm,Xm],r_e=[J3e,yNe],LT=[Zm,nxe,hFe,ETe,aRe,ORe,iNe,ONe,pLe,rOe,lUe,Zm,Zm,Zm,Zm,Zm];return{_llvm_bswap_i32:C7,dynCall_idd:F3e,dynCall_i:D3e,_i64Subtract:dD,___udivdi3:FT,dynCall_vif:c3e,setThrew:hu,dynCall_viii:b3e,_bitshift64Lshr:mD,_bitshift64Shl:m7,dynCall_vi:f3e,dynCall_viiddi:I3e,dynCall_diii:y3e,dynCall_iii:w3e,_memset:zm,_sbrk:kp,_memcpy:Dr,__GLOBAL__sub_I_Yoga_cpp:Om,dynCall_vii:p3e,___uremdi3:TT,dynCall_vid:u3e,stackAlloc:lo,_nbind_init:EUe,getTempRet0:Ua,dynCall_di:E3e,dynCall_iid:C3e,setTempRet0:xA,_i64Add:QT,dynCall_fiff:A3e,dynCall_iiii:m3e,_emscripten_get_global_libc:kUe,dynCall_viid:Q3e,dynCall_viiid:S3e,dynCall_viififi:x3e,dynCall_ii:h3e,__GLOBAL__sub_I_Binding_cc:NMe,dynCall_viiii:T3e,dynCall_iiiiii:P3e,stackSave:gc,dynCall_viiiii:l3e,__GLOBAL__sub_I_nbind_cc:Lve,dynCall_vidd:d3e,_free:hD,runPostSets:a3e,dynCall_viiiiii:B3e,establishStackSpace:ji,_memmove:Mw,stackRestore:pu,_malloc:pD,__GLOBAL__sub_I_common_cc:tLe,dynCall_viddi:g3e,dynCall_dii:v3e,dynCall_v:k3e}}(Module.asmGlobalArg,Module.asmLibraryArg,buffer),_llvm_bswap_i32=Module._llvm_bswap_i32=asm._llvm_bswap_i32,getTempRet0=Module.getTempRet0=asm.getTempRet0,___udivdi3=Module.___udivdi3=asm.___udivdi3,setThrew=Module.setThrew=asm.setThrew,_bitshift64Lshr=Module._bitshift64Lshr=asm._bitshift64Lshr,_bitshift64Shl=Module._bitshift64Shl=asm._bitshift64Shl,_memset=Module._memset=asm._memset,_sbrk=Module._sbrk=asm._sbrk,_memcpy=Module._memcpy=asm._memcpy,stackAlloc=Module.stackAlloc=asm.stackAlloc,___uremdi3=Module.___uremdi3=asm.___uremdi3,_nbind_init=Module._nbind_init=asm._nbind_init,_i64Subtract=Module._i64Subtract=asm._i64Subtract,setTempRet0=Module.setTempRet0=asm.setTempRet0,_i64Add=Module._i64Add=asm._i64Add,_emscripten_get_global_libc=Module._emscripten_get_global_libc=asm._emscripten_get_global_libc,__GLOBAL__sub_I_Yoga_cpp=Module.__GLOBAL__sub_I_Yoga_cpp=asm.__GLOBAL__sub_I_Yoga_cpp,__GLOBAL__sub_I_Binding_cc=Module.__GLOBAL__sub_I_Binding_cc=asm.__GLOBAL__sub_I_Binding_cc,stackSave=Module.stackSave=asm.stackSave,__GLOBAL__sub_I_nbind_cc=Module.__GLOBAL__sub_I_nbind_cc=asm.__GLOBAL__sub_I_nbind_cc,_free=Module._free=asm._free,runPostSets=Module.runPostSets=asm.runPostSets,establishStackSpace=Module.establishStackSpace=asm.establishStackSpace,_memmove=Module._memmove=asm._memmove,stackRestore=Module.stackRestore=asm.stackRestore,_malloc=Module._malloc=asm._malloc,__GLOBAL__sub_I_common_cc=Module.__GLOBAL__sub_I_common_cc=asm.__GLOBAL__sub_I_common_cc,dynCall_viiiii=Module.dynCall_viiiii=asm.dynCall_viiiii,dynCall_vif=Module.dynCall_vif=asm.dynCall_vif,dynCall_vid=Module.dynCall_vid=asm.dynCall_vid,dynCall_fiff=Module.dynCall_fiff=asm.dynCall_fiff,dynCall_vi=Module.dynCall_vi=asm.dynCall_vi,dynCall_vii=Module.dynCall_vii=asm.dynCall_vii,dynCall_ii=Module.dynCall_ii=asm.dynCall_ii,dynCall_viddi=Module.dynCall_viddi=asm.dynCall_viddi,dynCall_vidd=Module.dynCall_vidd=asm.dynCall_vidd,dynCall_iiii=Module.dynCall_iiii=asm.dynCall_iiii,dynCall_diii=Module.dynCall_diii=asm.dynCall_diii,dynCall_di=Module.dynCall_di=asm.dynCall_di,dynCall_iid=Module.dynCall_iid=asm.dynCall_iid,dynCall_iii=Module.dynCall_iii=asm.dynCall_iii,dynCall_viiddi=Module.dynCall_viiddi=asm.dynCall_viiddi,dynCall_viiiiii=Module.dynCall_viiiiii=asm.dynCall_viiiiii,dynCall_dii=Module.dynCall_dii=asm.dynCall_dii,dynCall_i=Module.dynCall_i=asm.dynCall_i,dynCall_iiiiii=Module.dynCall_iiiiii=asm.dynCall_iiiiii,dynCall_viiid=Module.dynCall_viiid=asm.dynCall_viiid,dynCall_viififi=Module.dynCall_viififi=asm.dynCall_viififi,dynCall_viii=Module.dynCall_viii=asm.dynCall_viii,dynCall_v=Module.dynCall_v=asm.dynCall_v,dynCall_viid=Module.dynCall_viid=asm.dynCall_viid,dynCall_idd=Module.dynCall_idd=asm.dynCall_idd,dynCall_viiii=Module.dynCall_viiii=asm.dynCall_viiii;Runtime.stackAlloc=Module.stackAlloc,Runtime.stackSave=Module.stackSave,Runtime.stackRestore=Module.stackRestore,Runtime.establishStackSpace=Module.establishStackSpace,Runtime.setTempRet0=Module.setTempRet0,Runtime.getTempRet0=Module.getTempRet0,Module.asm=asm;function ExitStatus(t){this.name="ExitStatus",this.message="Program terminated with exit("+t+")",this.status=t}ExitStatus.prototype=new Error,ExitStatus.prototype.constructor=ExitStatus;var initialStackTop,preloadStartTime=null,calledMain=!1;dependenciesFulfilled=function t(){Module.calledRun||run(),Module.calledRun||(dependenciesFulfilled=t)},Module.callMain=Module.callMain=function t(e){e=e||[],ensureInitRuntime();var r=e.length+1;function o(){for(var p=0;p<4-1;p++)a.push(0)}var a=[allocate(intArrayFromString(Module.thisProgram),"i8",ALLOC_NORMAL)];o();for(var n=0;n<r-1;n=n+1)a.push(allocate(intArrayFromString(e[n]),"i8",ALLOC_NORMAL)),o();a.push(0),a=allocate(a,"i32",ALLOC_NORMAL);try{var u=Module._main(r,a,0);exit(u,!0)}catch(p){if(p instanceof ExitStatus)return;if(p=="SimulateInfiniteLoop"){Module.noExitRuntime=!0;return}else{var A=p;p&&typeof p=="object"&&p.stack&&(A=[p,p.stack]),Module.printErr("exception thrown: "+A),Module.quit(1,p)}}finally{calledMain=!0}};function run(t){if(t=t||Module.arguments,preloadStartTime===null&&(preloadStartTime=Date.now()),runDependencies>0||(preRun(),runDependencies>0)||Module.calledRun)return;function e(){Module.calledRun||(Module.calledRun=!0,!ABORT&&(ensureInitRuntime(),preMain(),Module.onRuntimeInitialized&&Module.onRuntimeInitialized(),Module._main&&shouldRunNow&&Module.callMain(t),postRun()))}Module.setStatus?(Module.setStatus("Running..."),setTimeout(function(){setTimeout(function(){Module.setStatus("")},1),e()},1)):e()}Module.run=Module.run=run;function exit(t,e){e&&Module.noExitRuntime||(Module.noExitRuntime||(ABORT=!0,EXITSTATUS=t,STACKTOP=initialStackTop,exitRuntime(),Module.onExit&&Module.onExit(t)),ENVIRONMENT_IS_NODE&&process.exit(t),Module.quit(t,new ExitStatus(t)))}Module.exit=Module.exit=exit;var abortDecorators=[];function abort(t){Module.onAbort&&Module.onAbort(t),t!==void 0?(Module.print(t),Module.printErr(t),t=JSON.stringify(t)):t="",ABORT=!0,EXITSTATUS=1;var e=` +If this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.`,r="abort("+t+") at "+stackTrace()+e;throw abortDecorators&&abortDecorators.forEach(function(o){r=o(r,t)}),r}if(Module.abort=Module.abort=abort,Module.preInit)for(typeof Module.preInit=="function"&&(Module.preInit=[Module.preInit]);Module.preInit.length>0;)Module.preInit.pop()();var shouldRunNow=!0;Module.noInitialRun&&(shouldRunNow=!1),run()})});var om=_((wVt,OEe)=>{"use strict";var Jyt=LEe(),zyt=MEe(),Q6=!1,F6=null;zyt({},function(t,e){if(!Q6){if(Q6=!0,t)throw t;F6=e}});if(!Q6)throw new Error("Failed to load the yoga module - it needed to be loaded synchronously, but didn't");OEe.exports=Jyt(F6.bind,F6.lib)});var R6=_((IVt,T6)=>{"use strict";var UEe=t=>Number.isNaN(t)?!1:t>=4352&&(t<=4447||t===9001||t===9002||11904<=t&&t<=12871&&t!==12351||12880<=t&&t<=19903||19968<=t&&t<=42182||43360<=t&&t<=43388||44032<=t&&t<=55203||63744<=t&&t<=64255||65040<=t&&t<=65049||65072<=t&&t<=65131||65281<=t&&t<=65376||65504<=t&&t<=65510||110592<=t&&t<=110593||127488<=t&&t<=127569||131072<=t&&t<=262141);T6.exports=UEe;T6.exports.default=UEe});var HEe=_((BVt,_Ee)=>{"use strict";_Ee.exports=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g}});var Jk=_((vVt,N6)=>{"use strict";var Xyt=MP(),Zyt=R6(),$yt=HEe(),jEe=t=>{if(typeof t!="string"||t.length===0||(t=Xyt(t),t.length===0))return 0;t=t.replace($yt()," ");let e=0;for(let r=0;r<t.length;r++){let o=t.codePointAt(r);o<=31||o>=127&&o<=159||o>=768&&o<=879||(o>65535&&r++,e+=Zyt(o)?2:1)}return e};N6.exports=jEe;N6.exports.default=jEe});var M6=_((DVt,L6)=>{"use strict";var eEt=Jk(),qEe=t=>{let e=0;for(let r of t.split(` +`))e=Math.max(e,eEt(r));return e};L6.exports=qEe;L6.exports.default=qEe});var GEe=_(lB=>{"use strict";var tEt=lB&&lB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(lB,"__esModule",{value:!0});var rEt=tEt(M6()),O6={};lB.default=t=>{if(t.length===0)return{width:0,height:0};if(O6[t])return O6[t];let e=rEt.default(t),r=t.split(` +`).length;return O6[t]={width:e,height:r},{width:e,height:r}}});var YEe=_(cB=>{"use strict";var nEt=cB&&cB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(cB,"__esModule",{value:!0});var dn=nEt(om()),iEt=(t,e)=>{"position"in e&&t.setPositionType(e.position==="absolute"?dn.default.POSITION_TYPE_ABSOLUTE:dn.default.POSITION_TYPE_RELATIVE)},sEt=(t,e)=>{"marginLeft"in e&&t.setMargin(dn.default.EDGE_START,e.marginLeft||0),"marginRight"in e&&t.setMargin(dn.default.EDGE_END,e.marginRight||0),"marginTop"in e&&t.setMargin(dn.default.EDGE_TOP,e.marginTop||0),"marginBottom"in e&&t.setMargin(dn.default.EDGE_BOTTOM,e.marginBottom||0)},oEt=(t,e)=>{"paddingLeft"in e&&t.setPadding(dn.default.EDGE_LEFT,e.paddingLeft||0),"paddingRight"in e&&t.setPadding(dn.default.EDGE_RIGHT,e.paddingRight||0),"paddingTop"in e&&t.setPadding(dn.default.EDGE_TOP,e.paddingTop||0),"paddingBottom"in e&&t.setPadding(dn.default.EDGE_BOTTOM,e.paddingBottom||0)},aEt=(t,e)=>{var r;"flexGrow"in e&&t.setFlexGrow((r=e.flexGrow)!==null&&r!==void 0?r:0),"flexShrink"in e&&t.setFlexShrink(typeof e.flexShrink=="number"?e.flexShrink:1),"flexDirection"in e&&(e.flexDirection==="row"&&t.setFlexDirection(dn.default.FLEX_DIRECTION_ROW),e.flexDirection==="row-reverse"&&t.setFlexDirection(dn.default.FLEX_DIRECTION_ROW_REVERSE),e.flexDirection==="column"&&t.setFlexDirection(dn.default.FLEX_DIRECTION_COLUMN),e.flexDirection==="column-reverse"&&t.setFlexDirection(dn.default.FLEX_DIRECTION_COLUMN_REVERSE)),"flexBasis"in e&&(typeof e.flexBasis=="number"?t.setFlexBasis(e.flexBasis):typeof e.flexBasis=="string"?t.setFlexBasisPercent(Number.parseInt(e.flexBasis,10)):t.setFlexBasis(NaN)),"alignItems"in e&&((e.alignItems==="stretch"||!e.alignItems)&&t.setAlignItems(dn.default.ALIGN_STRETCH),e.alignItems==="flex-start"&&t.setAlignItems(dn.default.ALIGN_FLEX_START),e.alignItems==="center"&&t.setAlignItems(dn.default.ALIGN_CENTER),e.alignItems==="flex-end"&&t.setAlignItems(dn.default.ALIGN_FLEX_END)),"alignSelf"in e&&((e.alignSelf==="auto"||!e.alignSelf)&&t.setAlignSelf(dn.default.ALIGN_AUTO),e.alignSelf==="flex-start"&&t.setAlignSelf(dn.default.ALIGN_FLEX_START),e.alignSelf==="center"&&t.setAlignSelf(dn.default.ALIGN_CENTER),e.alignSelf==="flex-end"&&t.setAlignSelf(dn.default.ALIGN_FLEX_END)),"justifyContent"in e&&((e.justifyContent==="flex-start"||!e.justifyContent)&&t.setJustifyContent(dn.default.JUSTIFY_FLEX_START),e.justifyContent==="center"&&t.setJustifyContent(dn.default.JUSTIFY_CENTER),e.justifyContent==="flex-end"&&t.setJustifyContent(dn.default.JUSTIFY_FLEX_END),e.justifyContent==="space-between"&&t.setJustifyContent(dn.default.JUSTIFY_SPACE_BETWEEN),e.justifyContent==="space-around"&&t.setJustifyContent(dn.default.JUSTIFY_SPACE_AROUND))},lEt=(t,e)=>{var r,o;"width"in e&&(typeof e.width=="number"?t.setWidth(e.width):typeof e.width=="string"?t.setWidthPercent(Number.parseInt(e.width,10)):t.setWidthAuto()),"height"in e&&(typeof e.height=="number"?t.setHeight(e.height):typeof e.height=="string"?t.setHeightPercent(Number.parseInt(e.height,10)):t.setHeightAuto()),"minWidth"in e&&(typeof e.minWidth=="string"?t.setMinWidthPercent(Number.parseInt(e.minWidth,10)):t.setMinWidth((r=e.minWidth)!==null&&r!==void 0?r:0)),"minHeight"in e&&(typeof e.minHeight=="string"?t.setMinHeightPercent(Number.parseInt(e.minHeight,10)):t.setMinHeight((o=e.minHeight)!==null&&o!==void 0?o:0))},cEt=(t,e)=>{"display"in e&&t.setDisplay(e.display==="flex"?dn.default.DISPLAY_FLEX:dn.default.DISPLAY_NONE)},uEt=(t,e)=>{if("borderStyle"in e){let r=typeof e.borderStyle=="string"?1:0;t.setBorder(dn.default.EDGE_TOP,r),t.setBorder(dn.default.EDGE_BOTTOM,r),t.setBorder(dn.default.EDGE_LEFT,r),t.setBorder(dn.default.EDGE_RIGHT,r)}};cB.default=(t,e={})=>{iEt(t,e),sEt(t,e),oEt(t,e),aEt(t,e),lEt(t,e),cEt(t,e),uEt(t,e)}});var KEe=_((xVt,VEe)=>{"use strict";var uB=Jk(),AEt=MP(),fEt=vI(),_6=new Set(["\x1B","\x9B"]),pEt=39,WEe=t=>`${_6.values().next().value}[${t}m`,hEt=t=>t.split(" ").map(e=>uB(e)),U6=(t,e,r)=>{let o=[...e],a=!1,n=uB(AEt(t[t.length-1]));for(let[u,A]of o.entries()){let p=uB(A);if(n+p<=r?t[t.length-1]+=A:(t.push(A),n=0),_6.has(A))a=!0;else if(a&&A==="m"){a=!1;continue}a||(n+=p,n===r&&u<o.length-1&&(t.push(""),n=0))}!n&&t[t.length-1].length>0&&t.length>1&&(t[t.length-2]+=t.pop())},gEt=t=>{let e=t.split(" "),r=e.length;for(;r>0&&!(uB(e[r-1])>0);)r--;return r===e.length?t:e.slice(0,r).join(" ")+e.slice(r).join("")},dEt=(t,e,r={})=>{if(r.trim!==!1&&t.trim()==="")return"";let o="",a="",n,u=hEt(t),A=[""];for(let[p,h]of t.split(" ").entries()){r.trim!==!1&&(A[A.length-1]=A[A.length-1].trimLeft());let E=uB(A[A.length-1]);if(p!==0&&(E>=e&&(r.wordWrap===!1||r.trim===!1)&&(A.push(""),E=0),(E>0||r.trim===!1)&&(A[A.length-1]+=" ",E++)),r.hard&&u[p]>e){let I=e-E,v=1+Math.floor((u[p]-I-1)/e);Math.floor((u[p]-1)/e)<v&&A.push(""),U6(A,h,e);continue}if(E+u[p]>e&&E>0&&u[p]>0){if(r.wordWrap===!1&&E<e){U6(A,h,e);continue}A.push("")}if(E+u[p]>e&&r.wordWrap===!1){U6(A,h,e);continue}A[A.length-1]+=h}r.trim!==!1&&(A=A.map(gEt)),o=A.join(` +`);for(let[p,h]of[...o].entries()){if(a+=h,_6.has(h)){let I=parseFloat(/\d[^m]*/.exec(o.slice(p,p+4)));n=I===pEt?null:I}let E=fEt.codes.get(Number(n));n&&E&&(o[p+1]===` +`?a+=WEe(E):h===` +`&&(a+=WEe(n)))}return a};VEe.exports=(t,e,r)=>String(t).normalize().replace(/\r\n/g,` +`).split(` +`).map(o=>dEt(o,e,r)).join(` +`)});var XEe=_((bVt,zEe)=>{"use strict";var JEe="[\uD800-\uDBFF][\uDC00-\uDFFF]",mEt=t=>t&&t.exact?new RegExp(`^${JEe}$`):new RegExp(JEe,"g");zEe.exports=mEt});var H6=_((kVt,tCe)=>{"use strict";var yEt=R6(),EEt=XEe(),ZEe=vI(),eCe=["\x1B","\x9B"],zk=t=>`${eCe[0]}[${t}m`,$Ee=(t,e,r)=>{let o=[];t=[...t];for(let a of t){let n=a;a.match(";")&&(a=a.split(";")[0][0]+"0");let u=ZEe.codes.get(parseInt(a,10));if(u){let A=t.indexOf(u.toString());A>=0?t.splice(A,1):o.push(zk(e?u:n))}else if(e){o.push(zk(0));break}else o.push(zk(n))}if(e&&(o=o.filter((a,n)=>o.indexOf(a)===n),r!==void 0)){let a=zk(ZEe.codes.get(parseInt(r,10)));o=o.reduce((n,u)=>u===a?[u,...n]:[...n,u],[])}return o.join("")};tCe.exports=(t,e,r)=>{let o=[...t.normalize()],a=[];r=typeof r=="number"?r:o.length;let n=!1,u,A=0,p="";for(let[h,E]of o.entries()){let I=!1;if(eCe.includes(E)){let v=/\d[^m]*/.exec(t.slice(h,h+18));u=v&&v.length>0?v[0]:void 0,A<r&&(n=!0,u!==void 0&&a.push(u))}else n&&E==="m"&&(n=!1,I=!0);if(!n&&!I&&++A,!EEt({exact:!0}).test(E)&&yEt(E.codePointAt())&&++A,A>e&&A<=r)p+=E;else if(A===e&&!n&&u!==void 0)p=$Ee(a);else if(A>=r){p+=$Ee(a,!0,u);break}}return p}});var nCe=_((QVt,rCe)=>{"use strict";var y0=H6(),CEt=Jk();function Xk(t,e,r){if(t.charAt(e)===" ")return e;for(let o=1;o<=3;o++)if(r){if(t.charAt(e+o)===" ")return e+o}else if(t.charAt(e-o)===" ")return e-o;return e}rCe.exports=(t,e,r)=>{r={position:"end",preferTruncationOnSpace:!1,...r};let{position:o,space:a,preferTruncationOnSpace:n}=r,u="\u2026",A=1;if(typeof t!="string")throw new TypeError(`Expected \`input\` to be a string, got ${typeof t}`);if(typeof e!="number")throw new TypeError(`Expected \`columns\` to be a number, got ${typeof e}`);if(e<1)return"";if(e===1)return u;let p=CEt(t);if(p<=e)return t;if(o==="start"){if(n){let h=Xk(t,p-e+1,!0);return u+y0(t,h,p).trim()}return a===!0&&(u+=" ",A=2),u+y0(t,p-e+A,p)}if(o==="middle"){a===!0&&(u=" "+u+" ",A=3);let h=Math.floor(e/2);if(n){let E=Xk(t,h),I=Xk(t,p-(e-h)+1,!0);return y0(t,0,E)+u+y0(t,I,p).trim()}return y0(t,0,h)+u+y0(t,p-(e-h)+A,p)}if(o==="end"){if(n){let h=Xk(t,e-1);return y0(t,0,h)+u}return a===!0&&(u=" "+u,A=2),y0(t,0,e-A)+u}throw new Error(`Expected \`options.position\` to be either \`start\`, \`middle\` or \`end\`, got ${o}`)}});var q6=_(AB=>{"use strict";var iCe=AB&&AB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(AB,"__esModule",{value:!0});var wEt=iCe(KEe()),IEt=iCe(nCe()),j6={};AB.default=(t,e,r)=>{let o=t+String(e)+String(r);if(j6[o])return j6[o];let a=t;if(r==="wrap"&&(a=wEt.default(t,e,{trim:!1,hard:!0})),r.startsWith("truncate")){let n="end";r==="truncate-middle"&&(n="middle"),r==="truncate-start"&&(n="start"),a=IEt.default(t,e,{position:n})}return j6[o]=a,a}});var Y6=_(G6=>{"use strict";Object.defineProperty(G6,"__esModule",{value:!0});var sCe=t=>{let e="";if(t.childNodes.length>0)for(let r of t.childNodes){let o="";r.nodeName==="#text"?o=r.nodeValue:((r.nodeName==="ink-text"||r.nodeName==="ink-virtual-text")&&(o=sCe(r)),o.length>0&&typeof r.internal_transform=="function"&&(o=r.internal_transform(o))),e+=o}return e};G6.default=sCe});var W6=_(pi=>{"use strict";var fB=pi&&pi.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(pi,"__esModule",{value:!0});pi.setTextNodeValue=pi.createTextNode=pi.setStyle=pi.setAttribute=pi.removeChildNode=pi.insertBeforeNode=pi.appendChildNode=pi.createNode=pi.TEXT_NAME=void 0;var BEt=fB(om()),oCe=fB(GEe()),vEt=fB(YEe()),DEt=fB(q6()),PEt=fB(Y6());pi.TEXT_NAME="#text";pi.createNode=t=>{var e;let r={nodeName:t,style:{},attributes:{},childNodes:[],parentNode:null,yogaNode:t==="ink-virtual-text"?void 0:BEt.default.Node.create()};return t==="ink-text"&&((e=r.yogaNode)===null||e===void 0||e.setMeasureFunc(SEt.bind(null,r))),r};pi.appendChildNode=(t,e)=>{var r;e.parentNode&&pi.removeChildNode(e.parentNode,e),e.parentNode=t,t.childNodes.push(e),e.yogaNode&&((r=t.yogaNode)===null||r===void 0||r.insertChild(e.yogaNode,t.yogaNode.getChildCount())),(t.nodeName==="ink-text"||t.nodeName==="ink-virtual-text")&&Zk(t)};pi.insertBeforeNode=(t,e,r)=>{var o,a;e.parentNode&&pi.removeChildNode(e.parentNode,e),e.parentNode=t;let n=t.childNodes.indexOf(r);if(n>=0){t.childNodes.splice(n,0,e),e.yogaNode&&((o=t.yogaNode)===null||o===void 0||o.insertChild(e.yogaNode,n));return}t.childNodes.push(e),e.yogaNode&&((a=t.yogaNode)===null||a===void 0||a.insertChild(e.yogaNode,t.yogaNode.getChildCount())),(t.nodeName==="ink-text"||t.nodeName==="ink-virtual-text")&&Zk(t)};pi.removeChildNode=(t,e)=>{var r,o;e.yogaNode&&((o=(r=e.parentNode)===null||r===void 0?void 0:r.yogaNode)===null||o===void 0||o.removeChild(e.yogaNode)),e.parentNode=null;let a=t.childNodes.indexOf(e);a>=0&&t.childNodes.splice(a,1),(t.nodeName==="ink-text"||t.nodeName==="ink-virtual-text")&&Zk(t)};pi.setAttribute=(t,e,r)=>{t.attributes[e]=r};pi.setStyle=(t,e)=>{t.style=e,t.yogaNode&&vEt.default(t.yogaNode,e)};pi.createTextNode=t=>{let e={nodeName:"#text",nodeValue:t,yogaNode:void 0,parentNode:null,style:{}};return pi.setTextNodeValue(e,t),e};var SEt=function(t,e){var r,o;let a=t.nodeName==="#text"?t.nodeValue:PEt.default(t),n=oCe.default(a);if(n.width<=e||n.width>=1&&e>0&&e<1)return n;let u=(o=(r=t.style)===null||r===void 0?void 0:r.textWrap)!==null&&o!==void 0?o:"wrap",A=DEt.default(a,e,u);return oCe.default(A)},aCe=t=>{var e;if(!(!t||!t.parentNode))return(e=t.yogaNode)!==null&&e!==void 0?e:aCe(t.parentNode)},Zk=t=>{let e=aCe(t);e?.markDirty()};pi.setTextNodeValue=(t,e)=>{typeof e!="string"&&(e=String(e)),t.nodeValue=e,Zk(t)}});var fCe=_(pB=>{"use strict";var ACe=pB&&pB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(pB,"__esModule",{value:!0});var lCe=x6(),xEt=ACe(kEe()),cCe=ACe(om()),Mo=W6(),uCe=t=>{t?.unsetMeasureFunc(),t?.freeRecursive()};pB.default=xEt.default({schedulePassiveEffects:lCe.unstable_scheduleCallback,cancelPassiveEffects:lCe.unstable_cancelCallback,now:Date.now,getRootHostContext:()=>({isInsideText:!1}),prepareForCommit:()=>{},resetAfterCommit:t=>{if(t.isStaticDirty){t.isStaticDirty=!1,typeof t.onImmediateRender=="function"&&t.onImmediateRender();return}typeof t.onRender=="function"&&t.onRender()},getChildHostContext:(t,e)=>{let r=t.isInsideText,o=e==="ink-text"||e==="ink-virtual-text";return r===o?t:{isInsideText:o}},shouldSetTextContent:()=>!1,createInstance:(t,e,r,o)=>{if(o.isInsideText&&t==="ink-box")throw new Error("<Box> can\u2019t be nested inside <Text> component");let a=t==="ink-text"&&o.isInsideText?"ink-virtual-text":t,n=Mo.createNode(a);for(let[u,A]of Object.entries(e))u!=="children"&&(u==="style"?Mo.setStyle(n,A):u==="internal_transform"?n.internal_transform=A:u==="internal_static"?n.internal_static=!0:Mo.setAttribute(n,u,A));return n},createTextInstance:(t,e,r)=>{if(!r.isInsideText)throw new Error(`Text string "${t}" must be rendered inside <Text> component`);return Mo.createTextNode(t)},resetTextContent:()=>{},hideTextInstance:t=>{Mo.setTextNodeValue(t,"")},unhideTextInstance:(t,e)=>{Mo.setTextNodeValue(t,e)},getPublicInstance:t=>t,hideInstance:t=>{var e;(e=t.yogaNode)===null||e===void 0||e.setDisplay(cCe.default.DISPLAY_NONE)},unhideInstance:t=>{var e;(e=t.yogaNode)===null||e===void 0||e.setDisplay(cCe.default.DISPLAY_FLEX)},appendInitialChild:Mo.appendChildNode,appendChild:Mo.appendChildNode,insertBefore:Mo.insertBeforeNode,finalizeInitialChildren:(t,e,r,o)=>(t.internal_static&&(o.isStaticDirty=!0,o.staticNode=t),!1),supportsMutation:!0,appendChildToContainer:Mo.appendChildNode,insertInContainerBefore:Mo.insertBeforeNode,removeChildFromContainer:(t,e)=>{Mo.removeChildNode(t,e),uCe(e.yogaNode)},prepareUpdate:(t,e,r,o,a)=>{t.internal_static&&(a.isStaticDirty=!0);let n={},u=Object.keys(o);for(let A of u)if(o[A]!==r[A]){if(A==="style"&&typeof o.style=="object"&&typeof r.style=="object"){let h=o.style,E=r.style,I=Object.keys(h);for(let v of I){if(v==="borderStyle"||v==="borderColor"){if(typeof n.style!="object"){let b={};n.style=b}n.style.borderStyle=h.borderStyle,n.style.borderColor=h.borderColor}if(h[v]!==E[v]){if(typeof n.style!="object"){let b={};n.style=b}n.style[v]=h[v]}}continue}n[A]=o[A]}return n},commitUpdate:(t,e)=>{for(let[r,o]of Object.entries(e))r!=="children"&&(r==="style"?Mo.setStyle(t,o):r==="internal_transform"?t.internal_transform=o:r==="internal_static"?t.internal_static=!0:Mo.setAttribute(t,r,o))},commitTextUpdate:(t,e,r)=>{Mo.setTextNodeValue(t,r)},removeChild:(t,e)=>{Mo.removeChildNode(t,e),uCe(e.yogaNode)}})});var hCe=_((LVt,pCe)=>{"use strict";pCe.exports=(t,e=1,r)=>{if(r={indent:" ",includeEmptyLines:!1,...r},typeof t!="string")throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof t}\``);if(typeof e!="number")throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof e}\``);if(typeof r.indent!="string")throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof r.indent}\``);if(e===0)return t;let o=r.includeEmptyLines?/^/gm:/^(?!\s*$)/gm;return t.replace(o,r.indent.repeat(e))}});var gCe=_(hB=>{"use strict";var bEt=hB&&hB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(hB,"__esModule",{value:!0});var $k=bEt(om());hB.default=t=>t.getComputedWidth()-t.getComputedPadding($k.default.EDGE_LEFT)-t.getComputedPadding($k.default.EDGE_RIGHT)-t.getComputedBorder($k.default.EDGE_LEFT)-t.getComputedBorder($k.default.EDGE_RIGHT)});var dCe=_((OVt,kEt)=>{kEt.exports={single:{topLeft:"\u250C",topRight:"\u2510",bottomRight:"\u2518",bottomLeft:"\u2514",vertical:"\u2502",horizontal:"\u2500"},double:{topLeft:"\u2554",topRight:"\u2557",bottomRight:"\u255D",bottomLeft:"\u255A",vertical:"\u2551",horizontal:"\u2550"},round:{topLeft:"\u256D",topRight:"\u256E",bottomRight:"\u256F",bottomLeft:"\u2570",vertical:"\u2502",horizontal:"\u2500"},bold:{topLeft:"\u250F",topRight:"\u2513",bottomRight:"\u251B",bottomLeft:"\u2517",vertical:"\u2503",horizontal:"\u2501"},singleDouble:{topLeft:"\u2553",topRight:"\u2556",bottomRight:"\u255C",bottomLeft:"\u2559",vertical:"\u2551",horizontal:"\u2500"},doubleSingle:{topLeft:"\u2552",topRight:"\u2555",bottomRight:"\u255B",bottomLeft:"\u2558",vertical:"\u2502",horizontal:"\u2550"},classic:{topLeft:"+",topRight:"+",bottomRight:"+",bottomLeft:"+",vertical:"|",horizontal:"-"}}});var yCe=_((UVt,V6)=>{"use strict";var mCe=dCe();V6.exports=mCe;V6.exports.default=mCe});var CCe=_((_Vt,ECe)=>{"use strict";var QEt=(t,e,r)=>{let o=t.indexOf(e);if(o===-1)return t;let a=e.length,n=0,u="";do u+=t.substr(n,o-n)+e+r,n=o+a,o=t.indexOf(e,n);while(o!==-1);return u+=t.substr(n),u},FEt=(t,e,r,o)=>{let a=0,n="";do{let u=t[o-1]==="\r";n+=t.substr(a,(u?o-1:o)-a)+e+(u?`\r +`:` +`)+r,a=o+1,o=t.indexOf(` +`,a)}while(o!==-1);return n+=t.substr(a),n};ECe.exports={stringReplaceAll:QEt,stringEncaseCRLFWithFirstIndex:FEt}});var DCe=_((HVt,vCe)=>{"use strict";var TEt=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,wCe=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,REt=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,NEt=/\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi,LEt=new Map([["n",` +`],["r","\r"],["t"," "],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e","\x1B"],["a","\x07"]]);function BCe(t){let e=t[0]==="u",r=t[1]==="{";return e&&!r&&t.length===5||t[0]==="x"&&t.length===3?String.fromCharCode(parseInt(t.slice(1),16)):e&&r?String.fromCodePoint(parseInt(t.slice(2,-1),16)):LEt.get(t)||t}function MEt(t,e){let r=[],o=e.trim().split(/\s*,\s*/g),a;for(let n of o){let u=Number(n);if(!Number.isNaN(u))r.push(u);else if(a=n.match(REt))r.push(a[2].replace(NEt,(A,p,h)=>p?BCe(p):h));else throw new Error(`Invalid Chalk template style argument: ${n} (in style '${t}')`)}return r}function OEt(t){wCe.lastIndex=0;let e=[],r;for(;(r=wCe.exec(t))!==null;){let o=r[1];if(r[2]){let a=MEt(o,r[2]);e.push([o].concat(a))}else e.push([o])}return e}function ICe(t,e){let r={};for(let a of e)for(let n of a.styles)r[n[0]]=a.inverse?null:n.slice(1);let o=t;for(let[a,n]of Object.entries(r))if(!!Array.isArray(n)){if(!(a in o))throw new Error(`Unknown Chalk style: ${a}`);o=n.length>0?o[a](...n):o[a]}return o}vCe.exports=(t,e)=>{let r=[],o=[],a=[];if(e.replace(TEt,(n,u,A,p,h,E)=>{if(u)a.push(BCe(u));else if(p){let I=a.join("");a=[],o.push(r.length===0?I:ICe(t,r)(I)),r.push({inverse:A,styles:OEt(p)})}else if(h){if(r.length===0)throw new Error("Found extraneous } in Chalk template literal");o.push(ICe(t,r)(a.join(""))),a=[],r.pop()}else a.push(E)}),o.push(a.join("")),r.length>0){let n=`Chalk template literal is missing ${r.length} closing bracket${r.length===1?"":"s"} (\`}\`)`;throw new Error(n)}return o.join("")}});var iQ=_((jVt,QCe)=>{"use strict";var gB=vI(),{stdout:J6,stderr:z6}=yN(),{stringReplaceAll:UEt,stringEncaseCRLFWithFirstIndex:_Et}=CCe(),{isArray:eQ}=Array,SCe=["ansi","ansi","ansi256","ansi16m"],_C=Object.create(null),HEt=(t,e={})=>{if(e.level&&!(Number.isInteger(e.level)&&e.level>=0&&e.level<=3))throw new Error("The `level` option should be an integer from 0 to 3");let r=J6?J6.level:0;t.level=e.level===void 0?r:e.level},X6=class{constructor(e){return xCe(e)}},xCe=t=>{let e={};return HEt(e,t),e.template=(...r)=>kCe(e.template,...r),Object.setPrototypeOf(e,tQ.prototype),Object.setPrototypeOf(e.template,e),e.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},e.template.Instance=X6,e.template};function tQ(t){return xCe(t)}for(let[t,e]of Object.entries(gB))_C[t]={get(){let r=rQ(this,Z6(e.open,e.close,this._styler),this._isEmpty);return Object.defineProperty(this,t,{value:r}),r}};_C.visible={get(){let t=rQ(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:t}),t}};var bCe=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(let t of bCe)_C[t]={get(){let{level:e}=this;return function(...r){let o=Z6(gB.color[SCe[e]][t](...r),gB.color.close,this._styler);return rQ(this,o,this._isEmpty)}}};for(let t of bCe){let e="bg"+t[0].toUpperCase()+t.slice(1);_C[e]={get(){let{level:r}=this;return function(...o){let a=Z6(gB.bgColor[SCe[r]][t](...o),gB.bgColor.close,this._styler);return rQ(this,a,this._isEmpty)}}}}var jEt=Object.defineProperties(()=>{},{..._C,level:{enumerable:!0,get(){return this._generator.level},set(t){this._generator.level=t}}}),Z6=(t,e,r)=>{let o,a;return r===void 0?(o=t,a=e):(o=r.openAll+t,a=e+r.closeAll),{open:t,close:e,openAll:o,closeAll:a,parent:r}},rQ=(t,e,r)=>{let o=(...a)=>eQ(a[0])&&eQ(a[0].raw)?PCe(o,kCe(o,...a)):PCe(o,a.length===1?""+a[0]:a.join(" "));return Object.setPrototypeOf(o,jEt),o._generator=t,o._styler=e,o._isEmpty=r,o},PCe=(t,e)=>{if(t.level<=0||!e)return t._isEmpty?"":e;let r=t._styler;if(r===void 0)return e;let{openAll:o,closeAll:a}=r;if(e.indexOf("\x1B")!==-1)for(;r!==void 0;)e=UEt(e,r.close,r.open),r=r.parent;let n=e.indexOf(` +`);return n!==-1&&(e=_Et(e,a,o,n)),o+e+a},K6,kCe=(t,...e)=>{let[r]=e;if(!eQ(r)||!eQ(r.raw))return e.join(" ");let o=e.slice(1),a=[r.raw[0]];for(let n=1;n<r.length;n++)a.push(String(o[n-1]).replace(/[{}\\]/g,"\\$&"),String(r.raw[n]));return K6===void 0&&(K6=DCe()),K6(t,a.join(""))};Object.defineProperties(tQ.prototype,_C);var nQ=tQ();nQ.supportsColor=J6;nQ.stderr=tQ({level:z6?z6.level:0});nQ.stderr.supportsColor=z6;QCe.exports=nQ});var $6=_(mB=>{"use strict";var qEt=mB&&mB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(mB,"__esModule",{value:!0});var dB=qEt(iQ()),GEt=/^(rgb|hsl|hsv|hwb)\(\s?(\d+),\s?(\d+),\s?(\d+)\s?\)$/,YEt=/^(ansi|ansi256)\(\s?(\d+)\s?\)$/,sQ=(t,e)=>e==="foreground"?t:"bg"+t[0].toUpperCase()+t.slice(1);mB.default=(t,e,r)=>{if(!e)return t;if(e in dB.default){let a=sQ(e,r);return dB.default[a](t)}if(e.startsWith("#")){let a=sQ("hex",r);return dB.default[a](e)(t)}if(e.startsWith("ansi")){let a=YEt.exec(e);if(!a)return t;let n=sQ(a[1],r),u=Number(a[2]);return dB.default[n](u)(t)}if(e.startsWith("rgb")||e.startsWith("hsl")||e.startsWith("hsv")||e.startsWith("hwb")){let a=GEt.exec(e);if(!a)return t;let n=sQ(a[1],r),u=Number(a[2]),A=Number(a[3]),p=Number(a[4]);return dB.default[n](u,A,p)(t)}return t}});var TCe=_(yB=>{"use strict";var FCe=yB&&yB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(yB,"__esModule",{value:!0});var WEt=FCe(yCe()),ej=FCe($6());yB.default=(t,e,r,o)=>{if(typeof r.style.borderStyle=="string"){let a=r.yogaNode.getComputedWidth(),n=r.yogaNode.getComputedHeight(),u=r.style.borderColor,A=WEt.default[r.style.borderStyle],p=ej.default(A.topLeft+A.horizontal.repeat(a-2)+A.topRight,u,"foreground"),h=(ej.default(A.vertical,u,"foreground")+` +`).repeat(n-2),E=ej.default(A.bottomLeft+A.horizontal.repeat(a-2)+A.bottomRight,u,"foreground");o.write(t,e,p,{transformers:[]}),o.write(t,e+1,h,{transformers:[]}),o.write(t+a-1,e+1,h,{transformers:[]}),o.write(t,e+n-1,E,{transformers:[]})}}});var NCe=_(EB=>{"use strict";var am=EB&&EB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(EB,"__esModule",{value:!0});var VEt=am(om()),KEt=am(M6()),JEt=am(hCe()),zEt=am(q6()),XEt=am(gCe()),ZEt=am(Y6()),$Et=am(TCe()),eCt=(t,e)=>{var r;let o=(r=t.childNodes[0])===null||r===void 0?void 0:r.yogaNode;if(o){let a=o.getComputedLeft(),n=o.getComputedTop();e=` +`.repeat(n)+JEt.default(e,a)}return e},RCe=(t,e,r)=>{var o;let{offsetX:a=0,offsetY:n=0,transformers:u=[],skipStaticElements:A}=r;if(A&&t.internal_static)return;let{yogaNode:p}=t;if(p){if(p.getDisplay()===VEt.default.DISPLAY_NONE)return;let h=a+p.getComputedLeft(),E=n+p.getComputedTop(),I=u;if(typeof t.internal_transform=="function"&&(I=[t.internal_transform,...u]),t.nodeName==="ink-text"){let v=ZEt.default(t);if(v.length>0){let b=KEt.default(v),C=XEt.default(p);if(b>C){let T=(o=t.style.textWrap)!==null&&o!==void 0?o:"wrap";v=zEt.default(v,C,T)}v=eCt(t,v),e.write(h,E,v,{transformers:I})}return}if(t.nodeName==="ink-box"&&$Et.default(h,E,t,e),t.nodeName==="ink-root"||t.nodeName==="ink-box")for(let v of t.childNodes)RCe(v,e,{offsetX:h,offsetY:E,transformers:I,skipStaticElements:A})}};EB.default=RCe});var MCe=_((WVt,LCe)=>{"use strict";LCe.exports=t=>{t=Object.assign({onlyFirst:!1},t);let e=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(e,t.onlyFirst?void 0:"g")}});var UCe=_((VVt,tj)=>{"use strict";var tCt=MCe(),OCe=t=>typeof t=="string"?t.replace(tCt(),""):t;tj.exports=OCe;tj.exports.default=OCe});var jCe=_((KVt,HCe)=>{"use strict";var _Ce="[\uD800-\uDBFF][\uDC00-\uDFFF]";HCe.exports=t=>t&&t.exact?new RegExp(`^${_Ce}$`):new RegExp(_Ce,"g")});var GCe=_((JVt,rj)=>{"use strict";var rCt=UCe(),nCt=jCe(),qCe=t=>rCt(t).replace(nCt()," ").length;rj.exports=qCe;rj.exports.default=qCe});var VCe=_(CB=>{"use strict";var WCe=CB&&CB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(CB,"__esModule",{value:!0});var YCe=WCe(H6()),iCt=WCe(GCe()),nj=class{constructor(e){this.writes=[];let{width:r,height:o}=e;this.width=r,this.height=o}write(e,r,o,a){let{transformers:n}=a;!o||this.writes.push({x:e,y:r,text:o,transformers:n})}get(){let e=[];for(let o=0;o<this.height;o++)e.push(" ".repeat(this.width));for(let o of this.writes){let{x:a,y:n,text:u,transformers:A}=o,p=u.split(` +`),h=0;for(let E of p){let I=e[n+h];if(!I)continue;let v=iCt.default(E);for(let b of A)E=b(E);e[n+h]=YCe.default(I,0,a)+E+YCe.default(I,a+v),h++}}return{output:e.map(o=>o.trimRight()).join(` +`),height:e.length}}};CB.default=nj});var zCe=_(wB=>{"use strict";var ij=wB&&wB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(wB,"__esModule",{value:!0});var sCt=ij(om()),KCe=ij(NCe()),JCe=ij(VCe());wB.default=(t,e)=>{var r;if(t.yogaNode.setWidth(e),t.yogaNode){t.yogaNode.calculateLayout(void 0,void 0,sCt.default.DIRECTION_LTR);let o=new JCe.default({width:t.yogaNode.getComputedWidth(),height:t.yogaNode.getComputedHeight()});KCe.default(t,o,{skipStaticElements:!0});let a;!((r=t.staticNode)===null||r===void 0)&&r.yogaNode&&(a=new JCe.default({width:t.staticNode.yogaNode.getComputedWidth(),height:t.staticNode.yogaNode.getComputedHeight()}),KCe.default(t.staticNode,a,{skipStaticElements:!1}));let{output:n,height:u}=o.get();return{output:n,outputHeight:u,staticOutput:a?`${a.get().output} +`:""}}return{output:"",outputHeight:0,staticOutput:""}}});var ewe=_((ZVt,$Ce)=>{"use strict";var XCe=Be("stream"),ZCe=["assert","count","countReset","debug","dir","dirxml","error","group","groupCollapsed","groupEnd","info","log","table","time","timeEnd","timeLog","trace","warn"],sj={},oCt=t=>{let e=new XCe.PassThrough,r=new XCe.PassThrough;e.write=a=>t("stdout",a),r.write=a=>t("stderr",a);let o=new console.Console(e,r);for(let a of ZCe)sj[a]=console[a],console[a]=o[a];return()=>{for(let a of ZCe)console[a]=sj[a];sj={}}};$Ce.exports=oCt});var aj=_(oj=>{"use strict";Object.defineProperty(oj,"__esModule",{value:!0});oj.default=new WeakMap});var cj=_(lj=>{"use strict";Object.defineProperty(lj,"__esModule",{value:!0});var aCt=sn(),twe=aCt.createContext({exit:()=>{}});twe.displayName="InternalAppContext";lj.default=twe});var Aj=_(uj=>{"use strict";Object.defineProperty(uj,"__esModule",{value:!0});var lCt=sn(),rwe=lCt.createContext({stdin:void 0,setRawMode:()=>{},isRawModeSupported:!1,internal_exitOnCtrlC:!0});rwe.displayName="InternalStdinContext";uj.default=rwe});var pj=_(fj=>{"use strict";Object.defineProperty(fj,"__esModule",{value:!0});var cCt=sn(),nwe=cCt.createContext({stdout:void 0,write:()=>{}});nwe.displayName="InternalStdoutContext";fj.default=nwe});var gj=_(hj=>{"use strict";Object.defineProperty(hj,"__esModule",{value:!0});var uCt=sn(),iwe=uCt.createContext({stderr:void 0,write:()=>{}});iwe.displayName="InternalStderrContext";hj.default=iwe});var oQ=_(dj=>{"use strict";Object.defineProperty(dj,"__esModule",{value:!0});var ACt=sn(),swe=ACt.createContext({activeId:void 0,add:()=>{},remove:()=>{},activate:()=>{},deactivate:()=>{},enableFocus:()=>{},disableFocus:()=>{},focusNext:()=>{},focusPrevious:()=>{}});swe.displayName="InternalFocusContext";dj.default=swe});var awe=_((sKt,owe)=>{"use strict";var fCt=/[|\\{}()[\]^$+*?.-]/g;owe.exports=t=>{if(typeof t!="string")throw new TypeError("Expected a string");return t.replace(fCt,"\\$&")}});var Awe=_((oKt,uwe)=>{"use strict";var pCt=awe(),hCt=typeof process=="object"&&process&&typeof process.cwd=="function"?process.cwd():".",cwe=[].concat(Be("module").builtinModules,"bootstrap_node","node").map(t=>new RegExp(`(?:\\((?:node:)?${t}(?:\\.js)?:\\d+:\\d+\\)$|^\\s*at (?:node:)?${t}(?:\\.js)?:\\d+:\\d+$)`));cwe.push(/\((?:node:)?internal\/[^:]+:\d+:\d+\)$/,/\s*at (?:node:)?internal\/[^:]+:\d+:\d+$/,/\/\.node-spawn-wrap-\w+-\w+\/node:\d+:\d+\)?$/);var IB=class{constructor(e){e={ignoredPackages:[],...e},"internals"in e||(e.internals=IB.nodeInternals()),"cwd"in e||(e.cwd=hCt),this._cwd=e.cwd.replace(/\\/g,"/"),this._internals=[].concat(e.internals,gCt(e.ignoredPackages)),this._wrapCallSite=e.wrapCallSite||!1}static nodeInternals(){return[...cwe]}clean(e,r=0){r=" ".repeat(r),Array.isArray(e)||(e=e.split(` +`)),!/^\s*at /.test(e[0])&&/^\s*at /.test(e[1])&&(e=e.slice(1));let o=!1,a=null,n=[];return e.forEach(u=>{if(u=u.replace(/\\/g,"/"),this._internals.some(p=>p.test(u)))return;let A=/^\s*at /.test(u);o?u=u.trimEnd().replace(/^(\s+)at /,"$1"):(u=u.trim(),A&&(u=u.slice(3))),u=u.replace(`${this._cwd}/`,""),u&&(A?(a&&(n.push(a),a=null),n.push(u)):(o=!0,a=u))}),n.map(u=>`${r}${u} +`).join("")}captureString(e,r=this.captureString){typeof e=="function"&&(r=e,e=1/0);let{stackTraceLimit:o}=Error;e&&(Error.stackTraceLimit=e);let a={};Error.captureStackTrace(a,r);let{stack:n}=a;return Error.stackTraceLimit=o,this.clean(n)}capture(e,r=this.capture){typeof e=="function"&&(r=e,e=1/0);let{prepareStackTrace:o,stackTraceLimit:a}=Error;Error.prepareStackTrace=(A,p)=>this._wrapCallSite?p.map(this._wrapCallSite):p,e&&(Error.stackTraceLimit=e);let n={};Error.captureStackTrace(n,r);let{stack:u}=n;return Object.assign(Error,{prepareStackTrace:o,stackTraceLimit:a}),u}at(e=this.at){let[r]=this.capture(1,e);if(!r)return{};let o={line:r.getLineNumber(),column:r.getColumnNumber()};lwe(o,r.getFileName(),this._cwd),r.isConstructor()&&(o.constructor=!0),r.isEval()&&(o.evalOrigin=r.getEvalOrigin()),r.isNative()&&(o.native=!0);let a;try{a=r.getTypeName()}catch{}a&&a!=="Object"&&a!=="[object Object]"&&(o.type=a);let n=r.getFunctionName();n&&(o.function=n);let u=r.getMethodName();return u&&n!==u&&(o.method=u),o}parseLine(e){let r=e&&e.match(dCt);if(!r)return null;let o=r[1]==="new",a=r[2],n=r[3],u=r[4],A=Number(r[5]),p=Number(r[6]),h=r[7],E=r[8],I=r[9],v=r[10]==="native",b=r[11]===")",C,T={};if(E&&(T.line=Number(E)),I&&(T.column=Number(I)),b&&h){let L=0;for(let U=h.length-1;U>0;U--)if(h.charAt(U)===")")L++;else if(h.charAt(U)==="("&&h.charAt(U-1)===" "&&(L--,L===-1&&h.charAt(U-1)===" ")){let J=h.slice(0,U-1);h=h.slice(U+1),a+=` (${J}`;break}}if(a){let L=a.match(mCt);L&&(a=L[1],C=L[2])}return lwe(T,h,this._cwd),o&&(T.constructor=!0),n&&(T.evalOrigin=n,T.evalLine=A,T.evalColumn=p,T.evalFile=u&&u.replace(/\\/g,"/")),v&&(T.native=!0),a&&(T.function=a),C&&a!==C&&(T.method=C),T}};function lwe(t,e,r){e&&(e=e.replace(/\\/g,"/"),e.startsWith(`${r}/`)&&(e=e.slice(r.length+1)),t.file=e)}function gCt(t){if(t.length===0)return[];let e=t.map(r=>pCt(r));return new RegExp(`[/\\\\]node_modules[/\\\\](?:${e.join("|")})[/\\\\][^:]+:\\d+:\\d+`)}var dCt=new RegExp("^(?:\\s*at )?(?:(new) )?(?:(.*?) \\()?(?:eval at ([^ ]+) \\((.+?):(\\d+):(\\d+)\\), )?(?:(.+?):(\\d+):(\\d+)|(native))(\\)?)$"),mCt=/^(.*?) \[as (.*?)\]$/;uwe.exports=IB});var pwe=_((aKt,fwe)=>{"use strict";fwe.exports=(t,e)=>t.replace(/^\t+/gm,r=>" ".repeat(r.length*(e||2)))});var gwe=_((lKt,hwe)=>{"use strict";var yCt=pwe(),ECt=(t,e)=>{let r=[],o=t-e,a=t+e;for(let n=o;n<=a;n++)r.push(n);return r};hwe.exports=(t,e,r)=>{if(typeof t!="string")throw new TypeError("Source code is missing.");if(!e||e<1)throw new TypeError("Line number must start from `1`.");if(t=yCt(t).split(/\r?\n/),!(e>t.length))return r={around:3,...r},ECt(e,r.around).filter(o=>t[o-1]!==void 0).map(o=>({line:o,value:t[o-1]}))}});var aQ=_(ru=>{"use strict";var CCt=ru&&ru.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),wCt=ru&&ru.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),ICt=ru&&ru.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.hasOwnProperty.call(t,r)&&CCt(e,t,r);return wCt(e,t),e},BCt=ru&&ru.__rest||function(t,e){var r={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&e.indexOf(o)<0&&(r[o]=t[o]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var a=0,o=Object.getOwnPropertySymbols(t);a<o.length;a++)e.indexOf(o[a])<0&&Object.prototype.propertyIsEnumerable.call(t,o[a])&&(r[o[a]]=t[o[a]]);return r};Object.defineProperty(ru,"__esModule",{value:!0});var dwe=ICt(sn()),mj=dwe.forwardRef((t,e)=>{var{children:r}=t,o=BCt(t,["children"]);let a=Object.assign(Object.assign({},o),{marginLeft:o.marginLeft||o.marginX||o.margin||0,marginRight:o.marginRight||o.marginX||o.margin||0,marginTop:o.marginTop||o.marginY||o.margin||0,marginBottom:o.marginBottom||o.marginY||o.margin||0,paddingLeft:o.paddingLeft||o.paddingX||o.padding||0,paddingRight:o.paddingRight||o.paddingX||o.padding||0,paddingTop:o.paddingTop||o.paddingY||o.padding||0,paddingBottom:o.paddingBottom||o.paddingY||o.padding||0});return dwe.default.createElement("ink-box",{ref:e,style:a},r)});mj.displayName="Box";mj.defaultProps={flexDirection:"row",flexGrow:0,flexShrink:1};ru.default=mj});var Cj=_(BB=>{"use strict";var yj=BB&&BB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(BB,"__esModule",{value:!0});var vCt=yj(sn()),HC=yj(iQ()),mwe=yj($6()),Ej=({color:t,backgroundColor:e,dimColor:r,bold:o,italic:a,underline:n,strikethrough:u,inverse:A,wrap:p,children:h})=>{if(h==null)return null;let E=I=>(r&&(I=HC.default.dim(I)),t&&(I=mwe.default(I,t,"foreground")),e&&(I=mwe.default(I,e,"background")),o&&(I=HC.default.bold(I)),a&&(I=HC.default.italic(I)),n&&(I=HC.default.underline(I)),u&&(I=HC.default.strikethrough(I)),A&&(I=HC.default.inverse(I)),I);return vCt.default.createElement("ink-text",{style:{flexGrow:0,flexShrink:1,flexDirection:"row",textWrap:p},internal_transform:E},h)};Ej.displayName="Text";Ej.defaultProps={dimColor:!1,bold:!1,italic:!1,underline:!1,strikethrough:!1,wrap:"wrap"};BB.default=Ej});var wwe=_(nu=>{"use strict";var DCt=nu&&nu.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),PCt=nu&&nu.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),SCt=nu&&nu.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.hasOwnProperty.call(t,r)&&DCt(e,t,r);return PCt(e,t),e},vB=nu&&nu.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(nu,"__esModule",{value:!0});var ywe=SCt(Be("fs")),fs=vB(sn()),Ewe=vB(Awe()),xCt=vB(gwe()),Xf=vB(aQ()),hA=vB(Cj()),Cwe=new Ewe.default({cwd:process.cwd(),internals:Ewe.default.nodeInternals()}),bCt=({error:t})=>{let e=t.stack?t.stack.split(` +`).slice(1):void 0,r=e?Cwe.parseLine(e[0]):void 0,o,a=0;if(r?.file&&r?.line&&ywe.existsSync(r.file)){let n=ywe.readFileSync(r.file,"utf8");if(o=xCt.default(n,r.line),o)for(let{line:u}of o)a=Math.max(a,String(u).length)}return fs.default.createElement(Xf.default,{flexDirection:"column",padding:1},fs.default.createElement(Xf.default,null,fs.default.createElement(hA.default,{backgroundColor:"red",color:"white"}," ","ERROR"," "),fs.default.createElement(hA.default,null," ",t.message)),r&&fs.default.createElement(Xf.default,{marginTop:1},fs.default.createElement(hA.default,{dimColor:!0},r.file,":",r.line,":",r.column)),r&&o&&fs.default.createElement(Xf.default,{marginTop:1,flexDirection:"column"},o.map(({line:n,value:u})=>fs.default.createElement(Xf.default,{key:n},fs.default.createElement(Xf.default,{width:a+1},fs.default.createElement(hA.default,{dimColor:n!==r.line,backgroundColor:n===r.line?"red":void 0,color:n===r.line?"white":void 0},String(n).padStart(a," "),":")),fs.default.createElement(hA.default,{key:n,backgroundColor:n===r.line?"red":void 0,color:n===r.line?"white":void 0}," "+u)))),t.stack&&fs.default.createElement(Xf.default,{marginTop:1,flexDirection:"column"},t.stack.split(` +`).slice(1).map(n=>{let u=Cwe.parseLine(n);return u?fs.default.createElement(Xf.default,{key:n},fs.default.createElement(hA.default,{dimColor:!0},"- "),fs.default.createElement(hA.default,{dimColor:!0,bold:!0},u.function),fs.default.createElement(hA.default,{dimColor:!0,color:"gray"}," ","(",u.file,":",u.line,":",u.column,")")):fs.default.createElement(Xf.default,{key:n},fs.default.createElement(hA.default,{dimColor:!0},"- "),fs.default.createElement(hA.default,{dimColor:!0,bold:!0},n))})))};nu.default=bCt});var Bwe=_(iu=>{"use strict";var kCt=iu&&iu.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),QCt=iu&&iu.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),FCt=iu&&iu.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.hasOwnProperty.call(t,r)&&kCt(e,t,r);return QCt(e,t),e},cm=iu&&iu.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(iu,"__esModule",{value:!0});var lm=FCt(sn()),Iwe=cm(m6()),TCt=cm(cj()),RCt=cm(Aj()),NCt=cm(pj()),LCt=cm(gj()),MCt=cm(oQ()),OCt=cm(wwe()),UCt=" ",_Ct="\x1B[Z",HCt="\x1B",lQ=class extends lm.PureComponent{constructor(){super(...arguments),this.state={isFocusEnabled:!0,activeFocusId:void 0,focusables:[],error:void 0},this.rawModeEnabledCount=0,this.handleSetRawMode=e=>{let{stdin:r}=this.props;if(!this.isRawModeSupported())throw r===process.stdin?new Error(`Raw mode is not supported on the current process.stdin, which Ink uses as input stream by default. +Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported`):new Error(`Raw mode is not supported on the stdin provided to Ink. +Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported`);if(r.setEncoding("utf8"),e){this.rawModeEnabledCount===0&&(r.addListener("data",this.handleInput),r.resume(),r.setRawMode(!0)),this.rawModeEnabledCount++;return}--this.rawModeEnabledCount===0&&(r.setRawMode(!1),r.removeListener("data",this.handleInput),r.pause())},this.handleInput=e=>{e===""&&this.props.exitOnCtrlC&&this.handleExit(),e===HCt&&this.state.activeFocusId&&this.setState({activeFocusId:void 0}),this.state.isFocusEnabled&&this.state.focusables.length>0&&(e===UCt&&this.focusNext(),e===_Ct&&this.focusPrevious())},this.handleExit=e=>{this.isRawModeSupported()&&this.handleSetRawMode(!1),this.props.onExit(e)},this.enableFocus=()=>{this.setState({isFocusEnabled:!0})},this.disableFocus=()=>{this.setState({isFocusEnabled:!1})},this.focusNext=()=>{this.setState(e=>{let r=e.focusables[0].id;return{activeFocusId:this.findNextFocusable(e)||r}})},this.focusPrevious=()=>{this.setState(e=>{let r=e.focusables[e.focusables.length-1].id;return{activeFocusId:this.findPreviousFocusable(e)||r}})},this.addFocusable=(e,{autoFocus:r})=>{this.setState(o=>{let a=o.activeFocusId;return!a&&r&&(a=e),{activeFocusId:a,focusables:[...o.focusables,{id:e,isActive:!0}]}})},this.removeFocusable=e=>{this.setState(r=>({activeFocusId:r.activeFocusId===e?void 0:r.activeFocusId,focusables:r.focusables.filter(o=>o.id!==e)}))},this.activateFocusable=e=>{this.setState(r=>({focusables:r.focusables.map(o=>o.id!==e?o:{id:e,isActive:!0})}))},this.deactivateFocusable=e=>{this.setState(r=>({activeFocusId:r.activeFocusId===e?void 0:r.activeFocusId,focusables:r.focusables.map(o=>o.id!==e?o:{id:e,isActive:!1})}))},this.findNextFocusable=e=>{let r=e.focusables.findIndex(o=>o.id===e.activeFocusId);for(let o=r+1;o<e.focusables.length;o++)if(e.focusables[o].isActive)return e.focusables[o].id},this.findPreviousFocusable=e=>{let r=e.focusables.findIndex(o=>o.id===e.activeFocusId);for(let o=r-1;o>=0;o--)if(e.focusables[o].isActive)return e.focusables[o].id}}static getDerivedStateFromError(e){return{error:e}}isRawModeSupported(){return this.props.stdin.isTTY}render(){return lm.default.createElement(TCt.default.Provider,{value:{exit:this.handleExit}},lm.default.createElement(RCt.default.Provider,{value:{stdin:this.props.stdin,setRawMode:this.handleSetRawMode,isRawModeSupported:this.isRawModeSupported(),internal_exitOnCtrlC:this.props.exitOnCtrlC}},lm.default.createElement(NCt.default.Provider,{value:{stdout:this.props.stdout,write:this.props.writeToStdout}},lm.default.createElement(LCt.default.Provider,{value:{stderr:this.props.stderr,write:this.props.writeToStderr}},lm.default.createElement(MCt.default.Provider,{value:{activeId:this.state.activeFocusId,add:this.addFocusable,remove:this.removeFocusable,activate:this.activateFocusable,deactivate:this.deactivateFocusable,enableFocus:this.enableFocus,disableFocus:this.disableFocus,focusNext:this.focusNext,focusPrevious:this.focusPrevious}},this.state.error?lm.default.createElement(OCt.default,{error:this.state.error}):this.props.children)))))}componentDidMount(){Iwe.default.hide(this.props.stdout)}componentWillUnmount(){Iwe.default.show(this.props.stdout),this.isRawModeSupported()&&this.handleSetRawMode(!1)}componentDidCatch(e){this.handleExit(e)}};iu.default=lQ;lQ.displayName="InternalApp"});var Pwe=_(su=>{"use strict";var jCt=su&&su.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),qCt=su&&su.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),GCt=su&&su.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.hasOwnProperty.call(t,r)&&jCt(e,t,r);return qCt(e,t),e},ou=su&&su.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(su,"__esModule",{value:!0});var YCt=ou(sn()),vwe=uO(),WCt=ou(AEe()),VCt=ou(f6()),KCt=ou(mEe()),JCt=ou(EEe()),wj=ou(fCe()),zCt=ou(zCe()),XCt=ou(d6()),ZCt=ou(ewe()),$Ct=GCt(W6()),ewt=ou(aj()),twt=ou(Bwe()),jC=process.env.CI==="false"?!1:KCt.default,Dwe=()=>{},Ij=class{constructor(e){this.resolveExitPromise=()=>{},this.rejectExitPromise=()=>{},this.unsubscribeExit=()=>{},this.onRender=()=>{if(this.isUnmounted)return;let{output:r,outputHeight:o,staticOutput:a}=zCt.default(this.rootNode,this.options.stdout.columns||80),n=a&&a!==` +`;if(this.options.debug){n&&(this.fullStaticOutput+=a),this.options.stdout.write(this.fullStaticOutput+r);return}if(jC){n&&this.options.stdout.write(a),this.lastOutput=r;return}if(n&&(this.fullStaticOutput+=a),o>=this.options.stdout.rows){this.options.stdout.write(VCt.default.clearTerminal+this.fullStaticOutput+r),this.lastOutput=r;return}n&&(this.log.clear(),this.options.stdout.write(a),this.log(r)),!n&&r!==this.lastOutput&&this.throttledLog(r),this.lastOutput=r},JCt.default(this),this.options=e,this.rootNode=$Ct.createNode("ink-root"),this.rootNode.onRender=e.debug?this.onRender:vwe(this.onRender,32,{leading:!0,trailing:!0}),this.rootNode.onImmediateRender=this.onRender,this.log=WCt.default.create(e.stdout),this.throttledLog=e.debug?this.log:vwe(this.log,void 0,{leading:!0,trailing:!0}),this.isUnmounted=!1,this.lastOutput="",this.fullStaticOutput="",this.container=wj.default.createContainer(this.rootNode,!1,!1),this.unsubscribeExit=XCt.default(this.unmount,{alwaysLast:!1}),e.patchConsole&&this.patchConsole(),jC||(e.stdout.on("resize",this.onRender),this.unsubscribeResize=()=>{e.stdout.off("resize",this.onRender)})}render(e){let r=YCt.default.createElement(twt.default,{stdin:this.options.stdin,stdout:this.options.stdout,stderr:this.options.stderr,writeToStdout:this.writeToStdout,writeToStderr:this.writeToStderr,exitOnCtrlC:this.options.exitOnCtrlC,onExit:this.unmount},e);wj.default.updateContainer(r,this.container,null,Dwe)}writeToStdout(e){if(!this.isUnmounted){if(this.options.debug){this.options.stdout.write(e+this.fullStaticOutput+this.lastOutput);return}if(jC){this.options.stdout.write(e);return}this.log.clear(),this.options.stdout.write(e),this.log(this.lastOutput)}}writeToStderr(e){if(!this.isUnmounted){if(this.options.debug){this.options.stderr.write(e),this.options.stdout.write(this.fullStaticOutput+this.lastOutput);return}if(jC){this.options.stderr.write(e);return}this.log.clear(),this.options.stderr.write(e),this.log(this.lastOutput)}}unmount(e){this.isUnmounted||(this.onRender(),this.unsubscribeExit(),typeof this.restoreConsole=="function"&&this.restoreConsole(),typeof this.unsubscribeResize=="function"&&this.unsubscribeResize(),jC?this.options.stdout.write(this.lastOutput+` +`):this.options.debug||this.log.done(),this.isUnmounted=!0,wj.default.updateContainer(null,this.container,null,Dwe),ewt.default.delete(this.options.stdout),e instanceof Error?this.rejectExitPromise(e):this.resolveExitPromise())}waitUntilExit(){return this.exitPromise||(this.exitPromise=new Promise((e,r)=>{this.resolveExitPromise=e,this.rejectExitPromise=r})),this.exitPromise}clear(){!jC&&!this.options.debug&&this.log.clear()}patchConsole(){this.options.debug||(this.restoreConsole=ZCt.default((e,r)=>{e==="stdout"&&this.writeToStdout(r),e==="stderr"&&(r.startsWith("The above error occurred")||this.writeToStderr(r))}))}};su.default=Ij});var xwe=_(DB=>{"use strict";var Swe=DB&&DB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(DB,"__esModule",{value:!0});var rwt=Swe(Pwe()),cQ=Swe(aj()),nwt=Be("stream"),iwt=(t,e)=>{let r=Object.assign({stdout:process.stdout,stdin:process.stdin,stderr:process.stderr,debug:!1,exitOnCtrlC:!0,patchConsole:!0},swt(e)),o=owt(r.stdout,()=>new rwt.default(r));return o.render(t),{rerender:o.render,unmount:()=>o.unmount(),waitUntilExit:o.waitUntilExit,cleanup:()=>cQ.default.delete(r.stdout),clear:o.clear}};DB.default=iwt;var swt=(t={})=>t instanceof nwt.Stream?{stdout:t,stdin:process.stdin}:t,owt=(t,e)=>{let r;return cQ.default.has(t)?r=cQ.default.get(t):(r=e(),cQ.default.set(t,r)),r}});var kwe=_(Zf=>{"use strict";var awt=Zf&&Zf.__createBinding||(Object.create?function(t,e,r,o){o===void 0&&(o=r),Object.defineProperty(t,o,{enumerable:!0,get:function(){return e[r]}})}:function(t,e,r,o){o===void 0&&(o=r),t[o]=e[r]}),lwt=Zf&&Zf.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),cwt=Zf&&Zf.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.hasOwnProperty.call(t,r)&&awt(e,t,r);return lwt(e,t),e};Object.defineProperty(Zf,"__esModule",{value:!0});var PB=cwt(sn()),bwe=t=>{let{items:e,children:r,style:o}=t,[a,n]=PB.useState(0),u=PB.useMemo(()=>e.slice(a),[e,a]);PB.useLayoutEffect(()=>{n(e.length)},[e.length]);let A=u.map((h,E)=>r(h,a+E)),p=PB.useMemo(()=>Object.assign({position:"absolute",flexDirection:"column"},o),[o]);return PB.default.createElement("ink-box",{internal_static:!0,style:p},A)};bwe.displayName="Static";Zf.default=bwe});var Fwe=_(SB=>{"use strict";var uwt=SB&&SB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(SB,"__esModule",{value:!0});var Awt=uwt(sn()),Qwe=({children:t,transform:e})=>t==null?null:Awt.default.createElement("ink-text",{style:{flexGrow:0,flexShrink:1,flexDirection:"row"},internal_transform:e},t);Qwe.displayName="Transform";SB.default=Qwe});var Rwe=_(xB=>{"use strict";var fwt=xB&&xB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(xB,"__esModule",{value:!0});var pwt=fwt(sn()),Twe=({count:t=1})=>pwt.default.createElement("ink-text",null,` +`.repeat(t));Twe.displayName="Newline";xB.default=Twe});var Mwe=_(bB=>{"use strict";var Nwe=bB&&bB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(bB,"__esModule",{value:!0});var hwt=Nwe(sn()),gwt=Nwe(aQ()),Lwe=()=>hwt.default.createElement(gwt.default,{flexGrow:1});Lwe.displayName="Spacer";bB.default=Lwe});var uQ=_(kB=>{"use strict";var dwt=kB&&kB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(kB,"__esModule",{value:!0});var mwt=sn(),ywt=dwt(Aj()),Ewt=()=>mwt.useContext(ywt.default);kB.default=Ewt});var Uwe=_(QB=>{"use strict";var Cwt=QB&&QB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(QB,"__esModule",{value:!0});var Owe=sn(),wwt=Cwt(uQ()),Iwt=(t,e={})=>{let{stdin:r,setRawMode:o,internal_exitOnCtrlC:a}=wwt.default();Owe.useEffect(()=>{if(e.isActive!==!1)return o(!0),()=>{o(!1)}},[e.isActive,o]),Owe.useEffect(()=>{if(e.isActive===!1)return;let n=u=>{let A=String(u),p={upArrow:A==="\x1B[A",downArrow:A==="\x1B[B",leftArrow:A==="\x1B[D",rightArrow:A==="\x1B[C",pageDown:A==="\x1B[6~",pageUp:A==="\x1B[5~",return:A==="\r",escape:A==="\x1B",ctrl:!1,shift:!1,tab:A===" "||A==="\x1B[Z",backspace:A==="\b",delete:A==="\x7F"||A==="\x1B[3~",meta:!1};A<=""&&!p.return&&(A=String.fromCharCode(A.charCodeAt(0)+"a".charCodeAt(0)-1),p.ctrl=!0),A.startsWith("\x1B")&&(A=A.slice(1),p.meta=!0);let h=A>="A"&&A<="Z",E=A>="\u0410"&&A<="\u042F";A.length===1&&(h||E)&&(p.shift=!0),p.tab&&A==="[Z"&&(p.shift=!0),(p.tab||p.backspace||p.delete)&&(A=""),(!(A==="c"&&p.ctrl)||!a)&&t(A,p)};return r?.on("data",n),()=>{r?.off("data",n)}},[e.isActive,r,a,t])};QB.default=Iwt});var _we=_(FB=>{"use strict";var Bwt=FB&&FB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(FB,"__esModule",{value:!0});var vwt=sn(),Dwt=Bwt(cj()),Pwt=()=>vwt.useContext(Dwt.default);FB.default=Pwt});var Hwe=_(TB=>{"use strict";var Swt=TB&&TB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(TB,"__esModule",{value:!0});var xwt=sn(),bwt=Swt(pj()),kwt=()=>xwt.useContext(bwt.default);TB.default=kwt});var jwe=_(RB=>{"use strict";var Qwt=RB&&RB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(RB,"__esModule",{value:!0});var Fwt=sn(),Twt=Qwt(gj()),Rwt=()=>Fwt.useContext(Twt.default);RB.default=Rwt});var Gwe=_(LB=>{"use strict";var qwe=LB&&LB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(LB,"__esModule",{value:!0});var NB=sn(),Nwt=qwe(oQ()),Lwt=qwe(uQ()),Mwt=({isActive:t=!0,autoFocus:e=!1}={})=>{let{isRawModeSupported:r,setRawMode:o}=Lwt.default(),{activeId:a,add:n,remove:u,activate:A,deactivate:p}=NB.useContext(Nwt.default),h=NB.useMemo(()=>Math.random().toString().slice(2,7),[]);return NB.useEffect(()=>(n(h,{autoFocus:e}),()=>{u(h)}),[h,e]),NB.useEffect(()=>{t?A(h):p(h)},[t,h]),NB.useEffect(()=>{if(!(!r||!t))return o(!0),()=>{o(!1)}},[t]),{isFocused:Boolean(h)&&a===h}};LB.default=Mwt});var Ywe=_(MB=>{"use strict";var Owt=MB&&MB.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(MB,"__esModule",{value:!0});var Uwt=sn(),_wt=Owt(oQ()),Hwt=()=>{let t=Uwt.useContext(_wt.default);return{enableFocus:t.enableFocus,disableFocus:t.disableFocus,focusNext:t.focusNext,focusPrevious:t.focusPrevious}};MB.default=Hwt});var Wwe=_(Bj=>{"use strict";Object.defineProperty(Bj,"__esModule",{value:!0});Bj.default=t=>{var e,r,o,a;return{width:(r=(e=t.yogaNode)===null||e===void 0?void 0:e.getComputedWidth())!==null&&r!==void 0?r:0,height:(a=(o=t.yogaNode)===null||o===void 0?void 0:o.getComputedHeight())!==null&&a!==void 0?a:0}}});var ic=_(ro=>{"use strict";Object.defineProperty(ro,"__esModule",{value:!0});var jwt=xwe();Object.defineProperty(ro,"render",{enumerable:!0,get:function(){return jwt.default}});var qwt=aQ();Object.defineProperty(ro,"Box",{enumerable:!0,get:function(){return qwt.default}});var Gwt=Cj();Object.defineProperty(ro,"Text",{enumerable:!0,get:function(){return Gwt.default}});var Ywt=kwe();Object.defineProperty(ro,"Static",{enumerable:!0,get:function(){return Ywt.default}});var Wwt=Fwe();Object.defineProperty(ro,"Transform",{enumerable:!0,get:function(){return Wwt.default}});var Vwt=Rwe();Object.defineProperty(ro,"Newline",{enumerable:!0,get:function(){return Vwt.default}});var Kwt=Mwe();Object.defineProperty(ro,"Spacer",{enumerable:!0,get:function(){return Kwt.default}});var Jwt=Uwe();Object.defineProperty(ro,"useInput",{enumerable:!0,get:function(){return Jwt.default}});var zwt=_we();Object.defineProperty(ro,"useApp",{enumerable:!0,get:function(){return zwt.default}});var Xwt=uQ();Object.defineProperty(ro,"useStdin",{enumerable:!0,get:function(){return Xwt.default}});var Zwt=Hwe();Object.defineProperty(ro,"useStdout",{enumerable:!0,get:function(){return Zwt.default}});var $wt=jwe();Object.defineProperty(ro,"useStderr",{enumerable:!0,get:function(){return $wt.default}});var eIt=Gwe();Object.defineProperty(ro,"useFocus",{enumerable:!0,get:function(){return eIt.default}});var tIt=Ywe();Object.defineProperty(ro,"useFocusManager",{enumerable:!0,get:function(){return tIt.default}});var rIt=Wwe();Object.defineProperty(ro,"measureElement",{enumerable:!0,get:function(){return rIt.default}})});var Dj={};Kt(Dj,{Gem:()=>vj});var Vwe,um,vj,AQ=Et(()=>{Vwe=$e(ic()),um=$e(sn()),vj=(0,um.memo)(({active:t})=>{let e=(0,um.useMemo)(()=>t?"\u25C9":"\u25EF",[t]),r=(0,um.useMemo)(()=>t?"green":"yellow",[t]);return um.default.createElement(Vwe.Text,{color:r},e)})});var Jwe={};Kt(Jwe,{useKeypress:()=>Am});function Am({active:t},e,r){let{stdin:o}=(0,Kwe.useStdin)(),a=(0,fQ.useCallback)((n,u)=>e(n,u),r);(0,fQ.useEffect)(()=>{if(!(!t||!o))return o.on("keypress",a),()=>{o.off("keypress",a)}},[t,a,o])}var Kwe,fQ,OB=Et(()=>{Kwe=$e(ic()),fQ=$e(sn())});var Xwe={};Kt(Xwe,{FocusRequest:()=>zwe,useFocusRequest:()=>Pj});var zwe,Pj,Sj=Et(()=>{OB();zwe=(r=>(r.BEFORE="before",r.AFTER="after",r))(zwe||{}),Pj=function({active:t},e,r){Am({active:t},(o,a)=>{a.name==="tab"&&(a.shift?e("before"):e("after"))},r)}});var Zwe={};Kt(Zwe,{useListInput:()=>UB});var UB,pQ=Et(()=>{OB();UB=function(t,e,{active:r,minus:o,plus:a,set:n,loop:u=!0}){Am({active:r},(A,p)=>{let h=e.indexOf(t);switch(p.name){case o:{let E=h-1;if(u){n(e[(e.length+E)%e.length]);return}if(E<0)return;n(e[E])}break;case a:{let E=h+1;if(u){n(e[E%e.length]);return}if(E>=e.length)return;n(e[E])}break}},[e,t,a,n,u])}});var hQ={};Kt(hQ,{ScrollableItems:()=>nIt});var E0,La,nIt,gQ=Et(()=>{E0=$e(ic()),La=$e(sn());Sj();pQ();nIt=({active:t=!0,children:e=[],radius:r=10,size:o=1,loop:a=!0,onFocusRequest:n,willReachEnd:u})=>{let A=L=>{if(L.key===null)throw new Error("Expected all children to have a key");return L.key},p=La.default.Children.map(e,L=>A(L)),h=p[0],[E,I]=(0,La.useState)(h),v=p.indexOf(E);(0,La.useEffect)(()=>{p.includes(E)||I(h)},[e]),(0,La.useEffect)(()=>{u&&v>=p.length-2&&u()},[v]),Pj({active:t&&!!n},L=>{n?.(L)},[n]),UB(E,p,{active:t,minus:"up",plus:"down",set:I,loop:a});let b=v-r,C=v+r;C>p.length&&(b-=C-p.length,C=p.length),b<0&&(C+=-b,b=0),C>=p.length&&(C=p.length-1);let T=[];for(let L=b;L<=C;++L){let U=p[L],J=t&&U===E;T.push(La.default.createElement(E0.Box,{key:U,height:o},La.default.createElement(E0.Box,{marginLeft:1,marginRight:1},La.default.createElement(E0.Text,null,J?La.default.createElement(E0.Text,{color:"cyan",bold:!0},">"):" ")),La.default.createElement(E0.Box,null,La.default.cloneElement(e[L],{active:J}))))}return La.default.createElement(E0.Box,{flexDirection:"column",width:"100%"},T)}});var $we,$f,eIe,xj,tIe,bj=Et(()=>{$we=$e(ic()),$f=$e(sn()),eIe=Be("readline"),xj=$f.default.createContext(null),tIe=({children:t})=>{let{stdin:e,setRawMode:r}=(0,$we.useStdin)();(0,$f.useEffect)(()=>{r&&r(!0),e&&(0,eIe.emitKeypressEvents)(e)},[e,r]);let[o,a]=(0,$f.useState)(new Map),n=(0,$f.useMemo)(()=>({getAll:()=>o,get:u=>o.get(u),set:(u,A)=>a(new Map([...o,[u,A]]))}),[o,a]);return $f.default.createElement(xj.Provider,{value:n,children:t})}});var kj={};Kt(kj,{useMinistore:()=>iIt});function iIt(t,e){let r=(0,dQ.useContext)(xj);if(r===null)throw new Error("Expected this hook to run with a ministore context attached");if(typeof t>"u")return r.getAll();let o=(0,dQ.useCallback)(n=>{r.set(t,n)},[t,r.set]),a=r.get(t);return typeof a>"u"&&(a=e),[a,o]}var dQ,Qj=Et(()=>{dQ=$e(sn());bj()});var yQ={};Kt(yQ,{renderForm:()=>sIt});async function sIt(t,e,{stdin:r,stdout:o,stderr:a}){let n,u=p=>{let{exit:h}=(0,mQ.useApp)();Am({active:!0},(E,I)=>{I.name==="return"&&(n=p,h())},[h,p])},{waitUntilExit:A}=(0,mQ.render)(Fj.default.createElement(tIe,null,Fj.default.createElement(t,{...e,useSubmit:u})),{stdin:r,stdout:o,stderr:a});return await A(),n}var mQ,Fj,EQ=Et(()=>{mQ=$e(ic()),Fj=$e(sn());bj();OB()});var sIe=_(_B=>{"use strict";Object.defineProperty(_B,"__esModule",{value:!0});_B.UncontrolledTextInput=void 0;var nIe=sn(),Tj=sn(),rIe=ic(),fm=iQ(),iIe=({value:t,placeholder:e="",focus:r=!0,mask:o,highlightPastedText:a=!1,showCursor:n=!0,onChange:u,onSubmit:A})=>{let[{cursorOffset:p,cursorWidth:h},E]=Tj.useState({cursorOffset:(t||"").length,cursorWidth:0});Tj.useEffect(()=>{E(T=>{if(!r||!n)return T;let L=t||"";return T.cursorOffset>L.length-1?{cursorOffset:L.length,cursorWidth:0}:T})},[t,r,n]);let I=a?h:0,v=o?o.repeat(t.length):t,b=v,C=e?fm.grey(e):void 0;if(n&&r){C=e.length>0?fm.inverse(e[0])+fm.grey(e.slice(1)):fm.inverse(" "),b=v.length>0?"":fm.inverse(" ");let T=0;for(let L of v)T>=p-I&&T<=p?b+=fm.inverse(L):b+=L,T++;v.length>0&&p===v.length&&(b+=fm.inverse(" "))}return rIe.useInput((T,L)=>{if(L.upArrow||L.downArrow||L.ctrl&&T==="c"||L.tab||L.shift&&L.tab)return;if(L.return){A&&A(t);return}let U=p,J=t,te=0;L.leftArrow?n&&U--:L.rightArrow?n&&U++:L.backspace||L.delete?p>0&&(J=t.slice(0,p-1)+t.slice(p,t.length),U--):(J=t.slice(0,p)+T+t.slice(p,t.length),U+=T.length,T.length>1&&(te=T.length)),p<0&&(U=0),p>t.length&&(U=t.length),E({cursorOffset:U,cursorWidth:te}),J!==t&&u(J)},{isActive:r}),nIe.createElement(rIe.Text,null,e?v.length>0?b:C:b)};_B.default=iIe;_B.UncontrolledTextInput=t=>{let[e,r]=Tj.useState("");return nIe.createElement(iIe,Object.assign({},t,{value:e,onChange:r}))}});var lIe={};Kt(lIe,{Pad:()=>Rj});var oIe,aIe,Rj,Nj=Et(()=>{oIe=$e(ic()),aIe=$e(sn()),Rj=({length:t,active:e})=>{if(t===0)return null;let r=t>1?` ${"-".repeat(t-1)}`:" ";return aIe.default.createElement(oIe.Text,{dimColor:!e},r)}});var cIe={};Kt(cIe,{ItemOptions:()=>oIt});var jB,w0,oIt,uIe=Et(()=>{jB=$e(ic()),w0=$e(sn());pQ();AQ();Nj();oIt=function({active:t,skewer:e,options:r,value:o,onChange:a,sizes:n=[]}){let u=r.filter(({label:p})=>!!p).map(({value:p})=>p),A=r.findIndex(p=>p.value===o&&p.label!="");return UB(o,u,{active:t,minus:"left",plus:"right",set:a}),w0.default.createElement(w0.default.Fragment,null,r.map(({label:p},h)=>{let E=h===A,I=n[h]-1||0,v=p.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,""),b=Math.max(0,I-v.length-2);return p?w0.default.createElement(jB.Box,{key:p,width:I,marginLeft:1},w0.default.createElement(jB.Text,{wrap:"truncate"},w0.default.createElement(vj,{active:E})," ",p),e?w0.default.createElement(Rj,{active:t,length:b}):null):w0.default.createElement(jB.Box,{key:`spacer-${h}`,width:I,marginLeft:1})}))}});var PIe=_((zJt,DIe)=>{var Gj;DIe.exports=()=>(typeof Gj>"u"&&(Gj=Be("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),Gj)});var VIe=_((wzt,WIe)=>{var $j=Symbol("arg flag"),Ma=class extends Error{constructor(e,r){super(e),this.name="ArgError",this.code=r,Object.setPrototypeOf(this,Ma.prototype)}};function iv(t,{argv:e=process.argv.slice(2),permissive:r=!1,stopAtPositional:o=!1}={}){if(!t)throw new Ma("argument specification object is required","ARG_CONFIG_NO_SPEC");let a={_:[]},n={},u={};for(let A of Object.keys(t)){if(!A)throw new Ma("argument key cannot be an empty string","ARG_CONFIG_EMPTY_KEY");if(A[0]!=="-")throw new Ma(`argument key must start with '-' but found: '${A}'`,"ARG_CONFIG_NONOPT_KEY");if(A.length===1)throw new Ma(`argument key must have a name; singular '-' keys are not allowed: ${A}`,"ARG_CONFIG_NONAME_KEY");if(typeof t[A]=="string"){n[A]=t[A];continue}let p=t[A],h=!1;if(Array.isArray(p)&&p.length===1&&typeof p[0]=="function"){let[E]=p;p=(I,v,b=[])=>(b.push(E(I,v,b[b.length-1])),b),h=E===Boolean||E[$j]===!0}else if(typeof p=="function")h=p===Boolean||p[$j]===!0;else throw new Ma(`type missing or not a function or valid array type: ${A}`,"ARG_CONFIG_VAD_TYPE");if(A[1]!=="-"&&A.length>2)throw new Ma(`short argument keys (with a single hyphen) must have only one character: ${A}`,"ARG_CONFIG_SHORTOPT_TOOLONG");u[A]=[p,h]}for(let A=0,p=e.length;A<p;A++){let h=e[A];if(o&&a._.length>0){a._=a._.concat(e.slice(A));break}if(h==="--"){a._=a._.concat(e.slice(A+1));break}if(h.length>1&&h[0]==="-"){let E=h[1]==="-"||h.length===2?[h]:h.slice(1).split("").map(I=>`-${I}`);for(let I=0;I<E.length;I++){let v=E[I],[b,C]=v[1]==="-"?v.split(/=(.*)/,2):[v,void 0],T=b;for(;T in n;)T=n[T];if(!(T in u))if(r){a._.push(v);continue}else throw new Ma(`unknown or unexpected option: ${b}`,"ARG_UNKNOWN_OPTION");let[L,U]=u[T];if(!U&&I+1<E.length)throw new Ma(`option requires argument (but was followed by another short argument): ${b}`,"ARG_MISSING_REQUIRED_SHORTARG");if(U)a[T]=L(!0,T,a[T]);else if(C===void 0){if(e.length<A+2||e[A+1].length>1&&e[A+1][0]==="-"&&!(e[A+1].match(/^-?\d*(\.(?=\d))?\d*$/)&&(L===Number||typeof BigInt<"u"&&L===BigInt))){let J=b===T?"":` (alias for ${T})`;throw new Ma(`option requires argument: ${b}${J}`,"ARG_MISSING_REQUIRED_LONGARG")}a[T]=L(e[A+1],T,a[T]),++A}else a[T]=L(C,T,a[T])}}else a._.push(h)}return a}iv.flag=t=>(t[$j]=!0,t);iv.COUNT=iv.flag((t,e,r)=>(r||0)+1);iv.ArgError=Ma;WIe.exports=iv});var t1e=_((Kzt,e1e)=>{var nq;e1e.exports=()=>(typeof nq>"u"&&(nq=Be("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),nq)});var o1e=_((cq,uq)=>{(function(t){cq&&typeof cq=="object"&&typeof uq<"u"?uq.exports=t():typeof define=="function"&&define.amd?define([],t):typeof window<"u"?window.isWindows=t():typeof global<"u"?global.isWindows=t():typeof self<"u"?self.isWindows=t():this.isWindows=t()})(function(){"use strict";return function(){return process&&(process.platform==="win32"||/^(msys|cygwin)$/.test(process.env.OSTYPE))}})});var u1e=_((WXt,c1e)=>{"use strict";Aq.ifExists=n1t;var GC=Be("util"),sc=Be("path"),a1e=o1e(),e1t=/^#!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+)(.*)$/,t1t={createPwshFile:!0,createCmdFile:a1e(),fs:Be("fs")},r1t=new Map([[".js","node"],[".cjs","node"],[".mjs","node"],[".cmd","cmd"],[".bat","cmd"],[".ps1","pwsh"],[".sh","sh"]]);function l1e(t){let e={...t1t,...t},r=e.fs;return e.fs_={chmod:r.chmod?GC.promisify(r.chmod):async()=>{},mkdir:GC.promisify(r.mkdir),readFile:GC.promisify(r.readFile),stat:GC.promisify(r.stat),unlink:GC.promisify(r.unlink),writeFile:GC.promisify(r.writeFile)},e}async function Aq(t,e,r){let o=l1e(r);await o.fs_.stat(t),await s1t(t,e,o)}function n1t(t,e,r){return Aq(t,e,r).catch(()=>{})}function i1t(t,e){return e.fs_.unlink(t).catch(()=>{})}async function s1t(t,e,r){let o=await u1t(t,r);return await o1t(e,r),a1t(t,e,o,r)}function o1t(t,e){return e.fs_.mkdir(sc.dirname(t),{recursive:!0})}function a1t(t,e,r,o){let a=l1e(o),n=[{generator:p1t,extension:""}];return a.createCmdFile&&n.push({generator:f1t,extension:".cmd"}),a.createPwshFile&&n.push({generator:h1t,extension:".ps1"}),Promise.all(n.map(u=>A1t(t,e+u.extension,r,u.generator,a)))}function l1t(t,e){return i1t(t,e)}function c1t(t,e){return g1t(t,e)}async function u1t(t,e){let a=(await e.fs_.readFile(t,"utf8")).trim().split(/\r*\n/)[0].match(e1t);if(!a){let n=sc.extname(t).toLowerCase();return{program:r1t.get(n)||null,additionalArgs:""}}return{program:a[1],additionalArgs:a[2]}}async function A1t(t,e,r,o,a){let n=a.preserveSymlinks?"--preserve-symlinks":"",u=[r.additionalArgs,n].filter(A=>A).join(" ");return a=Object.assign({},a,{prog:r.program,args:u}),await l1t(e,a),await a.fs_.writeFile(e,o(t,e,a),"utf8"),c1t(e,a)}function f1t(t,e,r){let a=sc.relative(sc.dirname(e),t).split("/").join("\\"),n=sc.isAbsolute(a)?`"${a}"`:`"%~dp0\\${a}"`,u,A=r.prog,p=r.args||"",h=fq(r.nodePath).win32;A?(u=`"%~dp0\\${A}.exe"`,a=n):(A=n,p="",a="");let E=r.progArgs?`${r.progArgs.join(" ")} `:"",I=h?`@SET NODE_PATH=${h}\r +`:"";return u?I+=`@IF EXIST ${u} (\r + ${u} ${p} ${a} ${E}%*\r +) ELSE (\r + @SETLOCAL\r + @SET PATHEXT=%PATHEXT:;.JS;=;%\r + ${A} ${p} ${a} ${E}%*\r +)\r +`:I+=`@${A} ${p} ${a} ${E}%*\r +`,I}function p1t(t,e,r){let o=sc.relative(sc.dirname(e),t),a=r.prog&&r.prog.split("\\").join("/"),n;o=o.split("\\").join("/");let u=sc.isAbsolute(o)?`"${o}"`:`"$basedir/${o}"`,A=r.args||"",p=fq(r.nodePath).posix;a?(n=`"$basedir/${r.prog}"`,o=u):(a=u,A="",o="");let h=r.progArgs?`${r.progArgs.join(" ")} `:"",E=`#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')") + +case \`uname\` in + *CYGWIN*) basedir=\`cygpath -w "$basedir"\`;; +esac + +`,I=r.nodePath?`export NODE_PATH="${p}" +`:"";return n?E+=`${I}if [ -x ${n} ]; then + exec ${n} ${A} ${o} ${h}"$@" +else + exec ${a} ${A} ${o} ${h}"$@" +fi +`:E+=`${I}${a} ${A} ${o} ${h}"$@" +exit $? +`,E}function h1t(t,e,r){let o=sc.relative(sc.dirname(e),t),a=r.prog&&r.prog.split("\\").join("/"),n=a&&`"${a}$exe"`,u;o=o.split("\\").join("/");let A=sc.isAbsolute(o)?`"${o}"`:`"$basedir/${o}"`,p=r.args||"",h=fq(r.nodePath),E=h.win32,I=h.posix;n?(u=`"$basedir/${r.prog}$exe"`,o=A):(n=A,p="",o="");let v=r.progArgs?`${r.progArgs.join(" ")} `:"",b=`#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +${r.nodePath?`$env_node_path=$env:NODE_PATH +$env:NODE_PATH="${E}" +`:""}if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +}`;return r.nodePath&&(b+=` else { + $env:NODE_PATH="${I}" +}`),u?b+=` +$ret=0 +if (Test-Path ${u}) { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & ${u} ${p} ${o} ${v}$args + } else { + & ${u} ${p} ${o} ${v}$args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & ${n} ${p} ${o} ${v}$args + } else { + & ${n} ${p} ${o} ${v}$args + } + $ret=$LASTEXITCODE +} +${r.nodePath?`$env:NODE_PATH=$env_node_path +`:""}exit $ret +`:b+=` +# Support pipeline input +if ($MyInvocation.ExpectingInput) { + $input | & ${n} ${p} ${o} ${v}$args +} else { + & ${n} ${p} ${o} ${v}$args +} +${r.nodePath?`$env:NODE_PATH=$env_node_path +`:""}exit $LASTEXITCODE +`,b}function g1t(t,e){return e.fs_.chmod(t,493)}function fq(t){if(!t)return{win32:"",posix:""};let e=typeof t=="string"?t.split(sc.delimiter):Array.from(t),r={};for(let o=0;o<e.length;o++){let a=e[o].split("/").join("\\"),n=a1e()?e[o].split("\\").join("/").replace(/^([^:\\/]*):/,(u,A)=>`/mnt/${A.toLowerCase()}`):e[o];r.win32=r.win32?`${r.win32};${a}`:a,r.posix=r.posix?`${r.posix}:${n}`:n,r[o]={win32:a,posix:n}}return r}c1e.exports=Aq});var Sq=_((h$t,F1e)=>{F1e.exports=Be("stream")});var L1e=_((g$t,N1e)=>{"use strict";function T1e(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter(function(a){return Object.getOwnPropertyDescriptor(t,a).enumerable})),r.push.apply(r,o)}return r}function U1t(t){for(var e=1;e<arguments.length;e++){var r=arguments[e]!=null?arguments[e]:{};e%2?T1e(Object(r),!0).forEach(function(o){_1t(t,o,r[o])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):T1e(Object(r)).forEach(function(o){Object.defineProperty(t,o,Object.getOwnPropertyDescriptor(r,o))})}return t}function _1t(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function H1t(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function R1e(t,e){for(var r=0;r<e.length;r++){var o=e[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}function j1t(t,e,r){return e&&R1e(t.prototype,e),r&&R1e(t,r),t}var q1t=Be("buffer"),QQ=q1t.Buffer,G1t=Be("util"),xq=G1t.inspect,Y1t=xq&&xq.custom||"inspect";function W1t(t,e,r){QQ.prototype.copy.call(t,e,r)}N1e.exports=function(){function t(){H1t(this,t),this.head=null,this.tail=null,this.length=0}return j1t(t,[{key:"push",value:function(r){var o={data:r,next:null};this.length>0?this.tail.next=o:this.head=o,this.tail=o,++this.length}},{key:"unshift",value:function(r){var o={data:r,next:this.head};this.length===0&&(this.tail=o),this.head=o,++this.length}},{key:"shift",value:function(){if(this.length!==0){var r=this.head.data;return this.length===1?this.head=this.tail=null:this.head=this.head.next,--this.length,r}}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(r){if(this.length===0)return"";for(var o=this.head,a=""+o.data;o=o.next;)a+=r+o.data;return a}},{key:"concat",value:function(r){if(this.length===0)return QQ.alloc(0);for(var o=QQ.allocUnsafe(r>>>0),a=this.head,n=0;a;)W1t(a.data,o,n),n+=a.data.length,a=a.next;return o}},{key:"consume",value:function(r,o){var a;return r<this.head.data.length?(a=this.head.data.slice(0,r),this.head.data=this.head.data.slice(r)):r===this.head.data.length?a=this.shift():a=o?this._getString(r):this._getBuffer(r),a}},{key:"first",value:function(){return this.head.data}},{key:"_getString",value:function(r){var o=this.head,a=1,n=o.data;for(r-=n.length;o=o.next;){var u=o.data,A=r>u.length?u.length:r;if(A===u.length?n+=u:n+=u.slice(0,r),r-=A,r===0){A===u.length?(++a,o.next?this.head=o.next:this.head=this.tail=null):(this.head=o,o.data=u.slice(A));break}++a}return this.length-=a,n}},{key:"_getBuffer",value:function(r){var o=QQ.allocUnsafe(r),a=this.head,n=1;for(a.data.copy(o),r-=a.data.length;a=a.next;){var u=a.data,A=r>u.length?u.length:r;if(u.copy(o,o.length-r,0,A),r-=A,r===0){A===u.length?(++n,a.next?this.head=a.next:this.head=this.tail=null):(this.head=a,a.data=u.slice(A));break}++n}return this.length-=n,o}},{key:Y1t,value:function(r,o){return xq(this,U1t({},o,{depth:0,customInspect:!1}))}}]),t}()});var kq=_((d$t,O1e)=>{"use strict";function V1t(t,e){var r=this,o=this._readableState&&this._readableState.destroyed,a=this._writableState&&this._writableState.destroyed;return o||a?(e?e(t):t&&(this._writableState?this._writableState.errorEmitted||(this._writableState.errorEmitted=!0,process.nextTick(bq,this,t)):process.nextTick(bq,this,t)),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(t||null,function(n){!e&&n?r._writableState?r._writableState.errorEmitted?process.nextTick(FQ,r):(r._writableState.errorEmitted=!0,process.nextTick(M1e,r,n)):process.nextTick(M1e,r,n):e?(process.nextTick(FQ,r),e(n)):process.nextTick(FQ,r)}),this)}function M1e(t,e){bq(t,e),FQ(t)}function FQ(t){t._writableState&&!t._writableState.emitClose||t._readableState&&!t._readableState.emitClose||t.emit("close")}function K1t(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}function bq(t,e){t.emit("error",e)}function J1t(t,e){var r=t._readableState,o=t._writableState;r&&r.autoDestroy||o&&o.autoDestroy?t.destroy(e):t.emit("error",e)}O1e.exports={destroy:V1t,undestroy:K1t,errorOrDestroy:J1t}});var k0=_((m$t,H1e)=>{"use strict";var _1e={};function ac(t,e,r){r||(r=Error);function o(n,u,A){return typeof e=="string"?e:e(n,u,A)}class a extends r{constructor(u,A,p){super(o(u,A,p))}}a.prototype.name=r.name,a.prototype.code=t,_1e[t]=a}function U1e(t,e){if(Array.isArray(t)){let r=t.length;return t=t.map(o=>String(o)),r>2?`one of ${e} ${t.slice(0,r-1).join(", ")}, or `+t[r-1]:r===2?`one of ${e} ${t[0]} or ${t[1]}`:`of ${e} ${t[0]}`}else return`of ${e} ${String(t)}`}function z1t(t,e,r){return t.substr(!r||r<0?0:+r,e.length)===e}function X1t(t,e,r){return(r===void 0||r>t.length)&&(r=t.length),t.substring(r-e.length,r)===e}function Z1t(t,e,r){return typeof r!="number"&&(r=0),r+e.length>t.length?!1:t.indexOf(e,r)!==-1}ac("ERR_INVALID_OPT_VALUE",function(t,e){return'The value "'+e+'" is invalid for option "'+t+'"'},TypeError);ac("ERR_INVALID_ARG_TYPE",function(t,e,r){let o;typeof e=="string"&&z1t(e,"not ")?(o="must not be",e=e.replace(/^not /,"")):o="must be";let a;if(X1t(t," argument"))a=`The ${t} ${o} ${U1e(e,"type")}`;else{let n=Z1t(t,".")?"property":"argument";a=`The "${t}" ${n} ${o} ${U1e(e,"type")}`}return a+=`. Received type ${typeof r}`,a},TypeError);ac("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF");ac("ERR_METHOD_NOT_IMPLEMENTED",function(t){return"The "+t+" method is not implemented"});ac("ERR_STREAM_PREMATURE_CLOSE","Premature close");ac("ERR_STREAM_DESTROYED",function(t){return"Cannot call "+t+" after a stream was destroyed"});ac("ERR_MULTIPLE_CALLBACK","Callback called multiple times");ac("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable");ac("ERR_STREAM_WRITE_AFTER_END","write after end");ac("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError);ac("ERR_UNKNOWN_ENCODING",function(t){return"Unknown encoding: "+t},TypeError);ac("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event");H1e.exports.codes=_1e});var Qq=_((y$t,j1e)=>{"use strict";var $1t=k0().codes.ERR_INVALID_OPT_VALUE;function e2t(t,e,r){return t.highWaterMark!=null?t.highWaterMark:e?t[r]:null}function t2t(t,e,r,o){var a=e2t(e,o,r);if(a!=null){if(!(isFinite(a)&&Math.floor(a)===a)||a<0){var n=o?r:"highWaterMark";throw new $1t(n,a)}return Math.floor(a)}return t.objectMode?16:16*1024}j1e.exports={getHighWaterMark:t2t}});var q1e=_((E$t,Fq)=>{typeof Object.create=="function"?Fq.exports=function(e,r){r&&(e.super_=r,e.prototype=Object.create(r.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:Fq.exports=function(e,r){if(r){e.super_=r;var o=function(){};o.prototype=r.prototype,e.prototype=new o,e.prototype.constructor=e}}});var Q0=_((C$t,Rq)=>{try{if(Tq=Be("util"),typeof Tq.inherits!="function")throw"";Rq.exports=Tq.inherits}catch{Rq.exports=q1e()}var Tq});var Y1e=_((w$t,G1e)=>{G1e.exports=Be("util").deprecate});var Mq=_((I$t,X1e)=>{"use strict";X1e.exports=Ti;function V1e(t){var e=this;this.next=null,this.entry=null,this.finish=function(){x2t(e,t)}}var JC;Ti.WritableState=mv;var r2t={deprecate:Y1e()},K1e=Sq(),RQ=Be("buffer").Buffer,n2t=global.Uint8Array||function(){};function i2t(t){return RQ.from(t)}function s2t(t){return RQ.isBuffer(t)||t instanceof n2t}var Lq=kq(),o2t=Qq(),a2t=o2t.getHighWaterMark,F0=k0().codes,l2t=F0.ERR_INVALID_ARG_TYPE,c2t=F0.ERR_METHOD_NOT_IMPLEMENTED,u2t=F0.ERR_MULTIPLE_CALLBACK,A2t=F0.ERR_STREAM_CANNOT_PIPE,f2t=F0.ERR_STREAM_DESTROYED,p2t=F0.ERR_STREAM_NULL_VALUES,h2t=F0.ERR_STREAM_WRITE_AFTER_END,g2t=F0.ERR_UNKNOWN_ENCODING,zC=Lq.errorOrDestroy;Q0()(Ti,K1e);function d2t(){}function mv(t,e,r){JC=JC||Em(),t=t||{},typeof r!="boolean"&&(r=e instanceof JC),this.objectMode=!!t.objectMode,r&&(this.objectMode=this.objectMode||!!t.writableObjectMode),this.highWaterMark=a2t(this,t,"writableHighWaterMark",r),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var o=t.decodeStrings===!1;this.decodeStrings=!o,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(a){B2t(e,a)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=t.emitClose!==!1,this.autoDestroy=!!t.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new V1e(this)}mv.prototype.getBuffer=function(){for(var e=this.bufferedRequest,r=[];e;)r.push(e),e=e.next;return r};(function(){try{Object.defineProperty(mv.prototype,"buffer",{get:r2t.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch{}})();var TQ;typeof Symbol=="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]=="function"?(TQ=Function.prototype[Symbol.hasInstance],Object.defineProperty(Ti,Symbol.hasInstance,{value:function(e){return TQ.call(this,e)?!0:this!==Ti?!1:e&&e._writableState instanceof mv}})):TQ=function(e){return e instanceof this};function Ti(t){JC=JC||Em();var e=this instanceof JC;if(!e&&!TQ.call(Ti,this))return new Ti(t);this._writableState=new mv(t,this,e),this.writable=!0,t&&(typeof t.write=="function"&&(this._write=t.write),typeof t.writev=="function"&&(this._writev=t.writev),typeof t.destroy=="function"&&(this._destroy=t.destroy),typeof t.final=="function"&&(this._final=t.final)),K1e.call(this)}Ti.prototype.pipe=function(){zC(this,new A2t)};function m2t(t,e){var r=new h2t;zC(t,r),process.nextTick(e,r)}function y2t(t,e,r,o){var a;return r===null?a=new p2t:typeof r!="string"&&!e.objectMode&&(a=new l2t("chunk",["string","Buffer"],r)),a?(zC(t,a),process.nextTick(o,a),!1):!0}Ti.prototype.write=function(t,e,r){var o=this._writableState,a=!1,n=!o.objectMode&&s2t(t);return n&&!RQ.isBuffer(t)&&(t=i2t(t)),typeof e=="function"&&(r=e,e=null),n?e="buffer":e||(e=o.defaultEncoding),typeof r!="function"&&(r=d2t),o.ending?m2t(this,r):(n||y2t(this,o,t,r))&&(o.pendingcb++,a=C2t(this,o,n,t,e,r)),a};Ti.prototype.cork=function(){this._writableState.corked++};Ti.prototype.uncork=function(){var t=this._writableState;t.corked&&(t.corked--,!t.writing&&!t.corked&&!t.bufferProcessing&&t.bufferedRequest&&J1e(this,t))};Ti.prototype.setDefaultEncoding=function(e){if(typeof e=="string"&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new g2t(e);return this._writableState.defaultEncoding=e,this};Object.defineProperty(Ti.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}});function E2t(t,e,r){return!t.objectMode&&t.decodeStrings!==!1&&typeof e=="string"&&(e=RQ.from(e,r)),e}Object.defineProperty(Ti.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}});function C2t(t,e,r,o,a,n){if(!r){var u=E2t(e,o,a);o!==u&&(r=!0,a="buffer",o=u)}var A=e.objectMode?1:o.length;e.length+=A;var p=e.length<e.highWaterMark;if(p||(e.needDrain=!0),e.writing||e.corked){var h=e.lastBufferedRequest;e.lastBufferedRequest={chunk:o,encoding:a,isBuf:r,callback:n,next:null},h?h.next=e.lastBufferedRequest:e.bufferedRequest=e.lastBufferedRequest,e.bufferedRequestCount+=1}else Nq(t,e,!1,A,o,a,n);return p}function Nq(t,e,r,o,a,n,u){e.writelen=o,e.writecb=u,e.writing=!0,e.sync=!0,e.destroyed?e.onwrite(new f2t("write")):r?t._writev(a,e.onwrite):t._write(a,n,e.onwrite),e.sync=!1}function w2t(t,e,r,o,a){--e.pendingcb,r?(process.nextTick(a,o),process.nextTick(dv,t,e),t._writableState.errorEmitted=!0,zC(t,o)):(a(o),t._writableState.errorEmitted=!0,zC(t,o),dv(t,e))}function I2t(t){t.writing=!1,t.writecb=null,t.length-=t.writelen,t.writelen=0}function B2t(t,e){var r=t._writableState,o=r.sync,a=r.writecb;if(typeof a!="function")throw new u2t;if(I2t(r),e)w2t(t,r,o,e,a);else{var n=z1e(r)||t.destroyed;!n&&!r.corked&&!r.bufferProcessing&&r.bufferedRequest&&J1e(t,r),o?process.nextTick(W1e,t,r,n,a):W1e(t,r,n,a)}}function W1e(t,e,r,o){r||v2t(t,e),e.pendingcb--,o(),dv(t,e)}function v2t(t,e){e.length===0&&e.needDrain&&(e.needDrain=!1,t.emit("drain"))}function J1e(t,e){e.bufferProcessing=!0;var r=e.bufferedRequest;if(t._writev&&r&&r.next){var o=e.bufferedRequestCount,a=new Array(o),n=e.corkedRequestsFree;n.entry=r;for(var u=0,A=!0;r;)a[u]=r,r.isBuf||(A=!1),r=r.next,u+=1;a.allBuffers=A,Nq(t,e,!0,e.length,a,"",n.finish),e.pendingcb++,e.lastBufferedRequest=null,n.next?(e.corkedRequestsFree=n.next,n.next=null):e.corkedRequestsFree=new V1e(e),e.bufferedRequestCount=0}else{for(;r;){var p=r.chunk,h=r.encoding,E=r.callback,I=e.objectMode?1:p.length;if(Nq(t,e,!1,I,p,h,E),r=r.next,e.bufferedRequestCount--,e.writing)break}r===null&&(e.lastBufferedRequest=null)}e.bufferedRequest=r,e.bufferProcessing=!1}Ti.prototype._write=function(t,e,r){r(new c2t("_write()"))};Ti.prototype._writev=null;Ti.prototype.end=function(t,e,r){var o=this._writableState;return typeof t=="function"?(r=t,t=null,e=null):typeof e=="function"&&(r=e,e=null),t!=null&&this.write(t,e),o.corked&&(o.corked=1,this.uncork()),o.ending||S2t(this,o,r),this};Object.defineProperty(Ti.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}});function z1e(t){return t.ending&&t.length===0&&t.bufferedRequest===null&&!t.finished&&!t.writing}function D2t(t,e){t._final(function(r){e.pendingcb--,r&&zC(t,r),e.prefinished=!0,t.emit("prefinish"),dv(t,e)})}function P2t(t,e){!e.prefinished&&!e.finalCalled&&(typeof t._final=="function"&&!e.destroyed?(e.pendingcb++,e.finalCalled=!0,process.nextTick(D2t,t,e)):(e.prefinished=!0,t.emit("prefinish")))}function dv(t,e){var r=z1e(e);if(r&&(P2t(t,e),e.pendingcb===0&&(e.finished=!0,t.emit("finish"),e.autoDestroy))){var o=t._readableState;(!o||o.autoDestroy&&o.endEmitted)&&t.destroy()}return r}function S2t(t,e,r){e.ending=!0,dv(t,e),r&&(e.finished?process.nextTick(r):t.once("finish",r)),e.ended=!0,t.writable=!1}function x2t(t,e,r){var o=t.entry;for(t.entry=null;o;){var a=o.callback;e.pendingcb--,a(r),o=o.next}e.corkedRequestsFree.next=t}Object.defineProperty(Ti.prototype,"destroyed",{enumerable:!1,get:function(){return this._writableState===void 0?!1:this._writableState.destroyed},set:function(e){!this._writableState||(this._writableState.destroyed=e)}});Ti.prototype.destroy=Lq.destroy;Ti.prototype._undestroy=Lq.undestroy;Ti.prototype._destroy=function(t,e){e(t)}});var Em=_((B$t,$1e)=>{"use strict";var b2t=Object.keys||function(t){var e=[];for(var r in t)e.push(r);return e};$1e.exports=yA;var Z1e=_q(),Uq=Mq();Q0()(yA,Z1e);for(Oq=b2t(Uq.prototype),NQ=0;NQ<Oq.length;NQ++)LQ=Oq[NQ],yA.prototype[LQ]||(yA.prototype[LQ]=Uq.prototype[LQ]);var Oq,LQ,NQ;function yA(t){if(!(this instanceof yA))return new yA(t);Z1e.call(this,t),Uq.call(this,t),this.allowHalfOpen=!0,t&&(t.readable===!1&&(this.readable=!1),t.writable===!1&&(this.writable=!1),t.allowHalfOpen===!1&&(this.allowHalfOpen=!1,this.once("end",k2t)))}Object.defineProperty(yA.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}});Object.defineProperty(yA.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}});Object.defineProperty(yA.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}});function k2t(){this._writableState.ended||process.nextTick(Q2t,this)}function Q2t(t){t.end()}Object.defineProperty(yA.prototype,"destroyed",{enumerable:!1,get:function(){return this._readableState===void 0||this._writableState===void 0?!1:this._readableState.destroyed&&this._writableState.destroyed},set:function(e){this._readableState===void 0||this._writableState===void 0||(this._readableState.destroyed=e,this._writableState.destroyed=e)}})});var r2e=_((Hq,t2e)=>{var MQ=Be("buffer"),np=MQ.Buffer;function e2e(t,e){for(var r in t)e[r]=t[r]}np.from&&np.alloc&&np.allocUnsafe&&np.allocUnsafeSlow?t2e.exports=MQ:(e2e(MQ,Hq),Hq.Buffer=XC);function XC(t,e,r){return np(t,e,r)}e2e(np,XC);XC.from=function(t,e,r){if(typeof t=="number")throw new TypeError("Argument must not be a number");return np(t,e,r)};XC.alloc=function(t,e,r){if(typeof t!="number")throw new TypeError("Argument must be a number");var o=np(t);return e!==void 0?typeof r=="string"?o.fill(e,r):o.fill(e):o.fill(0),o};XC.allocUnsafe=function(t){if(typeof t!="number")throw new TypeError("Argument must be a number");return np(t)};XC.allocUnsafeSlow=function(t){if(typeof t!="number")throw new TypeError("Argument must be a number");return MQ.SlowBuffer(t)}});var Gq=_(i2e=>{"use strict";var qq=r2e().Buffer,n2e=qq.isEncoding||function(t){switch(t=""+t,t&&t.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function F2t(t){if(!t)return"utf8";for(var e;;)switch(t){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return t;default:if(e)return;t=(""+t).toLowerCase(),e=!0}}function T2t(t){var e=F2t(t);if(typeof e!="string"&&(qq.isEncoding===n2e||!n2e(t)))throw new Error("Unknown encoding: "+t);return e||t}i2e.StringDecoder=yv;function yv(t){this.encoding=T2t(t);var e;switch(this.encoding){case"utf16le":this.text=U2t,this.end=_2t,e=4;break;case"utf8":this.fillLast=L2t,e=4;break;case"base64":this.text=H2t,this.end=j2t,e=3;break;default:this.write=q2t,this.end=G2t;return}this.lastNeed=0,this.lastTotal=0,this.lastChar=qq.allocUnsafe(e)}yv.prototype.write=function(t){if(t.length===0)return"";var e,r;if(this.lastNeed){if(e=this.fillLast(t),e===void 0)return"";r=this.lastNeed,this.lastNeed=0}else r=0;return r<t.length?e?e+this.text(t,r):this.text(t,r):e||""};yv.prototype.end=O2t;yv.prototype.text=M2t;yv.prototype.fillLast=function(t){if(this.lastNeed<=t.length)return t.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);t.copy(this.lastChar,this.lastTotal-this.lastNeed,0,t.length),this.lastNeed-=t.length};function jq(t){return t<=127?0:t>>5===6?2:t>>4===14?3:t>>3===30?4:t>>6===2?-1:-2}function R2t(t,e,r){var o=e.length-1;if(o<r)return 0;var a=jq(e[o]);return a>=0?(a>0&&(t.lastNeed=a-1),a):--o<r||a===-2?0:(a=jq(e[o]),a>=0?(a>0&&(t.lastNeed=a-2),a):--o<r||a===-2?0:(a=jq(e[o]),a>=0?(a>0&&(a===2?a=0:t.lastNeed=a-3),a):0))}function N2t(t,e,r){if((e[0]&192)!==128)return t.lastNeed=0,"\uFFFD";if(t.lastNeed>1&&e.length>1){if((e[1]&192)!==128)return t.lastNeed=1,"\uFFFD";if(t.lastNeed>2&&e.length>2&&(e[2]&192)!==128)return t.lastNeed=2,"\uFFFD"}}function L2t(t){var e=this.lastTotal-this.lastNeed,r=N2t(this,t,e);if(r!==void 0)return r;if(this.lastNeed<=t.length)return t.copy(this.lastChar,e,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);t.copy(this.lastChar,e,0,t.length),this.lastNeed-=t.length}function M2t(t,e){var r=R2t(this,t,e);if(!this.lastNeed)return t.toString("utf8",e);this.lastTotal=r;var o=t.length-(r-this.lastNeed);return t.copy(this.lastChar,0,o),t.toString("utf8",e,o)}function O2t(t){var e=t&&t.length?this.write(t):"";return this.lastNeed?e+"\uFFFD":e}function U2t(t,e){if((t.length-e)%2===0){var r=t.toString("utf16le",e);if(r){var o=r.charCodeAt(r.length-1);if(o>=55296&&o<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=t[t.length-2],this.lastChar[1]=t[t.length-1],r.slice(0,-1)}return r}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=t[t.length-1],t.toString("utf16le",e,t.length-1)}function _2t(t){var e=t&&t.length?this.write(t):"";if(this.lastNeed){var r=this.lastTotal-this.lastNeed;return e+this.lastChar.toString("utf16le",0,r)}return e}function H2t(t,e){var r=(t.length-e)%3;return r===0?t.toString("base64",e):(this.lastNeed=3-r,this.lastTotal=3,r===1?this.lastChar[0]=t[t.length-1]:(this.lastChar[0]=t[t.length-2],this.lastChar[1]=t[t.length-1]),t.toString("base64",e,t.length-r))}function j2t(t){var e=t&&t.length?this.write(t):"";return this.lastNeed?e+this.lastChar.toString("base64",0,3-this.lastNeed):e}function q2t(t){return t.toString(this.encoding)}function G2t(t){return t&&t.length?this.write(t):""}});var OQ=_((D$t,a2e)=>{"use strict";var s2e=k0().codes.ERR_STREAM_PREMATURE_CLOSE;function Y2t(t){var e=!1;return function(){if(!e){e=!0;for(var r=arguments.length,o=new Array(r),a=0;a<r;a++)o[a]=arguments[a];t.apply(this,o)}}}function W2t(){}function V2t(t){return t.setHeader&&typeof t.abort=="function"}function o2e(t,e,r){if(typeof e=="function")return o2e(t,null,e);e||(e={}),r=Y2t(r||W2t);var o=e.readable||e.readable!==!1&&t.readable,a=e.writable||e.writable!==!1&&t.writable,n=function(){t.writable||A()},u=t._writableState&&t._writableState.finished,A=function(){a=!1,u=!0,o||r.call(t)},p=t._readableState&&t._readableState.endEmitted,h=function(){o=!1,p=!0,a||r.call(t)},E=function(C){r.call(t,C)},I=function(){var C;if(o&&!p)return(!t._readableState||!t._readableState.ended)&&(C=new s2e),r.call(t,C);if(a&&!u)return(!t._writableState||!t._writableState.ended)&&(C=new s2e),r.call(t,C)},v=function(){t.req.on("finish",A)};return V2t(t)?(t.on("complete",A),t.on("abort",I),t.req?v():t.on("request",v)):a&&!t._writableState&&(t.on("end",n),t.on("close",n)),t.on("end",h),t.on("finish",A),e.error!==!1&&t.on("error",E),t.on("close",I),function(){t.removeListener("complete",A),t.removeListener("abort",I),t.removeListener("request",v),t.req&&t.req.removeListener("finish",A),t.removeListener("end",n),t.removeListener("close",n),t.removeListener("finish",A),t.removeListener("end",h),t.removeListener("error",E),t.removeListener("close",I)}}a2e.exports=o2e});var c2e=_((P$t,l2e)=>{"use strict";var UQ;function T0(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}var K2t=OQ(),R0=Symbol("lastResolve"),Cm=Symbol("lastReject"),Ev=Symbol("error"),_Q=Symbol("ended"),wm=Symbol("lastPromise"),Yq=Symbol("handlePromise"),Im=Symbol("stream");function N0(t,e){return{value:t,done:e}}function J2t(t){var e=t[R0];if(e!==null){var r=t[Im].read();r!==null&&(t[wm]=null,t[R0]=null,t[Cm]=null,e(N0(r,!1)))}}function z2t(t){process.nextTick(J2t,t)}function X2t(t,e){return function(r,o){t.then(function(){if(e[_Q]){r(N0(void 0,!0));return}e[Yq](r,o)},o)}}var Z2t=Object.getPrototypeOf(function(){}),$2t=Object.setPrototypeOf((UQ={get stream(){return this[Im]},next:function(){var e=this,r=this[Ev];if(r!==null)return Promise.reject(r);if(this[_Q])return Promise.resolve(N0(void 0,!0));if(this[Im].destroyed)return new Promise(function(u,A){process.nextTick(function(){e[Ev]?A(e[Ev]):u(N0(void 0,!0))})});var o=this[wm],a;if(o)a=new Promise(X2t(o,this));else{var n=this[Im].read();if(n!==null)return Promise.resolve(N0(n,!1));a=new Promise(this[Yq])}return this[wm]=a,a}},T0(UQ,Symbol.asyncIterator,function(){return this}),T0(UQ,"return",function(){var e=this;return new Promise(function(r,o){e[Im].destroy(null,function(a){if(a){o(a);return}r(N0(void 0,!0))})})}),UQ),Z2t),eBt=function(e){var r,o=Object.create($2t,(r={},T0(r,Im,{value:e,writable:!0}),T0(r,R0,{value:null,writable:!0}),T0(r,Cm,{value:null,writable:!0}),T0(r,Ev,{value:null,writable:!0}),T0(r,_Q,{value:e._readableState.endEmitted,writable:!0}),T0(r,Yq,{value:function(n,u){var A=o[Im].read();A?(o[wm]=null,o[R0]=null,o[Cm]=null,n(N0(A,!1))):(o[R0]=n,o[Cm]=u)},writable:!0}),r));return o[wm]=null,K2t(e,function(a){if(a&&a.code!=="ERR_STREAM_PREMATURE_CLOSE"){var n=o[Cm];n!==null&&(o[wm]=null,o[R0]=null,o[Cm]=null,n(a)),o[Ev]=a;return}var u=o[R0];u!==null&&(o[wm]=null,o[R0]=null,o[Cm]=null,u(N0(void 0,!0))),o[_Q]=!0}),e.on("readable",z2t.bind(null,o)),o};l2e.exports=eBt});var p2e=_((S$t,f2e)=>{"use strict";function u2e(t,e,r,o,a,n,u){try{var A=t[n](u),p=A.value}catch(h){r(h);return}A.done?e(p):Promise.resolve(p).then(o,a)}function tBt(t){return function(){var e=this,r=arguments;return new Promise(function(o,a){var n=t.apply(e,r);function u(p){u2e(n,o,a,u,A,"next",p)}function A(p){u2e(n,o,a,u,A,"throw",p)}u(void 0)})}}function A2e(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter(function(a){return Object.getOwnPropertyDescriptor(t,a).enumerable})),r.push.apply(r,o)}return r}function rBt(t){for(var e=1;e<arguments.length;e++){var r=arguments[e]!=null?arguments[e]:{};e%2?A2e(Object(r),!0).forEach(function(o){nBt(t,o,r[o])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):A2e(Object(r)).forEach(function(o){Object.defineProperty(t,o,Object.getOwnPropertyDescriptor(r,o))})}return t}function nBt(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}var iBt=k0().codes.ERR_INVALID_ARG_TYPE;function sBt(t,e,r){var o;if(e&&typeof e.next=="function")o=e;else if(e&&e[Symbol.asyncIterator])o=e[Symbol.asyncIterator]();else if(e&&e[Symbol.iterator])o=e[Symbol.iterator]();else throw new iBt("iterable",["Iterable"],e);var a=new t(rBt({objectMode:!0},r)),n=!1;a._read=function(){n||(n=!0,u())};function u(){return A.apply(this,arguments)}function A(){return A=tBt(function*(){try{var p=yield o.next(),h=p.value,E=p.done;E?a.push(null):a.push(yield h)?u():n=!1}catch(I){a.destroy(I)}}),A.apply(this,arguments)}return a}f2e.exports=sBt});var _q=_((b$t,B2e)=>{"use strict";B2e.exports=mn;var ZC;mn.ReadableState=m2e;var x$t=Be("events").EventEmitter,d2e=function(e,r){return e.listeners(r).length},wv=Sq(),HQ=Be("buffer").Buffer,oBt=global.Uint8Array||function(){};function aBt(t){return HQ.from(t)}function lBt(t){return HQ.isBuffer(t)||t instanceof oBt}var Wq=Be("util"),$r;Wq&&Wq.debuglog?$r=Wq.debuglog("stream"):$r=function(){};var cBt=L1e(),$q=kq(),uBt=Qq(),ABt=uBt.getHighWaterMark,jQ=k0().codes,fBt=jQ.ERR_INVALID_ARG_TYPE,pBt=jQ.ERR_STREAM_PUSH_AFTER_EOF,hBt=jQ.ERR_METHOD_NOT_IMPLEMENTED,gBt=jQ.ERR_STREAM_UNSHIFT_AFTER_END_EVENT,$C,Vq,Kq;Q0()(mn,wv);var Cv=$q.errorOrDestroy,Jq=["error","close","destroy","pause","resume"];function dBt(t,e,r){if(typeof t.prependListener=="function")return t.prependListener(e,r);!t._events||!t._events[e]?t.on(e,r):Array.isArray(t._events[e])?t._events[e].unshift(r):t._events[e]=[r,t._events[e]]}function m2e(t,e,r){ZC=ZC||Em(),t=t||{},typeof r!="boolean"&&(r=e instanceof ZC),this.objectMode=!!t.objectMode,r&&(this.objectMode=this.objectMode||!!t.readableObjectMode),this.highWaterMark=ABt(this,t,"readableHighWaterMark",r),this.buffer=new cBt,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.paused=!0,this.emitClose=t.emitClose!==!1,this.autoDestroy=!!t.autoDestroy,this.destroyed=!1,this.defaultEncoding=t.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&($C||($C=Gq().StringDecoder),this.decoder=new $C(t.encoding),this.encoding=t.encoding)}function mn(t){if(ZC=ZC||Em(),!(this instanceof mn))return new mn(t);var e=this instanceof ZC;this._readableState=new m2e(t,this,e),this.readable=!0,t&&(typeof t.read=="function"&&(this._read=t.read),typeof t.destroy=="function"&&(this._destroy=t.destroy)),wv.call(this)}Object.defineProperty(mn.prototype,"destroyed",{enumerable:!1,get:function(){return this._readableState===void 0?!1:this._readableState.destroyed},set:function(e){!this._readableState||(this._readableState.destroyed=e)}});mn.prototype.destroy=$q.destroy;mn.prototype._undestroy=$q.undestroy;mn.prototype._destroy=function(t,e){e(t)};mn.prototype.push=function(t,e){var r=this._readableState,o;return r.objectMode?o=!0:typeof t=="string"&&(e=e||r.defaultEncoding,e!==r.encoding&&(t=HQ.from(t,e),e=""),o=!0),y2e(this,t,e,!1,o)};mn.prototype.unshift=function(t){return y2e(this,t,null,!0,!1)};function y2e(t,e,r,o,a){$r("readableAddChunk",e);var n=t._readableState;if(e===null)n.reading=!1,EBt(t,n);else{var u;if(a||(u=mBt(n,e)),u)Cv(t,u);else if(n.objectMode||e&&e.length>0)if(typeof e!="string"&&!n.objectMode&&Object.getPrototypeOf(e)!==HQ.prototype&&(e=aBt(e)),o)n.endEmitted?Cv(t,new gBt):zq(t,n,e,!0);else if(n.ended)Cv(t,new pBt);else{if(n.destroyed)return!1;n.reading=!1,n.decoder&&!r?(e=n.decoder.write(e),n.objectMode||e.length!==0?zq(t,n,e,!1):Zq(t,n)):zq(t,n,e,!1)}else o||(n.reading=!1,Zq(t,n))}return!n.ended&&(n.length<n.highWaterMark||n.length===0)}function zq(t,e,r,o){e.flowing&&e.length===0&&!e.sync?(e.awaitDrain=0,t.emit("data",r)):(e.length+=e.objectMode?1:r.length,o?e.buffer.unshift(r):e.buffer.push(r),e.needReadable&&qQ(t)),Zq(t,e)}function mBt(t,e){var r;return!lBt(e)&&typeof e!="string"&&e!==void 0&&!t.objectMode&&(r=new fBt("chunk",["string","Buffer","Uint8Array"],e)),r}mn.prototype.isPaused=function(){return this._readableState.flowing===!1};mn.prototype.setEncoding=function(t){$C||($C=Gq().StringDecoder);var e=new $C(t);this._readableState.decoder=e,this._readableState.encoding=this._readableState.decoder.encoding;for(var r=this._readableState.buffer.head,o="";r!==null;)o+=e.write(r.data),r=r.next;return this._readableState.buffer.clear(),o!==""&&this._readableState.buffer.push(o),this._readableState.length=o.length,this};var h2e=1073741824;function yBt(t){return t>=h2e?t=h2e:(t--,t|=t>>>1,t|=t>>>2,t|=t>>>4,t|=t>>>8,t|=t>>>16,t++),t}function g2e(t,e){return t<=0||e.length===0&&e.ended?0:e.objectMode?1:t!==t?e.flowing&&e.length?e.buffer.head.data.length:e.length:(t>e.highWaterMark&&(e.highWaterMark=yBt(t)),t<=e.length?t:e.ended?e.length:(e.needReadable=!0,0))}mn.prototype.read=function(t){$r("read",t),t=parseInt(t,10);var e=this._readableState,r=t;if(t!==0&&(e.emittedReadable=!1),t===0&&e.needReadable&&((e.highWaterMark!==0?e.length>=e.highWaterMark:e.length>0)||e.ended))return $r("read: emitReadable",e.length,e.ended),e.length===0&&e.ended?Xq(this):qQ(this),null;if(t=g2e(t,e),t===0&&e.ended)return e.length===0&&Xq(this),null;var o=e.needReadable;$r("need readable",o),(e.length===0||e.length-t<e.highWaterMark)&&(o=!0,$r("length less than watermark",o)),e.ended||e.reading?(o=!1,$r("reading or ended",o)):o&&($r("do read"),e.reading=!0,e.sync=!0,e.length===0&&(e.needReadable=!0),this._read(e.highWaterMark),e.sync=!1,e.reading||(t=g2e(r,e)));var a;return t>0?a=w2e(t,e):a=null,a===null?(e.needReadable=e.length<=e.highWaterMark,t=0):(e.length-=t,e.awaitDrain=0),e.length===0&&(e.ended||(e.needReadable=!0),r!==t&&e.ended&&Xq(this)),a!==null&&this.emit("data",a),a};function EBt(t,e){if($r("onEofChunk"),!e.ended){if(e.decoder){var r=e.decoder.end();r&&r.length&&(e.buffer.push(r),e.length+=e.objectMode?1:r.length)}e.ended=!0,e.sync?qQ(t):(e.needReadable=!1,e.emittedReadable||(e.emittedReadable=!0,E2e(t)))}}function qQ(t){var e=t._readableState;$r("emitReadable",e.needReadable,e.emittedReadable),e.needReadable=!1,e.emittedReadable||($r("emitReadable",e.flowing),e.emittedReadable=!0,process.nextTick(E2e,t))}function E2e(t){var e=t._readableState;$r("emitReadable_",e.destroyed,e.length,e.ended),!e.destroyed&&(e.length||e.ended)&&(t.emit("readable"),e.emittedReadable=!1),e.needReadable=!e.flowing&&!e.ended&&e.length<=e.highWaterMark,eG(t)}function Zq(t,e){e.readingMore||(e.readingMore=!0,process.nextTick(CBt,t,e))}function CBt(t,e){for(;!e.reading&&!e.ended&&(e.length<e.highWaterMark||e.flowing&&e.length===0);){var r=e.length;if($r("maybeReadMore read 0"),t.read(0),r===e.length)break}e.readingMore=!1}mn.prototype._read=function(t){Cv(this,new hBt("_read()"))};mn.prototype.pipe=function(t,e){var r=this,o=this._readableState;switch(o.pipesCount){case 0:o.pipes=t;break;case 1:o.pipes=[o.pipes,t];break;default:o.pipes.push(t);break}o.pipesCount+=1,$r("pipe count=%d opts=%j",o.pipesCount,e);var a=(!e||e.end!==!1)&&t!==process.stdout&&t!==process.stderr,n=a?A:T;o.endEmitted?process.nextTick(n):r.once("end",n),t.on("unpipe",u);function u(L,U){$r("onunpipe"),L===r&&U&&U.hasUnpiped===!1&&(U.hasUnpiped=!0,E())}function A(){$r("onend"),t.end()}var p=wBt(r);t.on("drain",p);var h=!1;function E(){$r("cleanup"),t.removeListener("close",b),t.removeListener("finish",C),t.removeListener("drain",p),t.removeListener("error",v),t.removeListener("unpipe",u),r.removeListener("end",A),r.removeListener("end",T),r.removeListener("data",I),h=!0,o.awaitDrain&&(!t._writableState||t._writableState.needDrain)&&p()}r.on("data",I);function I(L){$r("ondata");var U=t.write(L);$r("dest.write",U),U===!1&&((o.pipesCount===1&&o.pipes===t||o.pipesCount>1&&I2e(o.pipes,t)!==-1)&&!h&&($r("false write response, pause",o.awaitDrain),o.awaitDrain++),r.pause())}function v(L){$r("onerror",L),T(),t.removeListener("error",v),d2e(t,"error")===0&&Cv(t,L)}dBt(t,"error",v);function b(){t.removeListener("finish",C),T()}t.once("close",b);function C(){$r("onfinish"),t.removeListener("close",b),T()}t.once("finish",C);function T(){$r("unpipe"),r.unpipe(t)}return t.emit("pipe",r),o.flowing||($r("pipe resume"),r.resume()),t};function wBt(t){return function(){var r=t._readableState;$r("pipeOnDrain",r.awaitDrain),r.awaitDrain&&r.awaitDrain--,r.awaitDrain===0&&d2e(t,"data")&&(r.flowing=!0,eG(t))}}mn.prototype.unpipe=function(t){var e=this._readableState,r={hasUnpiped:!1};if(e.pipesCount===0)return this;if(e.pipesCount===1)return t&&t!==e.pipes?this:(t||(t=e.pipes),e.pipes=null,e.pipesCount=0,e.flowing=!1,t&&t.emit("unpipe",this,r),this);if(!t){var o=e.pipes,a=e.pipesCount;e.pipes=null,e.pipesCount=0,e.flowing=!1;for(var n=0;n<a;n++)o[n].emit("unpipe",this,{hasUnpiped:!1});return this}var u=I2e(e.pipes,t);return u===-1?this:(e.pipes.splice(u,1),e.pipesCount-=1,e.pipesCount===1&&(e.pipes=e.pipes[0]),t.emit("unpipe",this,r),this)};mn.prototype.on=function(t,e){var r=wv.prototype.on.call(this,t,e),o=this._readableState;return t==="data"?(o.readableListening=this.listenerCount("readable")>0,o.flowing!==!1&&this.resume()):t==="readable"&&!o.endEmitted&&!o.readableListening&&(o.readableListening=o.needReadable=!0,o.flowing=!1,o.emittedReadable=!1,$r("on readable",o.length,o.reading),o.length?qQ(this):o.reading||process.nextTick(IBt,this)),r};mn.prototype.addListener=mn.prototype.on;mn.prototype.removeListener=function(t,e){var r=wv.prototype.removeListener.call(this,t,e);return t==="readable"&&process.nextTick(C2e,this),r};mn.prototype.removeAllListeners=function(t){var e=wv.prototype.removeAllListeners.apply(this,arguments);return(t==="readable"||t===void 0)&&process.nextTick(C2e,this),e};function C2e(t){var e=t._readableState;e.readableListening=t.listenerCount("readable")>0,e.resumeScheduled&&!e.paused?e.flowing=!0:t.listenerCount("data")>0&&t.resume()}function IBt(t){$r("readable nexttick read 0"),t.read(0)}mn.prototype.resume=function(){var t=this._readableState;return t.flowing||($r("resume"),t.flowing=!t.readableListening,BBt(this,t)),t.paused=!1,this};function BBt(t,e){e.resumeScheduled||(e.resumeScheduled=!0,process.nextTick(vBt,t,e))}function vBt(t,e){$r("resume",e.reading),e.reading||t.read(0),e.resumeScheduled=!1,t.emit("resume"),eG(t),e.flowing&&!e.reading&&t.read(0)}mn.prototype.pause=function(){return $r("call pause flowing=%j",this._readableState.flowing),this._readableState.flowing!==!1&&($r("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this};function eG(t){var e=t._readableState;for($r("flow",e.flowing);e.flowing&&t.read()!==null;);}mn.prototype.wrap=function(t){var e=this,r=this._readableState,o=!1;t.on("end",function(){if($r("wrapped end"),r.decoder&&!r.ended){var u=r.decoder.end();u&&u.length&&e.push(u)}e.push(null)}),t.on("data",function(u){if($r("wrapped data"),r.decoder&&(u=r.decoder.write(u)),!(r.objectMode&&u==null)&&!(!r.objectMode&&(!u||!u.length))){var A=e.push(u);A||(o=!0,t.pause())}});for(var a in t)this[a]===void 0&&typeof t[a]=="function"&&(this[a]=function(A){return function(){return t[A].apply(t,arguments)}}(a));for(var n=0;n<Jq.length;n++)t.on(Jq[n],this.emit.bind(this,Jq[n]));return this._read=function(u){$r("wrapped _read",u),o&&(o=!1,t.resume())},this};typeof Symbol=="function"&&(mn.prototype[Symbol.asyncIterator]=function(){return Vq===void 0&&(Vq=c2e()),Vq(this)});Object.defineProperty(mn.prototype,"readableHighWaterMark",{enumerable:!1,get:function(){return this._readableState.highWaterMark}});Object.defineProperty(mn.prototype,"readableBuffer",{enumerable:!1,get:function(){return this._readableState&&this._readableState.buffer}});Object.defineProperty(mn.prototype,"readableFlowing",{enumerable:!1,get:function(){return this._readableState.flowing},set:function(e){this._readableState&&(this._readableState.flowing=e)}});mn._fromList=w2e;Object.defineProperty(mn.prototype,"readableLength",{enumerable:!1,get:function(){return this._readableState.length}});function w2e(t,e){if(e.length===0)return null;var r;return e.objectMode?r=e.buffer.shift():!t||t>=e.length?(e.decoder?r=e.buffer.join(""):e.buffer.length===1?r=e.buffer.first():r=e.buffer.concat(e.length),e.buffer.clear()):r=e.buffer.consume(t,e.decoder),r}function Xq(t){var e=t._readableState;$r("endReadable",e.endEmitted),e.endEmitted||(e.ended=!0,process.nextTick(DBt,e,t))}function DBt(t,e){if($r("endReadableNT",t.endEmitted,t.length),!t.endEmitted&&t.length===0&&(t.endEmitted=!0,e.readable=!1,e.emit("end"),t.autoDestroy)){var r=e._writableState;(!r||r.autoDestroy&&r.finished)&&e.destroy()}}typeof Symbol=="function"&&(mn.from=function(t,e){return Kq===void 0&&(Kq=p2e()),Kq(mn,t,e)});function I2e(t,e){for(var r=0,o=t.length;r<o;r++)if(t[r]===e)return r;return-1}});var tG=_((k$t,D2e)=>{"use strict";D2e.exports=ip;var GQ=k0().codes,PBt=GQ.ERR_METHOD_NOT_IMPLEMENTED,SBt=GQ.ERR_MULTIPLE_CALLBACK,xBt=GQ.ERR_TRANSFORM_ALREADY_TRANSFORMING,bBt=GQ.ERR_TRANSFORM_WITH_LENGTH_0,YQ=Em();Q0()(ip,YQ);function kBt(t,e){var r=this._transformState;r.transforming=!1;var o=r.writecb;if(o===null)return this.emit("error",new SBt);r.writechunk=null,r.writecb=null,e!=null&&this.push(e),o(t);var a=this._readableState;a.reading=!1,(a.needReadable||a.length<a.highWaterMark)&&this._read(a.highWaterMark)}function ip(t){if(!(this instanceof ip))return new ip(t);YQ.call(this,t),this._transformState={afterTransform:kBt.bind(this),needTransform:!1,transforming:!1,writecb:null,writechunk:null,writeencoding:null},this._readableState.needReadable=!0,this._readableState.sync=!1,t&&(typeof t.transform=="function"&&(this._transform=t.transform),typeof t.flush=="function"&&(this._flush=t.flush)),this.on("prefinish",QBt)}function QBt(){var t=this;typeof this._flush=="function"&&!this._readableState.destroyed?this._flush(function(e,r){v2e(t,e,r)}):v2e(this,null,null)}ip.prototype.push=function(t,e){return this._transformState.needTransform=!1,YQ.prototype.push.call(this,t,e)};ip.prototype._transform=function(t,e,r){r(new PBt("_transform()"))};ip.prototype._write=function(t,e,r){var o=this._transformState;if(o.writecb=r,o.writechunk=t,o.writeencoding=e,!o.transforming){var a=this._readableState;(o.needTransform||a.needReadable||a.length<a.highWaterMark)&&this._read(a.highWaterMark)}};ip.prototype._read=function(t){var e=this._transformState;e.writechunk!==null&&!e.transforming?(e.transforming=!0,this._transform(e.writechunk,e.writeencoding,e.afterTransform)):e.needTransform=!0};ip.prototype._destroy=function(t,e){YQ.prototype._destroy.call(this,t,function(r){e(r)})};function v2e(t,e,r){if(e)return t.emit("error",e);if(r!=null&&t.push(r),t._writableState.length)throw new bBt;if(t._transformState.transforming)throw new xBt;return t.push(null)}});var x2e=_((Q$t,S2e)=>{"use strict";S2e.exports=Iv;var P2e=tG();Q0()(Iv,P2e);function Iv(t){if(!(this instanceof Iv))return new Iv(t);P2e.call(this,t)}Iv.prototype._transform=function(t,e,r){r(null,t)}});var T2e=_((F$t,F2e)=>{"use strict";var rG;function FBt(t){var e=!1;return function(){e||(e=!0,t.apply(void 0,arguments))}}var Q2e=k0().codes,TBt=Q2e.ERR_MISSING_ARGS,RBt=Q2e.ERR_STREAM_DESTROYED;function b2e(t){if(t)throw t}function NBt(t){return t.setHeader&&typeof t.abort=="function"}function LBt(t,e,r,o){o=FBt(o);var a=!1;t.on("close",function(){a=!0}),rG===void 0&&(rG=OQ()),rG(t,{readable:e,writable:r},function(u){if(u)return o(u);a=!0,o()});var n=!1;return function(u){if(!a&&!n){if(n=!0,NBt(t))return t.abort();if(typeof t.destroy=="function")return t.destroy();o(u||new RBt("pipe"))}}}function k2e(t){t()}function MBt(t,e){return t.pipe(e)}function OBt(t){return!t.length||typeof t[t.length-1]!="function"?b2e:t.pop()}function UBt(){for(var t=arguments.length,e=new Array(t),r=0;r<t;r++)e[r]=arguments[r];var o=OBt(e);if(Array.isArray(e[0])&&(e=e[0]),e.length<2)throw new TBt("streams");var a,n=e.map(function(u,A){var p=A<e.length-1,h=A>0;return LBt(u,p,h,function(E){a||(a=E),E&&n.forEach(k2e),!p&&(n.forEach(k2e),o(a))})});return e.reduce(MBt)}F2e.exports=UBt});var ew=_((lc,vv)=>{var Bv=Be("stream");process.env.READABLE_STREAM==="disable"&&Bv?(vv.exports=Bv.Readable,Object.assign(vv.exports,Bv),vv.exports.Stream=Bv):(lc=vv.exports=_q(),lc.Stream=Bv||lc,lc.Readable=lc,lc.Writable=Mq(),lc.Duplex=Em(),lc.Transform=tG(),lc.PassThrough=x2e(),lc.finished=OQ(),lc.pipeline=T2e())});var L2e=_((T$t,N2e)=>{"use strict";var{Buffer:lu}=Be("buffer"),R2e=Symbol.for("BufferList");function ni(t){if(!(this instanceof ni))return new ni(t);ni._init.call(this,t)}ni._init=function(e){Object.defineProperty(this,R2e,{value:!0}),this._bufs=[],this.length=0,e&&this.append(e)};ni.prototype._new=function(e){return new ni(e)};ni.prototype._offset=function(e){if(e===0)return[0,0];let r=0;for(let o=0;o<this._bufs.length;o++){let a=r+this._bufs[o].length;if(e<a||o===this._bufs.length-1)return[o,e-r];r=a}};ni.prototype._reverseOffset=function(t){let e=t[0],r=t[1];for(let o=0;o<e;o++)r+=this._bufs[o].length;return r};ni.prototype.get=function(e){if(e>this.length||e<0)return;let r=this._offset(e);return this._bufs[r[0]][r[1]]};ni.prototype.slice=function(e,r){return typeof e=="number"&&e<0&&(e+=this.length),typeof r=="number"&&r<0&&(r+=this.length),this.copy(null,0,e,r)};ni.prototype.copy=function(e,r,o,a){if((typeof o!="number"||o<0)&&(o=0),(typeof a!="number"||a>this.length)&&(a=this.length),o>=this.length||a<=0)return e||lu.alloc(0);let n=!!e,u=this._offset(o),A=a-o,p=A,h=n&&r||0,E=u[1];if(o===0&&a===this.length){if(!n)return this._bufs.length===1?this._bufs[0]:lu.concat(this._bufs,this.length);for(let I=0;I<this._bufs.length;I++)this._bufs[I].copy(e,h),h+=this._bufs[I].length;return e}if(p<=this._bufs[u[0]].length-E)return n?this._bufs[u[0]].copy(e,r,E,E+p):this._bufs[u[0]].slice(E,E+p);n||(e=lu.allocUnsafe(A));for(let I=u[0];I<this._bufs.length;I++){let v=this._bufs[I].length-E;if(p>v)this._bufs[I].copy(e,h,E),h+=v;else{this._bufs[I].copy(e,h,E,E+p),h+=v;break}p-=v,E&&(E=0)}return e.length>h?e.slice(0,h):e};ni.prototype.shallowSlice=function(e,r){if(e=e||0,r=typeof r!="number"?this.length:r,e<0&&(e+=this.length),r<0&&(r+=this.length),e===r)return this._new();let o=this._offset(e),a=this._offset(r),n=this._bufs.slice(o[0],a[0]+1);return a[1]===0?n.pop():n[n.length-1]=n[n.length-1].slice(0,a[1]),o[1]!==0&&(n[0]=n[0].slice(o[1])),this._new(n)};ni.prototype.toString=function(e,r,o){return this.slice(r,o).toString(e)};ni.prototype.consume=function(e){if(e=Math.trunc(e),Number.isNaN(e)||e<=0)return this;for(;this._bufs.length;)if(e>=this._bufs[0].length)e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift();else{this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}return this};ni.prototype.duplicate=function(){let e=this._new();for(let r=0;r<this._bufs.length;r++)e.append(this._bufs[r]);return e};ni.prototype.append=function(e){if(e==null)return this;if(e.buffer)this._appendBuffer(lu.from(e.buffer,e.byteOffset,e.byteLength));else if(Array.isArray(e))for(let r=0;r<e.length;r++)this.append(e[r]);else if(this._isBufferList(e))for(let r=0;r<e._bufs.length;r++)this.append(e._bufs[r]);else typeof e=="number"&&(e=e.toString()),this._appendBuffer(lu.from(e));return this};ni.prototype._appendBuffer=function(e){this._bufs.push(e),this.length+=e.length};ni.prototype.indexOf=function(t,e,r){if(r===void 0&&typeof e=="string"&&(r=e,e=void 0),typeof t=="function"||Array.isArray(t))throw new TypeError('The "value" argument must be one of type string, Buffer, BufferList, or Uint8Array.');if(typeof t=="number"?t=lu.from([t]):typeof t=="string"?t=lu.from(t,r):this._isBufferList(t)?t=t.slice():Array.isArray(t.buffer)?t=lu.from(t.buffer,t.byteOffset,t.byteLength):lu.isBuffer(t)||(t=lu.from(t)),e=Number(e||0),isNaN(e)&&(e=0),e<0&&(e=this.length+e),e<0&&(e=0),t.length===0)return e>this.length?this.length:e;let o=this._offset(e),a=o[0],n=o[1];for(;a<this._bufs.length;a++){let u=this._bufs[a];for(;n<u.length;)if(u.length-n>=t.length){let p=u.indexOf(t,n);if(p!==-1)return this._reverseOffset([a,p]);n=u.length-t.length+1}else{let p=this._reverseOffset([a,n]);if(this._match(p,t))return p;n++}n=0}return-1};ni.prototype._match=function(t,e){if(this.length-t<e.length)return!1;for(let r=0;r<e.length;r++)if(this.get(t+r)!==e[r])return!1;return!0};(function(){let t={readDoubleBE:8,readDoubleLE:8,readFloatBE:4,readFloatLE:4,readInt32BE:4,readInt32LE:4,readUInt32BE:4,readUInt32LE:4,readInt16BE:2,readInt16LE:2,readUInt16BE:2,readUInt16LE:2,readInt8:1,readUInt8:1,readIntBE:null,readIntLE:null,readUIntBE:null,readUIntLE:null};for(let e in t)(function(r){t[r]===null?ni.prototype[r]=function(o,a){return this.slice(o,o+a)[r](0,a)}:ni.prototype[r]=function(o=0){return this.slice(o,o+t[r])[r](0)}})(e)})();ni.prototype._isBufferList=function(e){return e instanceof ni||ni.isBufferList(e)};ni.isBufferList=function(e){return e!=null&&e[R2e]};N2e.exports=ni});var M2e=_((R$t,WQ)=>{"use strict";var nG=ew().Duplex,_Bt=Q0(),Dv=L2e();function Uo(t){if(!(this instanceof Uo))return new Uo(t);if(typeof t=="function"){this._callback=t;let e=function(o){this._callback&&(this._callback(o),this._callback=null)}.bind(this);this.on("pipe",function(o){o.on("error",e)}),this.on("unpipe",function(o){o.removeListener("error",e)}),t=null}Dv._init.call(this,t),nG.call(this)}_Bt(Uo,nG);Object.assign(Uo.prototype,Dv.prototype);Uo.prototype._new=function(e){return new Uo(e)};Uo.prototype._write=function(e,r,o){this._appendBuffer(e),typeof o=="function"&&o()};Uo.prototype._read=function(e){if(!this.length)return this.push(null);e=Math.min(e,this.length),this.push(this.slice(0,e)),this.consume(e)};Uo.prototype.end=function(e){nG.prototype.end.call(this,e),this._callback&&(this._callback(null,this.slice()),this._callback=null)};Uo.prototype._destroy=function(e,r){this._bufs.length=0,this.length=0,r(e)};Uo.prototype._isBufferList=function(e){return e instanceof Uo||e instanceof Dv||Uo.isBufferList(e)};Uo.isBufferList=Dv.isBufferList;WQ.exports=Uo;WQ.exports.BufferListStream=Uo;WQ.exports.BufferList=Dv});var oG=_(rw=>{var HBt=Buffer.alloc,jBt="0000000000000000000",qBt="7777777777777777777",O2e="0".charCodeAt(0),U2e=Buffer.from("ustar\0","binary"),GBt=Buffer.from("00","binary"),YBt=Buffer.from("ustar ","binary"),WBt=Buffer.from(" \0","binary"),VBt=parseInt("7777",8),Pv=257,sG=263,KBt=function(t,e,r){return typeof t!="number"?r:(t=~~t,t>=e?e:t>=0||(t+=e,t>=0)?t:0)},JBt=function(t){switch(t){case 0:return"file";case 1:return"link";case 2:return"symlink";case 3:return"character-device";case 4:return"block-device";case 5:return"directory";case 6:return"fifo";case 7:return"contiguous-file";case 72:return"pax-header";case 55:return"pax-global-header";case 27:return"gnu-long-link-path";case 28:case 30:return"gnu-long-path"}return null},zBt=function(t){switch(t){case"file":return 0;case"link":return 1;case"symlink":return 2;case"character-device":return 3;case"block-device":return 4;case"directory":return 5;case"fifo":return 6;case"contiguous-file":return 7;case"pax-header":return 72}return 0},_2e=function(t,e,r,o){for(;r<o;r++)if(t[r]===e)return r;return o},H2e=function(t){for(var e=256,r=0;r<148;r++)e+=t[r];for(var o=156;o<512;o++)e+=t[o];return e},L0=function(t,e){return t=t.toString(8),t.length>e?qBt.slice(0,e)+" ":jBt.slice(0,e-t.length)+t+" "};function XBt(t){var e;if(t[0]===128)e=!0;else if(t[0]===255)e=!1;else return null;for(var r=[],o=t.length-1;o>0;o--){var a=t[o];e?r.push(a):r.push(255-a)}var n=0,u=r.length;for(o=0;o<u;o++)n+=r[o]*Math.pow(256,o);return e?n:-1*n}var M0=function(t,e,r){if(t=t.slice(e,e+r),e=0,t[e]&128)return XBt(t);for(;e<t.length&&t[e]===32;)e++;for(var o=KBt(_2e(t,32,e,t.length),t.length,t.length);e<o&&t[e]===0;)e++;return o===e?0:parseInt(t.slice(e,o).toString(),8)},tw=function(t,e,r,o){return t.slice(e,_2e(t,0,e,e+r)).toString(o)},iG=function(t){var e=Buffer.byteLength(t),r=Math.floor(Math.log(e)/Math.log(10))+1;return e+r>=Math.pow(10,r)&&r++,e+r+t};rw.decodeLongPath=function(t,e){return tw(t,0,t.length,e)};rw.encodePax=function(t){var e="";t.name&&(e+=iG(" path="+t.name+` +`)),t.linkname&&(e+=iG(" linkpath="+t.linkname+` +`));var r=t.pax;if(r)for(var o in r)e+=iG(" "+o+"="+r[o]+` +`);return Buffer.from(e)};rw.decodePax=function(t){for(var e={};t.length;){for(var r=0;r<t.length&&t[r]!==32;)r++;var o=parseInt(t.slice(0,r).toString(),10);if(!o)return e;var a=t.slice(r+1,o-1).toString(),n=a.indexOf("=");if(n===-1)return e;e[a.slice(0,n)]=a.slice(n+1),t=t.slice(o)}return e};rw.encode=function(t){var e=HBt(512),r=t.name,o="";if(t.typeflag===5&&r[r.length-1]!=="/"&&(r+="/"),Buffer.byteLength(r)!==r.length)return null;for(;Buffer.byteLength(r)>100;){var a=r.indexOf("/");if(a===-1)return null;o+=o?"/"+r.slice(0,a):r.slice(0,a),r=r.slice(a+1)}return Buffer.byteLength(r)>100||Buffer.byteLength(o)>155||t.linkname&&Buffer.byteLength(t.linkname)>100?null:(e.write(r),e.write(L0(t.mode&VBt,6),100),e.write(L0(t.uid,6),108),e.write(L0(t.gid,6),116),e.write(L0(t.size,11),124),e.write(L0(t.mtime.getTime()/1e3|0,11),136),e[156]=O2e+zBt(t.type),t.linkname&&e.write(t.linkname,157),U2e.copy(e,Pv),GBt.copy(e,sG),t.uname&&e.write(t.uname,265),t.gname&&e.write(t.gname,297),e.write(L0(t.devmajor||0,6),329),e.write(L0(t.devminor||0,6),337),o&&e.write(o,345),e.write(L0(H2e(e),6),148),e)};rw.decode=function(t,e,r){var o=t[156]===0?0:t[156]-O2e,a=tw(t,0,100,e),n=M0(t,100,8),u=M0(t,108,8),A=M0(t,116,8),p=M0(t,124,12),h=M0(t,136,12),E=JBt(o),I=t[157]===0?null:tw(t,157,100,e),v=tw(t,265,32),b=tw(t,297,32),C=M0(t,329,8),T=M0(t,337,8),L=H2e(t);if(L===8*32)return null;if(L!==M0(t,148,8))throw new Error("Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?");if(U2e.compare(t,Pv,Pv+6)===0)t[345]&&(a=tw(t,345,155,e)+"/"+a);else if(!(YBt.compare(t,Pv,Pv+6)===0&&WBt.compare(t,sG,sG+2)===0)){if(!r)throw new Error("Invalid tar header: unknown format.")}return o===0&&a&&a[a.length-1]==="/"&&(o=5),{name:a,mode:n,uid:u,gid:A,size:p,mtime:new Date(1e3*h),type:E,linkname:I,uname:v,gname:b,devmajor:C,devminor:T}}});var K2e=_((L$t,V2e)=>{var q2e=Be("util"),ZBt=M2e(),Sv=oG(),G2e=ew().Writable,Y2e=ew().PassThrough,W2e=function(){},j2e=function(t){return t&=511,t&&512-t},$Bt=function(t,e){var r=new VQ(t,e);return r.end(),r},evt=function(t,e){return e.path&&(t.name=e.path),e.linkpath&&(t.linkname=e.linkpath),e.size&&(t.size=parseInt(e.size,10)),t.pax=e,t},VQ=function(t,e){this._parent=t,this.offset=e,Y2e.call(this,{autoDestroy:!1})};q2e.inherits(VQ,Y2e);VQ.prototype.destroy=function(t){this._parent.destroy(t)};var sp=function(t){if(!(this instanceof sp))return new sp(t);G2e.call(this,t),t=t||{},this._offset=0,this._buffer=ZBt(),this._missing=0,this._partial=!1,this._onparse=W2e,this._header=null,this._stream=null,this._overflow=null,this._cb=null,this._locked=!1,this._destroyed=!1,this._pax=null,this._paxGlobal=null,this._gnuLongPath=null,this._gnuLongLinkPath=null;var e=this,r=e._buffer,o=function(){e._continue()},a=function(v){if(e._locked=!1,v)return e.destroy(v);e._stream||o()},n=function(){e._stream=null;var v=j2e(e._header.size);v?e._parse(v,u):e._parse(512,I),e._locked||o()},u=function(){e._buffer.consume(j2e(e._header.size)),e._parse(512,I),o()},A=function(){var v=e._header.size;e._paxGlobal=Sv.decodePax(r.slice(0,v)),r.consume(v),n()},p=function(){var v=e._header.size;e._pax=Sv.decodePax(r.slice(0,v)),e._paxGlobal&&(e._pax=Object.assign({},e._paxGlobal,e._pax)),r.consume(v),n()},h=function(){var v=e._header.size;this._gnuLongPath=Sv.decodeLongPath(r.slice(0,v),t.filenameEncoding),r.consume(v),n()},E=function(){var v=e._header.size;this._gnuLongLinkPath=Sv.decodeLongPath(r.slice(0,v),t.filenameEncoding),r.consume(v),n()},I=function(){var v=e._offset,b;try{b=e._header=Sv.decode(r.slice(0,512),t.filenameEncoding,t.allowUnknownFormat)}catch(C){e.emit("error",C)}if(r.consume(512),!b){e._parse(512,I),o();return}if(b.type==="gnu-long-path"){e._parse(b.size,h),o();return}if(b.type==="gnu-long-link-path"){e._parse(b.size,E),o();return}if(b.type==="pax-global-header"){e._parse(b.size,A),o();return}if(b.type==="pax-header"){e._parse(b.size,p),o();return}if(e._gnuLongPath&&(b.name=e._gnuLongPath,e._gnuLongPath=null),e._gnuLongLinkPath&&(b.linkname=e._gnuLongLinkPath,e._gnuLongLinkPath=null),e._pax&&(e._header=b=evt(b,e._pax),e._pax=null),e._locked=!0,!b.size||b.type==="directory"){e._parse(512,I),e.emit("entry",b,$Bt(e,v),a);return}e._stream=new VQ(e,v),e.emit("entry",b,e._stream,a),e._parse(b.size,n),o()};this._onheader=I,this._parse(512,I)};q2e.inherits(sp,G2e);sp.prototype.destroy=function(t){this._destroyed||(this._destroyed=!0,t&&this.emit("error",t),this.emit("close"),this._stream&&this._stream.emit("close"))};sp.prototype._parse=function(t,e){this._destroyed||(this._offset+=t,this._missing=t,e===this._onheader&&(this._partial=!1),this._onparse=e)};sp.prototype._continue=function(){if(!this._destroyed){var t=this._cb;this._cb=W2e,this._overflow?this._write(this._overflow,void 0,t):t()}};sp.prototype._write=function(t,e,r){if(!this._destroyed){var o=this._stream,a=this._buffer,n=this._missing;if(t.length&&(this._partial=!0),t.length<n)return this._missing-=t.length,this._overflow=null,o?o.write(t,r):(a.append(t),r());this._cb=r,this._missing=0;var u=null;t.length>n&&(u=t.slice(n),t=t.slice(0,n)),o?o.end(t):a.append(t),this._overflow=u,this._onparse()}};sp.prototype._final=function(t){if(this._partial)return this.destroy(new Error("Unexpected end of data"));t()};V2e.exports=sp});var z2e=_((M$t,J2e)=>{J2e.exports=Be("fs").constants||Be("constants")});var tBe=_((O$t,eBe)=>{var nw=z2e(),X2e=OO(),JQ=Q0(),tvt=Buffer.alloc,Z2e=ew().Readable,iw=ew().Writable,rvt=Be("string_decoder").StringDecoder,KQ=oG(),nvt=parseInt("755",8),ivt=parseInt("644",8),$2e=tvt(1024),lG=function(){},aG=function(t,e){e&=511,e&&t.push($2e.slice(0,512-e))};function svt(t){switch(t&nw.S_IFMT){case nw.S_IFBLK:return"block-device";case nw.S_IFCHR:return"character-device";case nw.S_IFDIR:return"directory";case nw.S_IFIFO:return"fifo";case nw.S_IFLNK:return"symlink"}return"file"}var zQ=function(t){iw.call(this),this.written=0,this._to=t,this._destroyed=!1};JQ(zQ,iw);zQ.prototype._write=function(t,e,r){if(this.written+=t.length,this._to.push(t))return r();this._to._drain=r};zQ.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var XQ=function(){iw.call(this),this.linkname="",this._decoder=new rvt("utf-8"),this._destroyed=!1};JQ(XQ,iw);XQ.prototype._write=function(t,e,r){this.linkname+=this._decoder.write(t),r()};XQ.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var xv=function(){iw.call(this),this._destroyed=!1};JQ(xv,iw);xv.prototype._write=function(t,e,r){r(new Error("No body allowed for this entry"))};xv.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var EA=function(t){if(!(this instanceof EA))return new EA(t);Z2e.call(this,t),this._drain=lG,this._finalized=!1,this._finalizing=!1,this._destroyed=!1,this._stream=null};JQ(EA,Z2e);EA.prototype.entry=function(t,e,r){if(this._stream)throw new Error("already piping an entry");if(!(this._finalized||this._destroyed)){typeof e=="function"&&(r=e,e=null),r||(r=lG);var o=this;if((!t.size||t.type==="symlink")&&(t.size=0),t.type||(t.type=svt(t.mode)),t.mode||(t.mode=t.type==="directory"?nvt:ivt),t.uid||(t.uid=0),t.gid||(t.gid=0),t.mtime||(t.mtime=new Date),typeof e=="string"&&(e=Buffer.from(e)),Buffer.isBuffer(e)){t.size=e.length,this._encode(t);var a=this.push(e);return aG(o,t.size),a?process.nextTick(r):this._drain=r,new xv}if(t.type==="symlink"&&!t.linkname){var n=new XQ;return X2e(n,function(A){if(A)return o.destroy(),r(A);t.linkname=n.linkname,o._encode(t),r()}),n}if(this._encode(t),t.type!=="file"&&t.type!=="contiguous-file")return process.nextTick(r),new xv;var u=new zQ(this);return this._stream=u,X2e(u,function(A){if(o._stream=null,A)return o.destroy(),r(A);if(u.written!==t.size)return o.destroy(),r(new Error("size mismatch"));aG(o,t.size),o._finalizing&&o.finalize(),r()}),u}};EA.prototype.finalize=function(){if(this._stream){this._finalizing=!0;return}this._finalized||(this._finalized=!0,this.push($2e),this.push(null))};EA.prototype.destroy=function(t){this._destroyed||(this._destroyed=!0,t&&this.emit("error",t),this.emit("close"),this._stream&&this._stream.destroy&&this._stream.destroy())};EA.prototype._encode=function(t){if(!t.pax){var e=KQ.encode(t);if(e){this.push(e);return}}this._encodePax(t)};EA.prototype._encodePax=function(t){var e=KQ.encodePax({name:t.name,linkname:t.linkname,pax:t.pax}),r={name:"PaxHeader",mode:t.mode,uid:t.uid,gid:t.gid,size:e.length,mtime:t.mtime,type:"pax-header",linkname:t.linkname&&"PaxHeader",uname:t.uname,gname:t.gname,devmajor:t.devmajor,devminor:t.devminor};this.push(KQ.encode(r)),this.push(e),aG(this,e.length),r.size=t.size,r.type=t.type,this.push(KQ.encode(r))};EA.prototype._read=function(t){var e=this._drain;this._drain=lG,e()};eBe.exports=EA});var rBe=_(cG=>{cG.extract=K2e();cG.pack=tBe()});var hBe=_((ier,pBe)=>{"use strict";var Bm=class{constructor(e,r,o){this.__specs=e||{},Object.keys(this.__specs).forEach(a=>{if(typeof this.__specs[a]=="string"){let n=this.__specs[a],u=this.__specs[n];if(u){let A=u.aliases||[];A.push(a,n),u.aliases=[...new Set(A)],this.__specs[a]=u}else throw new Error(`Alias refers to invalid key: ${n} -> ${a}`)}}),this.__opts=r||{},this.__providers=ABe(o.filter(a=>a!=null&&typeof a=="object")),this.__isFiggyPudding=!0}get(e){return gG(this,e,!0)}get[Symbol.toStringTag](){return"FiggyPudding"}forEach(e,r=this){for(let[o,a]of this.entries())e.call(r,a,o,this)}toJSON(){let e={};return this.forEach((r,o)=>{e[o]=r}),e}*entries(e){for(let o of Object.keys(this.__specs))yield[o,this.get(o)];let r=e||this.__opts.other;if(r){let o=new Set;for(let a of this.__providers){let n=a.entries?a.entries(r):Cvt(a);for(let[u,A]of n)r(u)&&!o.has(u)&&(o.add(u),yield[u,A])}}}*[Symbol.iterator](){for(let[e,r]of this.entries())yield[e,r]}*keys(){for(let[e]of this.entries())yield e}*values(){for(let[,e]of this.entries())yield e}concat(...e){return new Proxy(new Bm(this.__specs,this.__opts,ABe(this.__providers).concat(e)),fBe)}};try{let t=Be("util");Bm.prototype[t.inspect.custom]=function(e,r){return this[Symbol.toStringTag]+" "+t.inspect(this.toJSON(),r)}}catch{}function yvt(t){throw Object.assign(new Error(`invalid config key requested: ${t}`),{code:"EBADKEY"})}function gG(t,e,r){let o=t.__specs[e];if(r&&!o&&(!t.__opts.other||!t.__opts.other(e)))yvt(e);else{o||(o={});let a;for(let n of t.__providers){if(a=uBe(e,n),a===void 0&&o.aliases&&o.aliases.length){for(let u of o.aliases)if(u!==e&&(a=uBe(u,n),a!==void 0))break}if(a!==void 0)break}return a===void 0&&o.default!==void 0?typeof o.default=="function"?o.default(t):o.default:a}}function uBe(t,e){let r;return e.__isFiggyPudding?r=gG(e,t,!1):typeof e.get=="function"?r=e.get(t):r=e[t],r}var fBe={has(t,e){return e in t.__specs&&gG(t,e,!1)!==void 0},ownKeys(t){return Object.keys(t.__specs)},get(t,e){return typeof e=="symbol"||e.slice(0,2)==="__"||e in Bm.prototype?t[e]:t.get(e)},set(t,e,r){if(typeof e=="symbol"||e.slice(0,2)==="__")return t[e]=r,!0;throw new Error("figgyPudding options cannot be modified. Use .concat() instead.")},deleteProperty(){throw new Error("figgyPudding options cannot be deleted. Use .concat() and shadow them instead.")}};pBe.exports=Evt;function Evt(t,e){function r(...o){return new Proxy(new Bm(t,e,o),fBe)}return r}function ABe(t){let e=[];return t.forEach(r=>e.unshift(r)),e}function Cvt(t){return Object.keys(t).map(e=>[e,t[e]])}});var mBe=_((ser,IA)=>{"use strict";var kv=Be("crypto"),wvt=hBe(),Ivt=Be("stream").Transform,gBe=["sha256","sha384","sha512"],Bvt=/^[a-z0-9+/]+(?:=?=?)$/i,vvt=/^([^-]+)-([^?]+)([?\S*]*)$/,Dvt=/^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/,Pvt=/^[\x21-\x7E]+$/,ia=wvt({algorithms:{default:["sha512"]},error:{default:!1},integrity:{},options:{default:[]},pickAlgorithm:{default:()=>Rvt},Promise:{default:()=>Promise},sep:{default:" "},single:{default:!1},size:{},strict:{default:!1}}),U0=class{get isHash(){return!0}constructor(e,r){r=ia(r);let o=!!r.strict;this.source=e.trim();let a=this.source.match(o?Dvt:vvt);if(!a||o&&!gBe.some(u=>u===a[1]))return;this.algorithm=a[1],this.digest=a[2];let n=a[3];this.options=n?n.slice(1).split("?"):[]}hexDigest(){return this.digest&&Buffer.from(this.digest,"base64").toString("hex")}toJSON(){return this.toString()}toString(e){if(e=ia(e),e.strict&&!(gBe.some(o=>o===this.algorithm)&&this.digest.match(Bvt)&&(this.options||[]).every(o=>o.match(Pvt))))return"";let r=this.options&&this.options.length?`?${this.options.join("?")}`:"";return`${this.algorithm}-${this.digest}${r}`}},vm=class{get isIntegrity(){return!0}toJSON(){return this.toString()}toString(e){e=ia(e);let r=e.sep||" ";return e.strict&&(r=r.replace(/\S+/g," ")),Object.keys(this).map(o=>this[o].map(a=>U0.prototype.toString.call(a,e)).filter(a=>a.length).join(r)).filter(o=>o.length).join(r)}concat(e,r){r=ia(r);let o=typeof e=="string"?e:bv(e,r);return wA(`${this.toString(r)} ${o}`,r)}hexDigest(){return wA(this,{single:!0}).hexDigest()}match(e,r){r=ia(r);let o=wA(e,r),a=o.pickAlgorithm(r);return this[a]&&o[a]&&this[a].find(n=>o[a].find(u=>n.digest===u.digest))||!1}pickAlgorithm(e){e=ia(e);let r=e.pickAlgorithm,o=Object.keys(this);if(!o.length)throw new Error(`No algorithms available for ${JSON.stringify(this.toString())}`);return o.reduce((a,n)=>r(a,n)||a)}};IA.exports.parse=wA;function wA(t,e){if(e=ia(e),typeof t=="string")return dG(t,e);if(t.algorithm&&t.digest){let r=new vm;return r[t.algorithm]=[t],dG(bv(r,e),e)}else return dG(bv(t,e),e)}function dG(t,e){return e.single?new U0(t,e):t.trim().split(/\s+/).reduce((r,o)=>{let a=new U0(o,e);if(a.algorithm&&a.digest){let n=a.algorithm;r[n]||(r[n]=[]),r[n].push(a)}return r},new vm)}IA.exports.stringify=bv;function bv(t,e){return e=ia(e),t.algorithm&&t.digest?U0.prototype.toString.call(t,e):typeof t=="string"?bv(wA(t,e),e):vm.prototype.toString.call(t,e)}IA.exports.fromHex=Svt;function Svt(t,e,r){r=ia(r);let o=r.options&&r.options.length?`?${r.options.join("?")}`:"";return wA(`${e}-${Buffer.from(t,"hex").toString("base64")}${o}`,r)}IA.exports.fromData=xvt;function xvt(t,e){e=ia(e);let r=e.algorithms,o=e.options&&e.options.length?`?${e.options.join("?")}`:"";return r.reduce((a,n)=>{let u=kv.createHash(n).update(t).digest("base64"),A=new U0(`${n}-${u}${o}`,e);if(A.algorithm&&A.digest){let p=A.algorithm;a[p]||(a[p]=[]),a[p].push(A)}return a},new vm)}IA.exports.fromStream=bvt;function bvt(t,e){e=ia(e);let r=e.Promise||Promise,o=mG(e);return new r((a,n)=>{t.pipe(o),t.on("error",n),o.on("error",n);let u;o.on("integrity",A=>{u=A}),o.on("end",()=>a(u)),o.on("data",()=>{})})}IA.exports.checkData=kvt;function kvt(t,e,r){if(r=ia(r),e=wA(e,r),!Object.keys(e).length){if(r.error)throw Object.assign(new Error("No valid integrity hashes to check against"),{code:"EINTEGRITY"});return!1}let o=e.pickAlgorithm(r),a=kv.createHash(o).update(t).digest("base64"),n=wA({algorithm:o,digest:a}),u=n.match(e,r);if(u||!r.error)return u;if(typeof r.size=="number"&&t.length!==r.size){let A=new Error(`data size mismatch when checking ${e}. + Wanted: ${r.size} + Found: ${t.length}`);throw A.code="EBADSIZE",A.found=t.length,A.expected=r.size,A.sri=e,A}else{let A=new Error(`Integrity checksum failed when using ${o}: Wanted ${e}, but got ${n}. (${t.length} bytes)`);throw A.code="EINTEGRITY",A.found=n,A.expected=e,A.algorithm=o,A.sri=e,A}}IA.exports.checkStream=Qvt;function Qvt(t,e,r){r=ia(r);let o=r.Promise||Promise,a=mG(r.concat({integrity:e}));return new o((n,u)=>{t.pipe(a),t.on("error",u),a.on("error",u);let A;a.on("verified",p=>{A=p}),a.on("end",()=>n(A)),a.on("data",()=>{})})}IA.exports.integrityStream=mG;function mG(t){t=ia(t);let e=t.integrity&&wA(t.integrity,t),r=e&&Object.keys(e).length,o=r&&e.pickAlgorithm(t),a=r&&e[o],n=Array.from(new Set(t.algorithms.concat(o?[o]:[]))),u=n.map(kv.createHash),A=0,p=new Ivt({transform(h,E,I){A+=h.length,u.forEach(v=>v.update(h,E)),I(null,h,E)}}).on("end",()=>{let h=t.options&&t.options.length?`?${t.options.join("?")}`:"",E=wA(u.map((v,b)=>`${n[b]}-${v.digest("base64")}${h}`).join(" "),t),I=r&&E.match(e,t);if(typeof t.size=="number"&&A!==t.size){let v=new Error(`stream size mismatch when checking ${e}. + Wanted: ${t.size} + Found: ${A}`);v.code="EBADSIZE",v.found=A,v.expected=t.size,v.sri=e,p.emit("error",v)}else if(t.integrity&&!I){let v=new Error(`${e} integrity checksum failed when using ${o}: wanted ${a} but got ${E}. (${A} bytes)`);v.code="EINTEGRITY",v.found=E,v.expected=a,v.algorithm=o,v.sri=e,p.emit("error",v)}else p.emit("size",A),p.emit("integrity",E),I&&p.emit("verified",I)});return p}IA.exports.create=Fvt;function Fvt(t){t=ia(t);let e=t.algorithms,r=t.options.length?`?${t.options.join("?")}`:"",o=e.map(kv.createHash);return{update:function(a,n){return o.forEach(u=>u.update(a,n)),this},digest:function(a){return e.reduce((u,A)=>{let p=o.shift().digest("base64"),h=new U0(`${A}-${p}${r}`,t);if(h.algorithm&&h.digest){let E=h.algorithm;u[E]||(u[E]=[]),u[E].push(h)}return u},new vm)}}}var Tvt=new Set(kv.getHashes()),dBe=["md5","whirlpool","sha1","sha224","sha256","sha384","sha512","sha3","sha3-256","sha3-384","sha3-512","sha3_256","sha3_384","sha3_512"].filter(t=>Tvt.has(t));function Rvt(t,e){return dBe.indexOf(t.toLowerCase())>=dBe.indexOf(e.toLowerCase())?t:e}});var VBe=_((lir,WBe)=>{var TDt=uL();function RDt(t){return TDt(t)?void 0:t}WBe.exports=RDt});var JBe=_((cir,KBe)=>{var NDt=jx(),LDt=Q8(),MDt=N8(),ODt=jd(),UDt=gd(),_Dt=VBe(),HDt=P_(),jDt=k8(),qDt=1,GDt=2,YDt=4,WDt=HDt(function(t,e){var r={};if(t==null)return r;var o=!1;e=NDt(e,function(n){return n=ODt(n,t),o||(o=n.length>1),n}),UDt(t,jDt(t),r),o&&(r=LDt(r,qDt|GDt|YDt,_Dt));for(var a=e.length;a--;)MDt(r,e[a]);return r});KBe.exports=WDt});Pt();Ye();Pt();var eve=Be("child_process"),tve=$e(ed());qt();var uC=new Map([]);var o2={};Kt(o2,{BaseCommand:()=>ut,WorkspaceRequiredError:()=>rr,getCli:()=>the,getDynamicLibs:()=>ehe,getPluginConfiguration:()=>fC,openWorkspace:()=>AC,pluginCommands:()=>uC,runExit:()=>sk});qt();var ut=class extends nt{constructor(){super(...arguments);this.cwd=ge.String("--cwd",{hidden:!0})}validateAndExecute(){if(typeof this.cwd<"u")throw new it("The --cwd option is ambiguous when used anywhere else than the very first parameter provided in the command line, before even the command path");return super.validateAndExecute()}};Ye();Pt();qt();var rr=class extends it{constructor(e,r){let o=K.relative(e,r),a=K.join(e,Mt.fileName);super(`This command can only be run from within a workspace of your project (${o} isn't a workspace of ${a}).`)}};Ye();Pt();nA();Nl();b1();qt();var OAt=$e(zn());Za();var ehe=()=>new Map([["@yarnpkg/cli",o2],["@yarnpkg/core",s2],["@yarnpkg/fslib",Vw],["@yarnpkg/libzip",x1],["@yarnpkg/parsers",tI],["@yarnpkg/shell",T1],["clipanion",pI],["semver",OAt],["typanion",Ko]]);Ye();async function AC(t,e){let{project:r,workspace:o}=await St.find(t,e);if(!o)throw new rr(r.cwd,e);return o}Ye();Pt();nA();Nl();b1();qt();var tPt=$e(zn());Za();var tH={};Kt(tH,{AddCommand:()=>bh,BinCommand:()=>kh,CacheCleanCommand:()=>Qh,ClipanionCommand:()=>Wd,ConfigCommand:()=>Nh,ConfigGetCommand:()=>Fh,ConfigSetCommand:()=>Th,ConfigUnsetCommand:()=>Rh,DedupeCommand:()=>Lh,EntryCommand:()=>dC,ExecCommand:()=>Mh,ExplainCommand:()=>_h,ExplainPeerRequirementsCommand:()=>Oh,HelpCommand:()=>Vd,InfoCommand:()=>Hh,LinkCommand:()=>qh,NodeCommand:()=>Gh,PluginCheckCommand:()=>Yh,PluginImportCommand:()=>Kh,PluginImportSourcesCommand:()=>Jh,PluginListCommand:()=>Wh,PluginRemoveCommand:()=>zh,PluginRuntimeCommand:()=>Xh,RebuildCommand:()=>Zh,RemoveCommand:()=>$h,RunCommand:()=>e0,RunIndexCommand:()=>zd,SetResolutionCommand:()=>t0,SetVersionCommand:()=>Uh,SetVersionSourcesCommand:()=>Vh,UnlinkCommand:()=>r0,UpCommand:()=>Kf,VersionCommand:()=>Kd,WhyCommand:()=>n0,WorkspaceCommand:()=>o0,WorkspacesListCommand:()=>s0,YarnCommand:()=>jh,dedupeUtils:()=>gk,default:()=>Qgt,suggestUtils:()=>zc});var Tde=$e(ed());Ye();Ye();Ye();qt();var j0e=$e(A2());Za();var zc={};Kt(zc,{Modifier:()=>D8,Strategy:()=>fk,Target:()=>f2,WorkspaceModifier:()=>M0e,applyModifier:()=>ipt,extractDescriptorFromPath:()=>P8,extractRangeModifier:()=>O0e,fetchDescriptorFrom:()=>S8,findProjectDescriptors:()=>H0e,getModifier:()=>p2,getSuggestedDescriptors:()=>h2,makeWorkspaceDescriptor:()=>_0e,toWorkspaceModifier:()=>U0e});Ye();Ye();Pt();var v8=$e(zn()),rpt="workspace:",f2=(o=>(o.REGULAR="dependencies",o.DEVELOPMENT="devDependencies",o.PEER="peerDependencies",o))(f2||{}),D8=(o=>(o.CARET="^",o.TILDE="~",o.EXACT="",o))(D8||{}),M0e=(o=>(o.CARET="^",o.TILDE="~",o.EXACT="*",o))(M0e||{}),fk=(n=>(n.KEEP="keep",n.REUSE="reuse",n.PROJECT="project",n.LATEST="latest",n.CACHE="cache",n))(fk||{});function p2(t,e){return t.exact?"":t.caret?"^":t.tilde?"~":e.configuration.get("defaultSemverRangePrefix")}var npt=/^([\^~]?)[0-9]+(?:\.[0-9]+){0,2}(?:-\S+)?$/;function O0e(t,{project:e}){let r=t.match(npt);return r?r[1]:e.configuration.get("defaultSemverRangePrefix")}function ipt(t,e){let{protocol:r,source:o,params:a,selector:n}=W.parseRange(t.range);return v8.default.valid(n)&&(n=`${e}${t.range}`),W.makeDescriptor(t,W.makeRange({protocol:r,source:o,params:a,selector:n}))}function U0e(t){switch(t){case"^":return"^";case"~":return"~";case"":return"*";default:throw new Error(`Assertion failed: Unknown modifier: "${t}"`)}}function _0e(t,e){return W.makeDescriptor(t.anchoredDescriptor,`${rpt}${U0e(e)}`)}async function H0e(t,{project:e,target:r}){let o=new Map,a=n=>{let u=o.get(n.descriptorHash);return u||o.set(n.descriptorHash,u={descriptor:n,locators:[]}),u};for(let n of e.workspaces)if(r==="peerDependencies"){let u=n.manifest.peerDependencies.get(t.identHash);u!==void 0&&a(u).locators.push(n.anchoredLocator)}else{let u=n.manifest.dependencies.get(t.identHash),A=n.manifest.devDependencies.get(t.identHash);r==="devDependencies"?A!==void 0?a(A).locators.push(n.anchoredLocator):u!==void 0&&a(u).locators.push(n.anchoredLocator):u!==void 0?a(u).locators.push(n.anchoredLocator):A!==void 0&&a(A).locators.push(n.anchoredLocator)}return o}async function P8(t,{cwd:e,workspace:r}){return await spt(async o=>{K.isAbsolute(t)||(t=K.relative(r.cwd,K.resolve(e,t)),t.match(/^\.{0,2}\//)||(t=`./${t}`));let{project:a}=r,n=await S8(W.makeIdent(null,"archive"),t,{project:r.project,cache:o,workspace:r});if(!n)throw new Error("Assertion failed: The descriptor should have been found");let u=new Qi,A=a.configuration.makeResolver(),p=a.configuration.makeFetcher(),h={checksums:a.storedChecksums,project:a,cache:o,fetcher:p,report:u,resolver:A},E=A.bindDescriptor(n,r.anchoredLocator,h),I=W.convertDescriptorToLocator(E),v=await p.fetch(I,h),b=await Mt.find(v.prefixPath,{baseFs:v.packageFs});if(!b.name)throw new Error("Target path doesn't have a name");return W.makeDescriptor(b.name,t)})}async function h2(t,{project:e,workspace:r,cache:o,target:a,fixed:n,modifier:u,strategies:A,maxResults:p=1/0}){if(!(p>=0))throw new Error(`Invalid maxResults (${p})`);let[h,E]=t.range!=="unknown"?n||kr.validRange(t.range)||!t.range.match(/^[a-z0-9._-]+$/i)?[t.range,"latest"]:["unknown",t.range]:["unknown","latest"];if(h!=="unknown")return{suggestions:[{descriptor:t,name:`Use ${W.prettyDescriptor(e.configuration,t)}`,reason:"(unambiguous explicit request)"}],rejections:[]};let I=typeof r<"u"&&r!==null&&r.manifest[a].get(t.identHash)||null,v=[],b=[],C=async T=>{try{await T()}catch(L){b.push(L)}};for(let T of A){if(v.length>=p)break;switch(T){case"keep":await C(async()=>{I&&v.push({descriptor:I,name:`Keep ${W.prettyDescriptor(e.configuration,I)}`,reason:"(no changes)"})});break;case"reuse":await C(async()=>{for(let{descriptor:L,locators:U}of(await H0e(t,{project:e,target:a})).values()){if(U.length===1&&U[0].locatorHash===r.anchoredLocator.locatorHash&&A.includes("keep"))continue;let J=`(originally used by ${W.prettyLocator(e.configuration,U[0])}`;J+=U.length>1?` and ${U.length-1} other${U.length>2?"s":""})`:")",v.push({descriptor:L,name:`Reuse ${W.prettyDescriptor(e.configuration,L)}`,reason:J})}});break;case"cache":await C(async()=>{for(let L of e.storedDescriptors.values())L.identHash===t.identHash&&v.push({descriptor:L,name:`Reuse ${W.prettyDescriptor(e.configuration,L)}`,reason:"(already used somewhere in the lockfile)"})});break;case"project":await C(async()=>{if(r.manifest.name!==null&&t.identHash===r.manifest.name.identHash)return;let L=e.tryWorkspaceByIdent(t);if(L===null)return;let U=_0e(L,u);v.push({descriptor:U,name:`Attach ${W.prettyDescriptor(e.configuration,U)}`,reason:`(local workspace at ${de.pretty(e.configuration,L.relativeCwd,de.Type.PATH)})`})});break;case"latest":{let L=e.configuration.get("enableNetwork"),U=e.configuration.get("enableOfflineMode");await C(async()=>{if(a==="peerDependencies")v.push({descriptor:W.makeDescriptor(t,"*"),name:"Use *",reason:"(catch-all peer dependency pattern)"});else if(!L&&!U)v.push({descriptor:null,name:"Resolve from latest",reason:de.pretty(e.configuration,"(unavailable because enableNetwork is toggled off)","grey")});else{let J=await S8(t,E,{project:e,cache:o,workspace:r,modifier:u});J&&v.push({descriptor:J,name:`Use ${W.prettyDescriptor(e.configuration,J)}`,reason:`(resolved from ${U?"the cache":"latest"})`})}})}break}}return{suggestions:v.slice(0,p),rejections:b.slice(0,p)}}async function S8(t,e,{project:r,cache:o,workspace:a,preserveModifier:n=!0,modifier:u}){let A=r.configuration.normalizeDependency(W.makeDescriptor(t,e)),p=new Qi,h=r.configuration.makeFetcher(),E=r.configuration.makeResolver(),I={project:r,fetcher:h,cache:o,checksums:r.storedChecksums,report:p,cacheOptions:{skipIntegrityCheck:!0}},v={...I,resolver:E,fetchOptions:I},b=E.bindDescriptor(A,a.anchoredLocator,v),C=await E.getCandidates(b,{},v);if(C.length===0)return null;let T=C[0],{protocol:L,source:U,params:J,selector:te}=W.parseRange(W.convertToManifestRange(T.reference));if(L===r.configuration.get("defaultProtocol")&&(L=null),v8.default.valid(te)){let le=te;if(typeof u<"u")te=u+te;else if(n!==!1){let ye=typeof n=="string"?n:A.range;te=O0e(ye,{project:r})+te}let pe=W.makeDescriptor(T,W.makeRange({protocol:L,source:U,params:J,selector:te}));(await E.getCandidates(r.configuration.normalizeDependency(pe),{},v)).length!==1&&(te=le)}return W.makeDescriptor(T,W.makeRange({protocol:L,source:U,params:J,selector:te}))}async function spt(t){return await oe.mktempPromise(async e=>{let r=Ve.create(e);return r.useWithSource(e,{enableMirror:!1,compressionLevel:0},e,{overwrite:!0}),await t(new Lr(e,{configuration:r,check:!1,immutable:!1}))})}var bh=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.fixed=ge.Boolean("-F,--fixed",!1,{description:"Store dependency tags as-is instead of resolving them"});this.exact=ge.Boolean("-E,--exact",!1,{description:"Don't use any semver modifier on the resolved range"});this.tilde=ge.Boolean("-T,--tilde",!1,{description:"Use the `~` semver modifier on the resolved range"});this.caret=ge.Boolean("-C,--caret",!1,{description:"Use the `^` semver modifier on the resolved range"});this.dev=ge.Boolean("-D,--dev",!1,{description:"Add a package as a dev dependency"});this.peer=ge.Boolean("-P,--peer",!1,{description:"Add a package as a peer dependency"});this.optional=ge.Boolean("-O,--optional",!1,{description:"Add / upgrade a package to an optional regular / peer dependency"});this.preferDev=ge.Boolean("--prefer-dev",!1,{description:"Add / upgrade a package to a dev dependency"});this.interactive=ge.Boolean("-i,--interactive",{description:"Reuse the specified package from other workspaces in the project"});this.cached=ge.Boolean("--cached",!1,{description:"Reuse the highest version already used somewhere within the project"});this.mode=ge.String("--mode",{description:"Change what artifacts installs generate",validator:Vs(pl)});this.silent=ge.Boolean("--silent",{hidden:!0});this.packages=ge.Rest()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n=await Lr.find(r);if(!a)throw new rr(o.cwd,this.context.cwd);await o.restoreInstallState({restoreResolutions:!1});let u=this.fixed,A=this.interactive??r.get("preferInteractive"),p=A||r.get("preferReuse"),h=p2(this,o),E=[p?"reuse":void 0,"project",this.cached?"cache":void 0,"latest"].filter(U=>typeof U<"u"),I=A?1/0:1,v=await Promise.all(this.packages.map(async U=>{let J=U.match(/^\.{0,2}\//)?await P8(U,{cwd:this.context.cwd,workspace:a}):W.tryParseDescriptor(U),te=U.match(/^(https?:|git@github)/);if(te)throw new it(`It seems you are trying to add a package using a ${de.pretty(r,`${te[0]}...`,de.Type.RANGE)} url; we now require package names to be explicitly specified. +Try running the command again with the package name prefixed: ${de.pretty(r,"yarn add",de.Type.CODE)} ${de.pretty(r,W.makeDescriptor(W.makeIdent(null,"my-package"),`${te[0]}...`),de.Type.DESCRIPTOR)}`);if(!J)throw new it(`The ${de.pretty(r,U,de.Type.CODE)} string didn't match the required format (package-name@range). Did you perhaps forget to explicitly reference the package name?`);let le=opt(a,J,{dev:this.dev,peer:this.peer,preferDev:this.preferDev,optional:this.optional});return await Promise.all(le.map(async Ae=>{let ye=await h2(J,{project:o,workspace:a,cache:n,fixed:u,target:Ae,modifier:h,strategies:E,maxResults:I});return{request:J,suggestedDescriptors:ye,target:Ae}}))})).then(U=>U.flat()),b=await AA.start({configuration:r,stdout:this.context.stdout,suggestInstall:!1},async U=>{for(let{request:J,suggestedDescriptors:{suggestions:te,rejections:le}}of v)if(te.filter(Ae=>Ae.descriptor!==null).length===0){let[Ae]=le;if(typeof Ae>"u")throw new Error("Assertion failed: Expected an error to have been set");o.configuration.get("enableNetwork")?U.reportError(27,`${W.prettyDescriptor(r,J)} can't be resolved to a satisfying range`):U.reportError(27,`${W.prettyDescriptor(r,J)} can't be resolved to a satisfying range (note: network resolution has been disabled)`),U.reportSeparator(),U.reportExceptionOnce(Ae)}});if(b.hasErrors())return b.exitCode();let C=!1,T=[],L=[];for(let{suggestedDescriptors:{suggestions:U},target:J}of v){let te,le=U.filter(ae=>ae.descriptor!==null),pe=le[0].descriptor,Ae=le.every(ae=>W.areDescriptorsEqual(ae.descriptor,pe));le.length===1||Ae?te=pe:(C=!0,{answer:te}=await(0,j0e.prompt)({type:"select",name:"answer",message:"Which range do you want to use?",choices:U.map(({descriptor:ae,name:we,reason:Pe})=>ae?{name:we,hint:Pe,descriptor:ae}:{name:we,hint:Pe,disabled:!0}),onCancel:()=>process.exit(130),result(ae){return this.find(ae,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout}));let ye=a.manifest[J].get(te.identHash);(typeof ye>"u"||ye.descriptorHash!==te.descriptorHash)&&(a.manifest[J].set(te.identHash,te),this.optional&&(J==="dependencies"?a.manifest.ensureDependencyMeta({...te,range:"unknown"}).optional=!0:J==="peerDependencies"&&(a.manifest.ensurePeerDependencyMeta({...te,range:"unknown"}).optional=!0)),typeof ye>"u"?T.push([a,J,te,E]):L.push([a,J,ye,te]))}return await r.triggerMultipleHooks(U=>U.afterWorkspaceDependencyAddition,T),await r.triggerMultipleHooks(U=>U.afterWorkspaceDependencyReplacement,L),C&&this.context.stdout.write(` +`),await o.installWithNewReport({json:this.json,stdout:this.context.stdout,quiet:this.context.quiet},{cache:n,mode:this.mode})}};bh.paths=[["add"]],bh.usage=nt.Usage({description:"add dependencies to the project",details:"\n This command adds a package to the package.json for the nearest workspace.\n\n - If it didn't exist before, the package will by default be added to the regular `dependencies` field, but this behavior can be overriden thanks to the `-D,--dev` flag (which will cause the dependency to be added to the `devDependencies` field instead) and the `-P,--peer` flag (which will do the same but for `peerDependencies`).\n\n - If the package was already listed in your dependencies, it will by default be upgraded whether it's part of your `dependencies` or `devDependencies` (it won't ever update `peerDependencies`, though).\n\n - If set, the `--prefer-dev` flag will operate as a more flexible `-D,--dev` in that it will add the package to your `devDependencies` if it isn't already listed in either `dependencies` or `devDependencies`, but it will also happily upgrade your `dependencies` if that's what you already use (whereas `-D,--dev` would throw an exception).\n\n - If set, the `-O,--optional` flag will add the package to the `optionalDependencies` field and, in combination with the `-P,--peer` flag, it will add the package as an optional peer dependency. If the package was already listed in your `dependencies`, it will be upgraded to `optionalDependencies`. If the package was already listed in your `peerDependencies`, in combination with the `-P,--peer` flag, it will be upgraded to an optional peer dependency: `\"peerDependenciesMeta\": { \"<package>\": { \"optional\": true } }`\n\n - If the added package doesn't specify a range at all its `latest` tag will be resolved and the returned version will be used to generate a new semver range (using the `^` modifier by default unless otherwise configured via the `defaultSemverRangePrefix` configuration, or the `~` modifier if `-T,--tilde` is specified, or no modifier at all if `-E,--exact` is specified). Two exceptions to this rule: the first one is that if the package is a workspace then its local version will be used, and the second one is that if you use `-P,--peer` the default range will be `*` and won't be resolved at all.\n\n - If the added package specifies a range (such as `^1.0.0`, `latest`, or `rc`), Yarn will add this range as-is in the resulting package.json entry (in particular, tags such as `rc` will be encoded as-is rather than being converted into a semver range).\n\n If the `--cached` option is used, Yarn will preferably reuse the highest version already used somewhere within the project, even if through a transitive dependency.\n\n If the `-i,--interactive` option is used (or if the `preferInteractive` settings is toggled on) the command will first try to check whether other workspaces in the project use the specified package and, if so, will offer to reuse them.\n\n If the `--mode=<mode>` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n For a compilation of all the supported protocols, please consult the dedicated page from our website: https://yarnpkg.com/protocols.\n ",examples:[["Add a regular package to the current workspace","$0 add lodash"],["Add a specific version for a package to the current workspace","$0 add lodash@1.2.3"],["Add a package from a GitHub repository (the master branch) to the current workspace using a URL","$0 add lodash@https://github.com/lodash/lodash"],["Add a package from a GitHub repository (the master branch) to the current workspace using the GitHub protocol","$0 add lodash@github:lodash/lodash"],["Add a package from a GitHub repository (the master branch) to the current workspace using the GitHub protocol (shorthand)","$0 add lodash@lodash/lodash"],["Add a package from a specific branch of a GitHub repository to the current workspace using the GitHub protocol (shorthand)","$0 add lodash-es@lodash/lodash#es"]]});function opt(t,e,{dev:r,peer:o,preferDev:a,optional:n}){let u=t.manifest["dependencies"].has(e.identHash),A=t.manifest["devDependencies"].has(e.identHash),p=t.manifest["peerDependencies"].has(e.identHash);if((r||o)&&u)throw new it(`Package "${W.prettyIdent(t.project.configuration,e)}" is already listed as a regular dependency - remove the -D,-P flags or remove it from your dependencies first`);if(!r&&!o&&p)throw new it(`Package "${W.prettyIdent(t.project.configuration,e)}" is already listed as a peer dependency - use either of -D or -P, or remove it from your peer dependencies first`);if(n&&A)throw new it(`Package "${W.prettyIdent(t.project.configuration,e)}" is already listed as a dev dependency - remove the -O flag or remove it from your dev dependencies first`);if(n&&!o&&p)throw new it(`Package "${W.prettyIdent(t.project.configuration,e)}" is already listed as a peer dependency - remove the -O flag or add the -P flag or remove it from your peer dependencies first`);if((r||a)&&n)throw new it(`Package "${W.prettyIdent(t.project.configuration,e)}" cannot simultaneously be a dev dependency and an optional dependency`);let h=[];return o&&h.push("peerDependencies"),(r||a)&&h.push("devDependencies"),n&&h.push("dependencies"),h.length>0?h:A?["devDependencies"]:p?["peerDependencies"]:["dependencies"]}Ye();Ye();qt();var kh=class extends ut{constructor(){super(...arguments);this.verbose=ge.Boolean("-v,--verbose",!1,{description:"Print both the binary name and the locator of the package that provides the binary"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.name=ge.String({required:!1})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,locator:a}=await St.find(r,this.context.cwd);if(await o.restoreInstallState(),this.name){let A=(await un.getPackageAccessibleBinaries(a,{project:o})).get(this.name);if(!A)throw new it(`Couldn't find a binary named "${this.name}" for package "${W.prettyLocator(r,a)}"`);let[,p]=A;return this.context.stdout.write(`${p} +`),0}return(await Nt.start({configuration:r,json:this.json,stdout:this.context.stdout},async u=>{let A=await un.getPackageAccessibleBinaries(a,{project:o}),h=Array.from(A.keys()).reduce((E,I)=>Math.max(E,I.length),0);for(let[E,[I,v]]of A)u.reportJson({name:E,source:W.stringifyIdent(I),path:v});if(this.verbose)for(let[E,[I]]of A)u.reportInfo(null,`${E.padEnd(h," ")} ${W.prettyLocator(r,I)}`);else for(let E of A.keys())u.reportInfo(null,E)})).exitCode()}};kh.paths=[["bin"]],kh.usage=nt.Usage({description:"get the path to a binary script",details:` + When used without arguments, this command will print the list of all the binaries available in the current workspace. Adding the \`-v,--verbose\` flag will cause the output to contain both the binary name and the locator of the package that provides the binary. + + When an argument is specified, this command will just print the path to the binary on the standard output and exit. Note that the reported path may be stored within a zip archive. + `,examples:[["List all the available binaries","$0 bin"],["Print the path to a specific binary","$0 bin eslint"]]});Ye();Pt();qt();var Qh=class extends ut{constructor(){super(...arguments);this.mirror=ge.Boolean("--mirror",!1,{description:"Remove the global cache files instead of the local cache files"});this.all=ge.Boolean("--all",!1,{description:"Remove both the global cache files and the local cache files of the current project"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),o=await Lr.find(r);return(await Nt.start({configuration:r,stdout:this.context.stdout},async()=>{let n=(this.all||this.mirror)&&o.mirrorCwd!==null,u=!this.mirror;n&&(await oe.removePromise(o.mirrorCwd),await r.triggerHook(A=>A.cleanGlobalArtifacts,r)),u&&await oe.removePromise(o.cwd)})).exitCode()}};Qh.paths=[["cache","clean"],["cache","clear"]],Qh.usage=nt.Usage({description:"remove the shared cache files",details:` + This command will remove all the files from the cache. + `,examples:[["Remove all the local archives","$0 cache clean"],["Remove all the archives stored in the ~/.yarn directory","$0 cache clean --mirror"]]});Ye();qt();var G0e=$e(g2()),x8=Be("util"),Fh=class extends ut{constructor(){super(...arguments);this.why=ge.Boolean("--why",!1,{description:"Print the explanation for why a setting has its value"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.unsafe=ge.Boolean("--no-redacted",!1,{description:"Don't redact secrets (such as tokens) from the output"});this.name=ge.String()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),o=this.name.replace(/[.[].*$/,""),a=this.name.replace(/^[^.[]*/,"");if(typeof r.settings.get(o)>"u")throw new it(`Couldn't find a configuration settings named "${o}"`);let u=r.getSpecial(o,{hideSecrets:!this.unsafe,getNativePaths:!0}),A=je.convertMapsToIndexableObjects(u),p=a?(0,G0e.default)(A,a):A,h=await Nt.start({configuration:r,includeFooter:!1,json:this.json,stdout:this.context.stdout},async E=>{E.reportJson(p)});if(!this.json){if(typeof p=="string")return this.context.stdout.write(`${p} +`),h.exitCode();x8.inspect.styles.name="cyan",this.context.stdout.write(`${(0,x8.inspect)(p,{depth:1/0,colors:r.get("enableColors"),compact:!1})} +`)}return h.exitCode()}};Fh.paths=[["config","get"]],Fh.usage=nt.Usage({description:"read a configuration settings",details:` + This command will print a configuration setting. + + Secrets (such as tokens) will be redacted from the output by default. If this behavior isn't desired, set the \`--no-redacted\` to get the untransformed value. + `,examples:[["Print a simple configuration setting","yarn config get yarnPath"],["Print a complex configuration setting","yarn config get packageExtensions"],["Print a nested field from the configuration",`yarn config get 'npmScopes["my-company"].npmRegistryServer'`],["Print a token from the configuration","yarn config get npmAuthToken --no-redacted"],["Print a configuration setting as JSON","yarn config get packageExtensions --json"]]});Ye();qt();var Rge=$e(F8()),Nge=$e(g2()),Lge=$e(T8()),R8=Be("util"),Th=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Set complex configuration settings to JSON values"});this.home=ge.Boolean("-H,--home",!1,{description:"Update the home configuration instead of the project configuration"});this.name=ge.String();this.value=ge.String()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),o=()=>{if(!r.projectCwd)throw new it("This command must be run from within a project folder");return r.projectCwd},a=this.name.replace(/[.[].*$/,""),n=this.name.replace(/^[^.[]*\.?/,"");if(typeof r.settings.get(a)>"u")throw new it(`Couldn't find a configuration settings named "${a}"`);if(a==="enableStrictSettings")throw new it("This setting only affects the file it's in, and thus cannot be set from the CLI");let A=this.json?JSON.parse(this.value):this.value;await(this.home?C=>Ve.updateHomeConfiguration(C):C=>Ve.updateConfiguration(o(),C))(C=>{if(n){let T=(0,Rge.default)(C);return(0,Lge.default)(T,this.name,A),T}else return{...C,[a]:A}});let E=(await Ve.find(this.context.cwd,this.context.plugins)).getSpecial(a,{hideSecrets:!0,getNativePaths:!0}),I=je.convertMapsToIndexableObjects(E),v=n?(0,Nge.default)(I,n):I;return(await Nt.start({configuration:r,includeFooter:!1,stdout:this.context.stdout},async C=>{R8.inspect.styles.name="cyan",C.reportInfo(0,`Successfully set ${this.name} to ${(0,R8.inspect)(v,{depth:1/0,colors:r.get("enableColors"),compact:!1})}`)})).exitCode()}};Th.paths=[["config","set"]],Th.usage=nt.Usage({description:"change a configuration settings",details:` + This command will set a configuration setting. + + When used without the \`--json\` flag, it can only set a simple configuration setting (a string, a number, or a boolean). + + When used with the \`--json\` flag, it can set both simple and complex configuration settings, including Arrays and Objects. + `,examples:[["Set a simple configuration setting (a string, a number, or a boolean)","yarn config set initScope myScope"],["Set a simple configuration setting (a string, a number, or a boolean) using the `--json` flag",'yarn config set initScope --json \\"myScope\\"'],["Set a complex configuration setting (an Array) using the `--json` flag",`yarn config set unsafeHttpWhitelist --json '["*.example.com", "example.com"]'`],["Set a complex configuration setting (an Object) using the `--json` flag",`yarn config set packageExtensions --json '{ "@babel/parser@*": { "dependencies": { "@babel/types": "*" } } }'`],["Set a nested configuration setting",'yarn config set npmScopes.company.npmRegistryServer "https://npm.example.com"'],["Set a nested configuration setting using indexed access for non-simple keys",`yarn config set 'npmRegistries["//npm.example.com"].npmAuthToken' "ffffffff-ffff-ffff-ffff-ffffffffffff"`]]});Ye();qt();var Vge=$e(F8()),Kge=$e(_ge()),Jge=$e(L8()),Rh=class extends ut{constructor(){super(...arguments);this.home=ge.Boolean("-H,--home",!1,{description:"Update the home configuration instead of the project configuration"});this.name=ge.String()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),o=()=>{if(!r.projectCwd)throw new it("This command must be run from within a project folder");return r.projectCwd},a=this.name.replace(/[.[].*$/,""),n=this.name.replace(/^[^.[]*\.?/,"");if(typeof r.settings.get(a)>"u")throw new it(`Couldn't find a configuration settings named "${a}"`);let A=this.home?h=>Ve.updateHomeConfiguration(h):h=>Ve.updateConfiguration(o(),h);return(await Nt.start({configuration:r,includeFooter:!1,stdout:this.context.stdout},async h=>{let E=!1;await A(I=>{if(!(0,Kge.default)(I,this.name))return h.reportWarning(0,`Configuration doesn't contain setting ${this.name}; there is nothing to unset`),E=!0,I;let v=n?(0,Vge.default)(I):{...I};return(0,Jge.default)(v,this.name),v}),E||h.reportInfo(0,`Successfully unset ${this.name}`)})).exitCode()}};Rh.paths=[["config","unset"]],Rh.usage=nt.Usage({description:"unset a configuration setting",details:` + This command will unset a configuration setting. + `,examples:[["Unset a simple configuration setting","yarn config unset initScope"],["Unset a complex configuration setting","yarn config unset packageExtensions"],["Unset a nested configuration setting","yarn config unset npmScopes.company.npmRegistryServer"]]});Ye();Pt();qt();var hk=Be("util"),Nh=class extends ut{constructor(){super(...arguments);this.noDefaults=ge.Boolean("--no-defaults",!1,{description:"Omit the default values from the display"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.verbose=ge.Boolean("-v,--verbose",{hidden:!0});this.why=ge.Boolean("--why",{hidden:!0});this.names=ge.Rest()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins,{strict:!1}),o=await NE({configuration:r,stdout:this.context.stdout,forceError:this.json},[{option:this.verbose,message:"The --verbose option is deprecated, the settings' descriptions are now always displayed"},{option:this.why,message:"The --why option is deprecated, the settings' sources are now always displayed"}]);if(o!==null)return o;let a=this.names.length>0?[...new Set(this.names)].sort():[...r.settings.keys()].sort(),n,u=await Nt.start({configuration:r,json:this.json,stdout:this.context.stdout,includeFooter:!1},async A=>{if(r.invalid.size>0&&!this.json){for(let[p,h]of r.invalid)A.reportError(34,`Invalid configuration key "${p}" in ${h}`);A.reportSeparator()}if(this.json)for(let p of a){let h=r.settings.get(p);typeof h>"u"&&A.reportError(34,`No configuration key named "${p}"`);let E=r.getSpecial(p,{hideSecrets:!0,getNativePaths:!0}),I=r.sources.get(p)??"<default>",v=I&&I[0]!=="<"?ue.fromPortablePath(I):I;A.reportJson({key:p,effective:E,source:v,...h})}else{let p={breakLength:1/0,colors:r.get("enableColors"),maxArrayLength:2},h={},E={children:h};for(let I of a){if(this.noDefaults&&!r.sources.has(I))continue;let v=r.settings.get(I),b=r.sources.get(I)??"<default>",C=r.getSpecial(I,{hideSecrets:!0,getNativePaths:!0}),T={Description:{label:"Description",value:de.tuple(de.Type.MARKDOWN,{text:v.description,format:this.cli.format(),paragraphs:!1})},Source:{label:"Source",value:de.tuple(b[0]==="<"?de.Type.CODE:de.Type.PATH,b)}};h[I]={value:de.tuple(de.Type.CODE,I),children:T};let L=(U,J)=>{for(let[te,le]of J)if(le instanceof Map){let pe={};U[te]={children:pe},L(pe,le)}else U[te]={label:te,value:de.tuple(de.Type.NO_HINT,(0,hk.inspect)(le,p))}};C instanceof Map?L(T,C):T.Value={label:"Value",value:de.tuple(de.Type.NO_HINT,(0,hk.inspect)(C,p))}}a.length!==1&&(n=void 0),$s.emitTree(E,{configuration:r,json:this.json,stdout:this.context.stdout,separators:2})}});if(!this.json&&typeof n<"u"){let A=a[0],p=(0,hk.inspect)(r.getSpecial(A,{hideSecrets:!0,getNativePaths:!0}),{colors:r.get("enableColors")});this.context.stdout.write(` +`),this.context.stdout.write(`${p} +`)}return u.exitCode()}};Nh.paths=[["config"]],Nh.usage=nt.Usage({description:"display the current configuration",details:` + This command prints the current active configuration settings. + `,examples:[["Print the active configuration settings","$0 config"]]});Ye();qt();Za();var gk={};Kt(gk,{Strategy:()=>d2,acceptedStrategies:()=>j0t,dedupe:()=>M8});Ye();Ye();var zge=$e(Zo()),d2=(e=>(e.HIGHEST="highest",e))(d2||{}),j0t=new Set(Object.values(d2)),q0t={highest:async(t,e,{resolver:r,fetcher:o,resolveOptions:a,fetchOptions:n})=>{let u=new Map;for(let[p,h]of t.storedResolutions){let E=t.storedDescriptors.get(p);if(typeof E>"u")throw new Error(`Assertion failed: The descriptor (${p}) should have been registered`);je.getSetWithDefault(u,E.identHash).add(h)}let A=new Map(je.mapAndFilter(t.storedDescriptors.values(),p=>W.isVirtualDescriptor(p)?je.mapAndFilter.skip:[p.descriptorHash,je.makeDeferred()]));for(let p of t.storedDescriptors.values()){let h=A.get(p.descriptorHash);if(typeof h>"u")throw new Error(`Assertion failed: The descriptor (${p.descriptorHash}) should have been registered`);let E=t.storedResolutions.get(p.descriptorHash);if(typeof E>"u")throw new Error(`Assertion failed: The resolution (${p.descriptorHash}) should have been registered`);let I=t.originalPackages.get(E);if(typeof I>"u")throw new Error(`Assertion failed: The package (${E}) should have been registered`);Promise.resolve().then(async()=>{let v=r.getResolutionDependencies(p,a),b=Object.fromEntries(await je.allSettledSafe(Object.entries(v).map(async([te,le])=>{let pe=A.get(le.descriptorHash);if(typeof pe>"u")throw new Error(`Assertion failed: The descriptor (${le.descriptorHash}) should have been registered`);let Ae=await pe.promise;if(!Ae)throw new Error("Assertion failed: Expected the dependency to have been through the dedupe process itself");return[te,Ae.updatedPackage]})));if(e.length&&!zge.default.isMatch(W.stringifyIdent(p),e)||!r.shouldPersistResolution(I,a))return I;let C=u.get(p.identHash);if(typeof C>"u")throw new Error(`Assertion failed: The resolutions (${p.identHash}) should have been registered`);if(C.size===1)return I;let T=[...C].map(te=>{let le=t.originalPackages.get(te);if(typeof le>"u")throw new Error(`Assertion failed: The package (${te}) should have been registered`);return le}),L=await r.getSatisfying(p,b,T,a),U=L.locators?.[0];if(typeof U>"u"||!L.sorted)return I;let J=t.originalPackages.get(U.locatorHash);if(typeof J>"u")throw new Error(`Assertion failed: The package (${U.locatorHash}) should have been registered`);return J}).then(async v=>{let b=await t.preparePackage(v,{resolver:r,resolveOptions:a});h.resolve({descriptor:p,currentPackage:I,updatedPackage:v,resolvedPackage:b})}).catch(v=>{h.reject(v)})}return[...A.values()].map(p=>p.promise)}};async function M8(t,{strategy:e,patterns:r,cache:o,report:a}){let{configuration:n}=t,u=new Qi,A=n.makeResolver(),p=n.makeFetcher(),h={cache:o,checksums:t.storedChecksums,fetcher:p,project:t,report:u,cacheOptions:{skipIntegrityCheck:!0}},E={project:t,resolver:A,report:u,fetchOptions:h};return await a.startTimerPromise("Deduplication step",async()=>{let I=q0t[e],v=await I(t,r,{resolver:A,resolveOptions:E,fetcher:p,fetchOptions:h}),b=Xs.progressViaCounter(v.length);await a.reportProgress(b);let C=0;await Promise.all(v.map(U=>U.then(J=>{if(J===null||J.currentPackage.locatorHash===J.updatedPackage.locatorHash)return;C++;let{descriptor:te,currentPackage:le,updatedPackage:pe}=J;a.reportInfo(0,`${W.prettyDescriptor(n,te)} can be deduped from ${W.prettyLocator(n,le)} to ${W.prettyLocator(n,pe)}`),a.reportJson({descriptor:W.stringifyDescriptor(te),currentResolution:W.stringifyLocator(le),updatedResolution:W.stringifyLocator(pe)}),t.storedResolutions.set(te.descriptorHash,pe.locatorHash)}).finally(()=>b.tick())));let T;switch(C){case 0:T="No packages";break;case 1:T="One package";break;default:T=`${C} packages`}let L=de.pretty(n,e,de.Type.CODE);return a.reportInfo(0,`${T} can be deduped using the ${L} strategy`),C})}var Lh=class extends ut{constructor(){super(...arguments);this.strategy=ge.String("-s,--strategy","highest",{description:"The strategy to use when deduping dependencies",validator:Vs(d2)});this.check=ge.Boolean("-c,--check",!1,{description:"Exit with exit code 1 when duplicates are found, without persisting the dependency tree"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.mode=ge.String("--mode",{description:"Change what artifacts installs generate",validator:Vs(pl)});this.patterns=ge.Rest()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o}=await St.find(r,this.context.cwd),a=await Lr.find(r);await o.restoreInstallState({restoreResolutions:!1});let n=0,u=await Nt.start({configuration:r,includeFooter:!1,stdout:this.context.stdout,json:this.json},async A=>{n=await M8(o,{strategy:this.strategy,patterns:this.patterns,cache:a,report:A})});return u.hasErrors()?u.exitCode():this.check?n?1:0:await o.installWithNewReport({json:this.json,stdout:this.context.stdout},{cache:a,mode:this.mode})}};Lh.paths=[["dedupe"]],Lh.usage=nt.Usage({description:"deduplicate dependencies with overlapping ranges",details:"\n Duplicates are defined as descriptors with overlapping ranges being resolved and locked to different locators. They are a natural consequence of Yarn's deterministic installs, but they can sometimes pile up and unnecessarily increase the size of your project.\n\n This command dedupes dependencies in the current project using different strategies (only one is implemented at the moment):\n\n - `highest`: Reuses (where possible) the locators with the highest versions. This means that dependencies can only be upgraded, never downgraded. It's also guaranteed that it never takes more than a single pass to dedupe the entire dependency tree.\n\n **Note:** Even though it never produces a wrong dependency tree, this command should be used with caution, as it modifies the dependency tree, which can sometimes cause problems when packages don't strictly follow semver recommendations. Because of this, it is recommended to also review the changes manually.\n\n If set, the `-c,--check` flag will only report the found duplicates, without persisting the modified dependency tree. If changes are found, the command will exit with a non-zero exit code, making it suitable for CI purposes.\n\n If the `--mode=<mode>` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n This command accepts glob patterns as arguments (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n ### In-depth explanation:\n\n Yarn doesn't deduplicate dependencies by default, otherwise installs wouldn't be deterministic and the lockfile would be useless. What it actually does is that it tries to not duplicate dependencies in the first place.\n\n **Example:** If `foo@^2.3.4` (a dependency of a dependency) has already been resolved to `foo@2.3.4`, running `yarn add foo@*`will cause Yarn to reuse `foo@2.3.4`, even if the latest `foo` is actually `foo@2.10.14`, thus preventing unnecessary duplication.\n\n Duplication happens when Yarn can't unlock dependencies that have already been locked inside the lockfile.\n\n **Example:** If `foo@^2.3.4` (a dependency of a dependency) has already been resolved to `foo@2.3.4`, running `yarn add foo@2.10.14` will cause Yarn to install `foo@2.10.14` because the existing resolution doesn't satisfy the range `2.10.14`. This behavior can lead to (sometimes) unwanted duplication, since now the lockfile contains 2 separate resolutions for the 2 `foo` descriptors, even though they have overlapping ranges, which means that the lockfile can be simplified so that both descriptors resolve to `foo@2.10.14`.\n ",examples:[["Dedupe all packages","$0 dedupe"],["Dedupe all packages using a specific strategy","$0 dedupe --strategy highest"],["Dedupe a specific package","$0 dedupe lodash"],["Dedupe all packages with the `@babel/*` scope","$0 dedupe '@babel/*'"],["Check for duplicates (can be used as a CI step)","$0 dedupe --check"]]});Ye();qt();var Wd=class extends ut{async execute(){let{plugins:e}=await Ve.find(this.context.cwd,this.context.plugins),r=[];for(let u of e){let{commands:A}=u[1];if(A){let h=as.from(A).definitions();r.push([u[0],h])}}let o=this.cli.definitions(),a=(u,A)=>u.split(" ").slice(1).join()===A.split(" ").slice(1).join(),n=Xge()["@yarnpkg/builder"].bundles.standard;for(let u of r){let A=u[1];for(let p of A)o.find(h=>a(h.path,p.path)).plugin={name:u[0],isDefault:n.includes(u[0])}}this.context.stdout.write(`${JSON.stringify(o,null,2)} +`)}};Wd.paths=[["--clipanion=definitions"]];var Vd=class extends ut{async execute(){this.context.stdout.write(this.cli.usage(null))}};Vd.paths=[["help"],["--help"],["-h"]];Ye();Pt();qt();var dC=class extends ut{constructor(){super(...arguments);this.leadingArgument=ge.String();this.args=ge.Proxy()}async execute(){if(this.leadingArgument.match(/[\\/]/)&&!W.tryParseIdent(this.leadingArgument)){let r=K.resolve(this.context.cwd,ue.toPortablePath(this.leadingArgument));return await this.cli.run(this.args,{cwd:r})}else return await this.cli.run(["run",this.leadingArgument,...this.args])}};Ye();var Kd=class extends ut{async execute(){this.context.stdout.write(`${tn||"<unknown>"} +`)}};Kd.paths=[["-v"],["--version"]];Ye();Ye();qt();var Mh=class extends ut{constructor(){super(...arguments);this.commandName=ge.String();this.args=ge.Proxy()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,locator:a}=await St.find(r,this.context.cwd);return await o.restoreInstallState(),await un.executePackageShellcode(a,this.commandName,this.args,{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,project:o})}};Mh.paths=[["exec"]],Mh.usage=nt.Usage({description:"execute a shell script",details:` + This command simply executes a shell script within the context of the root directory of the active workspace using the portable shell. + + It also makes sure to call it in a way that's compatible with the current project (for example, on PnP projects the environment will be setup in such a way that PnP will be correctly injected into the environment). + `,examples:[["Execute a single shell command","$0 exec echo Hello World"],["Execute a shell script",'$0 exec "tsc & babel src --out-dir lib"']]});Ye();qt();Za();var Oh=class extends ut{constructor(){super(...arguments);this.hash=ge.String({validator:aP(Ey(),[sI(/^p[0-9a-f]{5}$/)])})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o}=await St.find(r,this.context.cwd);return await o.restoreInstallState({restoreResolutions:!1}),await o.applyLightResolution(),await Y0t(this.hash,o,{stdout:this.context.stdout})}};Oh.paths=[["explain","peer-requirements"]],Oh.usage=nt.Usage({description:"explain a set of peer requirements",details:` + A set of peer requirements represents all peer requirements that a dependent must satisfy when providing a given peer request to a requester and its descendants. + + When the hash argument is specified, this command prints a detailed explanation of all requirements of the set corresponding to the hash and whether they're satisfied or not. + + When used without arguments, this command lists all sets of peer requirements and the corresponding hash that can be used to get detailed information about a given set. + + **Note:** A hash is a six-letter p-prefixed code that can be obtained from peer dependency warnings or from the list of all peer requirements (\`yarn explain peer-requirements\`). + `,examples:[["Explain the corresponding set of peer requirements for a hash","$0 explain peer-requirements p1a4ed"],["List all sets of peer requirements","$0 explain peer-requirements"]]});async function Y0t(t,e,r){let o=e.peerWarnings.find(n=>n.hash===t);if(typeof o>"u")throw new Error(`No peerDependency requirements found for hash: "${t}"`);return(await Nt.start({configuration:e.configuration,stdout:r.stdout,includeFooter:!1,includePrefix:!1},async n=>{let u=de.mark(e.configuration);switch(o.type){case 2:{n.reportInfo(0,`We have a problem with ${de.pretty(e.configuration,o.requested,de.Type.IDENT)}, which is provided with version ${W.prettyReference(e.configuration,o.version)}.`),n.reportInfo(0,"It is needed by the following direct dependencies of workspaces in your project:"),n.reportSeparator();for(let h of o.requesters.values()){let E=e.storedPackages.get(h.locatorHash);if(!E)throw new Error("Assertion failed: Expected the package to be registered");let I=E?.peerDependencies.get(o.requested.identHash);if(!I)throw new Error("Assertion failed: Expected the package to list the peer dependency");let v=kr.satisfiesWithPrereleases(o.version,I.range)?u.Check:u.Cross;n.reportInfo(null,` ${v} ${W.prettyLocator(e.configuration,h)} (via ${W.prettyRange(e.configuration,I.range)})`)}let A=[...o.links.values()].filter(h=>!o.requesters.has(h.locatorHash));if(A.length>0){n.reportSeparator(),n.reportInfo(0,`However, those packages themselves have more dependencies listing ${W.prettyIdent(e.configuration,o.requested)} as peer dependency:`),n.reportSeparator();for(let h of A){let E=e.storedPackages.get(h.locatorHash);if(!E)throw new Error("Assertion failed: Expected the package to be registered");let I=E?.peerDependencies.get(o.requested.identHash);if(!I)throw new Error("Assertion failed: Expected the package to list the peer dependency");let v=kr.satisfiesWithPrereleases(o.version,I.range)?u.Check:u.Cross;n.reportInfo(null,` ${v} ${W.prettyLocator(e.configuration,h)} (via ${W.prettyRange(e.configuration,I.range)})`)}}let p=Array.from(o.links.values(),h=>{let E=e.storedPackages.get(h.locatorHash);if(typeof E>"u")throw new Error("Assertion failed: Expected the package to be registered");let I=E.peerDependencies.get(o.requested.identHash);if(typeof I>"u")throw new Error("Assertion failed: Expected the ident to be registered");return I.range});if(p.length>1){let h=kr.simplifyRanges(p);n.reportSeparator(),h===null?(n.reportInfo(0,"Unfortunately, put together, we found no single range that can satisfy all those peer requirements."),n.reportInfo(0,`Your best option may be to try to upgrade some dependencies with ${de.pretty(e.configuration,"yarn up",de.Type.CODE)}, or silence the warning via ${de.pretty(e.configuration,"logFilters",de.Type.CODE)}.`)):n.reportInfo(0,`Put together, the final range we computed is ${de.pretty(e.configuration,h,de.Type.RANGE)}`)}}break;default:n.reportInfo(0,`The ${de.pretty(e.configuration,"yarn explain peer-requirements",de.Type.CODE)} command doesn't support this warning type yet.`);break}})).exitCode()}Ye();qt();Za();Ye();Ye();Pt();qt();var Zge=$e(zn()),Uh=class extends ut{constructor(){super(...arguments);this.useYarnPath=ge.Boolean("--yarn-path",{description:"Set the yarnPath setting even if the version can be accessed by Corepack"});this.onlyIfNeeded=ge.Boolean("--only-if-needed",!1,{description:"Only lock the Yarn version if it isn't already locked"});this.version=ge.String()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins);if(this.onlyIfNeeded&&r.get("yarnPath")){let A=r.sources.get("yarnPath");if(!A)throw new Error("Assertion failed: Expected 'yarnPath' to have a source");let p=r.projectCwd??r.startingCwd;if(K.contains(p,A))return 0}let o=()=>{if(typeof tn>"u")throw new it("The --install flag can only be used without explicit version specifier from the Yarn CLI");return`file://${process.argv[1]}`},a,n=(A,p)=>({version:p,url:A.replace(/\{\}/g,p)});if(this.version==="self")a={url:o(),version:tn??"self"};else if(this.version==="latest"||this.version==="berry"||this.version==="stable")a=n("https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js",await m2(r,"stable"));else if(this.version==="canary")a=n("https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js",await m2(r,"canary"));else if(this.version==="classic")a={url:"https://classic.yarnpkg.com/latest.js",version:"classic"};else if(this.version.match(/^https?:/))a={url:this.version,version:"remote"};else if(this.version.match(/^\.{0,2}[\\/]/)||ue.isAbsolute(this.version))a={url:`file://${K.resolve(ue.toPortablePath(this.version))}`,version:"file"};else if(kr.satisfiesWithPrereleases(this.version,">=2.0.0"))a=n("https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js",this.version);else if(kr.satisfiesWithPrereleases(this.version,"^0.x || ^1.x"))a=n("https://github.com/yarnpkg/yarn/releases/download/v{}/yarn-{}.js",this.version);else if(kr.validRange(this.version))a=n("https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js",await W0t(r,this.version));else throw new it(`Invalid version descriptor "${this.version}"`);return(await Nt.start({configuration:r,stdout:this.context.stdout,includeLogs:!this.context.quiet},async A=>{let p=async()=>{let h="file://";return a.url.startsWith(h)?(A.reportInfo(0,`Retrieving ${de.pretty(r,a.url,de.Type.PATH)}`),await oe.readFilePromise(a.url.slice(h.length))):(A.reportInfo(0,`Downloading ${de.pretty(r,a.url,de.Type.URL)}`),await rn.get(a.url,{configuration:r}))};await O8(r,a.version,p,{report:A,useYarnPath:this.useYarnPath})})).exitCode()}};Uh.paths=[["set","version"]],Uh.usage=nt.Usage({description:"lock the Yarn version used by the project",details:"\n This command will set a specific release of Yarn to be used by Corepack: https://nodejs.org/api/corepack.html.\n\n By default it only will set the `packageManager` field at the root of your project, but if the referenced release cannot be represented this way, if you already have `yarnPath` configured, or if you set the `--yarn-path` command line flag, then the release will also be downloaded from the Yarn GitHub repository, stored inside your project, and referenced via the `yarnPath` settings from your project `.yarnrc.yml` file.\n\n A very good use case for this command is to enforce the version of Yarn used by any single member of your team inside the same project - by doing this you ensure that you have control over Yarn upgrades and downgrades (including on your deployment servers), and get rid of most of the headaches related to someone using a slightly different version and getting different behavior.\n\n The version specifier can be:\n\n - a tag:\n - `latest` / `berry` / `stable` -> the most recent stable berry (`>=2.0.0`) release\n - `canary` -> the most recent canary (release candidate) berry (`>=2.0.0`) release\n - `classic` -> the most recent classic (`^0.x || ^1.x`) release\n\n - a semver range (e.g. `2.x`) -> the most recent version satisfying the range (limited to berry releases)\n\n - a semver version (e.g. `2.4.1`, `1.22.1`)\n\n - a local file referenced through either a relative or absolute path\n\n - `self` -> the version used to invoke the command\n ",examples:[["Download the latest release from the Yarn repository","$0 set version latest"],["Download the latest canary release from the Yarn repository","$0 set version canary"],["Download the latest classic release from the Yarn repository","$0 set version classic"],["Download the most recent Yarn 3 build","$0 set version 3.x"],["Download a specific Yarn 2 build","$0 set version 2.0.0-rc.30"],["Switch back to a specific Yarn 1 release","$0 set version 1.22.1"],["Use a release from the local filesystem","$0 set version ./yarn.cjs"],["Use a release from a URL","$0 set version https://repo.yarnpkg.com/3.1.0/packages/yarnpkg-cli/bin/yarn.js"],["Download the version used to invoke the command","$0 set version self"]]});async function W0t(t,e){let o=(await rn.get("https://repo.yarnpkg.com/tags",{configuration:t,jsonResponse:!0})).tags.filter(a=>kr.satisfiesWithPrereleases(a,e));if(o.length===0)throw new it(`No matching release found for range ${de.pretty(t,e,de.Type.RANGE)}.`);return o[0]}async function m2(t,e){let r=await rn.get("https://repo.yarnpkg.com/tags",{configuration:t,jsonResponse:!0});if(!r.latest[e])throw new it(`Tag ${de.pretty(t,e,de.Type.RANGE)} not found`);return r.latest[e]}async function O8(t,e,r,{report:o,useYarnPath:a}){let n,u=async()=>(typeof n>"u"&&(n=await r()),n);if(e===null){let te=await u();await oe.mktempPromise(async le=>{let pe=K.join(le,"yarn.cjs");await oe.writeFilePromise(pe,te);let{stdout:Ae}=await Ur.execvp(process.execPath,[ue.fromPortablePath(pe),"--version"],{cwd:le,env:{...t.env,YARN_IGNORE_PATH:"1"}});if(e=Ae.trim(),!Zge.default.valid(e))throw new Error(`Invalid semver version. ${de.pretty(t,"yarn --version",de.Type.CODE)} returned: +${e}`)})}let A=t.projectCwd??t.startingCwd,p=K.resolve(A,".yarn/releases"),h=K.resolve(p,`yarn-${e}.cjs`),E=K.relative(t.startingCwd,h),I=je.isTaggedYarnVersion(e),v=t.get("yarnPath"),b=!I,C=b||!!v||!!a;if(a===!1){if(b)throw new zt(0,"You explicitly opted out of yarnPath usage in your command line, but the version you specified cannot be represented by Corepack");C=!1}else!C&&!process.env.COREPACK_ROOT&&(o.reportWarning(0,`You don't seem to have ${de.applyHyperlink(t,"Corepack","https://nodejs.org/api/corepack.html")} enabled; we'll have to rely on ${de.applyHyperlink(t,"yarnPath","https://yarnpkg.com/configuration/yarnrc#yarnPath")} instead`),C=!0);if(C){let te=await u();o.reportInfo(0,`Saving the new release in ${de.pretty(t,E,"magenta")}`),await oe.removePromise(K.dirname(h)),await oe.mkdirPromise(K.dirname(h),{recursive:!0}),await oe.writeFilePromise(h,te,{mode:493}),await Ve.updateConfiguration(A,{yarnPath:K.relative(A,h)})}else await oe.removePromise(K.dirname(h)),await Ve.updateConfiguration(A,{yarnPath:Ve.deleteProperty});let T=await Mt.tryFind(A)||new Mt;T.packageManager=`yarn@${I?e:await m2(t,"stable")}`;let L={};T.exportTo(L);let U=K.join(A,Mt.fileName),J=`${JSON.stringify(L,null,T.indent)} +`;return await oe.changeFilePromise(U,J,{automaticNewlines:!0}),{bundleVersion:e}}function $ge(t){return wr[fP(t)]}var V0t=/## (?<code>YN[0-9]{4}) - `(?<name>[A-Z_]+)`\n\n(?<details>(?:.(?!##))+)/gs;async function K0t(t){let r=`https://repo.yarnpkg.com/${je.isTaggedYarnVersion(tn)?tn:await m2(t,"canary")}/packages/gatsby/content/advanced/error-codes.md`,o=await rn.get(r,{configuration:t});return new Map(Array.from(o.toString().matchAll(V0t),({groups:a})=>{if(!a)throw new Error("Assertion failed: Expected the match to have been successful");let n=$ge(a.code);if(a.name!==n)throw new Error(`Assertion failed: Invalid error code data: Expected "${a.name}" to be named "${n}"`);return[a.code,a.details]}))}var _h=class extends ut{constructor(){super(...arguments);this.code=ge.String({required:!1,validator:oI(Ey(),[sI(/^YN[0-9]{4}$/)])});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins);if(typeof this.code<"u"){let o=$ge(this.code),a=de.pretty(r,o,de.Type.CODE),n=this.cli.format().header(`${this.code} - ${a}`),A=(await K0t(r)).get(this.code),p=typeof A<"u"?de.jsonOrPretty(this.json,r,de.tuple(de.Type.MARKDOWN,{text:A,format:this.cli.format(),paragraphs:!0})):`This error code does not have a description. + +You can help us by editing this page on GitHub \u{1F642}: +${de.jsonOrPretty(this.json,r,de.tuple(de.Type.URL,"https://github.com/yarnpkg/berry/blob/master/packages/gatsby/content/advanced/error-codes.md"))} +`;this.json?this.context.stdout.write(`${JSON.stringify({code:this.code,name:o,details:p})} +`):this.context.stdout.write(`${n} + +${p} +`)}else{let o={children:je.mapAndFilter(Object.entries(wr),([a,n])=>Number.isNaN(Number(a))?je.mapAndFilter.skip:{label:Wu(Number(a)),value:de.tuple(de.Type.CODE,n)})};$s.emitTree(o,{configuration:r,stdout:this.context.stdout,json:this.json})}}};_h.paths=[["explain"]],_h.usage=nt.Usage({description:"explain an error code",details:` + When the code argument is specified, this command prints its name and its details. + + When used without arguments, this command lists all error codes and their names. + `,examples:[["Explain an error code","$0 explain YN0006"],["List all error codes","$0 explain"]]});Ye();Pt();qt();var ede=$e(Zo()),Hh=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("-A,--all",!1,{description:"Print versions of a package from the whole project"});this.recursive=ge.Boolean("-R,--recursive",!1,{description:"Print information for all packages, including transitive dependencies"});this.extra=ge.Array("-X,--extra",[],{description:"An array of requests of extra data provided by plugins"});this.cache=ge.Boolean("--cache",!1,{description:"Print information about the cache entry of a package (path, size, checksum)"});this.dependents=ge.Boolean("--dependents",!1,{description:"Print all dependents for each matching package"});this.manifest=ge.Boolean("--manifest",!1,{description:"Print data obtained by looking at the package archive (license, homepage, ...)"});this.nameOnly=ge.Boolean("--name-only",!1,{description:"Only print the name for the matching packages"});this.virtuals=ge.Boolean("--virtuals",!1,{description:"Print each instance of the virtual packages"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.patterns=ge.Rest()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n=await Lr.find(r);if(!a&&!this.all)throw new rr(o.cwd,this.context.cwd);await o.restoreInstallState();let u=new Set(this.extra);this.cache&&u.add("cache"),this.dependents&&u.add("dependents"),this.manifest&&u.add("manifest");let A=(le,{recursive:pe})=>{let Ae=le.anchoredLocator.locatorHash,ye=new Map,ae=[Ae];for(;ae.length>0;){let we=ae.shift();if(ye.has(we))continue;let Pe=o.storedPackages.get(we);if(typeof Pe>"u")throw new Error("Assertion failed: Expected the package to be registered");if(ye.set(we,Pe),W.isVirtualLocator(Pe)&&ae.push(W.devirtualizeLocator(Pe).locatorHash),!(!pe&&we!==Ae))for(let g of Pe.dependencies.values()){let Ee=o.storedResolutions.get(g.descriptorHash);if(typeof Ee>"u")throw new Error("Assertion failed: Expected the resolution to be registered");ae.push(Ee)}}return ye.values()},p=({recursive:le})=>{let pe=new Map;for(let Ae of o.workspaces)for(let ye of A(Ae,{recursive:le}))pe.set(ye.locatorHash,ye);return pe.values()},h=({all:le,recursive:pe})=>le&&pe?o.storedPackages.values():le?p({recursive:pe}):A(a,{recursive:pe}),E=({all:le,recursive:pe})=>{let Ae=h({all:le,recursive:pe}),ye=this.patterns.map(Pe=>{let g=W.parseLocator(Pe),Ee=ede.default.makeRe(W.stringifyIdent(g)),De=W.isVirtualLocator(g),ce=De?W.devirtualizeLocator(g):g;return ne=>{let ee=W.stringifyIdent(ne);if(!Ee.test(ee))return!1;if(g.reference==="unknown")return!0;let Ie=W.isVirtualLocator(ne),ke=Ie?W.devirtualizeLocator(ne):ne;return!(De&&Ie&&g.reference!==ne.reference||ce.reference!==ke.reference)}}),ae=je.sortMap([...Ae],Pe=>W.stringifyLocator(Pe));return{selection:ae.filter(Pe=>ye.length===0||ye.some(g=>g(Pe))),sortedLookup:ae}},{selection:I,sortedLookup:v}=E({all:this.all,recursive:this.recursive});if(I.length===0)throw new it("No package matched your request");let b=new Map;if(this.dependents)for(let le of v)for(let pe of le.dependencies.values()){let Ae=o.storedResolutions.get(pe.descriptorHash);if(typeof Ae>"u")throw new Error("Assertion failed: Expected the resolution to be registered");je.getArrayWithDefault(b,Ae).push(le)}let C=new Map;for(let le of v){if(!W.isVirtualLocator(le))continue;let pe=W.devirtualizeLocator(le);je.getArrayWithDefault(C,pe.locatorHash).push(le)}let T={},L={children:T},U=r.makeFetcher(),J={project:o,fetcher:U,cache:n,checksums:o.storedChecksums,report:new Qi,cacheOptions:{skipIntegrityCheck:!0}},te=[async(le,pe,Ae)=>{if(!pe.has("manifest"))return;let ye=await U.fetch(le,J),ae;try{ae=await Mt.find(ye.prefixPath,{baseFs:ye.packageFs})}finally{ye.releaseFs?.()}Ae("Manifest",{License:de.tuple(de.Type.NO_HINT,ae.license),Homepage:de.tuple(de.Type.URL,ae.raw.homepage??null)})},async(le,pe,Ae)=>{if(!pe.has("cache"))return;let ye=o.storedChecksums.get(le.locatorHash)??null,ae=n.getLocatorPath(le,ye),we;if(ae!==null)try{we=await oe.statPromise(ae)}catch{}let Pe=typeof we<"u"?[we.size,de.Type.SIZE]:void 0;Ae("Cache",{Checksum:de.tuple(de.Type.NO_HINT,ye),Path:de.tuple(de.Type.PATH,ae),Size:Pe})}];for(let le of I){let pe=W.isVirtualLocator(le);if(!this.virtuals&&pe)continue;let Ae={},ye={value:[le,de.Type.LOCATOR],children:Ae};if(T[W.stringifyLocator(le)]=ye,this.nameOnly){delete ye.children;continue}let ae=C.get(le.locatorHash);typeof ae<"u"&&(Ae.Instances={label:"Instances",value:de.tuple(de.Type.NUMBER,ae.length)}),Ae.Version={label:"Version",value:de.tuple(de.Type.NO_HINT,le.version)};let we=(g,Ee)=>{let De={};if(Ae[g]=De,Array.isArray(Ee))De.children=Ee.map(ce=>({value:ce}));else{let ce={};De.children=ce;for(let[ne,ee]of Object.entries(Ee))typeof ee>"u"||(ce[ne]={label:ne,value:ee})}};if(!pe){for(let g of te)await g(le,u,we);await r.triggerHook(g=>g.fetchPackageInfo,le,u,we)}le.bin.size>0&&!pe&&we("Exported Binaries",[...le.bin.keys()].map(g=>de.tuple(de.Type.PATH,g)));let Pe=b.get(le.locatorHash);typeof Pe<"u"&&Pe.length>0&&we("Dependents",Pe.map(g=>de.tuple(de.Type.LOCATOR,g))),le.dependencies.size>0&&!pe&&we("Dependencies",[...le.dependencies.values()].map(g=>{let Ee=o.storedResolutions.get(g.descriptorHash),De=typeof Ee<"u"?o.storedPackages.get(Ee)??null:null;return de.tuple(de.Type.RESOLUTION,{descriptor:g,locator:De})})),le.peerDependencies.size>0&&pe&&we("Peer dependencies",[...le.peerDependencies.values()].map(g=>{let Ee=le.dependencies.get(g.identHash),De=typeof Ee<"u"?o.storedResolutions.get(Ee.descriptorHash)??null:null,ce=De!==null?o.storedPackages.get(De)??null:null;return de.tuple(de.Type.RESOLUTION,{descriptor:g,locator:ce})}))}$s.emitTree(L,{configuration:r,json:this.json,stdout:this.context.stdout,separators:this.nameOnly?0:2})}};Hh.paths=[["info"]],Hh.usage=nt.Usage({description:"see information related to packages",details:"\n This command prints various information related to the specified packages, accepting glob patterns.\n\n By default, if the locator reference is missing, Yarn will default to print the information about all the matching direct dependencies of the package for the active workspace. To instead print all versions of the package that are direct dependencies of any of your workspaces, use the `-A,--all` flag. Adding the `-R,--recursive` flag will also report transitive dependencies.\n\n Some fields will be hidden by default in order to keep the output readable, but can be selectively displayed by using additional options (`--dependents`, `--manifest`, `--virtuals`, ...) described in the option descriptions.\n\n Note that this command will only print the information directly related to the selected packages - if you wish to know why the package is there in the first place, use `yarn why` which will do just that (it also provides a `-R,--recursive` flag that may be of some help).\n ",examples:[["Show information about Lodash","$0 info lodash"]]});Ye();Pt();Nl();var dk=$e(ed());qt();var U8=$e(zn());Za();var J0t=[{selector:t=>t===-1,name:"nodeLinker",value:"node-modules"},{selector:t=>t!==-1&&t<8,name:"enableGlobalCache",value:!1},{selector:t=>t!==-1&&t<8,name:"compressionLevel",value:"mixed"}],jh=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.immutable=ge.Boolean("--immutable",{description:"Abort with an error exit code if the lockfile was to be modified"});this.immutableCache=ge.Boolean("--immutable-cache",{description:"Abort with an error exit code if the cache folder was to be modified"});this.refreshLockfile=ge.Boolean("--refresh-lockfile",{description:"Refresh the package metadata stored in the lockfile"});this.checkCache=ge.Boolean("--check-cache",{description:"Always refetch the packages and ensure that their checksums are consistent"});this.checkResolutions=ge.Boolean("--check-resolutions",{description:"Validates that the package resolutions are coherent"});this.inlineBuilds=ge.Boolean("--inline-builds",{description:"Verbosely print the output of the build steps of dependencies"});this.mode=ge.String("--mode",{description:"Change what artifacts installs generate",validator:Vs(pl)});this.cacheFolder=ge.String("--cache-folder",{hidden:!0});this.frozenLockfile=ge.Boolean("--frozen-lockfile",{hidden:!0});this.ignoreEngines=ge.Boolean("--ignore-engines",{hidden:!0});this.nonInteractive=ge.Boolean("--non-interactive",{hidden:!0});this.preferOffline=ge.Boolean("--prefer-offline",{hidden:!0});this.production=ge.Boolean("--production",{hidden:!0});this.registry=ge.String("--registry",{hidden:!0});this.silent=ge.Boolean("--silent",{hidden:!0});this.networkTimeout=ge.String("--network-timeout",{hidden:!0})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins);typeof this.inlineBuilds<"u"&&r.useWithSource("<cli>",{enableInlineBuilds:this.inlineBuilds},r.startingCwd,{overwrite:!0});let o=!!process.env.FUNCTION_TARGET||!!process.env.GOOGLE_RUNTIME,a=await NE({configuration:r,stdout:this.context.stdout},[{option:this.ignoreEngines,message:"The --ignore-engines option is deprecated; engine checking isn't a core feature anymore",error:!dk.default.VERCEL},{option:this.registry,message:"The --registry option is deprecated; prefer setting npmRegistryServer in your .yarnrc.yml file"},{option:this.preferOffline,message:"The --prefer-offline flag is deprecated; use the --cached flag with 'yarn add' instead",error:!dk.default.VERCEL},{option:this.production,message:"The --production option is deprecated on 'install'; use 'yarn workspaces focus' instead",error:!0},{option:this.nonInteractive,message:"The --non-interactive option is deprecated",error:!o},{option:this.frozenLockfile,message:"The --frozen-lockfile option is deprecated; use --immutable and/or --immutable-cache instead",callback:()=>this.immutable=this.frozenLockfile},{option:this.cacheFolder,message:"The cache-folder option has been deprecated; use rc settings instead",error:!dk.default.NETLIFY}]);if(a!==null)return a;let n=this.mode==="update-lockfile";if(n&&(this.immutable||this.immutableCache))throw new it(`${de.pretty(r,"--immutable",de.Type.CODE)} and ${de.pretty(r,"--immutable-cache",de.Type.CODE)} cannot be used with ${de.pretty(r,"--mode=update-lockfile",de.Type.CODE)}`);let u=(this.immutable??r.get("enableImmutableInstalls"))&&!n,A=this.immutableCache&&!n;if(r.projectCwd!==null){let T=await Nt.start({configuration:r,json:this.json,stdout:this.context.stdout,includeFooter:!1},async L=>{let U=!1;await Z0t(r,u)&&(L.reportInfo(48,"Automatically removed core plugins that are now builtins \u{1F44D}"),U=!0),await X0t(r,u)&&(L.reportInfo(48,"Automatically fixed merge conflicts \u{1F44D}"),U=!0),U&&L.reportSeparator()});if(T.hasErrors())return T.exitCode()}if(r.projectCwd!==null){let T=await Nt.start({configuration:r,json:this.json,stdout:this.context.stdout,includeFooter:!1},async L=>{if(Ve.telemetry?.isNew)Ve.telemetry.commitTips(),L.reportInfo(65,"Yarn will periodically gather anonymous telemetry: https://yarnpkg.com/advanced/telemetry"),L.reportInfo(65,`Run ${de.pretty(r,"yarn config set --home enableTelemetry 0",de.Type.CODE)} to disable`),L.reportSeparator();else if(Ve.telemetry?.shouldShowTips){let U=await rn.get("https://repo.yarnpkg.com/tags",{configuration:r,jsonResponse:!0}).catch(()=>null);if(U!==null){let J=null;if(tn!==null){let le=U8.default.prerelease(tn)?"canary":"stable",pe=U.latest[le];U8.default.gt(pe,tn)&&(J=[le,pe])}if(J)Ve.telemetry.commitTips(),L.reportInfo(88,`${de.applyStyle(r,`A new ${J[0]} version of Yarn is available:`,de.Style.BOLD)} ${W.prettyReference(r,J[1])}!`),L.reportInfo(88,`Upgrade now by running ${de.pretty(r,`yarn set version ${J[1]}`,de.Type.CODE)}`),L.reportSeparator();else{let te=Ve.telemetry.selectTip(U.tips);te&&(L.reportInfo(89,de.pretty(r,te.message,de.Type.MARKDOWN_INLINE)),te.url&&L.reportInfo(89,`Learn more at ${te.url}`),L.reportSeparator())}}}});if(T.hasErrors())return T.exitCode()}let{project:p,workspace:h}=await St.find(r,this.context.cwd),E=p.lockfileLastVersion;if(E!==null){let T=await Nt.start({configuration:r,json:this.json,stdout:this.context.stdout,includeFooter:!1},async L=>{let U={};for(let J of J0t)J.selector(E)&&typeof r.sources.get(J.name)>"u"&&(r.use("<compat>",{[J.name]:J.value},p.cwd,{overwrite:!0}),U[J.name]=J.value);Object.keys(U).length>0&&(await Ve.updateConfiguration(p.cwd,U),L.reportInfo(87,"Migrated your project to the latest Yarn version \u{1F680}"),L.reportSeparator())});if(T.hasErrors())return T.exitCode()}let I=await Lr.find(r,{immutable:A,check:this.checkCache});if(!h)throw new rr(p.cwd,this.context.cwd);await p.restoreInstallState({restoreResolutions:!1});let v=r.get("enableHardenedMode");v&&typeof r.sources.get("enableHardenedMode")>"u"&&await Nt.start({configuration:r,json:this.json,stdout:this.context.stdout,includeFooter:!1},async T=>{T.reportWarning(0,"Yarn detected that the current workflow is executed from a public pull request. For safety the hardened mode has been enabled."),T.reportWarning(0,`It will prevent malicious lockfile manipulations, in exchange for a slower install time. You can opt-out if necessary; check our ${de.applyHyperlink(r,"documentation","https://yarnpkg.com/features/security#hardened-mode")} for more details.`),T.reportSeparator()}),(this.refreshLockfile??v)&&(p.lockfileNeedsRefresh=!0);let b=this.checkResolutions??v;return(await Nt.start({configuration:r,json:this.json,stdout:this.context.stdout,forceSectionAlignment:!0,includeLogs:!0,includeVersion:!0},async T=>{await p.install({cache:I,report:T,immutable:u,checkResolutions:b,mode:this.mode})})).exitCode()}};jh.paths=[["install"],nt.Default],jh.usage=nt.Usage({description:"install the project dependencies",details:"\n This command sets up your project if needed. The installation is split into four different steps that each have their own characteristics:\n\n - **Resolution:** First the package manager will resolve your dependencies. The exact way a dependency version is privileged over another isn't standardized outside of the regular semver guarantees. If a package doesn't resolve to what you would expect, check that all dependencies are correctly declared (also check our website for more information: ).\n\n - **Fetch:** Then we download all the dependencies if needed, and make sure that they're all stored within our cache (check the value of `cacheFolder` in `yarn config` to see where the cache files are stored).\n\n - **Link:** Then we send the dependency tree information to internal plugins tasked with writing them on the disk in some form (for example by generating the .pnp.cjs file you might know).\n\n - **Build:** Once the dependency tree has been written on the disk, the package manager will now be free to run the build scripts for all packages that might need it, in a topological order compatible with the way they depend on one another. See https://yarnpkg.com/advanced/lifecycle-scripts for detail.\n\n Note that running this command is not part of the recommended workflow. Yarn supports zero-installs, which means that as long as you store your cache and your .pnp.cjs file inside your repository, everything will work without requiring any install right after cloning your repository or switching branches.\n\n If the `--immutable` option is set (defaults to true on CI), Yarn will abort with an error exit code if the lockfile was to be modified (other paths can be added using the `immutablePatterns` configuration setting). For backward compatibility we offer an alias under the name of `--frozen-lockfile`, but it will be removed in a later release.\n\n If the `--immutable-cache` option is set, Yarn will abort with an error exit code if the cache folder was to be modified (either because files would be added, or because they'd be removed).\n\n If the `--refresh-lockfile` option is set, Yarn will keep the same resolution for the packages currently in the lockfile but will refresh their metadata. If used together with `--immutable`, it can validate that the lockfile information are consistent. This flag is enabled by default when Yarn detects it runs within a pull request context.\n\n If the `--check-cache` option is set, Yarn will always refetch the packages and will ensure that their checksum matches what's 1/ described in the lockfile 2/ inside the existing cache files (if present). This is recommended as part of your CI workflow if you're both following the Zero-Installs model and accepting PRs from third-parties, as they'd otherwise have the ability to alter the checked-in packages before submitting them.\n\n If the `--inline-builds` option is set, Yarn will verbosely print the output of the build steps of your dependencies (instead of writing them into individual files). This is likely useful mostly for debug purposes only when using Docker-like environments.\n\n If the `--mode=<mode>` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n ",examples:[["Install the project","$0 install"],["Validate a project when using Zero-Installs","$0 install --immutable --immutable-cache"],["Validate a project when using Zero-Installs (slightly safer if you accept external PRs)","$0 install --immutable --immutable-cache --check-cache"]]});var z0t="<<<<<<<";async function X0t(t,e){if(!t.projectCwd)return!1;let r=K.join(t.projectCwd,dr.lockfile);if(!await oe.existsPromise(r)||!(await oe.readFilePromise(r,"utf8")).includes(z0t))return!1;if(e)throw new zt(47,"Cannot autofix a lockfile when running an immutable install");let a=await Ur.execvp("git",["rev-parse","MERGE_HEAD","HEAD"],{cwd:t.projectCwd});if(a.code!==0&&(a=await Ur.execvp("git",["rev-parse","REBASE_HEAD","HEAD"],{cwd:t.projectCwd})),a.code!==0&&(a=await Ur.execvp("git",["rev-parse","CHERRY_PICK_HEAD","HEAD"],{cwd:t.projectCwd})),a.code!==0)throw new zt(83,"Git returned an error when trying to find the commits pertaining to the conflict");let n=await Promise.all(a.stdout.trim().split(/\n/).map(async A=>{let p=await Ur.execvp("git",["show",`${A}:./${dr.lockfile}`],{cwd:t.projectCwd});if(p.code!==0)throw new zt(83,`Git returned an error when trying to access the lockfile content in ${A}`);try{return Vi(p.stdout)}catch{throw new zt(46,"A variant of the conflicting lockfile failed to parse")}}));n=n.filter(A=>!!A.__metadata);for(let A of n){if(A.__metadata.version<7)for(let p of Object.keys(A)){if(p==="__metadata")continue;let h=W.parseDescriptor(p,!0),E=t.normalizeDependency(h),I=W.stringifyDescriptor(E);I!==p&&(A[I]=A[p],delete A[p])}for(let p of Object.keys(A)){if(p==="__metadata")continue;let h=A[p].checksum;typeof h=="string"&&h.includes("/")||(A[p].checksum=`${A.__metadata.cacheKey}/${h}`)}}let u=Object.assign({},...n);u.__metadata.version=`${Math.min(...n.map(A=>parseInt(A.__metadata.version??0)))}`,u.__metadata.cacheKey="merged";for(let[A,p]of Object.entries(u))typeof p=="string"&&delete u[A];return await oe.changeFilePromise(r,Ba(u),{automaticNewlines:!0}),!0}async function Z0t(t,e){if(!t.projectCwd)return!1;let r=[],o=K.join(t.projectCwd,".yarn/plugins/@yarnpkg");return await Ve.updateConfiguration(t.projectCwd,{plugins:n=>{if(!Array.isArray(n))return n;let u=n.filter(A=>{if(!A.path)return!0;let p=K.resolve(t.projectCwd,A.path),h=B1.has(A.spec)&&K.contains(o,p);return h&&r.push(p),!h});return u.length===0?Ve.deleteProperty:u.length===n.length?n:u}},{immutable:e})?(await Promise.all(r.map(async n=>{await oe.removePromise(n)})),!0):!1}Ye();Pt();qt();var qh=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("-A,--all",!1,{description:"Link all workspaces belonging to the target projects to the current one"});this.private=ge.Boolean("-p,--private",!1,{description:"Also link private workspaces belonging to the target projects to the current one"});this.relative=ge.Boolean("-r,--relative",!1,{description:"Link workspaces using relative paths instead of absolute paths"});this.destinations=ge.Rest()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n=await Lr.find(r);if(!a)throw new rr(o.cwd,this.context.cwd);await o.restoreInstallState({restoreResolutions:!1});let u=o.topLevelWorkspace,A=[];for(let p of this.destinations){let h=K.resolve(this.context.cwd,ue.toPortablePath(p)),E=await Ve.find(h,this.context.plugins,{useRc:!1,strict:!1}),{project:I,workspace:v}=await St.find(E,h);if(o.cwd===I.cwd)throw new it(`Invalid destination '${p}'; Can't link the project to itself`);if(!v)throw new rr(I.cwd,h);if(this.all){let b=!1;for(let C of I.workspaces)C.manifest.name&&(!C.manifest.private||this.private)&&(A.push(C),b=!0);if(!b)throw new it(`No workspace found to be linked in the target project: ${p}`)}else{if(!v.manifest.name)throw new it(`The target workspace at '${p}' doesn't have a name and thus cannot be linked`);if(v.manifest.private&&!this.private)throw new it(`The target workspace at '${p}' is marked private - use the --private flag to link it anyway`);A.push(v)}}for(let p of A){let h=W.stringifyIdent(p.anchoredLocator),E=this.relative?K.relative(o.cwd,p.cwd):p.cwd;u.manifest.resolutions.push({pattern:{descriptor:{fullName:h}},reference:`portal:${E}`})}return await o.installWithNewReport({stdout:this.context.stdout},{cache:n})}};qh.paths=[["link"]],qh.usage=nt.Usage({description:"connect the local project to another one",details:"\n This command will set a new `resolutions` field in the project-level manifest and point it to the workspace at the specified location (even if part of another project).\n ",examples:[["Register one or more remote workspaces for use in the current project","$0 link ~/ts-loader ~/jest"],["Register all workspaces from a remote project for use in the current project","$0 link ~/jest --all"]]});qt();var Gh=class extends ut{constructor(){super(...arguments);this.args=ge.Proxy()}async execute(){return this.cli.run(["exec","node",...this.args])}};Gh.paths=[["node"]],Gh.usage=nt.Usage({description:"run node with the hook already setup",details:` + This command simply runs Node. It also makes sure to call it in a way that's compatible with the current project (for example, on PnP projects the environment will be setup in such a way that PnP will be correctly injected into the environment). + + The Node process will use the exact same version of Node as the one used to run Yarn itself, which might be a good way to ensure that your commands always use a consistent Node version. + `,examples:[["Run a Node script","$0 node ./my-script.js"]]});Ye();qt();var Yh=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),o=await Ve.findRcFiles(this.context.cwd);return(await Nt.start({configuration:r,json:this.json,stdout:this.context.stdout},async n=>{for(let u of o)if(!!u.data?.plugins)for(let A of u.data.plugins){if(!A.checksum||!A.spec.match(/^https?:/))continue;let p=await rn.get(A.spec,{configuration:r}),h=wn.makeHash(p);if(A.checksum===h)continue;let E=de.pretty(r,A.path,de.Type.PATH),I=de.pretty(r,A.spec,de.Type.URL),v=`${E} is different from the file provided by ${I}`;n.reportJson({...A,newChecksum:h}),n.reportError(0,v)}})).exitCode()}};Yh.paths=[["plugin","check"]],Yh.usage=nt.Usage({category:"Plugin-related commands",description:"find all third-party plugins that differ from their own spec",details:` + Check only the plugins from https. + + If this command detects any plugin differences in the CI environment, it will throw an error. + `,examples:[["find all third-party plugins that differ from their own spec","$0 plugin check"]]});Ye();Ye();Pt();qt();var ode=Be("os");Ye();Pt();qt();var tde=Be("os");Ye();Nl();qt();var $0t="https://raw.githubusercontent.com/yarnpkg/berry/master/plugins.yml";async function Jd(t,e){let r=await rn.get($0t,{configuration:t}),o=Vi(r.toString());return Object.fromEntries(Object.entries(o).filter(([a,n])=>!e||kr.satisfiesWithPrereleases(e,n.range??"<4.0.0-rc.1")))}var Wh=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins);return(await Nt.start({configuration:r,json:this.json,stdout:this.context.stdout},async a=>{let n=await Jd(r,tn);for(let[u,{experimental:A,...p}]of Object.entries(n)){let h=u;A&&(h+=" [experimental]"),a.reportJson({name:u,experimental:A,...p}),a.reportInfo(null,h)}})).exitCode()}};Wh.paths=[["plugin","list"]],Wh.usage=nt.Usage({category:"Plugin-related commands",description:"list the available official plugins",details:"\n This command prints the plugins available directly from the Yarn repository. Only those plugins can be referenced by name in `yarn plugin import`.\n ",examples:[["List the official plugins","$0 plugin list"]]});var egt=/^[0-9]+$/,tgt=process.platform==="win32";function rde(t){return egt.test(t)?`pull/${t}/head`:t}var rgt=({repository:t,branch:e},r)=>[["git","init",ue.fromPortablePath(r)],["git","remote","add","origin",t],["git","fetch","origin","--depth=1",rde(e)],["git","reset","--hard","FETCH_HEAD"]],ngt=({branch:t})=>[["git","fetch","origin","--depth=1",rde(t),"--force"],["git","reset","--hard","FETCH_HEAD"],["git","clean","-dfx","-e","packages/yarnpkg-cli/bundles"]],igt=({plugins:t,noMinify:e},r,o)=>[["yarn","build:cli",...new Array().concat(...t.map(a=>["--plugin",K.resolve(o,a)])),...e?["--no-minify"]:[],"|"],[tgt?"move":"mv","packages/yarnpkg-cli/bundles/yarn.js",ue.fromPortablePath(r),"|"]],Vh=class extends ut{constructor(){super(...arguments);this.installPath=ge.String("--path",{description:"The path where the repository should be cloned to"});this.repository=ge.String("--repository","https://github.com/yarnpkg/berry.git",{description:"The repository that should be cloned"});this.branch=ge.String("--branch","master",{description:"The branch of the repository that should be cloned"});this.plugins=ge.Array("--plugin",[],{description:"An array of additional plugins that should be included in the bundle"});this.dryRun=ge.Boolean("-n,--dry-run",!1,{description:"If set, the bundle will be built but not added to the project"});this.noMinify=ge.Boolean("--no-minify",!1,{description:"Build a bundle for development (debugging) - non-minified and non-mangled"});this.force=ge.Boolean("-f,--force",!1,{description:"Always clone the repository instead of trying to fetch the latest commits"});this.skipPlugins=ge.Boolean("--skip-plugins",!1,{description:"Skip updating the contrib plugins"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o}=await St.find(r,this.context.cwd),a=typeof this.installPath<"u"?K.resolve(this.context.cwd,ue.toPortablePath(this.installPath)):K.resolve(ue.toPortablePath((0,tde.tmpdir)()),"yarnpkg-sources",wn.makeHash(this.repository).slice(0,6));return(await Nt.start({configuration:r,stdout:this.context.stdout},async u=>{await _8(this,{configuration:r,report:u,target:a}),u.reportSeparator(),u.reportInfo(0,"Building a fresh bundle"),u.reportSeparator();let A=await Ur.execvp("git",["rev-parse","--short","HEAD"],{cwd:a,strict:!0}),p=K.join(a,`packages/yarnpkg-cli/bundles/yarn-${A.stdout.trim()}.js`);oe.existsSync(p)||(await y2(igt(this,p,a),{configuration:r,context:this.context,target:a}),u.reportSeparator());let h=await oe.readFilePromise(p);if(!this.dryRun){let{bundleVersion:E}=await O8(r,null,async()=>h,{report:u});this.skipPlugins||await sgt(this,E,{project:o,report:u,target:a})}})).exitCode()}};Vh.paths=[["set","version","from","sources"]],Vh.usage=nt.Usage({description:"build Yarn from master",details:` + This command will clone the Yarn repository into a temporary folder, then build it. The resulting bundle will then be copied into the local project. + + By default, it also updates all contrib plugins to the same commit the bundle is built from. This behavior can be disabled by using the \`--skip-plugins\` flag. + `,examples:[["Build Yarn from master","$0 set version from sources"]]});async function y2(t,{configuration:e,context:r,target:o}){for(let[a,...n]of t){let u=n[n.length-1]==="|";if(u&&n.pop(),u)await Ur.pipevp(a,n,{cwd:o,stdin:r.stdin,stdout:r.stdout,stderr:r.stderr,strict:!0});else{r.stdout.write(`${de.pretty(e,` $ ${[a,...n].join(" ")}`,"grey")} +`);try{await Ur.execvp(a,n,{cwd:o,strict:!0})}catch(A){throw r.stdout.write(A.stdout||A.stack),A}}}}async function _8(t,{configuration:e,report:r,target:o}){let a=!1;if(!t.force&&oe.existsSync(K.join(o,".git"))){r.reportInfo(0,"Fetching the latest commits"),r.reportSeparator();try{await y2(ngt(t),{configuration:e,context:t.context,target:o}),a=!0}catch{r.reportSeparator(),r.reportWarning(0,"Repository update failed; we'll try to regenerate it")}}a||(r.reportInfo(0,"Cloning the remote repository"),r.reportSeparator(),await oe.removePromise(o),await oe.mkdirPromise(o,{recursive:!0}),await y2(rgt(t,o),{configuration:e,context:t.context,target:o}))}async function sgt(t,e,{project:r,report:o,target:a}){let n=await Jd(r.configuration,e),u=new Set(Object.keys(n));for(let A of r.configuration.plugins.keys())!u.has(A)||await H8(A,t,{project:r,report:o,target:a})}Ye();Ye();Pt();qt();var nde=$e(zn()),ide=Be("url"),sde=Be("vm");var Kh=class extends ut{constructor(){super(...arguments);this.name=ge.String();this.checksum=ge.Boolean("--checksum",!0,{description:"Whether to care if this plugin is modified"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins);return(await Nt.start({configuration:r,stdout:this.context.stdout},async a=>{let{project:n}=await St.find(r,this.context.cwd),u,A;if(this.name.match(/^\.{0,2}[\\/]/)||ue.isAbsolute(this.name)){let p=K.resolve(this.context.cwd,ue.toPortablePath(this.name));a.reportInfo(0,`Reading ${de.pretty(r,p,de.Type.PATH)}`),u=K.relative(n.cwd,p),A=await oe.readFilePromise(p)}else{let p;if(this.name.match(/^https?:/)){try{new ide.URL(this.name)}catch{throw new zt(52,`Plugin specifier "${this.name}" is neither a plugin name nor a valid url`)}u=this.name,p=this.name}else{let h=W.parseLocator(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-"));if(h.reference!=="unknown"&&!nde.default.valid(h.reference))throw new zt(0,"Official plugins only accept strict version references. Use an explicit URL if you wish to download them from another location.");let E=W.stringifyIdent(h),I=await Jd(r,tn);if(!Object.hasOwn(I,E)){let v=`Couldn't find a plugin named ${W.prettyIdent(r,h)} on the remote registry. +`;throw r.plugins.has(E)?v+=`A plugin named ${W.prettyIdent(r,h)} is already installed; possibly attempting to import a built-in plugin.`:v+=`Note that only the plugins referenced on our website (${de.pretty(r,"https://github.com/yarnpkg/berry/blob/master/plugins.yml",de.Type.URL)}) can be referenced by their name; any other plugin will have to be referenced through its public url (for example ${de.pretty(r,"https://github.com/yarnpkg/berry/raw/master/packages/plugin-typescript/bin/%40yarnpkg/plugin-typescript.js",de.Type.URL)}).`,new zt(51,v)}u=E,p=I[E].url,h.reference!=="unknown"?p=p.replace(/\/master\//,`/${E}/${h.reference}/`):tn!==null&&(p=p.replace(/\/master\//,`/@yarnpkg/cli/${tn}/`))}a.reportInfo(0,`Downloading ${de.pretty(r,p,"green")}`),A=await rn.get(p,{configuration:r})}await j8(u,A,{checksum:this.checksum,project:n,report:a})})).exitCode()}};Kh.paths=[["plugin","import"]],Kh.usage=nt.Usage({category:"Plugin-related commands",description:"download a plugin",details:` + This command downloads the specified plugin from its remote location and updates the configuration to reference it in further CLI invocations. + + Three types of plugin references are accepted: + + - If the plugin is stored within the Yarn repository, it can be referenced by name. + - Third-party plugins can be referenced directly through their public urls. + - Local plugins can be referenced by their path on the disk. + + If the \`--no-checksum\` option is set, Yarn will no longer care if the plugin is modified. + + Plugins cannot be downloaded from the npm registry, and aren't allowed to have dependencies (they need to be bundled into a single file, possibly thanks to the \`@yarnpkg/builder\` package). + `,examples:[['Download and activate the "@yarnpkg/plugin-exec" plugin',"$0 plugin import @yarnpkg/plugin-exec"],['Download and activate the "@yarnpkg/plugin-exec" plugin (shorthand)',"$0 plugin import exec"],["Download and activate a community plugin","$0 plugin import https://example.org/path/to/plugin.js"],["Activate a local plugin","$0 plugin import ./path/to/plugin.js"]]});async function j8(t,e,{checksum:r=!0,project:o,report:a}){let{configuration:n}=o,u={},A={exports:u};(0,sde.runInNewContext)(e.toString(),{module:A,exports:u});let h=`.yarn/plugins/${A.exports.name}.cjs`,E=K.resolve(o.cwd,h);a.reportInfo(0,`Saving the new plugin in ${de.pretty(n,h,"magenta")}`),await oe.mkdirPromise(K.dirname(E),{recursive:!0}),await oe.writeFilePromise(E,e);let I={path:h,spec:t};r&&(I.checksum=wn.makeHash(e)),await Ve.addPlugin(o.cwd,[I])}var ogt=({pluginName:t,noMinify:e},r)=>[["yarn",`build:${t}`,...e?["--no-minify"]:[],"|"]],Jh=class extends ut{constructor(){super(...arguments);this.installPath=ge.String("--path",{description:"The path where the repository should be cloned to"});this.repository=ge.String("--repository","https://github.com/yarnpkg/berry.git",{description:"The repository that should be cloned"});this.branch=ge.String("--branch","master",{description:"The branch of the repository that should be cloned"});this.noMinify=ge.Boolean("--no-minify",!1,{description:"Build a plugin for development (debugging) - non-minified and non-mangled"});this.force=ge.Boolean("-f,--force",!1,{description:"Always clone the repository instead of trying to fetch the latest commits"});this.name=ge.String()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),o=typeof this.installPath<"u"?K.resolve(this.context.cwd,ue.toPortablePath(this.installPath)):K.resolve(ue.toPortablePath((0,ode.tmpdir)()),"yarnpkg-sources",wn.makeHash(this.repository).slice(0,6));return(await Nt.start({configuration:r,stdout:this.context.stdout},async n=>{let{project:u}=await St.find(r,this.context.cwd),A=W.parseIdent(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-")),p=W.stringifyIdent(A),h=await Jd(r,tn);if(!Object.hasOwn(h,p))throw new zt(51,`Couldn't find a plugin named "${p}" on the remote registry. Note that only the plugins referenced on our website (https://github.com/yarnpkg/berry/blob/master/plugins.yml) can be built and imported from sources.`);let E=p;await _8(this,{configuration:r,report:n,target:o}),await H8(E,this,{project:u,report:n,target:o})})).exitCode()}};Jh.paths=[["plugin","import","from","sources"]],Jh.usage=nt.Usage({category:"Plugin-related commands",description:"build a plugin from sources",details:` + This command clones the Yarn repository into a temporary folder, builds the specified contrib plugin and updates the configuration to reference it in further CLI invocations. + + The plugins can be referenced by their short name if sourced from the official Yarn repository. + `,examples:[['Build and activate the "@yarnpkg/plugin-exec" plugin',"$0 plugin import from sources @yarnpkg/plugin-exec"],['Build and activate the "@yarnpkg/plugin-exec" plugin (shorthand)',"$0 plugin import from sources exec"]]});async function H8(t,{context:e,noMinify:r},{project:o,report:a,target:n}){let u=t.replace(/@yarnpkg\//,""),{configuration:A}=o;a.reportSeparator(),a.reportInfo(0,`Building a fresh ${u}`),a.reportSeparator(),await y2(ogt({pluginName:u,noMinify:r},n),{configuration:A,context:e,target:n}),a.reportSeparator();let p=K.resolve(n,`packages/${u}/bundles/${t}.js`),h=await oe.readFilePromise(p);await j8(t,h,{project:o,report:a})}Ye();Pt();qt();var zh=class extends ut{constructor(){super(...arguments);this.name=ge.String()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o}=await St.find(r,this.context.cwd);return(await Nt.start({configuration:r,stdout:this.context.stdout},async n=>{let u=this.name,A=W.parseIdent(u);if(!r.plugins.has(u))throw new it(`${W.prettyIdent(r,A)} isn't referenced by the current configuration`);let p=`.yarn/plugins/${u}.cjs`,h=K.resolve(o.cwd,p);oe.existsSync(h)&&(n.reportInfo(0,`Removing ${de.pretty(r,p,de.Type.PATH)}...`),await oe.removePromise(h)),n.reportInfo(0,"Updating the configuration..."),await Ve.updateConfiguration(o.cwd,{plugins:E=>{if(!Array.isArray(E))return E;let I=E.filter(v=>v.path!==p);return I.length===0?Ve.deleteProperty:I.length===E.length?E:I}})})).exitCode()}};zh.paths=[["plugin","remove"]],zh.usage=nt.Usage({category:"Plugin-related commands",description:"remove a plugin",details:` + This command deletes the specified plugin from the .yarn/plugins folder and removes it from the configuration. + + **Note:** The plugins have to be referenced by their name property, which can be obtained using the \`yarn plugin runtime\` command. Shorthands are not allowed. + `,examples:[["Remove a plugin imported from the Yarn repository","$0 plugin remove @yarnpkg/plugin-typescript"],["Remove a plugin imported from a local file","$0 plugin remove my-local-plugin"]]});Ye();qt();var Xh=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins);return(await Nt.start({configuration:r,json:this.json,stdout:this.context.stdout},async a=>{for(let n of r.plugins.keys()){let u=this.context.plugins.plugins.has(n),A=n;u&&(A+=" [builtin]"),a.reportJson({name:n,builtin:u}),a.reportInfo(null,`${A}`)}})).exitCode()}};Xh.paths=[["plugin","runtime"]],Xh.usage=nt.Usage({category:"Plugin-related commands",description:"list the active plugins",details:` + This command prints the currently active plugins. Will be displayed both builtin plugins and external plugins. + `,examples:[["List the currently active plugins","$0 plugin runtime"]]});Ye();Ye();qt();var Zh=class extends ut{constructor(){super(...arguments);this.idents=ge.Rest()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n=await Lr.find(r);if(!a)throw new rr(o.cwd,this.context.cwd);let u=new Set;for(let A of this.idents)u.add(W.parseIdent(A).identHash);if(await o.restoreInstallState({restoreResolutions:!1}),await o.resolveEverything({cache:n,report:new Qi}),u.size>0)for(let A of o.storedPackages.values())u.has(A.identHash)&&(o.storedBuildState.delete(A.locatorHash),o.skippedBuilds.delete(A.locatorHash));else o.storedBuildState.clear(),o.skippedBuilds.clear();return await o.installWithNewReport({stdout:this.context.stdout,quiet:this.context.quiet},{cache:n})}};Zh.paths=[["rebuild"]],Zh.usage=nt.Usage({description:"rebuild the project's native packages",details:` + This command will automatically cause Yarn to forget about previous compilations of the given packages and to run them again. + + Note that while Yarn forgets the compilation, the previous artifacts aren't erased from the filesystem and may affect the next builds (in good or bad). To avoid this, you may remove the .yarn/unplugged folder, or any other relevant location where packages might have been stored (Yarn may offer a way to do that automatically in the future). + + By default all packages will be rebuilt, but you can filter the list by specifying the names of the packages you want to clear from memory. + `,examples:[["Rebuild all packages","$0 rebuild"],["Rebuild fsevents only","$0 rebuild fsevents"]]});Ye();Ye();Ye();qt();var q8=$e(Zo());Za();var $h=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("-A,--all",!1,{description:"Apply the operation to all workspaces from the current project"});this.mode=ge.String("--mode",{description:"Change what artifacts installs generate",validator:Vs(pl)});this.patterns=ge.Rest()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n=await Lr.find(r);if(!a)throw new rr(o.cwd,this.context.cwd);await o.restoreInstallState({restoreResolutions:!1});let u=this.all?o.workspaces:[a],A=["dependencies","devDependencies","peerDependencies"],p=[],h=!1,E=[];for(let C of this.patterns){let T=!1,L=W.parseIdent(C);for(let U of u){let J=[...U.manifest.peerDependenciesMeta.keys()];for(let te of(0,q8.default)(J,C))U.manifest.peerDependenciesMeta.delete(te),h=!0,T=!0;for(let te of A){let le=U.manifest.getForScope(te),pe=[...le.values()].map(Ae=>W.stringifyIdent(Ae));for(let Ae of(0,q8.default)(pe,W.stringifyIdent(L))){let{identHash:ye}=W.parseIdent(Ae),ae=le.get(ye);if(typeof ae>"u")throw new Error("Assertion failed: Expected the descriptor to be registered");U.manifest[te].delete(ye),E.push([U,te,ae]),h=!0,T=!0}}}T||p.push(C)}let I=p.length>1?"Patterns":"Pattern",v=p.length>1?"don't":"doesn't",b=this.all?"any":"this";if(p.length>0)throw new it(`${I} ${de.prettyList(r,p,de.Type.CODE)} ${v} match any packages referenced by ${b} workspace`);return h?(await r.triggerMultipleHooks(C=>C.afterWorkspaceDependencyRemoval,E),await o.installWithNewReport({stdout:this.context.stdout},{cache:n,mode:this.mode})):0}};$h.paths=[["remove"]],$h.usage=nt.Usage({description:"remove dependencies from the project",details:` + This command will remove the packages matching the specified patterns from the current workspace. + + If the \`--mode=<mode>\` option is set, Yarn will change which artifacts are generated. The modes currently supported are: + + - \`skip-build\` will not run the build scripts at all. Note that this is different from setting \`enableScripts\` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run. + + - \`update-lockfile\` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost. + + This command accepts glob patterns as arguments (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them. + `,examples:[["Remove a dependency from the current project","$0 remove lodash"],["Remove a dependency from all workspaces at once","$0 remove lodash --all"],["Remove all dependencies starting with `eslint-`","$0 remove 'eslint-*'"],["Remove all dependencies with the `@babel` scope","$0 remove '@babel/*'"],["Remove all dependencies matching `react-dom` or `react-helmet`","$0 remove 'react-{dom,helmet}'"]]});Ye();Ye();var ade=Be("util"),zd=class extends ut{async execute(){let e=await Ve.find(this.context.cwd,this.context.plugins),{project:r,workspace:o}=await St.find(e,this.context.cwd);if(!o)throw new rr(r.cwd,this.context.cwd);return(await Nt.start({configuration:e,stdout:this.context.stdout},async n=>{let u=o.manifest.scripts,A=je.sortMap(u.keys(),E=>E),p={breakLength:1/0,colors:e.get("enableColors"),maxArrayLength:2},h=A.reduce((E,I)=>Math.max(E,I.length),0);for(let[E,I]of u.entries())n.reportInfo(null,`${E.padEnd(h," ")} ${(0,ade.inspect)(I,p)}`)})).exitCode()}};zd.paths=[["run"]];Ye();Ye();qt();var e0=class extends ut{constructor(){super(...arguments);this.inspect=ge.String("--inspect",!1,{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"});this.inspectBrk=ge.String("--inspect-brk",!1,{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"});this.topLevel=ge.Boolean("-T,--top-level",!1,{description:"Check the root workspace for scripts and/or binaries instead of the current one"});this.binariesOnly=ge.Boolean("-B,--binaries-only",!1,{description:"Ignore any user defined scripts and only check for binaries"});this.require=ge.String("--require",{description:"Forwarded to the underlying Node process when executing a binary"});this.silent=ge.Boolean("--silent",{hidden:!0});this.scriptName=ge.String();this.args=ge.Proxy()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a,locator:n}=await St.find(r,this.context.cwd);await o.restoreInstallState();let u=this.topLevel?o.topLevelWorkspace.anchoredLocator:n;if(!this.binariesOnly&&await un.hasPackageScript(u,this.scriptName,{project:o}))return await un.executePackageScript(u,this.scriptName,this.args,{project:o,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});let A=await un.getPackageAccessibleBinaries(u,{project:o});if(A.get(this.scriptName)){let h=[];return this.inspect&&(typeof this.inspect=="string"?h.push(`--inspect=${this.inspect}`):h.push("--inspect")),this.inspectBrk&&(typeof this.inspectBrk=="string"?h.push(`--inspect-brk=${this.inspectBrk}`):h.push("--inspect-brk")),this.require&&h.push(`--require=${this.require}`),await un.executePackageAccessibleBinary(u,this.scriptName,this.args,{cwd:this.context.cwd,project:o,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,nodeArgs:h,packageAccessibleBinaries:A})}if(!this.topLevel&&!this.binariesOnly&&a&&this.scriptName.includes(":")){let E=(await Promise.all(o.workspaces.map(async I=>I.manifest.scripts.has(this.scriptName)?I:null))).filter(I=>I!==null);if(E.length===1)return await un.executeWorkspaceScript(E[0],this.scriptName,this.args,{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})}if(this.topLevel)throw this.scriptName==="node-gyp"?new it(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${W.prettyLocator(r,n)}). This typically happens because some package depends on "node-gyp" to build itself, but didn't list it in their dependencies. To fix that, please run "yarn add node-gyp" into your top-level workspace. You also can open an issue on the repository of the specified package to suggest them to use an optional peer dependency.`):new it(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${W.prettyLocator(r,n)}).`);{if(this.scriptName==="global")throw new it("The 'yarn global' commands have been removed in 2.x - consider using 'yarn dlx' or a third-party plugin instead");let h=[this.scriptName].concat(this.args);for(let[E,I]of uC)for(let v of I)if(h.length>=v.length&&JSON.stringify(h.slice(0,v.length))===JSON.stringify(v))throw new it(`Couldn't find a script named "${this.scriptName}", but a matching command can be found in the ${E} plugin. You can install it with "yarn plugin import ${E}".`);throw new it(`Couldn't find a script named "${this.scriptName}".`)}}};e0.paths=[["run"]],e0.usage=nt.Usage({description:"run a script defined in the package.json",details:` + This command will run a tool. The exact tool that will be executed will depend on the current state of your workspace: + + - If the \`scripts\` field from your local package.json contains a matching script name, its definition will get executed. + + - Otherwise, if one of the local workspace's dependencies exposes a binary with a matching name, this binary will get executed. + + - Otherwise, if the specified name contains a colon character and if one of the workspaces in the project contains exactly one script with a matching name, then this script will get executed. + + Whatever happens, the cwd of the spawned process will be the workspace that declares the script (which makes it possible to call commands cross-workspaces using the third syntax). + `,examples:[["Run the tests from the local workspace","$0 run test"],['Same thing, but without the "run" keyword',"$0 test"],["Inspect Webpack while running","$0 run --inspect-brk webpack"]]});Ye();Ye();qt();var t0=class extends ut{constructor(){super(...arguments);this.descriptor=ge.String();this.resolution=ge.String()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n=await Lr.find(r);if(await o.restoreInstallState({restoreResolutions:!1}),!a)throw new rr(o.cwd,this.context.cwd);let u=W.parseDescriptor(this.descriptor,!0),A=W.makeDescriptor(u,this.resolution);return o.storedDescriptors.set(u.descriptorHash,u),o.storedDescriptors.set(A.descriptorHash,A),o.resolutionAliases.set(u.descriptorHash,A.descriptorHash),await o.installWithNewReport({stdout:this.context.stdout},{cache:n})}};t0.paths=[["set","resolution"]],t0.usage=nt.Usage({description:"enforce a package resolution",details:'\n This command updates the resolution table so that `descriptor` is resolved by `resolution`.\n\n Note that by default this command only affect the current resolution table - meaning that this "manual override" will disappear if you remove the lockfile, or if the package disappear from the table. If you wish to make the enforced resolution persist whatever happens, edit the `resolutions` field in your top-level manifest.\n\n Note that no attempt is made at validating that `resolution` is a valid resolution entry for `descriptor`.\n ',examples:[["Force all instances of lodash@npm:^1.2.3 to resolve to 1.5.0","$0 set resolution lodash@npm:^1.2.3 1.5.0"]]});Ye();Pt();qt();var lde=$e(Zo()),r0=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("-A,--all",!1,{description:"Unlink all workspaces belonging to the target project from the current one"});this.leadingArguments=ge.Rest()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n=await Lr.find(r);if(!a)throw new rr(o.cwd,this.context.cwd);let u=o.topLevelWorkspace,A=new Set;if(this.leadingArguments.length===0&&this.all)for(let{pattern:p,reference:h}of u.manifest.resolutions)h.startsWith("portal:")&&A.add(p.descriptor.fullName);if(this.leadingArguments.length>0)for(let p of this.leadingArguments){let h=K.resolve(this.context.cwd,ue.toPortablePath(p));if(je.isPathLike(p)){let E=await Ve.find(h,this.context.plugins,{useRc:!1,strict:!1}),{project:I,workspace:v}=await St.find(E,h);if(!v)throw new rr(I.cwd,h);if(this.all){for(let b of I.workspaces)b.manifest.name&&A.add(W.stringifyIdent(b.anchoredLocator));if(A.size===0)throw new it("No workspace found to be unlinked in the target project")}else{if(!v.manifest.name)throw new it("The target workspace doesn't have a name and thus cannot be unlinked");A.add(W.stringifyIdent(v.anchoredLocator))}}else{let E=[...u.manifest.resolutions.map(({pattern:I})=>I.descriptor.fullName)];for(let I of(0,lde.default)(E,p))A.add(I)}}return u.manifest.resolutions=u.manifest.resolutions.filter(({pattern:p})=>!A.has(p.descriptor.fullName)),await o.installWithNewReport({stdout:this.context.stdout,quiet:this.context.quiet},{cache:n})}};r0.paths=[["unlink"]],r0.usage=nt.Usage({description:"disconnect the local project from another one",details:` + This command will remove any resolutions in the project-level manifest that would have been added via a yarn link with similar arguments. + `,examples:[["Unregister a remote workspace in the current project","$0 unlink ~/ts-loader"],["Unregister all workspaces from a remote project in the current project","$0 unlink ~/jest --all"],["Unregister all previously linked workspaces","$0 unlink --all"],["Unregister all workspaces matching a glob","$0 unlink '@babel/*' 'pkg-{a,b}'"]]});Ye();Ye();Ye();qt();var cde=$e(A2()),G8=$e(Zo());Za();var Kf=class extends ut{constructor(){super(...arguments);this.interactive=ge.Boolean("-i,--interactive",{description:"Offer various choices, depending on the detected upgrade paths"});this.fixed=ge.Boolean("-F,--fixed",!1,{description:"Store dependency tags as-is instead of resolving them"});this.exact=ge.Boolean("-E,--exact",!1,{description:"Don't use any semver modifier on the resolved range"});this.tilde=ge.Boolean("-T,--tilde",!1,{description:"Use the `~` semver modifier on the resolved range"});this.caret=ge.Boolean("-C,--caret",!1,{description:"Use the `^` semver modifier on the resolved range"});this.recursive=ge.Boolean("-R,--recursive",!1,{description:"Resolve again ALL resolutions for those packages"});this.mode=ge.String("--mode",{description:"Change what artifacts installs generate",validator:Vs(pl)});this.patterns=ge.Rest()}async execute(){return this.recursive?await this.executeUpRecursive():await this.executeUpClassic()}async executeUpRecursive(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n=await Lr.find(r);if(!a)throw new rr(o.cwd,this.context.cwd);await o.restoreInstallState({restoreResolutions:!1});let u=[...o.storedDescriptors.values()],A=u.map(E=>W.stringifyIdent(E)),p=new Set;for(let E of this.patterns){if(W.parseDescriptor(E).range!=="unknown")throw new it("Ranges aren't allowed when using --recursive");for(let I of(0,G8.default)(A,E)){let v=W.parseIdent(I);p.add(v.identHash)}}let h=u.filter(E=>p.has(E.identHash));for(let E of h)o.storedDescriptors.delete(E.descriptorHash),o.storedResolutions.delete(E.descriptorHash);return await o.installWithNewReport({stdout:this.context.stdout},{cache:n,mode:this.mode})}async executeUpClassic(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n=await Lr.find(r);if(!a)throw new rr(o.cwd,this.context.cwd);await o.restoreInstallState({restoreResolutions:!1});let u=this.fixed,A=this.interactive??r.get("preferInteractive"),p=p2(this,o),h=A?["keep","reuse","project","latest"]:["project","latest"],E=[],I=[];for(let L of this.patterns){let U=!1,J=W.parseDescriptor(L),te=W.stringifyIdent(J);for(let le of o.workspaces)for(let pe of["dependencies","devDependencies"]){let ye=[...le.manifest.getForScope(pe).values()].map(we=>W.stringifyIdent(we)),ae=te==="*"?ye:(0,G8.default)(ye,te);for(let we of ae){let Pe=W.parseIdent(we),g=le.manifest[pe].get(Pe.identHash);if(typeof g>"u")throw new Error("Assertion failed: Expected the descriptor to be registered");let Ee=W.makeDescriptor(Pe,J.range);E.push(Promise.resolve().then(async()=>[le,pe,g,await h2(Ee,{project:o,workspace:le,cache:n,target:pe,fixed:u,modifier:p,strategies:h})])),U=!0}}U||I.push(L)}if(I.length>1)throw new it(`Patterns ${de.prettyList(r,I,de.Type.CODE)} don't match any packages referenced by any workspace`);if(I.length>0)throw new it(`Pattern ${de.prettyList(r,I,de.Type.CODE)} doesn't match any packages referenced by any workspace`);let v=await Promise.all(E),b=await AA.start({configuration:r,stdout:this.context.stdout,suggestInstall:!1},async L=>{for(let[,,U,{suggestions:J,rejections:te}]of v){let le=J.filter(pe=>pe.descriptor!==null);if(le.length===0){let[pe]=te;if(typeof pe>"u")throw new Error("Assertion failed: Expected an error to have been set");let Ae=this.cli.error(pe);o.configuration.get("enableNetwork")?L.reportError(27,`${W.prettyDescriptor(r,U)} can't be resolved to a satisfying range + +${Ae}`):L.reportError(27,`${W.prettyDescriptor(r,U)} can't be resolved to a satisfying range (note: network resolution has been disabled) + +${Ae}`)}else le.length>1&&!A&&L.reportError(27,`${W.prettyDescriptor(r,U)} has multiple possible upgrade strategies; use -i to disambiguate manually`)}});if(b.hasErrors())return b.exitCode();let C=!1,T=[];for(let[L,U,,{suggestions:J}]of v){let te,le=J.filter(ae=>ae.descriptor!==null),pe=le[0].descriptor,Ae=le.every(ae=>W.areDescriptorsEqual(ae.descriptor,pe));le.length===1||Ae?te=pe:(C=!0,{answer:te}=await(0,cde.prompt)({type:"select",name:"answer",message:`Which range do you want to use in ${W.prettyWorkspace(r,L)} \u276F ${U}?`,choices:J.map(({descriptor:ae,name:we,reason:Pe})=>ae?{name:we,hint:Pe,descriptor:ae}:{name:we,hint:Pe,disabled:!0}),onCancel:()=>process.exit(130),result(ae){return this.find(ae,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout}));let ye=L.manifest[U].get(te.identHash);if(typeof ye>"u")throw new Error("Assertion failed: This descriptor should have a matching entry");if(ye.descriptorHash!==te.descriptorHash)L.manifest[U].set(te.identHash,te),T.push([L,U,ye,te]);else{let ae=r.makeResolver(),we={project:o,resolver:ae},Pe=r.normalizeDependency(ye),g=ae.bindDescriptor(Pe,L.anchoredLocator,we);o.forgetResolution(g)}}return await r.triggerMultipleHooks(L=>L.afterWorkspaceDependencyReplacement,T),C&&this.context.stdout.write(` +`),await o.installWithNewReport({stdout:this.context.stdout},{cache:n,mode:this.mode})}};Kf.paths=[["up"]],Kf.usage=nt.Usage({description:"upgrade dependencies across the project",details:"\n This command upgrades the packages matching the list of specified patterns to their latest available version across the whole project (regardless of whether they're part of `dependencies` or `devDependencies` - `peerDependencies` won't be affected). This is a project-wide command: all workspaces will be upgraded in the process.\n\n If `-R,--recursive` is set the command will change behavior and no other switch will be allowed. When operating under this mode `yarn up` will force all ranges matching the selected packages to be resolved again (often to the highest available versions) before being stored in the lockfile. It however won't touch your manifests anymore, so depending on your needs you might want to run both `yarn up` and `yarn up -R` to cover all bases.\n\n If `-i,--interactive` is set (or if the `preferInteractive` settings is toggled on) the command will offer various choices, depending on the detected upgrade paths. Some upgrades require this flag in order to resolve ambiguities.\n\n The, `-C,--caret`, `-E,--exact` and `-T,--tilde` options have the same meaning as in the `add` command (they change the modifier used when the range is missing or a tag, and are ignored when the range is explicitly set).\n\n If the `--mode=<mode>` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n Generally you can see `yarn up` as a counterpart to what was `yarn upgrade --latest` in Yarn 1 (ie it ignores the ranges previously listed in your manifests), but unlike `yarn upgrade` which only upgraded dependencies in the current workspace, `yarn up` will upgrade all workspaces at the same time.\n\n This command accepts glob patterns as arguments (if valid Descriptors and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n **Note:** The ranges have to be static, only the package scopes and names can contain glob patterns.\n ",examples:[["Upgrade all instances of lodash to the latest release","$0 up lodash"],["Upgrade all instances of lodash to the latest release, but ask confirmation for each","$0 up lodash -i"],["Upgrade all instances of lodash to 1.2.3","$0 up lodash@1.2.3"],["Upgrade all instances of packages with the `@babel` scope to the latest release","$0 up '@babel/*'"],["Upgrade all instances of packages containing the word `jest` to the latest release","$0 up '*jest*'"],["Upgrade all instances of packages with the `@babel` scope to 7.0.0","$0 up '@babel/*@7.0.0'"]]}),Kf.schema=[lI("recursive",Gu.Forbids,["interactive","exact","tilde","caret"],{ignore:[void 0,!1]})];Ye();Ye();Ye();qt();var n0=class extends ut{constructor(){super(...arguments);this.recursive=ge.Boolean("-R,--recursive",!1,{description:"List, for each workspace, what are all the paths that lead to the dependency"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.peers=ge.Boolean("--peers",!1,{description:"Also print the peer dependencies that match the specified name"});this.package=ge.String()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd);if(!a)throw new rr(o.cwd,this.context.cwd);await o.restoreInstallState();let n=W.parseIdent(this.package).identHash,u=this.recursive?lgt(o,n,{configuration:r,peers:this.peers}):agt(o,n,{configuration:r,peers:this.peers});$s.emitTree(u,{configuration:r,stdout:this.context.stdout,json:this.json,separators:1})}};n0.paths=[["why"]],n0.usage=nt.Usage({description:"display the reason why a package is needed",details:` + This command prints the exact reasons why a package appears in the dependency tree. + + If \`-R,--recursive\` is set, the listing will go in depth and will list, for each workspaces, what are all the paths that lead to the dependency. Note that the display is somewhat optimized in that it will not print the package listing twice for a single package, so if you see a leaf named "Foo" when looking for "Bar", it means that "Foo" already got printed higher in the tree. + `,examples:[["Explain why lodash is used in your project","$0 why lodash"]]});function agt(t,e,{configuration:r,peers:o}){let a=je.sortMap(t.storedPackages.values(),A=>W.stringifyLocator(A)),n={},u={children:n};for(let A of a){let p={};for(let E of A.dependencies.values()){if(!o&&A.peerDependencies.has(E.identHash))continue;let I=t.storedResolutions.get(E.descriptorHash);if(!I)throw new Error("Assertion failed: The resolution should have been registered");let v=t.storedPackages.get(I);if(!v)throw new Error("Assertion failed: The package should have been registered");if(v.identHash!==e)continue;{let C=W.stringifyLocator(A);n[C]={value:[A,de.Type.LOCATOR],children:p}}let b=W.stringifyLocator(v);p[b]={value:[{descriptor:E,locator:v},de.Type.DEPENDENT]}}}return u}function lgt(t,e,{configuration:r,peers:o}){let a=je.sortMap(t.workspaces,v=>W.stringifyLocator(v.anchoredLocator)),n=new Set,u=new Set,A=v=>{if(n.has(v.locatorHash))return u.has(v.locatorHash);if(n.add(v.locatorHash),v.identHash===e)return u.add(v.locatorHash),!0;let b=!1;v.identHash===e&&(b=!0);for(let C of v.dependencies.values()){if(!o&&v.peerDependencies.has(C.identHash))continue;let T=t.storedResolutions.get(C.descriptorHash);if(!T)throw new Error("Assertion failed: The resolution should have been registered");let L=t.storedPackages.get(T);if(!L)throw new Error("Assertion failed: The package should have been registered");A(L)&&(b=!0)}return b&&u.add(v.locatorHash),b};for(let v of a)A(v.anchoredPackage);let p=new Set,h={},E={children:h},I=(v,b,C)=>{if(!u.has(v.locatorHash))return;let T=C!==null?de.tuple(de.Type.DEPENDENT,{locator:v,descriptor:C}):de.tuple(de.Type.LOCATOR,v),L={},U={value:T,children:L},J=W.stringifyLocator(v);if(b[J]=U,!p.has(v.locatorHash)&&(p.add(v.locatorHash),!(C!==null&&t.tryWorkspaceByLocator(v))))for(let te of v.dependencies.values()){if(!o&&v.peerDependencies.has(te.identHash))continue;let le=t.storedResolutions.get(te.descriptorHash);if(!le)throw new Error("Assertion failed: The resolution should have been registered");let pe=t.storedPackages.get(le);if(!pe)throw new Error("Assertion failed: The package should have been registered");I(pe,L,te)}};for(let v of a)I(v.anchoredPackage,h,null);return E}Ye();var eH={};Kt(eH,{GitFetcher:()=>C2,GitResolver:()=>w2,default:()=>bgt,gitUtils:()=>ra});Ye();Pt();var ra={};Kt(ra,{TreeishProtocols:()=>E2,clone:()=>$8,fetchBase:()=>Qde,fetchChangedFiles:()=>Fde,fetchChangedWorkspaces:()=>Sgt,fetchRoot:()=>kde,isGitUrl:()=>EC,lsRemote:()=>bde,normalizeLocator:()=>Pgt,normalizeRepoUrl:()=>mC,resolveUrl:()=>Z8,splitRepoUrl:()=>i0,validateRepoUrl:()=>X8});Ye();Pt();qt();var Pde=$e(Bde()),Sde=$e(EU()),yC=$e(Be("querystring")),J8=$e(zn());function K8(t,e,r){let o=t.indexOf(r);return t.lastIndexOf(e,o>-1?o:1/0)}function vde(t){try{return new URL(t)}catch{return}}function vgt(t){let e=K8(t,"@","#"),r=K8(t,":","#");return r>e&&(t=`${t.slice(0,r)}/${t.slice(r+1)}`),K8(t,":","#")===-1&&t.indexOf("//")===-1&&(t=`ssh://${t}`),t}function Dde(t){return vde(t)||vde(vgt(t))}function mC(t,{git:e=!1}={}){if(t=t.replace(/^git\+https:/,"https:"),t=t.replace(/^(?:github:|https:\/\/github\.com\/|git:\/\/github\.com\/)?(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)(?:\.git)?(#.*)?$/,"https://github.com/$1/$2.git$3"),t=t.replace(/^https:\/\/github\.com\/(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)\/tarball\/(.+)?$/,"https://github.com/$1/$2.git#$3"),e){let r=Dde(t);r&&(t=r.href),t=t.replace(/^git\+([^:]+):/,"$1:")}return t}function xde(){return{...process.env,GIT_SSH_COMMAND:process.env.GIT_SSH_COMMAND||`${process.env.GIT_SSH||"ssh"} -o BatchMode=yes`}}var Dgt=[/^ssh:/,/^git(?:\+[^:]+)?:/,/^(?:git\+)?https?:[^#]+\/[^#]+(?:\.git)(?:#.*)?$/,/^git@[^#]+\/[^#]+\.git(?:#.*)?$/,/^(?:github:|https:\/\/github\.com\/)?(?!\.{1,2}\/)([a-zA-Z._0-9-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z._0-9-]+?)(?:\.git)?(?:#.*)?$/,/^https:\/\/github\.com\/(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)\/tarball\/(.+)?$/],E2=(a=>(a.Commit="commit",a.Head="head",a.Tag="tag",a.Semver="semver",a))(E2||{});function EC(t){return t?Dgt.some(e=>!!t.match(e)):!1}function i0(t){t=mC(t);let e=t.indexOf("#");if(e===-1)return{repo:t,treeish:{protocol:"head",request:"HEAD"},extra:{}};let r=t.slice(0,e),o=t.slice(e+1);if(o.match(/^[a-z]+=/)){let a=yC.default.parse(o);for(let[p,h]of Object.entries(a))if(typeof h!="string")throw new Error(`Assertion failed: The ${p} parameter must be a literal string`);let n=Object.values(E2).find(p=>Object.hasOwn(a,p)),[u,A]=typeof n<"u"?[n,a[n]]:["head","HEAD"];for(let p of Object.values(E2))delete a[p];return{repo:r,treeish:{protocol:u,request:A},extra:a}}else{let a=o.indexOf(":"),[n,u]=a===-1?[null,o]:[o.slice(0,a),o.slice(a+1)];return{repo:r,treeish:{protocol:n,request:u},extra:{}}}}function Pgt(t){return W.makeLocator(t,mC(t.reference))}function X8(t,{configuration:e}){let r=mC(t,{git:!0});if(!rn.getNetworkSettings(`https://${(0,Pde.default)(r).resource}`,{configuration:e}).enableNetwork)throw new zt(80,`Request to '${r}' has been blocked because of your configuration settings`);return r}async function bde(t,e){let r=X8(t,{configuration:e}),o=await z8("listing refs",["ls-remote",r],{cwd:e.startingCwd,env:xde()},{configuration:e,normalizedRepoUrl:r}),a=new Map,n=/^([a-f0-9]{40})\t([^\n]+)/gm,u;for(;(u=n.exec(o.stdout))!==null;)a.set(u[2],u[1]);return a}async function Z8(t,e){let{repo:r,treeish:{protocol:o,request:a},extra:n}=i0(t),u=await bde(r,e),A=(h,E)=>{switch(h){case"commit":{if(!E.match(/^[a-f0-9]{40}$/))throw new Error("Invalid commit hash");return yC.default.stringify({...n,commit:E})}case"head":{let I=u.get(E==="HEAD"?E:`refs/heads/${E}`);if(typeof I>"u")throw new Error(`Unknown head ("${E}")`);return yC.default.stringify({...n,commit:I})}case"tag":{let I=u.get(`refs/tags/${E}`);if(typeof I>"u")throw new Error(`Unknown tag ("${E}")`);return yC.default.stringify({...n,commit:I})}case"semver":{let I=kr.validRange(E);if(!I)throw new Error(`Invalid range ("${E}")`);let v=new Map([...u.entries()].filter(([C])=>C.startsWith("refs/tags/")).map(([C,T])=>[J8.default.parse(C.slice(10)),T]).filter(C=>C[0]!==null)),b=J8.default.maxSatisfying([...v.keys()],I);if(b===null)throw new Error(`No matching range ("${E}")`);return yC.default.stringify({...n,commit:v.get(b)})}case null:{let I;if((I=p("commit",E))!==null||(I=p("tag",E))!==null||(I=p("head",E))!==null)return I;throw E.match(/^[a-f0-9]+$/)?new Error(`Couldn't resolve "${E}" as either a commit, a tag, or a head - if a commit, use the 40-characters commit hash`):new Error(`Couldn't resolve "${E}" as either a commit, a tag, or a head`)}default:throw new Error(`Invalid Git resolution protocol ("${h}")`)}},p=(h,E)=>{try{return A(h,E)}catch{return null}};return mC(`${r}#${A(o,a)}`)}async function $8(t,e){return await e.getLimit("cloneConcurrency")(async()=>{let{repo:r,treeish:{protocol:o,request:a}}=i0(t);if(o!=="commit")throw new Error("Invalid treeish protocol when cloning");let n=X8(r,{configuration:e}),u=await oe.mktempPromise(),A={cwd:u,env:xde()};return await z8("cloning the repository",["clone","-c core.autocrlf=false",n,ue.fromPortablePath(u)],A,{configuration:e,normalizedRepoUrl:n}),await z8("switching branch",["checkout",`${a}`],A,{configuration:e,normalizedRepoUrl:n}),u})}async function kde(t){let e,r=t;do{if(e=r,await oe.existsPromise(K.join(e,".git")))return e;r=K.dirname(e)}while(r!==e);return null}async function Qde(t,{baseRefs:e}){if(e.length===0)throw new it("Can't run this command with zero base refs specified.");let r=[];for(let A of e){let{code:p}=await Ur.execvp("git",["merge-base",A,"HEAD"],{cwd:t});p===0&&r.push(A)}if(r.length===0)throw new it(`No ancestor could be found between any of HEAD and ${e.join(", ")}`);let{stdout:o}=await Ur.execvp("git",["merge-base","HEAD",...r],{cwd:t,strict:!0}),a=o.trim(),{stdout:n}=await Ur.execvp("git",["show","--quiet","--pretty=format:%s",a],{cwd:t,strict:!0}),u=n.trim();return{hash:a,title:u}}async function Fde(t,{base:e,project:r}){let o=je.buildIgnorePattern(r.configuration.get("changesetIgnorePatterns")),{stdout:a}=await Ur.execvp("git",["diff","--name-only",`${e}`],{cwd:t,strict:!0}),n=a.split(/\r\n|\r|\n/).filter(h=>h.length>0).map(h=>K.resolve(t,ue.toPortablePath(h))),{stdout:u}=await Ur.execvp("git",["ls-files","--others","--exclude-standard"],{cwd:t,strict:!0}),A=u.split(/\r\n|\r|\n/).filter(h=>h.length>0).map(h=>K.resolve(t,ue.toPortablePath(h))),p=[...new Set([...n,...A].sort())];return o?p.filter(h=>!K.relative(r.cwd,h).match(o)):p}async function Sgt({ref:t,project:e}){if(e.configuration.projectCwd===null)throw new it("This command can only be run from within a Yarn project");let r=[K.resolve(e.cwd,dr.lockfile),K.resolve(e.cwd,e.configuration.get("cacheFolder")),K.resolve(e.cwd,e.configuration.get("installStatePath")),K.resolve(e.cwd,e.configuration.get("virtualFolder"))];await e.configuration.triggerHook(u=>u.populateYarnPaths,e,u=>{u!=null&&r.push(u)});let o=await kde(e.configuration.projectCwd);if(o==null)throw new it("This command can only be run on Git repositories");let a=await Qde(o,{baseRefs:typeof t=="string"?[t]:e.configuration.get("changesetBaseRefs")}),n=await Fde(o,{base:a.hash,project:e});return new Set(je.mapAndFilter(n,u=>{let A=e.tryWorkspaceByFilePath(u);return A===null?je.mapAndFilter.skip:r.some(p=>u.startsWith(p))?je.mapAndFilter.skip:A}))}async function z8(t,e,r,{configuration:o,normalizedRepoUrl:a}){try{return await Ur.execvp("git",e,{...r,strict:!0})}catch(n){if(!(n instanceof Ur.ExecError))throw n;let u=n.reportExtra,A=n.stderr.toString();throw new zt(1,`Failed ${t}`,p=>{p.reportError(1,` ${de.prettyField(o,{label:"Repository URL",value:de.tuple(de.Type.URL,a)})}`);for(let h of A.matchAll(/^(.+?): (.*)$/gm)){let[,E,I]=h;E=E.toLowerCase();let v=E==="error"?"Error":`${(0,Sde.default)(E)} Error`;p.reportError(1,` ${de.prettyField(o,{label:v,value:de.tuple(de.Type.NO_HINT,I)})}`)}u?.(p)})}}var C2=class{supports(e,r){return EC(e.reference)}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,a=new Map(r.checksums);a.set(e.locatorHash,o);let n={...r,checksums:a},u=await this.downloadHosted(e,n);if(u!==null)return u;let[A,p,h]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${W.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the remote repository`),loader:()=>this.cloneFromRemote(e,n),...r.cacheOptions});return{packageFs:A,releaseFs:p,prefixPath:W.getIdentVendorPath(e),checksum:h}}async downloadHosted(e,r){return r.project.configuration.reduceHook(o=>o.fetchHostedRepository,null,e,r)}async cloneFromRemote(e,r){let o=await $8(e.reference,r.project.configuration),a=i0(e.reference),n=K.join(o,"package.tgz");await un.prepareExternalProject(o,n,{configuration:r.project.configuration,report:r.report,workspace:a.extra.workspace,locator:e});let u=await oe.readFilePromise(n);return await je.releaseAfterUseAsync(async()=>await Xi.convertToZip(u,{configuration:r.project.configuration,prefixPath:W.getIdentVendorPath(e),stripComponents:1}))}};Ye();Ye();var w2=class{supportsDescriptor(e,r){return EC(e.range)}supportsLocator(e,r){return EC(e.reference)}shouldPersistResolution(e,r){return!0}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){let a=await Z8(e.range,o.project.configuration);return[W.makeLocator(e,a)]}async getSatisfying(e,r,o,a){let n=i0(e.range);return{locators:o.filter(A=>{if(A.identHash!==e.identHash)return!1;let p=i0(A.reference);return!(n.repo!==p.repo||n.treeish.protocol==="commit"&&n.treeish.request!==p.treeish.request)}),sorted:!1}}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let o=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),a=await je.releaseAfterUseAsync(async()=>await Mt.find(o.prefixPath,{baseFs:o.packageFs}),o.releaseFs);return{...e,version:a.version||"0.0.0",languageName:a.languageName||r.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:a.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(a.dependencies),peerDependencies:a.peerDependencies,dependenciesMeta:a.dependenciesMeta,peerDependenciesMeta:a.peerDependenciesMeta,bin:a.bin}}};var xgt={configuration:{changesetBaseRefs:{description:"The base git refs that the current HEAD is compared against when detecting changes. Supports git branches, tags, and commits.",type:"STRING",isArray:!0,isNullable:!1,default:["master","origin/master","upstream/master","main","origin/main","upstream/main"]},changesetIgnorePatterns:{description:"Array of glob patterns; files matching them will be ignored when fetching the changed files",type:"STRING",default:[],isArray:!0},cloneConcurrency:{description:"Maximal number of concurrent clones",type:"NUMBER",default:2}},fetchers:[C2],resolvers:[w2]};var bgt=xgt;qt();var s0=class extends ut{constructor(){super(...arguments);this.since=ge.String("--since",{description:"Only include workspaces that have been changed since the specified ref.",tolerateBoolean:!0});this.recursive=ge.Boolean("-R,--recursive",!1,{description:"Find packages via dependencies/devDependencies instead of using the workspaces field"});this.noPrivate=ge.Boolean("--no-private",{description:"Exclude workspaces that have the private field set to true"});this.verbose=ge.Boolean("-v,--verbose",!1,{description:"Also return the cross-dependencies between workspaces"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o}=await St.find(r,this.context.cwd);return(await Nt.start({configuration:r,json:this.json,stdout:this.context.stdout},async n=>{let u=this.since?await ra.fetchChangedWorkspaces({ref:this.since,project:o}):o.workspaces,A=new Set(u);if(this.recursive)for(let p of[...u].map(h=>h.getRecursiveWorkspaceDependents()))for(let h of p)A.add(h);for(let p of A){let{manifest:h}=p;if(h.private&&this.noPrivate)continue;let E;if(this.verbose){let I=new Set,v=new Set;for(let b of Mt.hardDependencies)for(let[C,T]of h.getForScope(b)){let L=o.tryWorkspaceByDescriptor(T);L===null?o.workspacesByIdent.has(C)&&v.add(T):I.add(L)}E={workspaceDependencies:Array.from(I).map(b=>b.relativeCwd),mismatchedWorkspaceDependencies:Array.from(v).map(b=>W.stringifyDescriptor(b))}}n.reportInfo(null,`${p.relativeCwd}`),n.reportJson({location:p.relativeCwd,name:h.name?W.stringifyIdent(h.name):null,...E})}})).exitCode()}};s0.paths=[["workspaces","list"]],s0.usage=nt.Usage({category:"Workspace-related commands",description:"list all available workspaces",details:"\n This command will print the list of all workspaces in the project.\n\n - If `--since` is set, Yarn will only list workspaces that have been modified since the specified ref. By default Yarn will use the refs specified by the `changesetBaseRefs` configuration option.\n\n - If `-R,--recursive` is set, Yarn will find workspaces to run the command on by recursively evaluating `dependencies` and `devDependencies` fields, instead of looking at the `workspaces` fields.\n\n - If `--no-private` is set, Yarn will not list any workspaces that have the `private` field set to `true`.\n\n - If both the `-v,--verbose` and `--json` options are set, Yarn will also return the cross-dependencies between each workspaces (useful when you wish to automatically generate Buck / Bazel rules).\n "});Ye();Ye();qt();var o0=class extends ut{constructor(){super(...arguments);this.workspaceName=ge.String();this.commandName=ge.String();this.args=ge.Proxy()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd);if(!a)throw new rr(o.cwd,this.context.cwd);let n=o.workspaces,u=new Map(n.map(p=>[W.stringifyIdent(p.anchoredLocator),p])),A=u.get(this.workspaceName);if(A===void 0){let p=Array.from(u.keys()).sort();throw new it(`Workspace '${this.workspaceName}' not found. Did you mean any of the following: + - ${p.join(` + - `)}?`)}return this.cli.run([this.commandName,...this.args],{cwd:A.cwd})}};o0.paths=[["workspace"]],o0.usage=nt.Usage({category:"Workspace-related commands",description:"run a command within the specified workspace",details:` + This command will run a given sub-command on a single workspace. + `,examples:[["Add a package to a single workspace","yarn workspace components add -D react"],["Run build script on a single workspace","yarn workspace components run build"]]});var kgt={configuration:{enableImmutableInstalls:{description:"If true (the default on CI), prevents the install command from modifying the lockfile",type:"BOOLEAN",default:Tde.isCI},defaultSemverRangePrefix:{description:"The default save prefix: '^', '~' or ''",type:"STRING",values:["^","~",""],default:"^"},preferReuse:{description:"If true, `yarn add` will attempt to reuse the most common dependency range in other workspaces.",type:"BOOLEAN",default:!1}},commands:[Qh,Fh,Th,Rh,t0,Vh,Uh,s0,Wd,Vd,dC,Kd,bh,kh,Nh,Lh,Mh,Oh,_h,Hh,jh,qh,r0,Gh,Yh,Jh,Kh,zh,Wh,Xh,Zh,$h,zd,e0,Kf,n0,o0]},Qgt=kgt;var oH={};Kt(oH,{default:()=>Tgt});Ye();var kt={optional:!0},rH=[["@tailwindcss/aspect-ratio@<0.2.1",{peerDependencies:{tailwindcss:"^2.0.2"}}],["@tailwindcss/line-clamp@<0.2.1",{peerDependencies:{tailwindcss:"^2.0.2"}}],["@fullhuman/postcss-purgecss@3.1.3 || 3.1.3-alpha.0",{peerDependencies:{postcss:"^8.0.0"}}],["@samverschueren/stream-to-observable@<0.3.1",{peerDependenciesMeta:{rxjs:kt,zenObservable:kt}}],["any-observable@<0.5.1",{peerDependenciesMeta:{rxjs:kt,zenObservable:kt}}],["@pm2/agent@<1.0.4",{dependencies:{debug:"*"}}],["debug@<4.2.0",{peerDependenciesMeta:{["supports-color"]:kt}}],["got@<11",{dependencies:{["@types/responselike"]:"^1.0.0",["@types/keyv"]:"^3.1.1"}}],["cacheable-lookup@<4.1.2",{dependencies:{["@types/keyv"]:"^3.1.1"}}],["http-link-dataloader@*",{peerDependencies:{graphql:"^0.13.1 || ^14.0.0"}}],["typescript-language-server@*",{dependencies:{["vscode-jsonrpc"]:"^5.0.1",["vscode-languageserver-protocol"]:"^3.15.0"}}],["postcss-syntax@*",{peerDependenciesMeta:{["postcss-html"]:kt,["postcss-jsx"]:kt,["postcss-less"]:kt,["postcss-markdown"]:kt,["postcss-scss"]:kt}}],["jss-plugin-rule-value-function@<=10.1.1",{dependencies:{["tiny-warning"]:"^1.0.2"}}],["ink-select-input@<4.1.0",{peerDependencies:{react:"^16.8.2"}}],["license-webpack-plugin@<2.3.18",{peerDependenciesMeta:{webpack:kt}}],["snowpack@>=3.3.0",{dependencies:{["node-gyp"]:"^7.1.0"}}],["promise-inflight@*",{peerDependenciesMeta:{bluebird:kt}}],["reactcss@*",{peerDependencies:{react:"*"}}],["react-color@<=2.19.0",{peerDependencies:{react:"*"}}],["gatsby-plugin-i18n@*",{dependencies:{ramda:"^0.24.1"}}],["useragent@^2.0.0",{dependencies:{request:"^2.88.0",yamlparser:"0.0.x",semver:"5.5.x"}}],["@apollographql/apollo-tools@<=0.5.2",{peerDependencies:{graphql:"^14.2.1 || ^15.0.0"}}],["material-table@^2.0.0",{dependencies:{"@babel/runtime":"^7.11.2"}}],["@babel/parser@*",{dependencies:{"@babel/types":"^7.8.3"}}],["fork-ts-checker-webpack-plugin@<=6.3.4",{peerDependencies:{eslint:">= 6",typescript:">= 2.7",webpack:">= 4","vue-template-compiler":"*"},peerDependenciesMeta:{eslint:kt,"vue-template-compiler":kt}}],["rc-animate@<=3.1.1",{peerDependencies:{react:">=16.9.0","react-dom":">=16.9.0"}}],["react-bootstrap-table2-paginator@*",{dependencies:{classnames:"^2.2.6"}}],["react-draggable@<=4.4.3",{peerDependencies:{react:">= 16.3.0","react-dom":">= 16.3.0"}}],["apollo-upload-client@<14",{peerDependencies:{graphql:"14 - 15"}}],["react-instantsearch-core@<=6.7.0",{peerDependencies:{algoliasearch:">= 3.1 < 5"}}],["react-instantsearch-dom@<=6.7.0",{dependencies:{"react-fast-compare":"^3.0.0"}}],["ws@<7.2.1",{peerDependencies:{bufferutil:"^4.0.1","utf-8-validate":"^5.0.2"},peerDependenciesMeta:{bufferutil:kt,"utf-8-validate":kt}}],["react-portal@<4.2.2",{peerDependencies:{"react-dom":"^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0"}}],["react-scripts@<=4.0.1",{peerDependencies:{react:"*"}}],["testcafe@<=1.10.1",{dependencies:{"@babel/plugin-transform-for-of":"^7.12.1","@babel/runtime":"^7.12.5"}}],["testcafe-legacy-api@<=4.2.0",{dependencies:{"testcafe-hammerhead":"^17.0.1","read-file-relative":"^1.2.0"}}],["@google-cloud/firestore@<=4.9.3",{dependencies:{protobufjs:"^6.8.6"}}],["gatsby-source-apiserver@*",{dependencies:{["babel-polyfill"]:"^6.26.0"}}],["@webpack-cli/package-utils@<=1.0.1-alpha.4",{dependencies:{["cross-spawn"]:"^7.0.3"}}],["gatsby-remark-prismjs@<3.3.28",{dependencies:{lodash:"^4"}}],["gatsby-plugin-favicon@*",{peerDependencies:{webpack:"*"}}],["gatsby-plugin-sharp@<=4.6.0-next.3",{dependencies:{debug:"^4.3.1"}}],["gatsby-react-router-scroll@<=5.6.0-next.0",{dependencies:{["prop-types"]:"^15.7.2"}}],["@rebass/forms@*",{dependencies:{["@styled-system/should-forward-prop"]:"^5.0.0"},peerDependencies:{react:"^16.8.6"}}],["rebass@*",{peerDependencies:{react:"^16.8.6"}}],["@ant-design/react-slick@<=0.28.3",{peerDependencies:{react:">=16.0.0"}}],["mqtt@<4.2.7",{dependencies:{duplexify:"^4.1.1"}}],["vue-cli-plugin-vuetify@<=2.0.3",{dependencies:{semver:"^6.3.0"},peerDependenciesMeta:{"sass-loader":kt,"vuetify-loader":kt}}],["vue-cli-plugin-vuetify@<=2.0.4",{dependencies:{"null-loader":"^3.0.0"}}],["vue-cli-plugin-vuetify@>=2.4.3",{peerDependencies:{vue:"*"}}],["@vuetify/cli-plugin-utils@<=0.0.4",{dependencies:{semver:"^6.3.0"},peerDependenciesMeta:{"sass-loader":kt}}],["@vue/cli-plugin-typescript@<=5.0.0-alpha.0",{dependencies:{"babel-loader":"^8.1.0"}}],["@vue/cli-plugin-typescript@<=5.0.0-beta.0",{dependencies:{"@babel/core":"^7.12.16"},peerDependencies:{"vue-template-compiler":"^2.0.0"},peerDependenciesMeta:{"vue-template-compiler":kt}}],["cordova-ios@<=6.3.0",{dependencies:{underscore:"^1.9.2"}}],["cordova-lib@<=10.0.1",{dependencies:{underscore:"^1.9.2"}}],["git-node-fs@*",{peerDependencies:{"js-git":"^0.7.8"},peerDependenciesMeta:{"js-git":kt}}],["consolidate@<0.16.0",{peerDependencies:{mustache:"^3.0.0"},peerDependenciesMeta:{mustache:kt}}],["consolidate@<=0.16.0",{peerDependencies:{velocityjs:"^2.0.1",tinyliquid:"^0.2.34","liquid-node":"^3.0.1",jade:"^1.11.0","then-jade":"*",dust:"^0.3.0","dustjs-helpers":"^1.7.4","dustjs-linkedin":"^2.7.5",swig:"^1.4.2","swig-templates":"^2.0.3","razor-tmpl":"^1.3.1",atpl:">=0.7.6",liquor:"^0.0.5",twig:"^1.15.2",ejs:"^3.1.5",eco:"^1.1.0-rc-3",jazz:"^0.0.18",jqtpl:"~1.1.0",hamljs:"^0.6.2",hamlet:"^0.3.3",whiskers:"^0.4.0","haml-coffee":"^1.14.1","hogan.js":"^3.0.2",templayed:">=0.2.3",handlebars:"^4.7.6",underscore:"^1.11.0",lodash:"^4.17.20",pug:"^3.0.0","then-pug":"*",qejs:"^3.0.5",walrus:"^0.10.1",mustache:"^4.0.1",just:"^0.1.8",ect:"^0.5.9",mote:"^0.2.0",toffee:"^0.3.6",dot:"^1.1.3","bracket-template":"^1.1.5",ractive:"^1.3.12",nunjucks:"^3.2.2",htmling:"^0.0.8","babel-core":"^6.26.3",plates:"~0.4.11","react-dom":"^16.13.1",react:"^16.13.1","arc-templates":"^0.5.3",vash:"^0.13.0",slm:"^2.0.0",marko:"^3.14.4",teacup:"^2.0.0","coffee-script":"^1.12.7",squirrelly:"^5.1.0",twing:"^5.0.2"},peerDependenciesMeta:{velocityjs:kt,tinyliquid:kt,"liquid-node":kt,jade:kt,"then-jade":kt,dust:kt,"dustjs-helpers":kt,"dustjs-linkedin":kt,swig:kt,"swig-templates":kt,"razor-tmpl":kt,atpl:kt,liquor:kt,twig:kt,ejs:kt,eco:kt,jazz:kt,jqtpl:kt,hamljs:kt,hamlet:kt,whiskers:kt,"haml-coffee":kt,"hogan.js":kt,templayed:kt,handlebars:kt,underscore:kt,lodash:kt,pug:kt,"then-pug":kt,qejs:kt,walrus:kt,mustache:kt,just:kt,ect:kt,mote:kt,toffee:kt,dot:kt,"bracket-template":kt,ractive:kt,nunjucks:kt,htmling:kt,"babel-core":kt,plates:kt,"react-dom":kt,react:kt,"arc-templates":kt,vash:kt,slm:kt,marko:kt,teacup:kt,"coffee-script":kt,squirrelly:kt,twing:kt}}],["vue-loader@<=16.3.3",{peerDependencies:{"@vue/compiler-sfc":"^3.0.8",webpack:"^4.1.0 || ^5.0.0-0"},peerDependenciesMeta:{"@vue/compiler-sfc":kt}}],["vue-loader@^16.7.0",{peerDependencies:{"@vue/compiler-sfc":"^3.0.8",vue:"^3.2.13"},peerDependenciesMeta:{"@vue/compiler-sfc":kt,vue:kt}}],["scss-parser@<=1.0.5",{dependencies:{lodash:"^4.17.21"}}],["query-ast@<1.0.5",{dependencies:{lodash:"^4.17.21"}}],["redux-thunk@<=2.3.0",{peerDependencies:{redux:"^4.0.0"}}],["skypack@<=0.3.2",{dependencies:{tar:"^6.1.0"}}],["@npmcli/metavuln-calculator@<2.0.0",{dependencies:{"json-parse-even-better-errors":"^2.3.1"}}],["bin-links@<2.3.0",{dependencies:{"mkdirp-infer-owner":"^1.0.2"}}],["rollup-plugin-polyfill-node@<=0.8.0",{peerDependencies:{rollup:"^1.20.0 || ^2.0.0"}}],["snowpack@<3.8.6",{dependencies:{"magic-string":"^0.25.7"}}],["elm-webpack-loader@*",{dependencies:{temp:"^0.9.4"}}],["winston-transport@<=4.4.0",{dependencies:{logform:"^2.2.0"}}],["jest-vue-preprocessor@*",{dependencies:{"@babel/core":"7.8.7","@babel/template":"7.8.6"},peerDependencies:{pug:"^2.0.4"},peerDependenciesMeta:{pug:kt}}],["redux-persist@*",{peerDependencies:{react:">=16"},peerDependenciesMeta:{react:kt}}],["sodium@>=3",{dependencies:{"node-gyp":"^3.8.0"}}],["babel-plugin-graphql-tag@<=3.1.0",{peerDependencies:{graphql:"^14.0.0 || ^15.0.0"}}],["@playwright/test@<=1.14.1",{dependencies:{"jest-matcher-utils":"^26.4.2"}}],...["babel-plugin-remove-graphql-queries@<3.14.0-next.1","babel-preset-gatsby-package@<1.14.0-next.1","create-gatsby@<1.14.0-next.1","gatsby-admin@<0.24.0-next.1","gatsby-cli@<3.14.0-next.1","gatsby-core-utils@<2.14.0-next.1","gatsby-design-tokens@<3.14.0-next.1","gatsby-legacy-polyfills@<1.14.0-next.1","gatsby-plugin-benchmark-reporting@<1.14.0-next.1","gatsby-plugin-graphql-config@<0.23.0-next.1","gatsby-plugin-image@<1.14.0-next.1","gatsby-plugin-mdx@<2.14.0-next.1","gatsby-plugin-netlify-cms@<5.14.0-next.1","gatsby-plugin-no-sourcemaps@<3.14.0-next.1","gatsby-plugin-page-creator@<3.14.0-next.1","gatsby-plugin-preact@<5.14.0-next.1","gatsby-plugin-preload-fonts@<2.14.0-next.1","gatsby-plugin-schema-snapshot@<2.14.0-next.1","gatsby-plugin-styletron@<6.14.0-next.1","gatsby-plugin-subfont@<3.14.0-next.1","gatsby-plugin-utils@<1.14.0-next.1","gatsby-recipes@<0.25.0-next.1","gatsby-source-shopify@<5.6.0-next.1","gatsby-source-wikipedia@<3.14.0-next.1","gatsby-transformer-screenshot@<3.14.0-next.1","gatsby-worker@<0.5.0-next.1"].map(t=>[t,{dependencies:{"@babel/runtime":"^7.14.8"}}]),["gatsby-core-utils@<2.14.0-next.1",{dependencies:{got:"8.3.2"}}],["gatsby-plugin-gatsby-cloud@<=3.1.0-next.0",{dependencies:{"gatsby-core-utils":"^2.13.0-next.0"}}],["gatsby-plugin-gatsby-cloud@<=3.2.0-next.1",{peerDependencies:{webpack:"*"}}],["babel-plugin-remove-graphql-queries@<=3.14.0-next.1",{dependencies:{"gatsby-core-utils":"^2.8.0-next.1"}}],["gatsby-plugin-netlify@3.13.0-next.1",{dependencies:{"gatsby-core-utils":"^2.13.0-next.0"}}],["clipanion-v3-codemod@<=0.2.0",{peerDependencies:{jscodeshift:"^0.11.0"}}],["react-live@*",{peerDependencies:{"react-dom":"*",react:"*"}}],["webpack@<4.44.1",{peerDependenciesMeta:{"webpack-cli":kt,"webpack-command":kt}}],["webpack@<5.0.0-beta.23",{peerDependenciesMeta:{"webpack-cli":kt}}],["webpack-dev-server@<3.10.2",{peerDependenciesMeta:{"webpack-cli":kt}}],["@docusaurus/responsive-loader@<1.5.0",{peerDependenciesMeta:{sharp:kt,jimp:kt}}],["eslint-module-utils@*",{peerDependenciesMeta:{"eslint-import-resolver-node":kt,"eslint-import-resolver-typescript":kt,"eslint-import-resolver-webpack":kt,"@typescript-eslint/parser":kt}}],["eslint-plugin-import@*",{peerDependenciesMeta:{"@typescript-eslint/parser":kt}}],["critters-webpack-plugin@<3.0.2",{peerDependenciesMeta:{"html-webpack-plugin":kt}}],["terser@<=5.10.0",{dependencies:{acorn:"^8.5.0"}}],["babel-preset-react-app@10.0.x",{dependencies:{"@babel/plugin-proposal-private-property-in-object":"^7.16.0"}}],["eslint-config-react-app@*",{peerDependenciesMeta:{typescript:kt}}],["@vue/eslint-config-typescript@<11.0.0",{peerDependenciesMeta:{typescript:kt}}],["unplugin-vue2-script-setup@<0.9.1",{peerDependencies:{"@vue/composition-api":"^1.4.3","@vue/runtime-dom":"^3.2.26"}}],["@cypress/snapshot@*",{dependencies:{debug:"^3.2.7"}}],["auto-relay@<=0.14.0",{peerDependencies:{"reflect-metadata":"^0.1.13"}}],["vue-template-babel-compiler@<1.2.0",{peerDependencies:{["vue-template-compiler"]:"^2.6.0"}}],["@parcel/transformer-image@<2.5.0",{peerDependencies:{["@parcel/core"]:"*"}}],["@parcel/transformer-js@<2.5.0",{peerDependencies:{["@parcel/core"]:"*"}}],["parcel@*",{peerDependenciesMeta:{["@parcel/core"]:kt}}],["react-scripts@*",{peerDependencies:{eslint:"*"}}],["focus-trap-react@^8.0.0",{dependencies:{tabbable:"^5.3.2"}}],["react-rnd@<10.3.7",{peerDependencies:{react:">=16.3.0","react-dom":">=16.3.0"}}],["connect-mongo@*",{peerDependencies:{"express-session":"^1.17.1"}}],["vue-i18n@<9",{peerDependencies:{vue:"^2"}}],["vue-router@<4",{peerDependencies:{vue:"^2"}}],["unified@<10",{dependencies:{"@types/unist":"^2.0.0"}}],["react-github-btn@<=1.3.0",{peerDependencies:{react:">=16.3.0"}}],["react-dev-utils@*",{peerDependencies:{typescript:">=2.7",webpack:">=4"},peerDependenciesMeta:{typescript:kt}}],["@asyncapi/react-component@<=1.0.0-next.39",{peerDependencies:{react:">=16.8.0","react-dom":">=16.8.0"}}],["xo@*",{peerDependencies:{webpack:">=1.11.0"},peerDependenciesMeta:{webpack:kt}}],["babel-plugin-remove-graphql-queries@<=4.20.0-next.0",{dependencies:{"@babel/types":"^7.15.4"}}],["gatsby-plugin-page-creator@<=4.20.0-next.1",{dependencies:{"fs-extra":"^10.1.0"}}],["gatsby-plugin-utils@<=3.14.0-next.1",{dependencies:{fastq:"^1.13.0"},peerDependencies:{graphql:"^15.0.0"}}],["gatsby-plugin-mdx@<3.1.0-next.1",{dependencies:{mkdirp:"^1.0.4"}}],["gatsby-plugin-mdx@^2",{peerDependencies:{gatsby:"^3.0.0-next"}}],["fdir@<=5.2.0",{peerDependencies:{picomatch:"2.x"},peerDependenciesMeta:{picomatch:kt}}],["babel-plugin-transform-typescript-metadata@<=0.3.2",{peerDependencies:{"@babel/core":"^7","@babel/traverse":"^7"},peerDependenciesMeta:{"@babel/traverse":kt}}],["graphql-compose@>=9.0.10",{peerDependencies:{graphql:"^14.2.0 || ^15.0.0 || ^16.0.0"}}]];var nH;function Rde(){return typeof nH>"u"&&(nH=Be("zlib").brotliDecompressSync(Buffer.from("G7weAByFTVk3Vs7UfHhq4yykgEM7pbW7TI43SG2S5tvGrwHBAzdz+s/npQ6tgEvobvxisrPIadkXeUAJotBn5bDZ5kAhcRqsIHe3F75Walet5hNalwgFDtxb0BiDUjiUQkjG0yW2hto9HPgiCkm316d6bC0kST72YN7D7rfkhCE9x4J0XwB0yavalxpUu2t9xszHrmtwalOxT7VslsxWcB1qpqZwERUra4psWhTV8BgwWeizurec82Caf1ABL11YMfbf8FJ9JBceZOkgmvrQPbC9DUldX/yMbmX06UQluCEjSwUoyO+EZPIjofr+/oAZUck2enraRD+oWLlnlYnj8xB+gwSo9lmmks4fXv574qSqcWA6z21uYkzMu3EWj+K23RxeQlLqiE35/rC8GcS4CGkKHKKq+zAIQwD9iRDNfiAqueLLpicFFrNsAI4zeTD/eO9MHcnRa5m8UT+M2+V+AkFST4BlKneiAQRSdST8KEAIyFlULt6wa9EBd0Ds28VmpaxquJdVt+nwdEs5xUskI13OVtFyY0UrQIRAlCuvvWivvlSKQfTO+2Q8OyUR1W5RvetaPz4jD27hdtwHFFA1Ptx6Ee/t2cY2rg2G46M1pNDRf2pWhvpy8pqMnuI3++4OF3+7OFIWXGjh+o7Nr2jNvbiYcQdQS1h903/jVFgOpA0yJ78z+x759bFA0rq+6aY5qPB4FzS3oYoLupDUhD9nDz6F6H7hpnlMf18KNKDu4IKjTWwrAnY6MFQw1W6ymOALHlFyCZmQhldg1MQHaMVVQTVgDC60TfaBqG++Y8PEoFhN/PBTZT175KNP/BlHDYGOOBmnBdzqJKplZ/ljiVG0ZBzfqeBRrrUkn6rA54462SgiliKoYVnbeptMdXNfAuaupIEi0bApF10TlgHfmEJAPUVidRVFyDupSem5po5vErPqWKhKbUIp0LozpYsIKK57dM/HKr+nguF+7924IIWMICkQ8JUigs9D+W+c4LnNoRtPPKNRUiCYmP+Jfo2lfKCKw8qpraEeWU3uiNRO6zcyKQoXPR5htmzzLznke7b4YbXW3I1lIRzmgG02Udb58U+7TpwyN7XymCgH+wuPDthZVQvRZuEP+SnLtMicz9m5zASWOBiAcLmkuFlTKuHspSIhCBD0yUPKcxu81A+4YD78rA2vtwsUEday9WNyrShyrl60rWmA+SmbYZkQOwFJWArxRYYc5jGhA5ikxYw1rx3ei4NmeX/lKiwpZ9Ln1tV2Ae7sArvxuVLbJjqJRjW1vFXAyHpvLG+8MJ6T2Ubx5M2KDa2SN6vuIGxJ9WQM9Mk3Q7aCNiZONXllhqq24DmoLbQfW2rYWsOgHWjtOmIQMyMKdiHZDjoyIq5+U700nZ6odJAoYXPQBvFNiQ78d5jaXliBqLTJEqUCwi+LiH2mx92EmNKDsJL74Z613+3lf20pxkV1+erOrjj8pW00vsPaahKUM+05ssd5uwM7K482KWEf3TCwlg/o3e5ngto7qSMz7YteIgCsF1UOcsLk7F7MxWbvrPMY473ew0G+noVL8EPbkmEMftMSeL6HFub/zy+2JQ==","base64")).toString()),nH}var iH;function Nde(){return typeof iH>"u"&&(iH=Be("zlib").brotliDecompressSync(Buffer.from("G8MSIIzURnVBnObTcvb3XE6v2S9Qgc2K801Oa5otNKEtK8BINZNcaQHy+9/vf/WXBimwutXC33P2DPc64pps5rz7NGGWaOKNSPL4Y2KRE8twut2lFOIN+OXPtRmPMRhMTILib2bEQx43az2I5d3YS8Roa5UZpF/ujHb3Djd3GDvYUfvFYSUQ39vb2cmifp/rgB4J/65JK3wRBTvMBoNBmn3mbXC63/gbBkW/2IRPri0O8bcsRBsmarF328pAln04nyJFkwUAvNu934supAqLtyerZZpJ8I8suJHhf/ocMV+scKwa8NOiDKIPXw6Ex/EEZD6TEGaW8N5zvNHYF10l6Lfooj7D5W2k3dgvQSbp2Wv8TGOayS978gxlOLVjTGXs66ozewbrjwElLtyrYNnWTfzzdEutgROUFPVMhnMoy8EjJLLlWwIEoySxliim9kYW30JUHiPVyjt0iAw/ZpPmCbUCltYPnq6ZNblIKhTNhqS/oqC9iya5sGKZTOVsTEg34n92uZTf2iPpcZih8rPW8CzA+adIGmyCPcKdLMsBLShd+zuEbTrqpwuh+DLmracZcjPC5Sdf5odDAhKpFuOsQS67RT+1VgWWygSv3YwxDnylc04/PYuaMeIzhBkLrvs7e/OUzRTF56MmfY6rI63QtEjEQzq637zQqJ39nNhu3NmoRRhW/086bHGBUtx0PE0j3aEGvkdh9WJC8y8j8mqqke9/dQ5la+Q3ba4RlhvTbnfQhPDDab3tUifkjKuOsp13mXEmO00Mu88F/M67R7LXfoFDFLNtgCSWjWX+3Jn1371pJTK9xPBiMJafvDjtFyAzu8rxeQ0TKMQXNPs5xxiBOd+BRJP8KP88XPtJIbZKh/cdW8KvBUkpqKpGoiIaA32c3/JnQr4efXt85mXvidOvn/eU3Pase1typLYBalJ14mCso9h79nuMOuCa/kZAOkJHmTjP5RM2WNoPasZUAnT1TAE/NH25hUxcQv6hQWR/m1PKk4ooXMcM4SR1iYU3fUohvqk4RY2hbmTVVIXv6TvqO+0doOjgeVFAcom+RlwJQmOVH7pr1Q9LoJT6n1DeQEB+NHygsATbIwTcOKZlJsY8G4+suX1uQLjUWwLjjs0mvSvZcLTpIGAekeR7GCgl8eo3ndAqEe2XCav4huliHjdbIPBsGJuPX7lrO9HX1UbXRH5opOe1x6JsOSgHZR+EaxuXVhpLLxm6jk1LJtZfHSc6BKPun3CpYYVMJGwEUyk8MTGG0XL5MfEwaXpnc9TKnBmlGn6nHiGREc3ysn47XIBDzA+YvFdjZzVIEDcKGpS6PbUJehFRjEne8D0lVU1XuRtlgszq6pTNlQ/3MzNOEgCWPyTct22V2mEi2krizn5VDo9B19/X2DB3hCGRMM7ONbtnAcIx/OWB1u5uPbW1gsH8irXxT/IzG0PoXWYjhbMsH3KTuoOl5o17PulcgvsfTSnKFM354GWI8luqZnrswWjiXy3G+Vbyo1KMopFmmvBwNELgaS8z8dNZchx/Cl/xjddxhMcyqtzFyONb2Zdu90NkI8pAeufe7YlXrp53v8Dj/l8vWeVspRKBGXScBBPI/HinSTGmLDOGGOCIyH0JFdOZx0gWsacNlQLJMIrBhqRxXxHF/5pseWwejlAAvZ3klZSDSYY8mkToaWejXhgNomeGtx1DTLEUFMRkgF5yFB22WYdJnaWN14r1YJj81hGi45+jrADS5nYRhCiSlCJJ1nL8pYX+HDSMhdTEWyRcgHVp/IsUIZYMfT+YYncUQPgcxNGCHfZ88vDdrcUuaGIl6zhAsiaq7R5dfqrqXH/JcBhfjT8D0azayIyEz75Nxp6YkcyDxlJq3EXnJUpqDohJJOysL1t1uNiHESlvsxPb5cpbW0+ICZqJmUZus1BMW0F5IVBODLIo2zHHjA0=","base64")).toString()),iH}var sH;function Lde(){return typeof sH>"u"&&(sH=Be("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),sH}var Mde=new Map([[W.makeIdent(null,"fsevents").identHash,Rde],[W.makeIdent(null,"resolve").identHash,Nde],[W.makeIdent(null,"typescript").identHash,Lde]]),Fgt={hooks:{registerPackageExtensions:async(t,e)=>{for(let[r,o]of rH)e(W.parseDescriptor(r,!0),o)},getBuiltinPatch:async(t,e)=>{let r="compat/";if(!e.startsWith(r))return;let o=W.parseIdent(e.slice(r.length)),a=Mde.get(o.identHash)?.();return typeof a<"u"?a:null},reduceDependency:async(t,e,r,o)=>typeof Mde.get(t.identHash)>"u"?t:W.makeDescriptor(t,W.makeRange({protocol:"patch:",source:W.stringifyDescriptor(t),selector:`optional!builtin<compat/${W.stringifyIdent(t)}>`,params:null}))}},Tgt=Fgt;var BH={};Kt(BH,{ConstraintsCheckCommand:()=>p0,ConstraintsQueryCommand:()=>A0,ConstraintsSourceCommand:()=>f0,default:()=>odt});Ye();Ye();B2();var wC=class{constructor(e){this.project=e}createEnvironment(){let e=new CC(["cwd","ident"]),r=new CC(["workspace","type","ident"]),o=new CC(["ident"]),a={manifestUpdates:new Map,reportedErrors:new Map},n=new Map,u=new Map;for(let A of this.project.storedPackages.values()){let p=Array.from(A.peerDependencies.values(),h=>[W.stringifyIdent(h),h.range]);n.set(A.locatorHash,{workspace:null,ident:W.stringifyIdent(A),version:A.version,dependencies:new Map,peerDependencies:new Map(p.filter(([h])=>A.peerDependenciesMeta.get(h)?.optional!==!0)),optionalPeerDependencies:new Map(p.filter(([h])=>A.peerDependenciesMeta.get(h)?.optional===!0))})}for(let A of this.project.storedPackages.values()){let p=n.get(A.locatorHash);p.dependencies=new Map(Array.from(A.dependencies.values(),h=>{let E=this.project.storedResolutions.get(h.descriptorHash);if(typeof E>"u")throw new Error("Assertion failed: The resolution should have been registered");let I=n.get(E);if(typeof I>"u")throw new Error("Assertion failed: The package should have been registered");return[W.stringifyIdent(h),I]})),p.dependencies.delete(p.ident)}for(let A of this.project.workspaces){let p=W.stringifyIdent(A.anchoredLocator),h=A.manifest.exportTo({}),E=n.get(A.anchoredLocator.locatorHash);if(typeof E>"u")throw new Error("Assertion failed: The package should have been registered");let I=(T,L,{caller:U=Ji.getCaller()}={})=>{let J=I2(T),te=je.getMapWithDefault(a.manifestUpdates,A.cwd),le=je.getMapWithDefault(te,J),pe=je.getSetWithDefault(le,L);U!==null&&pe.add(U)},v=T=>I(T,void 0,{caller:Ji.getCaller()}),b=T=>{je.getArrayWithDefault(a.reportedErrors,A.cwd).push(T)},C=e.insert({cwd:A.relativeCwd,ident:p,manifest:h,pkg:E,set:I,unset:v,error:b});u.set(A,C);for(let T of Mt.allDependencies)for(let L of A.manifest[T].values()){let U=W.stringifyIdent(L),J=()=>{I([T,U],void 0,{caller:Ji.getCaller()})},te=pe=>{I([T,U],pe,{caller:Ji.getCaller()})},le=null;if(T!=="peerDependencies"&&(T!=="dependencies"||!A.manifest.devDependencies.has(L.identHash))){let pe=A.anchoredPackage.dependencies.get(L.identHash);if(pe){if(typeof pe>"u")throw new Error("Assertion failed: The dependency should have been registered");let Ae=this.project.storedResolutions.get(pe.descriptorHash);if(typeof Ae>"u")throw new Error("Assertion failed: The resolution should have been registered");let ye=n.get(Ae);if(typeof ye>"u")throw new Error("Assertion failed: The package should have been registered");le=ye}}r.insert({workspace:C,ident:U,range:L.range,type:T,resolution:le,update:te,delete:J,error:b})}}for(let A of this.project.storedPackages.values()){let p=this.project.tryWorkspaceByLocator(A);if(!p)continue;let h=u.get(p);if(typeof h>"u")throw new Error("Assertion failed: The workspace should have been registered");let E=n.get(A.locatorHash);if(typeof E>"u")throw new Error("Assertion failed: The package should have been registered");E.workspace=h}return{workspaces:e,dependencies:r,packages:o,result:a}}async process(){let e=this.createEnvironment(),r={Yarn:{workspace:a=>e.workspaces.find(a)[0]??null,workspaces:a=>e.workspaces.find(a),dependency:a=>e.dependencies.find(a)[0]??null,dependencies:a=>e.dependencies.find(a),package:a=>e.packages.find(a)[0]??null,packages:a=>e.packages.find(a)}},o=await this.project.loadUserConfig();return o?.constraints?(await o.constraints(r),e.result):null}};Ye();Ye();qt();var A0=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.query=ge.String()}async execute(){let{Constraints:r}=await Promise.resolve().then(()=>(x2(),S2)),o=await Ve.find(this.context.cwd,this.context.plugins),{project:a}=await St.find(o,this.context.cwd),n=await r.find(a),u=this.query;return u.endsWith(".")||(u=`${u}.`),(await Nt.start({configuration:o,json:this.json,stdout:this.context.stdout},async p=>{for await(let h of n.query(u)){let E=Array.from(Object.entries(h)),I=E.length,v=E.reduce((b,[C])=>Math.max(b,C.length),0);for(let b=0;b<I;b++){let[C,T]=E[b];p.reportInfo(null,`${idt(b,I)}${C.padEnd(v," ")} = ${ndt(T)}`)}p.reportJson(h)}})).exitCode()}};A0.paths=[["constraints","query"]],A0.usage=nt.Usage({category:"Constraints-related commands",description:"query the constraints fact database",details:` + This command will output all matches to the given prolog query. + `,examples:[["List all dependencies throughout the workspace","yarn constraints query 'workspace_has_dependency(_, DependencyName, _, _).'"]]});function ndt(t){return typeof t!="string"?`${t}`:t.match(/^[a-zA-Z][a-zA-Z0-9_]+$/)?t:`'${t}'`}function idt(t,e){let r=t===0,o=t===e-1;return r&&o?"":r?"\u250C ":o?"\u2514 ":"\u2502 "}Ye();qt();var f0=class extends ut{constructor(){super(...arguments);this.verbose=ge.Boolean("-v,--verbose",!1,{description:"Also print the fact database automatically compiled from the workspace manifests"})}async execute(){let{Constraints:r}=await Promise.resolve().then(()=>(x2(),S2)),o=await Ve.find(this.context.cwd,this.context.plugins),{project:a}=await St.find(o,this.context.cwd),n=await r.find(a);this.context.stdout.write(this.verbose?n.fullSource:n.source)}};f0.paths=[["constraints","source"]],f0.usage=nt.Usage({category:"Constraints-related commands",description:"print the source code for the constraints",details:"\n This command will print the Prolog source code used by the constraints engine. Adding the `-v,--verbose` flag will print the *full* source code, including the fact database automatically compiled from the workspace manifests.\n ",examples:[["Prints the source code","yarn constraints source"],["Print the source code and the fact database","yarn constraints source -v"]]});Ye();Ye();qt();B2();var p0=class extends ut{constructor(){super(...arguments);this.fix=ge.Boolean("--fix",!1,{description:"Attempt to automatically fix unambiguous issues, following a multi-pass process"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o}=await St.find(r,this.context.cwd);await o.restoreInstallState();let a=await o.loadUserConfig(),n;if(a?.constraints)n=new wC(o);else{let{Constraints:h}=await Promise.resolve().then(()=>(x2(),S2));n=await h.find(o)}let u,A=!1,p=!1;for(let h=this.fix?10:1;h>0;--h){let E=await n.process();if(!E)break;let{changedWorkspaces:I,remainingErrors:v}=mk(o,E,{fix:this.fix}),b=[];for(let[C,T]of I){let L=C.manifest.indent;C.manifest=new Mt,C.manifest.indent=L,C.manifest.load(T),b.push(C.persistManifest())}if(await Promise.all(b),!(I.size>0&&h>1)){u=Gde(v,{configuration:r}),A=!1,p=!0;for(let[,C]of v)for(let T of C)T.fixable?A=!0:p=!1}}if(u.children.length===0)return 0;if(A){let h=p?`Those errors can all be fixed by running ${de.pretty(r,"yarn constraints --fix",de.Type.CODE)}`:`Errors prefixed by '\u2699' can be fixed by running ${de.pretty(r,"yarn constraints --fix",de.Type.CODE)}`;await Nt.start({configuration:r,stdout:this.context.stdout,includeNames:!1,includeFooter:!1},async E=>{E.reportInfo(0,h),E.reportSeparator()})}return u.children=je.sortMap(u.children,h=>h.value[1]),$s.emitTree(u,{configuration:r,stdout:this.context.stdout,json:this.json,separators:1}),1}};p0.paths=[["constraints"]],p0.usage=nt.Usage({category:"Constraints-related commands",description:"check that the project constraints are met",details:` + This command will run constraints on your project and emit errors for each one that is found but isn't met. If any error is emitted the process will exit with a non-zero exit code. + + If the \`--fix\` flag is used, Yarn will attempt to automatically fix the issues the best it can, following a multi-pass process (with a maximum of 10 iterations). Some ambiguous patterns cannot be autofixed, in which case you'll have to manually specify the right resolution. + + For more information as to how to write constraints, please consult our dedicated page on our website: https://yarnpkg.com/features/constraints. + `,examples:[["Check that all constraints are satisfied","yarn constraints"],["Autofix all unmet constraints","yarn constraints --fix"]]});B2();var sdt={configuration:{enableConstraintsChecks:{description:"If true, constraints will run during installs",type:"BOOLEAN",default:!1},constraintsPath:{description:"The path of the constraints file.",type:"ABSOLUTE_PATH",default:"./constraints.pro"}},commands:[A0,f0,p0],hooks:{async validateProjectAfterInstall(t,{reportError:e}){if(!t.configuration.get("enableConstraintsChecks"))return;let r=await t.loadUserConfig(),o;if(r?.constraints)o=new wC(t);else{let{Constraints:u}=await Promise.resolve().then(()=>(x2(),S2));o=await u.find(t)}let a=await o.process();if(!a)return;let{remainingErrors:n}=mk(t,a);if(n.size!==0)if(t.configuration.isCI)for(let[u,A]of n)for(let p of A)e(84,`${de.pretty(t.configuration,u.anchoredLocator,de.Type.IDENT)}: ${p.text}`);else e(84,`Constraint check failed; run ${de.pretty(t.configuration,"yarn constraints",de.Type.CODE)} for more details`)}}},odt=sdt;var vH={};Kt(vH,{CreateCommand:()=>em,DlxCommand:()=>h0,default:()=>ldt});Ye();qt();var em=class extends ut{constructor(){super(...arguments);this.pkg=ge.String("-p,--package",{description:"The package to run the provided command from"});this.quiet=ge.Boolean("-q,--quiet",!1,{description:"Only report critical errors instead of printing the full install logs"});this.command=ge.String();this.args=ge.Proxy()}async execute(){let r=[];this.pkg&&r.push("--package",this.pkg),this.quiet&&r.push("--quiet");let o=this.command.replace(/^(@[^@/]+)(@|$)/,"$1/create$2"),a=W.parseDescriptor(o),n=a.name.match(/^create(-|$)/)?a:a.scope?W.makeIdent(a.scope,`create-${a.name}`):W.makeIdent(null,`create-${a.name}`),u=W.stringifyIdent(n);return a.range!=="unknown"&&(u+=`@${a.range}`),this.cli.run(["dlx",...r,u,...this.args])}};em.paths=[["create"]];Ye();Ye();Pt();qt();var h0=class extends ut{constructor(){super(...arguments);this.packages=ge.Array("-p,--package",{description:"The package(s) to install before running the command"});this.quiet=ge.Boolean("-q,--quiet",!1,{description:"Only report critical errors instead of printing the full install logs"});this.command=ge.String();this.args=ge.Proxy()}async execute(){return Ve.telemetry=null,await oe.mktempPromise(async r=>{let o=K.join(r,`dlx-${process.pid}`);await oe.mkdirPromise(o),await oe.writeFilePromise(K.join(o,"package.json"),`{} +`),await oe.writeFilePromise(K.join(o,"yarn.lock"),"");let a=K.join(o,".yarnrc.yml"),n=await Ve.findProjectCwd(this.context.cwd),A={enableGlobalCache:!(await Ve.find(this.context.cwd,null,{strict:!1})).get("enableGlobalCache"),enableTelemetry:!1,logFilters:[{code:Wu(68),level:de.LogLevel.Discard}]},p=n!==null?K.join(n,".yarnrc.yml"):null;p!==null&&oe.existsSync(p)?(await oe.copyFilePromise(p,a),await Ve.updateConfiguration(o,L=>{let U=je.toMerged(L,A);return Array.isArray(L.plugins)&&(U.plugins=L.plugins.map(J=>{let te=typeof J=="string"?J:J.path,le=ue.isAbsolute(te)?te:ue.resolve(ue.fromPortablePath(n),te);return typeof J=="string"?le:{path:le,spec:J.spec}})),U})):await oe.writeJsonPromise(a,A);let h=this.packages??[this.command],E=W.parseDescriptor(this.command).name,I=await this.cli.run(["add","--fixed","--",...h],{cwd:o,quiet:this.quiet});if(I!==0)return I;this.quiet||this.context.stdout.write(` +`);let v=await Ve.find(o,this.context.plugins),{project:b,workspace:C}=await St.find(v,o);if(C===null)throw new rr(b.cwd,o);await b.restoreInstallState();let T=await un.getWorkspaceAccessibleBinaries(C);return T.has(E)===!1&&T.size===1&&typeof this.packages>"u"&&(E=Array.from(T)[0][0]),await un.executeWorkspaceAccessibleBinary(C,E,this.args,{packageAccessibleBinaries:T,cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})})}};h0.paths=[["dlx"]],h0.usage=nt.Usage({description:"run a package in a temporary environment",details:"\n This command will install a package within a temporary environment, and run its binary script if it contains any. The binary will run within the current cwd.\n\n By default Yarn will download the package named `command`, but this can be changed through the use of the `-p,--package` flag which will instruct Yarn to still run the same command but from a different package.\n\n Using `yarn dlx` as a replacement of `yarn add` isn't recommended, as it makes your project non-deterministic (Yarn doesn't keep track of the packages installed through `dlx` - neither their name, nor their version).\n ",examples:[["Use create-react-app to create a new React app","yarn dlx create-react-app ./my-app"],["Install multiple packages for a single command",`yarn dlx -p typescript -p ts-node ts-node --transpile-only -e "console.log('hello!')"`]]});var adt={commands:[em,h0]},ldt=adt;var SH={};Kt(SH,{ExecFetcher:()=>k2,ExecResolver:()=>Q2,default:()=>Adt,execUtils:()=>wk});Ye();Ye();Pt();var fA="exec:";var wk={};Kt(wk,{loadGeneratorFile:()=>b2,makeLocator:()=>PH,makeSpec:()=>dme,parseSpec:()=>DH});Ye();Pt();function DH(t){let{params:e,selector:r}=W.parseRange(t),o=ue.toPortablePath(r);return{parentLocator:e&&typeof e.locator=="string"?W.parseLocator(e.locator):null,path:o}}function dme({parentLocator:t,path:e,generatorHash:r,protocol:o}){let a=t!==null?{locator:W.stringifyLocator(t)}:{},n=typeof r<"u"?{hash:r}:{};return W.makeRange({protocol:o,source:e,selector:e,params:{...n,...a}})}function PH(t,{parentLocator:e,path:r,generatorHash:o,protocol:a}){return W.makeLocator(t,dme({parentLocator:e,path:r,generatorHash:o,protocol:a}))}async function b2(t,e,r){let{parentLocator:o,path:a}=W.parseFileStyleRange(t,{protocol:e}),n=K.isAbsolute(a)?{packageFs:new gn(Bt.root),prefixPath:Bt.dot,localPath:Bt.root}:await r.fetcher.fetch(o,r),u=n.localPath?{packageFs:new gn(Bt.root),prefixPath:K.relative(Bt.root,n.localPath)}:n;n!==u&&n.releaseFs&&n.releaseFs();let A=u.packageFs,p=K.join(u.prefixPath,a);return await A.readFilePromise(p,"utf8")}var k2=class{supports(e,r){return!!e.reference.startsWith(fA)}getLocalPath(e,r){let{parentLocator:o,path:a}=W.parseFileStyleRange(e.reference,{protocol:fA});if(K.isAbsolute(a))return a;let n=r.fetcher.getLocalPath(o,r);return n===null?null:K.resolve(n,a)}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e),loader:()=>this.fetchFromDisk(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:W.getIdentVendorPath(e),localPath:this.getLocalPath(e,r),checksum:u}}async fetchFromDisk(e,r){let o=await b2(e.reference,fA,r);return oe.mktempPromise(async a=>{let n=K.join(a,"generator.js");return await oe.writeFilePromise(n,o),oe.mktempPromise(async u=>{if(await this.generatePackage(u,e,n,r),!oe.existsSync(K.join(u,"build")))throw new Error("The script should have generated a build directory");return await Xi.makeArchiveFromDirectory(K.join(u,"build"),{prefixPath:W.getIdentVendorPath(e),compressionLevel:r.project.configuration.get("compressionLevel")})})})}async generatePackage(e,r,o,a){return await oe.mktempPromise(async n=>{let u=await un.makeScriptEnv({project:a.project,binFolder:n}),A=K.join(e,"runtime.js");return await oe.mktempPromise(async p=>{let h=K.join(p,"buildfile.log"),E=K.join(e,"generator"),I=K.join(e,"build");await oe.mkdirPromise(E),await oe.mkdirPromise(I);let v={tempDir:ue.fromPortablePath(E),buildDir:ue.fromPortablePath(I),locator:W.stringifyLocator(r)};await oe.writeFilePromise(A,` + // Expose 'Module' as a global variable + Object.defineProperty(global, 'Module', { + get: () => require('module'), + configurable: true, + enumerable: false, + }); + + // Expose non-hidden built-in modules as global variables + for (const name of Module.builtinModules.filter((name) => name !== 'module' && !name.startsWith('_'))) { + Object.defineProperty(global, name, { + get: () => require(name), + configurable: true, + enumerable: false, + }); + } + + // Expose the 'execEnv' global variable + Object.defineProperty(global, 'execEnv', { + value: { + ...${JSON.stringify(v)}, + }, + enumerable: true, + }); + `);let b=u.NODE_OPTIONS||"",C=/\s*--require\s+\S*\.pnp\.c?js\s*/g;b=b.replace(C," ").trim(),u.NODE_OPTIONS=b;let{stdout:T,stderr:L}=a.project.configuration.getSubprocessStreams(h,{header:`# This file contains the result of Yarn generating a package (${W.stringifyLocator(r)}) +`,prefix:W.prettyLocator(a.project.configuration,r),report:a.report}),{code:U}=await Ur.pipevp(process.execPath,["--require",ue.fromPortablePath(A),ue.fromPortablePath(o),W.stringifyIdent(r)],{cwd:e,env:u,stdin:null,stdout:T,stderr:L});if(U!==0)throw oe.detachTemp(p),new Error(`Package generation failed (exit code ${U}, logs can be found here: ${de.pretty(a.project.configuration,h,de.Type.PATH)})`)})})}};Ye();Ye();var cdt=2,Q2=class{supportsDescriptor(e,r){return!!e.range.startsWith(fA)}supportsLocator(e,r){return!!e.reference.startsWith(fA)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){return W.bindDescriptor(e,{locator:W.stringifyLocator(r)})}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){if(!o.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{path:a,parentLocator:n}=DH(e.range);if(n===null)throw new Error("Assertion failed: The descriptor should have been bound");let u=await b2(W.makeRange({protocol:fA,source:a,selector:a,params:{locator:W.stringifyLocator(n)}}),fA,o.fetchOptions),A=wn.makeHash(`${cdt}`,u).slice(0,6);return[PH(e,{parentLocator:n,path:a,generatorHash:A,protocol:fA})]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let o=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),a=await je.releaseAfterUseAsync(async()=>await Mt.find(o.prefixPath,{baseFs:o.packageFs}),o.releaseFs);return{...e,version:a.version||"0.0.0",languageName:a.languageName||r.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:a.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(a.dependencies),peerDependencies:a.peerDependencies,dependenciesMeta:a.dependenciesMeta,peerDependenciesMeta:a.peerDependenciesMeta,bin:a.bin}}};var udt={fetchers:[k2],resolvers:[Q2]},Adt=udt;var bH={};Kt(bH,{FileFetcher:()=>N2,FileResolver:()=>L2,TarballFileFetcher:()=>M2,TarballFileResolver:()=>O2,default:()=>hdt,fileUtils:()=>tm});Ye();Pt();var DC=/^(?:[a-zA-Z]:[\\/]|\.{0,2}\/)/,F2=/^[^?]*\.(?:tar\.gz|tgz)(?:::.*)?$/,Ui="file:";var tm={};Kt(tm,{fetchArchiveFromLocator:()=>R2,makeArchiveFromLocator:()=>Ik,makeBufferFromLocator:()=>xH,makeLocator:()=>PC,makeSpec:()=>mme,parseSpec:()=>T2});Ye();Pt();function T2(t){let{params:e,selector:r}=W.parseRange(t),o=ue.toPortablePath(r);return{parentLocator:e&&typeof e.locator=="string"?W.parseLocator(e.locator):null,path:o}}function mme({parentLocator:t,path:e,hash:r,protocol:o}){let a=t!==null?{locator:W.stringifyLocator(t)}:{},n=typeof r<"u"?{hash:r}:{};return W.makeRange({protocol:o,source:e,selector:e,params:{...n,...a}})}function PC(t,{parentLocator:e,path:r,hash:o,protocol:a}){return W.makeLocator(t,mme({parentLocator:e,path:r,hash:o,protocol:a}))}async function R2(t,e){let{parentLocator:r,path:o}=W.parseFileStyleRange(t.reference,{protocol:Ui}),a=K.isAbsolute(o)?{packageFs:new gn(Bt.root),prefixPath:Bt.dot,localPath:Bt.root}:await e.fetcher.fetch(r,e),n=a.localPath?{packageFs:new gn(Bt.root),prefixPath:K.relative(Bt.root,a.localPath)}:a;a!==n&&a.releaseFs&&a.releaseFs();let u=n.packageFs,A=K.join(n.prefixPath,o);return await je.releaseAfterUseAsync(async()=>await u.readFilePromise(A),n.releaseFs)}async function Ik(t,{protocol:e,fetchOptions:r,inMemory:o=!1}){let{parentLocator:a,path:n}=W.parseFileStyleRange(t.reference,{protocol:e}),u=K.isAbsolute(n)?{packageFs:new gn(Bt.root),prefixPath:Bt.dot,localPath:Bt.root}:await r.fetcher.fetch(a,r),A=u.localPath?{packageFs:new gn(Bt.root),prefixPath:K.relative(Bt.root,u.localPath)}:u;u!==A&&u.releaseFs&&u.releaseFs();let p=A.packageFs,h=K.join(A.prefixPath,n);return await je.releaseAfterUseAsync(async()=>await Xi.makeArchiveFromDirectory(h,{baseFs:p,prefixPath:W.getIdentVendorPath(t),compressionLevel:r.project.configuration.get("compressionLevel"),inMemory:o}),A.releaseFs)}async function xH(t,{protocol:e,fetchOptions:r}){return(await Ik(t,{protocol:e,fetchOptions:r,inMemory:!0})).getBufferAndClose()}var N2=class{supports(e,r){return!!e.reference.startsWith(Ui)}getLocalPath(e,r){let{parentLocator:o,path:a}=W.parseFileStyleRange(e.reference,{protocol:Ui});if(K.isAbsolute(a))return a;let n=r.fetcher.getLocalPath(o,r);return n===null?null:K.resolve(n,a)}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${W.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.fetchFromDisk(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:W.getIdentVendorPath(e),localPath:this.getLocalPath(e,r),checksum:u}}async fetchFromDisk(e,r){return Ik(e,{protocol:Ui,fetchOptions:r})}};Ye();Ye();var fdt=2,L2=class{supportsDescriptor(e,r){return e.range.match(DC)?!0:!!e.range.startsWith(Ui)}supportsLocator(e,r){return!!e.reference.startsWith(Ui)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){return DC.test(e.range)&&(e=W.makeDescriptor(e,`${Ui}${e.range}`)),W.bindDescriptor(e,{locator:W.stringifyLocator(r)})}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){if(!o.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{path:a,parentLocator:n}=T2(e.range);if(n===null)throw new Error("Assertion failed: The descriptor should have been bound");let u=await xH(W.makeLocator(e,W.makeRange({protocol:Ui,source:a,selector:a,params:{locator:W.stringifyLocator(n)}})),{protocol:Ui,fetchOptions:o.fetchOptions}),A=wn.makeHash(`${fdt}`,u).slice(0,6);return[PC(e,{parentLocator:n,path:a,hash:A,protocol:Ui})]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let o=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),a=await je.releaseAfterUseAsync(async()=>await Mt.find(o.prefixPath,{baseFs:o.packageFs}),o.releaseFs);return{...e,version:a.version||"0.0.0",languageName:a.languageName||r.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:a.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(a.dependencies),peerDependencies:a.peerDependencies,dependenciesMeta:a.dependenciesMeta,peerDependenciesMeta:a.peerDependenciesMeta,bin:a.bin}}};Ye();var M2=class{supports(e,r){return F2.test(e.reference)?!!e.reference.startsWith(Ui):!1}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${W.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.fetchFromDisk(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:W.getIdentVendorPath(e),checksum:u}}async fetchFromDisk(e,r){let o=await R2(e,r);return await Xi.convertToZip(o,{configuration:r.project.configuration,prefixPath:W.getIdentVendorPath(e),stripComponents:1})}};Ye();Ye();Ye();var O2=class{supportsDescriptor(e,r){return F2.test(e.range)?!!(e.range.startsWith(Ui)||DC.test(e.range)):!1}supportsLocator(e,r){return F2.test(e.reference)?!!e.reference.startsWith(Ui):!1}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){return DC.test(e.range)&&(e=W.makeDescriptor(e,`${Ui}${e.range}`)),W.bindDescriptor(e,{locator:W.stringifyLocator(r)})}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){if(!o.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{path:a,parentLocator:n}=T2(e.range);if(n===null)throw new Error("Assertion failed: The descriptor should have been bound");let u=PC(e,{parentLocator:n,path:a,hash:"",protocol:Ui}),A=await R2(u,o.fetchOptions),p=wn.makeHash(A).slice(0,6);return[PC(e,{parentLocator:n,path:a,hash:p,protocol:Ui})]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let o=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),a=await je.releaseAfterUseAsync(async()=>await Mt.find(o.prefixPath,{baseFs:o.packageFs}),o.releaseFs);return{...e,version:a.version||"0.0.0",languageName:a.languageName||r.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:a.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(a.dependencies),peerDependencies:a.peerDependencies,dependenciesMeta:a.dependenciesMeta,peerDependenciesMeta:a.peerDependenciesMeta,bin:a.bin}}};var pdt={fetchers:[M2,N2],resolvers:[O2,L2]},hdt=pdt;var FH={};Kt(FH,{GithubFetcher:()=>U2,default:()=>ddt,githubUtils:()=>Bk});Ye();Pt();var Bk={};Kt(Bk,{invalidGithubUrlMessage:()=>Cme,isGithubUrl:()=>kH,parseGithubUrl:()=>QH});var yme=$e(Be("querystring")),Eme=[/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+)\/tarball\/([^/#]+)(?:#(.*))?$/,/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+?)(?:\.git)?(?:#(.*))?$/];function kH(t){return t?Eme.some(e=>!!t.match(e)):!1}function QH(t){let e;for(let A of Eme)if(e=t.match(A),e)break;if(!e)throw new Error(Cme(t));let[,r,o,a,n="master"]=e,{commit:u}=yme.default.parse(n);return n=u||n.replace(/[^:]*:/,""),{auth:r,username:o,reponame:a,treeish:n}}function Cme(t){return`Input cannot be parsed as a valid GitHub URL ('${t}').`}var U2=class{supports(e,r){return!!kH(e.reference)}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${W.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from GitHub`),loader:()=>this.fetchFromNetwork(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:W.getIdentVendorPath(e),checksum:u}}async fetchFromNetwork(e,r){let o=await rn.get(this.getLocatorUrl(e,r),{configuration:r.project.configuration});return await oe.mktempPromise(async a=>{let n=new gn(a);await Xi.extractArchiveTo(o,n,{stripComponents:1});let u=ra.splitRepoUrl(e.reference),A=K.join(a,"package.tgz");await un.prepareExternalProject(a,A,{configuration:r.project.configuration,report:r.report,workspace:u.extra.workspace,locator:e});let p=await oe.readFilePromise(A);return await Xi.convertToZip(p,{configuration:r.project.configuration,prefixPath:W.getIdentVendorPath(e),stripComponents:1})})}getLocatorUrl(e,r){let{auth:o,username:a,reponame:n,treeish:u}=QH(e.reference);return`https://${o?`${o}@`:""}github.com/${a}/${n}/archive/${u}.tar.gz`}};var gdt={hooks:{async fetchHostedRepository(t,e,r){if(t!==null)return t;let o=new U2;if(!o.supports(e,r))return null;try{return await o.fetch(e,r)}catch{return null}}}},ddt=gdt;var TH={};Kt(TH,{TarballHttpFetcher:()=>H2,TarballHttpResolver:()=>j2,default:()=>ydt});Ye();function _2(t){let e;try{e=new URL(t)}catch{return!1}return!(e.protocol!=="http:"&&e.protocol!=="https:"||!e.pathname.match(/(\.tar\.gz|\.tgz|\/[^.]+)$/))}var H2=class{supports(e,r){return _2(e.reference)}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${W.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the remote server`),loader:()=>this.fetchFromNetwork(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:W.getIdentVendorPath(e),checksum:u}}async fetchFromNetwork(e,r){let o=await rn.get(e.reference,{configuration:r.project.configuration});return await Xi.convertToZip(o,{configuration:r.project.configuration,prefixPath:W.getIdentVendorPath(e),stripComponents:1})}};Ye();Ye();var j2=class{supportsDescriptor(e,r){return _2(e.range)}supportsLocator(e,r){return _2(e.reference)}shouldPersistResolution(e,r){return!0}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){return[W.convertDescriptorToLocator(e)]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let o=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),a=await je.releaseAfterUseAsync(async()=>await Mt.find(o.prefixPath,{baseFs:o.packageFs}),o.releaseFs);return{...e,version:a.version||"0.0.0",languageName:a.languageName||r.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:a.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(a.dependencies),peerDependencies:a.peerDependencies,dependenciesMeta:a.dependenciesMeta,peerDependenciesMeta:a.peerDependenciesMeta,bin:a.bin}}};var mdt={fetchers:[H2],resolvers:[j2]},ydt=mdt;var RH={};Kt(RH,{InitCommand:()=>g0,default:()=>Cdt});Ye();Ye();Pt();qt();var g0=class extends ut{constructor(){super(...arguments);this.private=ge.Boolean("-p,--private",!1,{description:"Initialize a private package"});this.workspace=ge.Boolean("-w,--workspace",!1,{description:"Initialize a workspace root with a `packages/` directory"});this.install=ge.String("-i,--install",!1,{tolerateBoolean:!0,description:"Initialize a package with a specific bundle that will be locked in the project"});this.name=ge.String("-n,--name",{description:"Initialize a package with the given name"});this.usev2=ge.Boolean("-2",!1,{hidden:!0});this.yes=ge.Boolean("-y,--yes",{hidden:!0})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),o=typeof this.install=="string"?this.install:this.usev2||this.install===!0?"latest":null;return o!==null?await this.executeProxy(r,o):await this.executeRegular(r)}async executeProxy(r,o){if(r.projectCwd!==null&&r.projectCwd!==this.context.cwd)throw new it("Cannot use the --install flag from within a project subdirectory");oe.existsSync(this.context.cwd)||await oe.mkdirPromise(this.context.cwd,{recursive:!0});let a=K.join(this.context.cwd,dr.lockfile);oe.existsSync(a)||await oe.writeFilePromise(a,"");let n=await this.cli.run(["set","version",o],{quiet:!0});if(n!==0)return n;let u=[];return this.private&&u.push("-p"),this.workspace&&u.push("-w"),this.name&&u.push(`-n=${this.name}`),this.yes&&u.push("-y"),await oe.mktempPromise(async A=>{let{code:p}=await Ur.pipevp("yarn",["init",...u],{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,env:await un.makeScriptEnv({binFolder:A})});return p})}async executeRegular(r){let o=null;try{o=(await St.find(r,this.context.cwd)).project}catch{o=null}oe.existsSync(this.context.cwd)||await oe.mkdirPromise(this.context.cwd,{recursive:!0});let a=await Mt.tryFind(this.context.cwd),n=a??new Mt,u=Object.fromEntries(r.get("initFields").entries());n.load(u),n.name=n.name??W.makeIdent(r.get("initScope"),this.name??K.basename(this.context.cwd)),n.packageManager=tn&&je.isTaggedYarnVersion(tn)?`yarn@${tn}`:null,(!a&&this.workspace||this.private)&&(n.private=!0),this.workspace&&n.workspaceDefinitions.length===0&&(await oe.mkdirPromise(K.join(this.context.cwd,"packages"),{recursive:!0}),n.workspaceDefinitions=[{pattern:"packages/*"}]);let A={};n.exportTo(A);let p=K.join(this.context.cwd,Mt.fileName);await oe.changeFilePromise(p,`${JSON.stringify(A,null,2)} +`,{automaticNewlines:!0});let h=[p],E=K.join(this.context.cwd,"README.md");if(oe.existsSync(E)||(await oe.writeFilePromise(E,`# ${W.stringifyIdent(n.name)} +`),h.push(E)),!o||o.cwd===this.context.cwd){let I=K.join(this.context.cwd,dr.lockfile);oe.existsSync(I)||(await oe.writeFilePromise(I,""),h.push(I));let b=[".yarn/*","!.yarn/patches","!.yarn/plugins","!.yarn/releases","!.yarn/sdks","!.yarn/versions","","# Swap the comments on the following lines if you wish to use zero-installs","# In that case, don't forget to run `yarn config set enableGlobalCache false`!","# Documentation here: https://yarnpkg.com/features/caching#zero-installs","","#!.yarn/cache",".pnp.*"].map(pe=>`${pe} +`).join(""),C=K.join(this.context.cwd,".gitignore");oe.existsSync(C)||(await oe.writeFilePromise(C,b),h.push(C));let L=["/.yarn/** linguist-vendored","/.yarn/releases/* binary","/.yarn/plugins/**/* binary","/.pnp.* binary linguist-generated"].map(pe=>`${pe} +`).join(""),U=K.join(this.context.cwd,".gitattributes");oe.existsSync(U)||(await oe.writeFilePromise(U,L),h.push(U));let J={["*"]:{endOfLine:"lf",insertFinalNewline:!0},["*.{js,json,yml}"]:{charset:"utf-8",indentStyle:"space",indentSize:2}};je.mergeIntoTarget(J,r.get("initEditorConfig"));let te=`root = true +`;for(let[pe,Ae]of Object.entries(J)){te+=` +[${pe}] +`;for(let[ye,ae]of Object.entries(Ae)){let we=ye.replace(/[A-Z]/g,Pe=>`_${Pe.toLowerCase()}`);te+=`${we} = ${ae} +`}}let le=K.join(this.context.cwd,".editorconfig");oe.existsSync(le)||(await oe.writeFilePromise(le,te),h.push(le)),await this.cli.run(["install"],{quiet:!0}),oe.existsSync(K.join(this.context.cwd,".git"))||(await Ur.execvp("git",["init"],{cwd:this.context.cwd}),await Ur.execvp("git",["add","--",...h],{cwd:this.context.cwd}),await Ur.execvp("git",["commit","--allow-empty","-m","First commit"],{cwd:this.context.cwd}))}}};g0.paths=[["init"]],g0.usage=nt.Usage({description:"create a new package",details:"\n This command will setup a new package in your local directory.\n\n If the `-p,--private` or `-w,--workspace` options are set, the package will be private by default.\n\n If the `-w,--workspace` option is set, the package will be configured to accept a set of workspaces in the `packages/` directory.\n\n If the `-i,--install` option is given a value, Yarn will first download it using `yarn set version` and only then forward the init call to the newly downloaded bundle. Without arguments, the downloaded bundle will be `latest`.\n\n The initial settings of the manifest can be changed by using the `initScope` and `initFields` configuration values. Additionally, Yarn will generate an EditorConfig file whose rules can be altered via `initEditorConfig`, and will initialize a Git repository in the current directory.\n ",examples:[["Create a new package in the local directory","yarn init"],["Create a new private package in the local directory","yarn init -p"],["Create a new package and store the Yarn release inside","yarn init -i=latest"],["Create a new private package and defines it as a workspace root","yarn init -w"]]});var Edt={configuration:{initScope:{description:"Scope used when creating packages via the init command",type:"STRING",default:null},initFields:{description:"Additional fields to set when creating packages via the init command",type:"MAP",valueDefinition:{description:"",type:"ANY"}},initEditorConfig:{description:"Extra rules to define in the generator editorconfig",type:"MAP",valueDefinition:{description:"",type:"ANY"}}},commands:[g0]},Cdt=Edt;var Lj={};Kt(Lj,{SearchCommand:()=>C0,UpgradeInteractiveCommand:()=>I0,default:()=>lIt});Ye();var Ime=$e(Be("os"));function SC({stdout:t}){if(Ime.default.endianness()==="BE")throw new Error("Interactive commands cannot be used on big-endian systems because ink depends on yoga-layout-prebuilt which only supports little-endian architectures");if(!t.isTTY)throw new Error("Interactive commands can only be used inside a TTY environment")}qt();var Rye=$e(ZH()),$H={appId:"OFCNCOG2CU",apiKey:"6fe4476ee5a1832882e326b506d14126",indexName:"npm-search"},myt=(0,Rye.default)($H.appId,$H.apiKey).initIndex($H.indexName),e6=async(t,e=0)=>await myt.search(t,{analyticsTags:["yarn-plugin-interactive-tools"],attributesToRetrieve:["name","version","owner","repository","humanDownloadsLast30Days"],page:e,hitsPerPage:10});var HB=["regular","dev","peer"],C0=class extends ut{async execute(){SC(this.context);let{Gem:e}=await Promise.resolve().then(()=>(AQ(),Dj)),{ScrollableItems:r}=await Promise.resolve().then(()=>(gQ(),hQ)),{useKeypress:o}=await Promise.resolve().then(()=>(OB(),Jwe)),{useMinistore:a}=await Promise.resolve().then(()=>(Qj(),kj)),{renderForm:n}=await Promise.resolve().then(()=>(EQ(),yQ)),{default:u}=await Promise.resolve().then(()=>$e(sIe())),{Box:A,Text:p}=await Promise.resolve().then(()=>$e(ic())),{default:h,useEffect:E,useState:I}=await Promise.resolve().then(()=>$e(sn())),v=await Ve.find(this.context.cwd,this.context.plugins),b=()=>h.createElement(A,{flexDirection:"row"},h.createElement(A,{flexDirection:"column",width:48},h.createElement(A,null,h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"<up>"),"/",h.createElement(p,{bold:!0,color:"cyanBright"},"<down>")," to move between packages.")),h.createElement(A,null,h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"<space>")," to select a package.")),h.createElement(A,null,h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"<space>")," again to change the target."))),h.createElement(A,{flexDirection:"column"},h.createElement(A,{marginLeft:1},h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"<enter>")," to install the selected packages.")),h.createElement(A,{marginLeft:1},h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"<ctrl+c>")," to abort.")))),C=()=>h.createElement(h.Fragment,null,h.createElement(A,{width:15},h.createElement(p,{bold:!0,underline:!0,color:"gray"},"Owner")),h.createElement(A,{width:11},h.createElement(p,{bold:!0,underline:!0,color:"gray"},"Version")),h.createElement(A,{width:10},h.createElement(p,{bold:!0,underline:!0,color:"gray"},"Downloads"))),T=()=>h.createElement(A,{width:17},h.createElement(p,{bold:!0,underline:!0,color:"gray"},"Target")),L=({hit:ae,active:we})=>{let[Pe,g]=a(ae.name,null);o({active:we},(ce,ne)=>{if(ne.name!=="space")return;if(!Pe){g(HB[0]);return}let ee=HB.indexOf(Pe)+1;ee===HB.length?g(null):g(HB[ee])},[Pe,g]);let Ee=W.parseIdent(ae.name),De=W.prettyIdent(v,Ee);return h.createElement(A,null,h.createElement(A,{width:45},h.createElement(p,{bold:!0,wrap:"wrap"},De)),h.createElement(A,{width:14,marginLeft:1},h.createElement(p,{bold:!0,wrap:"truncate"},ae.owner.name)),h.createElement(A,{width:10,marginLeft:1},h.createElement(p,{italic:!0,wrap:"truncate"},ae.version)),h.createElement(A,{width:16,marginLeft:1},h.createElement(p,null,ae.humanDownloadsLast30Days)))},U=({name:ae,active:we})=>{let[Pe]=a(ae,null),g=W.parseIdent(ae);return h.createElement(A,null,h.createElement(A,{width:47},h.createElement(p,{bold:!0}," - ",W.prettyIdent(v,g))),HB.map(Ee=>h.createElement(A,{key:Ee,width:14,marginLeft:1},h.createElement(p,null," ",h.createElement(e,{active:Pe===Ee})," ",h.createElement(p,{bold:!0},Ee)))))},J=()=>h.createElement(A,{marginTop:1},h.createElement(p,null,"Powered by Algolia.")),le=await n(({useSubmit:ae})=>{let we=a();ae(we);let Pe=Array.from(we.keys()).filter(H=>we.get(H)!==null),[g,Ee]=I(""),[De,ce]=I(0),[ne,ee]=I([]),Ie=H=>{H.match(/\t| /)||Ee(H)},ke=async()=>{ce(0);let H=await e6(g);H.query===g&&ee(H.hits)},ht=async()=>{let H=await e6(g,De+1);H.query===g&&H.page-1===De&&(ce(H.page),ee([...ne,...H.hits]))};return E(()=>{g?ke():ee([])},[g]),h.createElement(A,{flexDirection:"column"},h.createElement(b,null),h.createElement(A,{flexDirection:"row",marginTop:1},h.createElement(p,{bold:!0},"Search: "),h.createElement(A,{width:41},h.createElement(u,{value:g,onChange:Ie,placeholder:"i.e. babel, webpack, react...",showCursor:!1})),h.createElement(C,null)),ne.length?h.createElement(r,{radius:2,loop:!1,children:ne.map(H=>h.createElement(L,{key:H.name,hit:H,active:!1})),willReachEnd:ht}):h.createElement(p,{color:"gray"},"Start typing..."),h.createElement(A,{flexDirection:"row",marginTop:1},h.createElement(A,{width:49},h.createElement(p,{bold:!0},"Selected:")),h.createElement(T,null)),Pe.length?Pe.map(H=>h.createElement(U,{key:H,name:H,active:!1})):h.createElement(p,{color:"gray"},"No selected packages..."),h.createElement(J,null))},{},{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});if(typeof le>"u")return 1;let pe=Array.from(le.keys()).filter(ae=>le.get(ae)==="regular"),Ae=Array.from(le.keys()).filter(ae=>le.get(ae)==="dev"),ye=Array.from(le.keys()).filter(ae=>le.get(ae)==="peer");return pe.length&&await this.cli.run(["add",...pe]),Ae.length&&await this.cli.run(["add","--dev",...Ae]),ye&&await this.cli.run(["add","--peer",...ye]),0}};C0.paths=[["search"]],C0.usage=nt.Usage({category:"Interactive commands",description:"open the search interface",details:` + This command opens a fullscreen terminal interface where you can search for and install packages from the npm registry. + `,examples:[["Open the search window","yarn search"]]});Ye();qt();w_();var fIe=$e(zn()),AIe=/^((?:[\^~]|>=?)?)([0-9]+)(\.[0-9]+)(\.[0-9]+)((?:-\S+)?)$/,pIe=(t,e)=>t.length>0?[t.slice(0,e)].concat(pIe(t.slice(e),e)):[],I0=class extends ut{async execute(){SC(this.context);let{ItemOptions:e}=await Promise.resolve().then(()=>(uIe(),cIe)),{Pad:r}=await Promise.resolve().then(()=>(Nj(),lIe)),{ScrollableItems:o}=await Promise.resolve().then(()=>(gQ(),hQ)),{useMinistore:a}=await Promise.resolve().then(()=>(Qj(),kj)),{renderForm:n}=await Promise.resolve().then(()=>(EQ(),yQ)),{Box:u,Text:A}=await Promise.resolve().then(()=>$e(ic())),{default:p,useEffect:h,useRef:E,useState:I}=await Promise.resolve().then(()=>$e(sn())),v=await Ve.find(this.context.cwd,this.context.plugins),{project:b,workspace:C}=await St.find(v,this.context.cwd),T=await Lr.find(v);if(!C)throw new rr(b.cwd,this.context.cwd);await b.restoreInstallState({restoreResolutions:!1});let L=this.context.stdout.rows-7,U=(Ee,De)=>{let ce=fpe(Ee,De),ne="";for(let ee of ce)ee.added?ne+=de.pretty(v,ee.value,"green"):ee.removed||(ne+=ee.value);return ne},J=(Ee,De)=>{if(Ee===De)return De;let ce=W.parseRange(Ee),ne=W.parseRange(De),ee=ce.selector.match(AIe),Ie=ne.selector.match(AIe);if(!ee||!Ie)return U(Ee,De);let ke=["gray","red","yellow","green","magenta"],ht=null,H="";for(let lt=1;lt<ke.length;++lt)ht!==null||ee[lt]!==Ie[lt]?(ht===null&&(ht=ke[lt-1]),H+=de.pretty(v,Ie[lt],ht)):H+=Ie[lt];return H},te=async(Ee,De,ce)=>{let ne=await zc.fetchDescriptorFrom(Ee,ce,{project:b,cache:T,preserveModifier:De,workspace:C});return ne!==null?ne.range:Ee.range},le=async Ee=>{let De=fIe.default.valid(Ee.range)?`^${Ee.range}`:Ee.range,[ce,ne]=await Promise.all([te(Ee,Ee.range,De).catch(()=>null),te(Ee,Ee.range,"latest").catch(()=>null)]),ee=[{value:null,label:Ee.range}];return ce&&ce!==Ee.range?ee.push({value:ce,label:J(Ee.range,ce)}):ee.push({value:null,label:""}),ne&&ne!==ce&&ne!==Ee.range?ee.push({value:ne,label:J(Ee.range,ne)}):ee.push({value:null,label:""}),ee},pe=()=>p.createElement(u,{flexDirection:"row"},p.createElement(u,{flexDirection:"column",width:49},p.createElement(u,{marginLeft:1},p.createElement(A,null,"Press ",p.createElement(A,{bold:!0,color:"cyanBright"},"<up>"),"/",p.createElement(A,{bold:!0,color:"cyanBright"},"<down>")," to select packages.")),p.createElement(u,{marginLeft:1},p.createElement(A,null,"Press ",p.createElement(A,{bold:!0,color:"cyanBright"},"<left>"),"/",p.createElement(A,{bold:!0,color:"cyanBright"},"<right>")," to select versions."))),p.createElement(u,{flexDirection:"column"},p.createElement(u,{marginLeft:1},p.createElement(A,null,"Press ",p.createElement(A,{bold:!0,color:"cyanBright"},"<enter>")," to install.")),p.createElement(u,{marginLeft:1},p.createElement(A,null,"Press ",p.createElement(A,{bold:!0,color:"cyanBright"},"<ctrl+c>")," to abort.")))),Ae=()=>p.createElement(u,{flexDirection:"row",paddingTop:1,paddingBottom:1},p.createElement(u,{width:50},p.createElement(A,{bold:!0},p.createElement(A,{color:"greenBright"},"?")," Pick the packages you want to upgrade.")),p.createElement(u,{width:17},p.createElement(A,{bold:!0,underline:!0,color:"gray"},"Current")),p.createElement(u,{width:17},p.createElement(A,{bold:!0,underline:!0,color:"gray"},"Range")),p.createElement(u,{width:17},p.createElement(A,{bold:!0,underline:!0,color:"gray"},"Latest"))),ye=({active:Ee,descriptor:De,suggestions:ce})=>{let[ne,ee]=a(De.descriptorHash,null),Ie=W.stringifyIdent(De),ke=Math.max(0,45-Ie.length);return p.createElement(p.Fragment,null,p.createElement(u,null,p.createElement(u,{width:45},p.createElement(A,{bold:!0},W.prettyIdent(v,De)),p.createElement(r,{active:Ee,length:ke})),p.createElement(e,{active:Ee,options:ce,value:ne,skewer:!0,onChange:ee,sizes:[17,17,17]})))},ae=({dependencies:Ee})=>{let[De,ce]=I(Ee.map(()=>null)),ne=E(!0),ee=async Ie=>{let ke=await le(Ie);return ke.filter(ht=>ht.label!=="").length<=1?null:{descriptor:Ie,suggestions:ke}};return h(()=>()=>{ne.current=!1},[]),h(()=>{let Ie=Math.trunc(L*1.75),ke=Ee.slice(0,Ie),ht=Ee.slice(Ie),H=pIe(ht,L),lt=ke.map(ee).reduce(async(Re,Qe)=>{await Re;let be=await Qe;be!==null&&(!ne.current||ce(_e=>{let Te=_e.findIndex(He=>He===null),Je=[..._e];return Je[Te]=be,Je}))},Promise.resolve());H.reduce((Re,Qe)=>Promise.all(Qe.map(be=>Promise.resolve().then(()=>ee(be)))).then(async be=>{be=be.filter(_e=>_e!==null),await Re,ne.current&&ce(_e=>{let Te=_e.findIndex(Je=>Je===null);return _e.slice(0,Te).concat(be).concat(_e.slice(Te+be.length))})}),lt).then(()=>{ne.current&&ce(Re=>Re.filter(Qe=>Qe!==null))})},[]),De.length?p.createElement(o,{radius:L>>1,children:De.map((Ie,ke)=>Ie!==null?p.createElement(ye,{key:ke,active:!1,descriptor:Ie.descriptor,suggestions:Ie.suggestions}):p.createElement(A,{key:ke},"Loading..."))}):p.createElement(A,null,"No upgrades found")},Pe=await n(({useSubmit:Ee})=>{Ee(a());let De=new Map;for(let ne of b.workspaces)for(let ee of["dependencies","devDependencies"])for(let Ie of ne.manifest[ee].values())b.tryWorkspaceByDescriptor(Ie)===null&&(Ie.range.startsWith("link:")||De.set(Ie.descriptorHash,Ie));let ce=je.sortMap(De.values(),ne=>W.stringifyDescriptor(ne));return p.createElement(u,{flexDirection:"column"},p.createElement(pe,null),p.createElement(Ae,null),p.createElement(ae,{dependencies:ce}))},{},{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});if(typeof Pe>"u")return 1;let g=!1;for(let Ee of b.workspaces)for(let De of["dependencies","devDependencies"]){let ce=Ee.manifest[De];for(let ne of ce.values()){let ee=Pe.get(ne.descriptorHash);typeof ee<"u"&&ee!==null&&(ce.set(ne.identHash,W.makeDescriptor(ne,ee)),g=!0)}}return g?await b.installWithNewReport({quiet:this.context.quiet,stdout:this.context.stdout},{cache:T}):0}};I0.paths=[["upgrade-interactive"]],I0.usage=nt.Usage({category:"Interactive commands",description:"open the upgrade interface",details:` + This command opens a fullscreen terminal interface where you can see any out of date packages used by your application, their status compared to the latest versions available on the remote registry, and select packages to upgrade. + `,examples:[["Open the upgrade window","yarn upgrade-interactive"]]});var aIt={commands:[C0,I0]},lIt=aIt;var Mj={};Kt(Mj,{LinkFetcher:()=>qB,LinkResolver:()=>GB,PortalFetcher:()=>YB,PortalResolver:()=>WB,default:()=>uIt});Ye();Pt();var ep="portal:",tp="link:";var qB=class{supports(e,r){return!!e.reference.startsWith(tp)}getLocalPath(e,r){let{parentLocator:o,path:a}=W.parseFileStyleRange(e.reference,{protocol:tp});if(K.isAbsolute(a))return a;let n=r.fetcher.getLocalPath(o,r);return n===null?null:K.resolve(n,a)}async fetch(e,r){let{parentLocator:o,path:a}=W.parseFileStyleRange(e.reference,{protocol:tp}),n=K.isAbsolute(a)?{packageFs:new gn(Bt.root),prefixPath:Bt.dot,localPath:Bt.root}:await r.fetcher.fetch(o,r),u=n.localPath?{packageFs:new gn(Bt.root),prefixPath:K.relative(Bt.root,n.localPath),localPath:Bt.root}:n;n!==u&&n.releaseFs&&n.releaseFs();let A=u.packageFs,p=K.resolve(u.localPath??u.packageFs.getRealPath(),u.prefixPath,a);return n.localPath?{packageFs:new gn(p,{baseFs:A}),releaseFs:u.releaseFs,prefixPath:Bt.dot,discardFromLookup:!0,localPath:p}:{packageFs:new _u(p,{baseFs:A}),releaseFs:u.releaseFs,prefixPath:Bt.dot,discardFromLookup:!0}}};Ye();Pt();var GB=class{supportsDescriptor(e,r){return!!e.range.startsWith(tp)}supportsLocator(e,r){return!!e.reference.startsWith(tp)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){return W.bindDescriptor(e,{locator:W.stringifyLocator(r)})}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){let a=e.range.slice(tp.length);return[W.makeLocator(e,`${tp}${ue.toPortablePath(a)}`)]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){return{...e,version:"0.0.0",languageName:r.project.configuration.get("defaultLanguageName"),linkType:"SOFT",conditions:null,dependencies:new Map,peerDependencies:new Map,dependenciesMeta:new Map,peerDependenciesMeta:new Map,bin:new Map}}};Ye();Pt();var YB=class{supports(e,r){return!!e.reference.startsWith(ep)}getLocalPath(e,r){let{parentLocator:o,path:a}=W.parseFileStyleRange(e.reference,{protocol:ep});if(K.isAbsolute(a))return a;let n=r.fetcher.getLocalPath(o,r);return n===null?null:K.resolve(n,a)}async fetch(e,r){let{parentLocator:o,path:a}=W.parseFileStyleRange(e.reference,{protocol:ep}),n=K.isAbsolute(a)?{packageFs:new gn(Bt.root),prefixPath:Bt.dot,localPath:Bt.root}:await r.fetcher.fetch(o,r),u=n.localPath?{packageFs:new gn(Bt.root),prefixPath:K.relative(Bt.root,n.localPath),localPath:Bt.root}:n;n!==u&&n.releaseFs&&n.releaseFs();let A=u.packageFs,p=K.resolve(u.localPath??u.packageFs.getRealPath(),u.prefixPath,a);return n.localPath?{packageFs:new gn(p,{baseFs:A}),releaseFs:u.releaseFs,prefixPath:Bt.dot,localPath:p}:{packageFs:new _u(p,{baseFs:A}),releaseFs:u.releaseFs,prefixPath:Bt.dot}}};Ye();Ye();Pt();var WB=class{supportsDescriptor(e,r){return!!e.range.startsWith(ep)}supportsLocator(e,r){return!!e.reference.startsWith(ep)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){return W.bindDescriptor(e,{locator:W.stringifyLocator(r)})}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){let a=e.range.slice(ep.length);return[W.makeLocator(e,`${ep}${ue.toPortablePath(a)}`)]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){if(!r.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let o=await r.fetchOptions.fetcher.fetch(e,r.fetchOptions),a=await je.releaseAfterUseAsync(async()=>await Mt.find(o.prefixPath,{baseFs:o.packageFs}),o.releaseFs);return{...e,version:a.version||"0.0.0",languageName:a.languageName||r.project.configuration.get("defaultLanguageName"),linkType:"SOFT",conditions:a.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(a.dependencies),peerDependencies:a.peerDependencies,dependenciesMeta:a.dependenciesMeta,peerDependenciesMeta:a.peerDependenciesMeta,bin:a.bin}}};var cIt={fetchers:[qB,YB],resolvers:[GB,WB]},uIt=cIt;var Cq={};Kt(Cq,{NodeModulesLinker:()=>lv,NodeModulesMode:()=>dq,PnpLooseLinker:()=>cv,default:()=>P1t});Pt();Ye();Pt();Pt();var Uj=(t,e)=>`${t}@${e}`,hIe=(t,e)=>{let r=e.indexOf("#"),o=r>=0?e.substring(r+1):e;return Uj(t,o)};var mIe=(t,e={})=>{let r=e.debugLevel||Number(process.env.NM_DEBUG_LEVEL||-1),o=e.check||r>=9,a=e.hoistingLimits||new Map,n={check:o,debugLevel:r,hoistingLimits:a,fastLookupPossible:!0},u;n.debugLevel>=0&&(u=Date.now());let A=mIt(t,n),p=!1,h=0;do p=_j(A,[A],new Set([A.locator]),new Map,n).anotherRoundNeeded,n.fastLookupPossible=!1,h++;while(p);if(n.debugLevel>=0&&console.log(`hoist time: ${Date.now()-u}ms, rounds: ${h}`),n.debugLevel>=1){let E=VB(A);if(_j(A,[A],new Set([A.locator]),new Map,n).isGraphChanged)throw new Error(`The hoisting result is not terminal, prev tree: +${E}, next tree: +${VB(A)}`);let v=yIe(A);if(v)throw new Error(`${v}, after hoisting finished: +${VB(A)}`)}return n.debugLevel>=2&&console.log(VB(A)),yIt(A)},AIt=t=>{let e=t[t.length-1],r=new Map,o=new Set,a=n=>{if(!o.has(n)){o.add(n);for(let u of n.hoistedDependencies.values())r.set(u.name,u);for(let u of n.dependencies.values())n.peerNames.has(u.name)||a(u)}};return a(e),r},fIt=t=>{let e=t[t.length-1],r=new Map,o=new Set,a=new Set,n=(u,A)=>{if(o.has(u))return;o.add(u);for(let h of u.hoistedDependencies.values())if(!A.has(h.name)){let E;for(let I of t)E=I.dependencies.get(h.name),E&&r.set(E.name,E)}let p=new Set;for(let h of u.dependencies.values())p.add(h.name);for(let h of u.dependencies.values())u.peerNames.has(h.name)||n(h,p)};return n(e,a),r},gIe=(t,e)=>{if(e.decoupled)return e;let{name:r,references:o,ident:a,locator:n,dependencies:u,originalDependencies:A,hoistedDependencies:p,peerNames:h,reasons:E,isHoistBorder:I,hoistPriority:v,dependencyKind:b,hoistedFrom:C,hoistedTo:T}=e,L={name:r,references:new Set(o),ident:a,locator:n,dependencies:new Map(u),originalDependencies:new Map(A),hoistedDependencies:new Map(p),peerNames:new Set(h),reasons:new Map(E),decoupled:!0,isHoistBorder:I,hoistPriority:v,dependencyKind:b,hoistedFrom:new Map(C),hoistedTo:new Map(T)},U=L.dependencies.get(r);return U&&U.ident==L.ident&&L.dependencies.set(r,L),t.dependencies.set(L.name,L),L},pIt=(t,e)=>{let r=new Map([[t.name,[t.ident]]]);for(let a of t.dependencies.values())t.peerNames.has(a.name)||r.set(a.name,[a.ident]);let o=Array.from(e.keys());o.sort((a,n)=>{let u=e.get(a),A=e.get(n);return A.hoistPriority!==u.hoistPriority?A.hoistPriority-u.hoistPriority:A.peerDependents.size!==u.peerDependents.size?A.peerDependents.size-u.peerDependents.size:A.dependents.size-u.dependents.size});for(let a of o){let n=a.substring(0,a.indexOf("@",1)),u=a.substring(n.length+1);if(!t.peerNames.has(n)){let A=r.get(n);A||(A=[],r.set(n,A)),A.indexOf(u)<0&&A.push(u)}}return r},Oj=t=>{let e=new Set,r=(o,a=new Set)=>{if(!a.has(o)){a.add(o);for(let n of o.peerNames)if(!t.peerNames.has(n)){let u=t.dependencies.get(n);u&&!e.has(u)&&r(u,a)}e.add(o)}};for(let o of t.dependencies.values())t.peerNames.has(o.name)||r(o);return e},_j=(t,e,r,o,a,n=new Set)=>{let u=e[e.length-1];if(n.has(u))return{anotherRoundNeeded:!1,isGraphChanged:!1};n.add(u);let A=EIt(u),p=pIt(u,A),h=t==u?new Map:a.fastLookupPossible?AIt(e):fIt(e),E,I=!1,v=!1,b=new Map(Array.from(p.entries()).map(([T,L])=>[T,L[0]])),C=new Map;do{let T=dIt(t,e,r,h,b,p,o,C,a);T.isGraphChanged&&(v=!0),T.anotherRoundNeeded&&(I=!0),E=!1;for(let[L,U]of p)U.length>1&&!u.dependencies.has(L)&&(b.delete(L),U.shift(),b.set(L,U[0]),E=!0)}while(E);for(let T of u.dependencies.values())if(!u.peerNames.has(T.name)&&!r.has(T.locator)){r.add(T.locator);let L=_j(t,[...e,T],r,C,a);L.isGraphChanged&&(v=!0),L.anotherRoundNeeded&&(I=!0),r.delete(T.locator)}return{anotherRoundNeeded:I,isGraphChanged:v}},hIt=t=>{for(let[e,r]of t.dependencies)if(!t.peerNames.has(e)&&r.ident!==t.ident)return!0;return!1},gIt=(t,e,r,o,a,n,u,A,{outputReason:p,fastLookupPossible:h})=>{let E,I=null,v=new Set;p&&(E=`${Array.from(e).map(L=>no(L)).join("\u2192")}`);let b=r[r.length-1],T=!(o.ident===b.ident);if(p&&!T&&(I="- self-reference"),T&&(T=o.dependencyKind!==1,p&&!T&&(I="- workspace")),T&&o.dependencyKind===2&&(T=!hIt(o),p&&!T&&(I="- external soft link with unhoisted dependencies")),T&&(T=b.dependencyKind!==1||b.hoistedFrom.has(o.name)||e.size===1,p&&!T&&(I=b.reasons.get(o.name))),T&&(T=!t.peerNames.has(o.name),p&&!T&&(I=`- cannot shadow peer: ${no(t.originalDependencies.get(o.name).locator)} at ${E}`)),T){let L=!1,U=a.get(o.name);if(L=!U||U.ident===o.ident,p&&!L&&(I=`- filled by: ${no(U.locator)} at ${E}`),L)for(let J=r.length-1;J>=1;J--){let le=r[J].dependencies.get(o.name);if(le&&le.ident!==o.ident){L=!1;let pe=A.get(b);pe||(pe=new Set,A.set(b,pe)),pe.add(o.name),p&&(I=`- filled by ${no(le.locator)} at ${r.slice(0,J).map(Ae=>no(Ae.locator)).join("\u2192")}`);break}}T=L}if(T&&(T=n.get(o.name)===o.ident,p&&!T&&(I=`- filled by: ${no(u.get(o.name)[0])} at ${E}`)),T){let L=!0,U=new Set(o.peerNames);for(let J=r.length-1;J>=1;J--){let te=r[J];for(let le of U){if(te.peerNames.has(le)&&te.originalDependencies.has(le))continue;let pe=te.dependencies.get(le);pe&&t.dependencies.get(le)!==pe&&(J===r.length-1?v.add(pe):(v=null,L=!1,p&&(I=`- peer dependency ${no(pe.locator)} from parent ${no(te.locator)} was not hoisted to ${E}`))),U.delete(le)}if(!L)break}T=L}if(T&&!h)for(let L of o.hoistedDependencies.values()){let U=a.get(L.name)||t.dependencies.get(L.name);if(!U||L.ident!==U.ident){T=!1,p&&(I=`- previously hoisted dependency mismatch, needed: ${no(L.locator)}, available: ${no(U?.locator)}`);break}}return v!==null&&v.size>0?{isHoistable:2,dependsOn:v,reason:I}:{isHoistable:T?0:1,reason:I}},CQ=t=>`${t.name}@${t.locator}`,dIt=(t,e,r,o,a,n,u,A,p)=>{let h=e[e.length-1],E=new Set,I=!1,v=!1,b=(U,J,te,le,pe)=>{if(E.has(le))return;let Ae=[...J,CQ(le)],ye=[...te,CQ(le)],ae=new Map,we=new Map;for(let ce of Oj(le)){let ne=gIt(h,r,[h,...U,le],ce,o,a,n,A,{outputReason:p.debugLevel>=2,fastLookupPossible:p.fastLookupPossible});if(we.set(ce,ne),ne.isHoistable===2)for(let ee of ne.dependsOn){let Ie=ae.get(ee.name)||new Set;Ie.add(ce.name),ae.set(ee.name,Ie)}}let Pe=new Set,g=(ce,ne,ee)=>{if(!Pe.has(ce)){Pe.add(ce),we.set(ce,{isHoistable:1,reason:ee});for(let Ie of ae.get(ce.name)||[])g(le.dependencies.get(Ie),ne,p.debugLevel>=2?`- peer dependency ${no(ce.locator)} from parent ${no(le.locator)} was not hoisted`:"")}};for(let[ce,ne]of we)ne.isHoistable===1&&g(ce,ne,ne.reason);let Ee=!1;for(let ce of we.keys())if(!Pe.has(ce)){v=!0;let ne=u.get(le);ne&&ne.has(ce.name)&&(I=!0),Ee=!0,le.dependencies.delete(ce.name),le.hoistedDependencies.set(ce.name,ce),le.reasons.delete(ce.name);let ee=h.dependencies.get(ce.name);if(p.debugLevel>=2){let Ie=Array.from(J).concat([le.locator]).map(ht=>no(ht)).join("\u2192"),ke=h.hoistedFrom.get(ce.name);ke||(ke=[],h.hoistedFrom.set(ce.name,ke)),ke.push(Ie),le.hoistedTo.set(ce.name,Array.from(e).map(ht=>no(ht.locator)).join("\u2192"))}if(!ee)h.ident!==ce.ident&&(h.dependencies.set(ce.name,ce),pe.add(ce));else for(let Ie of ce.references)ee.references.add(Ie)}if(le.dependencyKind===2&&Ee&&(I=!0),p.check){let ce=yIe(t);if(ce)throw new Error(`${ce}, after hoisting dependencies of ${[h,...U,le].map(ne=>no(ne.locator)).join("\u2192")}: +${VB(t)}`)}let De=Oj(le);for(let ce of De)if(Pe.has(ce)){let ne=we.get(ce);if((a.get(ce.name)===ce.ident||!le.reasons.has(ce.name))&&ne.isHoistable!==0&&le.reasons.set(ce.name,ne.reason),!ce.isHoistBorder&&ye.indexOf(CQ(ce))<0){E.add(le);let Ie=gIe(le,ce);b([...U,le],Ae,ye,Ie,T),E.delete(le)}}},C,T=new Set(Oj(h)),L=Array.from(e).map(U=>CQ(U));do{C=T,T=new Set;for(let U of C){if(U.locator===h.locator||U.isHoistBorder)continue;let J=gIe(h,U);b([],Array.from(r),L,J,T)}}while(T.size>0);return{anotherRoundNeeded:I,isGraphChanged:v}},yIe=t=>{let e=[],r=new Set,o=new Set,a=(n,u,A)=>{if(r.has(n)||(r.add(n),o.has(n)))return;let p=new Map(u);for(let h of n.dependencies.values())n.peerNames.has(h.name)||p.set(h.name,h);for(let h of n.originalDependencies.values()){let E=p.get(h.name),I=()=>`${Array.from(o).concat([n]).map(v=>no(v.locator)).join("\u2192")}`;if(n.peerNames.has(h.name)){let v=u.get(h.name);(v!==E||!v||v.ident!==h.ident)&&e.push(`${I()} - broken peer promise: expected ${h.ident} but found ${v&&v.ident}`)}else{let v=A.hoistedFrom.get(n.name),b=n.hoistedTo.get(h.name),C=`${v?` hoisted from ${v.join(", ")}`:""}`,T=`${b?` hoisted to ${b}`:""}`,L=`${I()}${C}`;E?E.ident!==h.ident&&e.push(`${L} - broken require promise for ${h.name}${T}: expected ${h.ident}, but found: ${E.ident}`):e.push(`${L} - broken require promise: no required dependency ${h.name}${T} found`)}}o.add(n);for(let h of n.dependencies.values())n.peerNames.has(h.name)||a(h,p,n);o.delete(n)};return a(t,t.dependencies,t),e.join(` +`)},mIt=(t,e)=>{let{identName:r,name:o,reference:a,peerNames:n}=t,u={name:o,references:new Set([a]),locator:Uj(r,a),ident:hIe(r,a),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(n),reasons:new Map,decoupled:!0,isHoistBorder:!0,hoistPriority:0,dependencyKind:1,hoistedFrom:new Map,hoistedTo:new Map},A=new Map([[t,u]]),p=(h,E)=>{let I=A.get(h),v=!!I;if(!I){let{name:b,identName:C,reference:T,peerNames:L,hoistPriority:U,dependencyKind:J}=h,te=e.hoistingLimits.get(E.locator);I={name:b,references:new Set([T]),locator:Uj(C,T),ident:hIe(C,T),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(L),reasons:new Map,decoupled:!0,isHoistBorder:te?te.has(b):!1,hoistPriority:U||0,dependencyKind:J||0,hoistedFrom:new Map,hoistedTo:new Map},A.set(h,I)}if(E.dependencies.set(h.name,I),E.originalDependencies.set(h.name,I),v){let b=new Set,C=T=>{if(!b.has(T)){b.add(T),T.decoupled=!1;for(let L of T.dependencies.values())T.peerNames.has(L.name)||C(L)}};C(I)}else for(let b of h.dependencies)p(b,I)};for(let h of t.dependencies)p(h,u);return u},Hj=t=>t.substring(0,t.indexOf("@",1)),yIt=t=>{let e={name:t.name,identName:Hj(t.locator),references:new Set(t.references),dependencies:new Set},r=new Set([t]),o=(a,n,u)=>{let A=r.has(a),p;if(n===a)p=u;else{let{name:h,references:E,locator:I}=a;p={name:h,identName:Hj(I),references:E,dependencies:new Set}}if(u.dependencies.add(p),!A){r.add(a);for(let h of a.dependencies.values())a.peerNames.has(h.name)||o(h,a,p);r.delete(a)}};for(let a of t.dependencies.values())o(a,t,e);return e},EIt=t=>{let e=new Map,r=new Set([t]),o=u=>`${u.name}@${u.ident}`,a=u=>{let A=o(u),p=e.get(A);return p||(p={dependents:new Set,peerDependents:new Set,hoistPriority:0},e.set(A,p)),p},n=(u,A)=>{let p=!!r.has(A);if(a(A).dependents.add(u.ident),!p){r.add(A);for(let E of A.dependencies.values()){let I=a(E);I.hoistPriority=Math.max(I.hoistPriority,E.hoistPriority),A.peerNames.has(E.name)?I.peerDependents.add(A.ident):n(A,E)}}};for(let u of t.dependencies.values())t.peerNames.has(u.name)||n(t,u);return e},no=t=>{if(!t)return"none";let e=t.indexOf("@",1),r=t.substring(0,e);r.endsWith("$wsroot$")&&(r=`wh:${r.replace("$wsroot$","")}`);let o=t.substring(e+1);if(o==="workspace:.")return".";if(o){let a=(o.indexOf("#")>0?o.split("#")[1]:o).replace("npm:","");return o.startsWith("virtual")&&(r=`v:${r}`),a.startsWith("workspace")&&(r=`w:${r}`,a=""),`${r}${a?`@${a}`:""}`}else return`${r}`},dIe=5e4,VB=t=>{let e=0,r=(a,n,u="")=>{if(e>dIe||n.has(a))return"";e++;let A=Array.from(a.dependencies.values()).sort((h,E)=>h.name===E.name?0:h.name>E.name?1:-1),p="";n.add(a);for(let h=0;h<A.length;h++){let E=A[h];if(!a.peerNames.has(E.name)&&E!==a){let I=a.reasons.get(E.name),v=Hj(E.locator);p+=`${u}${h<A.length-1?"\u251C\u2500":"\u2514\u2500"}${(n.has(E)?">":"")+(v!==E.name?`a:${E.name}:`:"")+no(E.locator)+(I?` ${I}`:"")} +`,p+=r(E,n,`${u}${h<A.length-1?"\u2502 ":" "}`)}}return n.delete(a),p};return r(t,new Set)+(e>dIe?` +Tree is too large, part of the tree has been dunped +`:"")};var KB=(o=>(o.WORKSPACES="workspaces",o.DEPENDENCIES="dependencies",o.NONE="none",o))(KB||{}),EIe="node_modules",B0="$wsroot$";var JB=(t,e)=>{let{packageTree:r,hoistingLimits:o,errors:a,preserveSymlinksRequired:n}=wIt(t,e),u=null;if(a.length===0){let A=mIe(r,{hoistingLimits:o});u=BIt(t,A,e)}return{tree:u,errors:a,preserveSymlinksRequired:n}},gA=t=>`${t.name}@${t.reference}`,qj=t=>{let e=new Map;for(let[r,o]of t.entries())if(!o.dirList){let a=e.get(o.locator);a||(a={target:o.target,linkType:o.linkType,locations:[],aliases:o.aliases},e.set(o.locator,a)),a.locations.push(r)}for(let r of e.values())r.locations=r.locations.sort((o,a)=>{let n=o.split(K.delimiter).length,u=a.split(K.delimiter).length;return a===o?0:n!==u?u-n:a>o?1:-1});return e},CIe=(t,e)=>{let r=W.isVirtualLocator(t)?W.devirtualizeLocator(t):t,o=W.isVirtualLocator(e)?W.devirtualizeLocator(e):e;return W.areLocatorsEqual(r,o)},jj=(t,e,r,o)=>{if(t.linkType!=="SOFT")return!1;let a=ue.toPortablePath(r.resolveVirtual&&e.reference&&e.reference.startsWith("virtual:")?r.resolveVirtual(t.packageLocation):t.packageLocation);return K.contains(o,a)===null},CIt=t=>{let e=t.getPackageInformation(t.topLevel);if(e===null)throw new Error("Assertion failed: Expected the top-level package to have been registered");if(t.findPackageLocator(e.packageLocation)===null)throw new Error("Assertion failed: Expected the top-level package to have a physical locator");let o=ue.toPortablePath(e.packageLocation.slice(0,-1)),a=new Map,n={children:new Map},u=t.getDependencyTreeRoots(),A=new Map,p=new Set,h=(v,b)=>{let C=gA(v);if(p.has(C))return;p.add(C);let T=t.getPackageInformation(v);if(T){let L=b?gA(b):"";if(gA(v)!==L&&T.linkType==="SOFT"&&!jj(T,v,t,o)){let U=wIe(T,v,t);(!A.get(U)||v.reference.startsWith("workspace:"))&&A.set(U,v)}for(let[U,J]of T.packageDependencies)J!==null&&(T.packagePeers.has(U)||h(t.getLocator(U,J),v))}};for(let v of u)h(v,null);let E=o.split(K.sep);for(let v of A.values()){let b=t.getPackageInformation(v),T=ue.toPortablePath(b.packageLocation.slice(0,-1)).split(K.sep).slice(E.length),L=n;for(let U of T){let J=L.children.get(U);J||(J={children:new Map},L.children.set(U,J)),L=J}L.workspaceLocator=v}let I=(v,b)=>{if(v.workspaceLocator){let C=gA(b),T=a.get(C);T||(T=new Set,a.set(C,T)),T.add(v.workspaceLocator)}for(let C of v.children.values())I(C,v.workspaceLocator||b)};for(let v of n.children.values())I(v,n.workspaceLocator);return a},wIt=(t,e)=>{let r=[],o=!1,a=new Map,n=CIt(t),u=t.getPackageInformation(t.topLevel);if(u===null)throw new Error("Assertion failed: Expected the top-level package to have been registered");let A=t.findPackageLocator(u.packageLocation);if(A===null)throw new Error("Assertion failed: Expected the top-level package to have a physical locator");let p=ue.toPortablePath(u.packageLocation.slice(0,-1)),h={name:A.name,identName:A.name,reference:A.reference,peerNames:u.packagePeers,dependencies:new Set,dependencyKind:1},E=new Map,I=(b,C)=>`${gA(C)}:${b}`,v=(b,C,T,L,U,J,te,le)=>{let pe=I(b,T),Ae=E.get(pe),ye=!!Ae;!ye&&T.name===A.name&&T.reference===A.reference&&(Ae=h,E.set(pe,h));let ae=jj(C,T,t,p);if(!Ae){let ce=0;ae?ce=2:C.linkType==="SOFT"&&T.name.endsWith(B0)&&(ce=1),Ae={name:b,identName:T.name,reference:T.reference,dependencies:new Set,peerNames:ce===1?new Set:C.packagePeers,dependencyKind:ce},E.set(pe,Ae)}let we;if(ae?we=2:U.linkType==="SOFT"?we=1:we=0,Ae.hoistPriority=Math.max(Ae.hoistPriority||0,we),le&&!ae){let ce=gA({name:L.identName,reference:L.reference}),ne=a.get(ce)||new Set;a.set(ce,ne),ne.add(Ae.name)}let Pe=new Map(C.packageDependencies);if(e.project){let ce=e.project.workspacesByCwd.get(ue.toPortablePath(C.packageLocation.slice(0,-1)));if(ce){let ne=new Set([...Array.from(ce.manifest.peerDependencies.values(),ee=>W.stringifyIdent(ee)),...Array.from(ce.manifest.peerDependenciesMeta.keys())]);for(let ee of ne)Pe.has(ee)||(Pe.set(ee,J.get(ee)||null),Ae.peerNames.add(ee))}}let g=gA({name:T.name.replace(B0,""),reference:T.reference}),Ee=n.get(g);if(Ee)for(let ce of Ee)Pe.set(`${ce.name}${B0}`,ce.reference);(C!==U||C.linkType!=="SOFT"||!ae&&(!e.selfReferencesByCwd||e.selfReferencesByCwd.get(te)))&&L.dependencies.add(Ae);let De=T!==A&&C.linkType==="SOFT"&&!T.name.endsWith(B0)&&!ae;if(!ye&&!De){let ce=new Map;for(let[ne,ee]of Pe)if(ee!==null){let Ie=t.getLocator(ne,ee),ke=t.getLocator(ne.replace(B0,""),ee),ht=t.getPackageInformation(ke);if(ht===null)throw new Error("Assertion failed: Expected the package to have been registered");let H=jj(ht,Ie,t,p);if(e.validateExternalSoftLinks&&e.project&&H){ht.packageDependencies.size>0&&(o=!0);for(let[_e,Te]of ht.packageDependencies)if(Te!==null){let Je=W.parseLocator(Array.isArray(Te)?`${Te[0]}@${Te[1]}`:`${_e}@${Te}`);if(gA(Je)!==gA(Ie)){let He=Pe.get(_e);if(He){let x=W.parseLocator(Array.isArray(He)?`${He[0]}@${He[1]}`:`${_e}@${He}`);CIe(x,Je)||r.push({messageName:71,text:`Cannot link ${W.prettyIdent(e.project.configuration,W.parseIdent(Ie.name))} into ${W.prettyLocator(e.project.configuration,W.parseLocator(`${T.name}@${T.reference}`))} dependency ${W.prettyLocator(e.project.configuration,Je)} conflicts with parent dependency ${W.prettyLocator(e.project.configuration,x)}`})}else{let x=ce.get(_e);if(x){let w=x.target,S=W.parseLocator(Array.isArray(w)?`${w[0]}@${w[1]}`:`${_e}@${w}`);CIe(S,Je)||r.push({messageName:71,text:`Cannot link ${W.prettyIdent(e.project.configuration,W.parseIdent(Ie.name))} into ${W.prettyLocator(e.project.configuration,W.parseLocator(`${T.name}@${T.reference}`))} dependency ${W.prettyLocator(e.project.configuration,Je)} conflicts with dependency ${W.prettyLocator(e.project.configuration,S)} from sibling portal ${W.prettyIdent(e.project.configuration,W.parseIdent(x.portal.name))}`})}else ce.set(_e,{target:Je.reference,portal:Ie})}}}}let lt=e.hoistingLimitsByCwd?.get(te),Re=H?te:K.relative(p,ue.toPortablePath(ht.packageLocation))||Bt.dot,Qe=e.hoistingLimitsByCwd?.get(Re);v(ne,ht,Ie,Ae,C,Pe,Re,lt==="dependencies"||Qe==="dependencies"||Qe==="workspaces")}}};return v(A.name,u,A,h,u,u.packageDependencies,Bt.dot,!1),{packageTree:h,hoistingLimits:a,errors:r,preserveSymlinksRequired:o}};function wIe(t,e,r){let o=r.resolveVirtual&&e.reference&&e.reference.startsWith("virtual:")?r.resolveVirtual(t.packageLocation):t.packageLocation;return ue.toPortablePath(o||t.packageLocation)}function IIt(t,e,r){let o=e.getLocator(t.name.replace(B0,""),t.reference),a=e.getPackageInformation(o);if(a===null)throw new Error("Assertion failed: Expected the package to be registered");return r.pnpifyFs?{linkType:"SOFT",target:ue.toPortablePath(a.packageLocation)}:{linkType:a.linkType,target:wIe(a,t,e)}}var BIt=(t,e,r)=>{let o=new Map,a=(E,I,v)=>{let{linkType:b,target:C}=IIt(E,t,r);return{locator:gA(E),nodePath:I,target:C,linkType:b,aliases:v}},n=E=>{let[I,v]=E.split("/");return v?{scope:I,name:v}:{scope:null,name:I}},u=new Set,A=(E,I,v)=>{if(u.has(E))return;u.add(E);let b=Array.from(E.references).sort().join("#");for(let C of E.dependencies){let T=Array.from(C.references).sort().join("#");if(C.identName===E.identName.replace(B0,"")&&T===b)continue;let L=Array.from(C.references).sort(),U={name:C.identName,reference:L[0]},{name:J,scope:te}=n(C.name),le=te?[te,J]:[J],pe=K.join(I,EIe),Ae=K.join(pe,...le),ye=`${v}/${U.name}`,ae=a(U,v,L.slice(1)),we=!1;if(ae.linkType==="SOFT"&&r.project){let Pe=r.project.workspacesByCwd.get(ae.target.slice(0,-1));we=!!(Pe&&!Pe.manifest.name)}if(!C.name.endsWith(B0)&&!we){let Pe=o.get(Ae);if(Pe){if(Pe.dirList)throw new Error(`Assertion failed: ${Ae} cannot merge dir node with leaf node`);{let De=W.parseLocator(Pe.locator),ce=W.parseLocator(ae.locator);if(Pe.linkType!==ae.linkType)throw new Error(`Assertion failed: ${Ae} cannot merge nodes with different link types ${Pe.nodePath}/${W.stringifyLocator(De)} and ${v}/${W.stringifyLocator(ce)}`);if(De.identHash!==ce.identHash)throw new Error(`Assertion failed: ${Ae} cannot merge nodes with different idents ${Pe.nodePath}/${W.stringifyLocator(De)} and ${v}/s${W.stringifyLocator(ce)}`);ae.aliases=[...ae.aliases,...Pe.aliases,W.parseLocator(Pe.locator).reference]}}o.set(Ae,ae);let g=Ae.split("/"),Ee=g.indexOf(EIe);for(let De=g.length-1;Ee>=0&&De>Ee;De--){let ce=ue.toPortablePath(g.slice(0,De).join(K.sep)),ne=g[De],ee=o.get(ce);if(!ee)o.set(ce,{dirList:new Set([ne])});else if(ee.dirList){if(ee.dirList.has(ne))break;ee.dirList.add(ne)}}}A(C,ae.linkType==="SOFT"?ae.target:Ae,ye)}},p=a({name:e.name,reference:Array.from(e.references)[0]},"",[]),h=p.target;return o.set(h,p),A(e,h,""),o};Ye();Ye();Pt();Pt();nA();Nl();var lq={};Kt(lq,{PnpInstaller:()=>dm,PnpLinker:()=>P0,UnplugCommand:()=>x0,default:()=>$It,getPnpPath:()=>S0,jsInstallUtils:()=>mA,pnpUtils:()=>av,quotePathIfNeeded:()=>s1e});Pt();var i1e=Be("url");Ye();Ye();Pt();Pt();var IIe={["DEFAULT"]:{collapsed:!1,next:{["*"]:"DEFAULT"}},["TOP_LEVEL"]:{collapsed:!1,next:{fallbackExclusionList:"FALLBACK_EXCLUSION_LIST",packageRegistryData:"PACKAGE_REGISTRY_DATA",["*"]:"DEFAULT"}},["FALLBACK_EXCLUSION_LIST"]:{collapsed:!1,next:{["*"]:"FALLBACK_EXCLUSION_ENTRIES"}},["FALLBACK_EXCLUSION_ENTRIES"]:{collapsed:!0,next:{["*"]:"FALLBACK_EXCLUSION_DATA"}},["FALLBACK_EXCLUSION_DATA"]:{collapsed:!0,next:{["*"]:"DEFAULT"}},["PACKAGE_REGISTRY_DATA"]:{collapsed:!1,next:{["*"]:"PACKAGE_REGISTRY_ENTRIES"}},["PACKAGE_REGISTRY_ENTRIES"]:{collapsed:!0,next:{["*"]:"PACKAGE_STORE_DATA"}},["PACKAGE_STORE_DATA"]:{collapsed:!1,next:{["*"]:"PACKAGE_STORE_ENTRIES"}},["PACKAGE_STORE_ENTRIES"]:{collapsed:!0,next:{["*"]:"PACKAGE_INFORMATION_DATA"}},["PACKAGE_INFORMATION_DATA"]:{collapsed:!1,next:{packageDependencies:"PACKAGE_DEPENDENCIES",["*"]:"DEFAULT"}},["PACKAGE_DEPENDENCIES"]:{collapsed:!1,next:{["*"]:"PACKAGE_DEPENDENCY"}},["PACKAGE_DEPENDENCY"]:{collapsed:!0,next:{["*"]:"DEFAULT"}}};function vIt(t,e,r){let o="";o+="[";for(let a=0,n=t.length;a<n;++a)o+=wQ(String(a),t[a],e,r).replace(/^ +/g,""),a+1<n&&(o+=", ");return o+="]",o}function DIt(t,e,r){let o=`${r} `,a="";a+=r,a+=`[ +`;for(let n=0,u=t.length;n<u;++n)a+=o+wQ(String(n),t[n],e,o).replace(/^ +/,""),n+1<u&&(a+=","),a+=` +`;return a+=r,a+="]",a}function PIt(t,e,r){let o=Object.keys(t),a="";a+="{";for(let n=0,u=o.length,A=0;n<u;++n){let p=o[n],h=t[p];typeof h>"u"||(A!==0&&(a+=", "),a+=JSON.stringify(p),a+=": ",a+=wQ(p,h,e,r).replace(/^ +/g,""),A+=1)}return a+="}",a}function SIt(t,e,r){let o=Object.keys(t),a=`${r} `,n="";n+=r,n+=`{ +`;let u=0;for(let A=0,p=o.length;A<p;++A){let h=o[A],E=t[h];typeof E>"u"||(u!==0&&(n+=",",n+=` +`),n+=a,n+=JSON.stringify(h),n+=": ",n+=wQ(h,E,e,a).replace(/^ +/g,""),u+=1)}return u!==0&&(n+=` +`),n+=r,n+="}",n}function wQ(t,e,r,o){let{next:a}=IIe[r],n=a[t]||a["*"];return BIe(e,n,o)}function BIe(t,e,r){let{collapsed:o}=IIe[e];return Array.isArray(t)?o?vIt(t,e,r):DIt(t,e,r):typeof t=="object"&&t!==null?o?PIt(t,e,r):SIt(t,e,r):JSON.stringify(t)}function vIe(t){return BIe(t,"TOP_LEVEL","")}function zB(t,e){let r=Array.from(t);Array.isArray(e)||(e=[e]);let o=[];for(let n of e)o.push(r.map(u=>n(u)));let a=r.map((n,u)=>u);return a.sort((n,u)=>{for(let A of o){let p=A[n]<A[u]?-1:A[n]>A[u]?1:0;if(p!==0)return p}return 0}),a.map(n=>r[n])}function xIt(t){let e=new Map,r=zB(t.fallbackExclusionList||[],[({name:o,reference:a})=>o,({name:o,reference:a})=>a]);for(let{name:o,reference:a}of r){let n=e.get(o);typeof n>"u"&&e.set(o,n=new Set),n.add(a)}return Array.from(e).map(([o,a])=>[o,Array.from(a)])}function bIt(t){return zB(t.fallbackPool||[],([e])=>e)}function kIt(t){let e=[];for(let[r,o]of zB(t.packageRegistry,([a])=>a===null?"0":`1${a}`)){let a=[];e.push([r,a]);for(let[n,{packageLocation:u,packageDependencies:A,packagePeers:p,linkType:h,discardFromLookup:E}]of zB(o,([I])=>I===null?"0":`1${I}`)){let I=[];r!==null&&n!==null&&!A.has(r)&&I.push([r,n]);for(let[C,T]of zB(A.entries(),([L])=>L))I.push([C,T]);let v=p&&p.size>0?Array.from(p):void 0,b=E||void 0;a.push([n,{packageLocation:u,packageDependencies:I,packagePeers:v,linkType:h,discardFromLookup:b}])}}return e}function XB(t){return{__info:["This file is automatically generated. Do not touch it, or risk","your modifications being lost."],dependencyTreeRoots:t.dependencyTreeRoots,enableTopLevelFallback:t.enableTopLevelFallback||!1,ignorePatternData:t.ignorePattern||null,fallbackExclusionList:xIt(t),fallbackPool:bIt(t),packageRegistryData:kIt(t)}}var SIe=$e(PIe());function xIe(t,e){return[t?`${t} +`:"",`/* eslint-disable */ +`,`"use strict"; +`,` +`,e,` +`,(0,SIe.default)()].join("")}function QIt(t){return JSON.stringify(t,null,2)}function FIt(t){return`'${t.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,`\\ +`)}'`}function TIt(t){return[`const RAW_RUNTIME_STATE = +`,`${FIt(vIe(t))}; + +`,`function $$SETUP_STATE(hydrateRuntimeState, basePath) { +`,` return hydrateRuntimeState(JSON.parse(RAW_RUNTIME_STATE), {basePath: basePath || __dirname}); +`,`} +`].join("")}function RIt(){return[`function $$SETUP_STATE(hydrateRuntimeState, basePath) { +`,` const fs = require('fs'); +`,` const path = require('path'); +`,` const pnpDataFilepath = path.resolve(__dirname, ${JSON.stringify(dr.pnpData)}); +`,` return hydrateRuntimeState(JSON.parse(fs.readFileSync(pnpDataFilepath, 'utf8')), {basePath: basePath || __dirname}); +`,`} +`].join("")}function bIe(t){let e=XB(t),r=TIt(e);return xIe(t.shebang,r)}function kIe(t){let e=XB(t),r=RIt(),o=xIe(t.shebang,r);return{dataFile:QIt(e),loaderFile:o}}Pt();function Yj(t,{basePath:e}){let r=ue.toPortablePath(e),o=K.resolve(r),a=t.ignorePatternData!==null?new RegExp(t.ignorePatternData):null,n=new Map,u=new Map(t.packageRegistryData.map(([I,v])=>[I,new Map(v.map(([b,C])=>{if(I===null!=(b===null))throw new Error("Assertion failed: The name and reference should be null, or neither should");let T=C.discardFromLookup??!1,L={name:I,reference:b},U=n.get(C.packageLocation);U?(U.discardFromLookup=U.discardFromLookup&&T,T||(U.locator=L)):n.set(C.packageLocation,{locator:L,discardFromLookup:T});let J=null;return[b,{packageDependencies:new Map(C.packageDependencies),packagePeers:new Set(C.packagePeers),linkType:C.linkType,discardFromLookup:T,get packageLocation(){return J||(J=K.join(o,C.packageLocation))}}]}))])),A=new Map(t.fallbackExclusionList.map(([I,v])=>[I,new Set(v)])),p=new Map(t.fallbackPool),h=t.dependencyTreeRoots,E=t.enableTopLevelFallback;return{basePath:r,dependencyTreeRoots:h,enableTopLevelFallback:E,fallbackExclusionList:A,fallbackPool:p,ignorePattern:a,packageLocatorsByLocations:n,packageRegistry:u}}Pt();Pt();var rp=Be("module"),gm=Be("url"),tq=Be("util");var Oo=Be("url");var RIe=$e(Be("assert"));var Wj=Array.isArray,ZB=JSON.stringify,$B=Object.getOwnPropertyNames,pm=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),Vj=(t,e)=>RegExp.prototype.exec.call(t,e),Kj=(t,...e)=>RegExp.prototype[Symbol.replace].apply(t,e),v0=(t,...e)=>String.prototype.endsWith.apply(t,e),Jj=(t,...e)=>String.prototype.includes.apply(t,e),zj=(t,...e)=>String.prototype.lastIndexOf.apply(t,e),ev=(t,...e)=>String.prototype.indexOf.apply(t,e),QIe=(t,...e)=>String.prototype.replace.apply(t,e),D0=(t,...e)=>String.prototype.slice.apply(t,e),dA=(t,...e)=>String.prototype.startsWith.apply(t,e),FIe=Map,TIe=JSON.parse;function tv(t,e,r){return class extends r{constructor(...o){super(e(...o)),this.code=t,this.name=`${r.name} [${t}]`}}}var NIe=tv("ERR_PACKAGE_IMPORT_NOT_DEFINED",(t,e,r)=>`Package import specifier "${t}" is not defined${e?` in package ${e}package.json`:""} imported from ${r}`,TypeError),Xj=tv("ERR_INVALID_MODULE_SPECIFIER",(t,e,r=void 0)=>`Invalid module "${t}" ${e}${r?` imported from ${r}`:""}`,TypeError),LIe=tv("ERR_INVALID_PACKAGE_TARGET",(t,e,r,o=!1,a=void 0)=>{let n=typeof r=="string"&&!o&&r.length&&!dA(r,"./");return e==="."?((0,RIe.default)(o===!1),`Invalid "exports" main target ${ZB(r)} defined in the package config ${t}package.json${a?` imported from ${a}`:""}${n?'; targets must start with "./"':""}`):`Invalid "${o?"imports":"exports"}" target ${ZB(r)} defined for '${e}' in the package config ${t}package.json${a?` imported from ${a}`:""}${n?'; targets must start with "./"':""}`},Error),rv=tv("ERR_INVALID_PACKAGE_CONFIG",(t,e,r)=>`Invalid package config ${t}${e?` while importing ${e}`:""}${r?`. ${r}`:""}`,Error),MIe=tv("ERR_PACKAGE_PATH_NOT_EXPORTED",(t,e,r=void 0)=>e==="."?`No "exports" main defined in ${t}package.json${r?` imported from ${r}`:""}`:`Package subpath '${e}' is not defined by "exports" in ${t}package.json${r?` imported from ${r}`:""}`,Error);var BQ=Be("url");function OIe(t,e){let r=Object.create(null);for(let o=0;o<e.length;o++){let a=e[o];pm(t,a)&&(r[a]=t[a])}return r}var IQ=new FIe;function NIt(t,e,r,o){let a=IQ.get(t);if(a!==void 0)return a;let n=o(t);if(n===void 0){let b={pjsonPath:t,exists:!1,main:void 0,name:void 0,type:"none",exports:void 0,imports:void 0};return IQ.set(t,b),b}let u;try{u=TIe(n)}catch(b){throw new rv(t,(r?`"${e}" from `:"")+(0,BQ.fileURLToPath)(r||e),b.message)}let{imports:A,main:p,name:h,type:E}=OIe(u,["imports","main","name","type"]),I=pm(u,"exports")?u.exports:void 0;(typeof A!="object"||A===null)&&(A=void 0),typeof p!="string"&&(p=void 0),typeof h!="string"&&(h=void 0),E!=="module"&&E!=="commonjs"&&(E="none");let v={pjsonPath:t,exists:!0,main:p,name:h,type:E,exports:I,imports:A};return IQ.set(t,v),v}function UIe(t,e){let r=new URL("./package.json",t);for(;;){let n=r.pathname;if(v0(n,"node_modules/package.json"))break;let u=NIt((0,BQ.fileURLToPath)(r),t,void 0,e);if(u.exists)return u;let A=r;if(r=new URL("../package.json",r),r.pathname===A.pathname)break}let o=(0,BQ.fileURLToPath)(r),a={pjsonPath:o,exists:!1,main:void 0,name:void 0,type:"none",exports:void 0,imports:void 0};return IQ.set(o,a),a}function LIt(t,e,r){throw new NIe(t,e&&(0,Oo.fileURLToPath)(new URL(".",e)),(0,Oo.fileURLToPath)(r))}function MIt(t,e,r,o){let a=`request is not a valid subpath for the "${r?"imports":"exports"}" resolution of ${(0,Oo.fileURLToPath)(e)}`;throw new Xj(t,a,o&&(0,Oo.fileURLToPath)(o))}function nv(t,e,r,o,a){throw typeof e=="object"&&e!==null?e=ZB(e,null,""):e=`${e}`,new LIe((0,Oo.fileURLToPath)(new URL(".",r)),t,e,o,a&&(0,Oo.fileURLToPath)(a))}var _Ie=/(^|\\|\/)((\.|%2e)(\.|%2e)?|(n|%6e|%4e)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(_|%5f)(m|%6d|%4d)(o|%6f|%4f)(d|%64|%44)(u|%75|%55)(l|%6c|%4c)(e|%65|%45)(s|%73|%53))(\\|\/|$)/i,HIe=/\*/g;function OIt(t,e,r,o,a,n,u,A){if(e!==""&&!n&&t[t.length-1]!=="/"&&nv(r,t,o,u,a),!dA(t,"./")){if(u&&!dA(t,"../")&&!dA(t,"/")){let I=!1;try{new URL(t),I=!0}catch{}if(!I)return n?Kj(HIe,t,()=>e):t+e}nv(r,t,o,u,a)}Vj(_Ie,D0(t,2))!==null&&nv(r,t,o,u,a);let p=new URL(t,o),h=p.pathname,E=new URL(".",o).pathname;if(dA(h,E)||nv(r,t,o,u,a),e==="")return p;if(Vj(_Ie,e)!==null){let I=n?QIe(r,"*",()=>e):r+e;MIt(I,o,u,a)}return n?new URL(Kj(HIe,p.href,()=>e)):new URL(e,p)}function UIt(t){let e=+t;return`${e}`!==t?!1:e>=0&&e<4294967295}function qC(t,e,r,o,a,n,u,A){if(typeof e=="string")return OIt(e,r,o,t,a,n,u,A);if(Wj(e)){if(e.length===0)return null;let p;for(let h=0;h<e.length;h++){let E=e[h],I;try{I=qC(t,E,r,o,a,n,u,A)}catch(v){if(p=v,v.code==="ERR_INVALID_PACKAGE_TARGET")continue;throw v}if(I!==void 0){if(I===null){p=null;continue}return I}}if(p==null)return p;throw p}else if(typeof e=="object"&&e!==null){let p=$B(e);for(let h=0;h<p.length;h++){let E=p[h];if(UIt(E))throw new rv((0,Oo.fileURLToPath)(t),a,'"exports" cannot contain numeric property keys.')}for(let h=0;h<p.length;h++){let E=p[h];if(E==="default"||A.has(E)){let I=e[E],v=qC(t,I,r,o,a,n,u,A);if(v===void 0)continue;return v}}return}else if(e===null)return null;nv(o,e,t,u,a)}function qIe(t,e){let r=ev(t,"*"),o=ev(e,"*"),a=r===-1?t.length:r+1,n=o===-1?e.length:o+1;return a>n?-1:n>a||r===-1?1:o===-1||t.length>e.length?-1:e.length>t.length?1:0}function _It(t,e,r){if(typeof t=="string"||Wj(t))return!0;if(typeof t!="object"||t===null)return!1;let o=$B(t),a=!1,n=0;for(let u=0;u<o.length;u++){let A=o[u],p=A===""||A[0]!==".";if(n++===0)a=p;else if(a!==p)throw new rv((0,Oo.fileURLToPath)(e),r,`"exports" cannot contain some keys starting with '.' and some not. The exports object must either be an object of package subpath keys or an object of main entry condition name keys only.`)}return a}function Zj(t,e,r){throw new MIe((0,Oo.fileURLToPath)(new URL(".",e)),t,r&&(0,Oo.fileURLToPath)(r))}var jIe=new Set;function HIt(t,e,r){let o=(0,Oo.fileURLToPath)(e);jIe.has(o+"|"+t)||(jIe.add(o+"|"+t),process.emitWarning(`Use of deprecated trailing slash pattern mapping "${t}" in the "exports" field module resolution of the package at ${o}${r?` imported from ${(0,Oo.fileURLToPath)(r)}`:""}. Mapping specifiers ending in "/" is no longer supported.`,"DeprecationWarning","DEP0155"))}function GIe({packageJSONUrl:t,packageSubpath:e,exports:r,base:o,conditions:a}){if(_It(r,t,o)&&(r={".":r}),pm(r,e)&&!Jj(e,"*")&&!v0(e,"/")){let p=r[e],h=qC(t,p,"",e,o,!1,!1,a);return h==null&&Zj(e,t,o),h}let n="",u,A=$B(r);for(let p=0;p<A.length;p++){let h=A[p],E=ev(h,"*");if(E!==-1&&dA(e,D0(h,0,E))){v0(e,"/")&&HIt(e,t,o);let I=D0(h,E+1);e.length>=h.length&&v0(e,I)&&qIe(n,h)===1&&zj(h,"*")===E&&(n=h,u=D0(e,E,e.length-I.length))}}if(n){let p=r[n],h=qC(t,p,u,n,o,!0,!1,a);return h==null&&Zj(e,t,o),h}Zj(e,t,o)}function YIe({name:t,base:e,conditions:r,readFileSyncFn:o}){if(t==="#"||dA(t,"#/")||v0(t,"/")){let u="is not a valid internal imports specifier name";throw new Xj(t,u,(0,Oo.fileURLToPath)(e))}let a,n=UIe(e,o);if(n.exists){a=(0,Oo.pathToFileURL)(n.pjsonPath);let u=n.imports;if(u)if(pm(u,t)&&!Jj(t,"*")){let A=qC(a,u[t],"",t,e,!1,!0,r);if(A!=null)return A}else{let A="",p,h=$B(u);for(let E=0;E<h.length;E++){let I=h[E],v=ev(I,"*");if(v!==-1&&dA(t,D0(I,0,v))){let b=D0(I,v+1);t.length>=I.length&&v0(t,b)&&qIe(A,I)===1&&zj(I,"*")===v&&(A=I,p=D0(t,v,t.length-b.length))}}if(A){let E=u[A],I=qC(a,E,p,A,e,!0,!0,r);if(I!=null)return I}}}LIt(t,a,e)}Pt();var jIt=new Set(["BUILTIN_NODE_RESOLUTION_FAILED","MISSING_DEPENDENCY","MISSING_PEER_DEPENDENCY","QUALIFIED_PATH_RESOLUTION_FAILED","UNDECLARED_DEPENDENCY"]);function $i(t,e,r={},o){o??=jIt.has(t)?"MODULE_NOT_FOUND":t;let a={configurable:!0,writable:!0,enumerable:!1};return Object.defineProperties(new Error(e),{code:{...a,value:o},pnpCode:{...a,value:t},data:{...a,value:r}})}function au(t){return ue.normalize(ue.fromPortablePath(t))}var JIe=$e(VIe());function zIe(t){return qIt(),eq[t]}var eq;function qIt(){eq||(eq={"--conditions":[],...KIe(GIt()),...KIe(process.execArgv)})}function KIe(t){return(0,JIe.default)({"--conditions":[String],"-C":"--conditions"},{argv:t,permissive:!0})}function GIt(){let t=[],e=YIt(process.env.NODE_OPTIONS||"",t);return t.length,e}function YIt(t,e){let r=[],o=!1,a=!0;for(let n=0;n<t.length;++n){let u=t[n];if(u==="\\"&&o){if(n+1===t.length)return e.push(`invalid value for NODE_OPTIONS (invalid escape) +`),r;u=t[++n]}else if(u===" "&&!o){a=!0;continue}else if(u==='"'){o=!o;continue}a?(r.push(u),a=!1):r[r.length-1]+=u}return o&&e.push(`invalid value for NODE_OPTIONS (unterminated string) +`),r}Pt();var[hm,sv]=process.versions.node.split(".").map(t=>parseInt(t,10)),XIe=hm>19||hm===19&&sv>=2||hm===18&&sv>=13,Bzt=hm===20&&sv<6||hm===19&&sv>=3,vzt=hm>19||hm===19&&sv>=6;function ZIe(t){if(process.env.WATCH_REPORT_DEPENDENCIES&&process.send)if(t=t.map(e=>ue.fromPortablePath(mi.resolveVirtual(ue.toPortablePath(e)))),XIe)process.send({"watch:require":t});else for(let e of t)process.send({"watch:require":e})}function rq(t,e){let r=Number(process.env.PNP_ALWAYS_WARN_ON_FALLBACK)>0,o=Number(process.env.PNP_DEBUG_LEVEL),a=/^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:node:)?(?:@[^/]+\/)?[^/]+)\/*(.*|)$/,n=/^(\/|\.{1,2}(\/|$))/,u=/\/$/,A=/^\.{0,2}\//,p={name:null,reference:null},h=[],E=new Set;if(t.enableTopLevelFallback===!0&&h.push(p),e.compatibilityMode!==!1)for(let Re of["react-scripts","gatsby"]){let Qe=t.packageRegistry.get(Re);if(Qe)for(let be of Qe.keys()){if(be===null)throw new Error("Assertion failed: This reference shouldn't be null");h.push({name:Re,reference:be})}}let{ignorePattern:I,packageRegistry:v,packageLocatorsByLocations:b}=t;function C(Re,Qe){return{fn:Re,args:Qe,error:null,result:null}}function T(Re){let Qe=process.stderr?.hasColors?.()??process.stdout.isTTY,be=(Je,He)=>`\x1B[${Je}m${He}\x1B[0m`,_e=Re.error;console.error(_e?be("31;1",`\u2716 ${Re.error?.message.replace(/\n.*/s,"")}`):be("33;1","\u203C Resolution")),Re.args.length>0&&console.error();for(let Je of Re.args)console.error(` ${be("37;1","In \u2190")} ${(0,tq.inspect)(Je,{colors:Qe,compact:!0})}`);Re.result&&(console.error(),console.error(` ${be("37;1","Out \u2192")} ${(0,tq.inspect)(Re.result,{colors:Qe,compact:!0})}`));let Te=new Error().stack.match(/(?<=^ +)at.*/gm)?.slice(2)??[];if(Te.length>0){console.error();for(let Je of Te)console.error(` ${be("38;5;244",Je)}`)}console.error()}function L(Re,Qe){if(e.allowDebug===!1)return Qe;if(Number.isFinite(o)){if(o>=2)return(...be)=>{let _e=C(Re,be);try{return _e.result=Qe(...be)}catch(Te){throw _e.error=Te}finally{T(_e)}};if(o>=1)return(...be)=>{try{return Qe(...be)}catch(_e){let Te=C(Re,be);throw Te.error=_e,T(Te),_e}}}return Qe}function U(Re){let Qe=g(Re);if(!Qe)throw $i("INTERNAL","Couldn't find a matching entry in the dependency tree for the specified parent (this is probably an internal error)");return Qe}function J(Re){if(Re.name===null)return!0;for(let Qe of t.dependencyTreeRoots)if(Qe.name===Re.name&&Qe.reference===Re.reference)return!0;return!1}let te=new Set(["node","require",...zIe("--conditions")]);function le(Re,Qe=te,be){let _e=ce(K.join(Re,"internal.js"),{resolveIgnored:!0,includeDiscardFromLookup:!0});if(_e===null)throw $i("INTERNAL",`The locator that owns the "${Re}" path can't be found inside the dependency tree (this is probably an internal error)`);let{packageLocation:Te}=U(_e),Je=K.join(Te,dr.manifest);if(!e.fakeFs.existsSync(Je))return null;let He=JSON.parse(e.fakeFs.readFileSync(Je,"utf8"));if(He.exports==null)return null;let x=K.contains(Te,Re);if(x===null)throw $i("INTERNAL","unqualifiedPath doesn't contain the packageLocation (this is probably an internal error)");x!=="."&&!A.test(x)&&(x=`./${x}`);try{let w=GIe({packageJSONUrl:(0,gm.pathToFileURL)(ue.fromPortablePath(Je)),packageSubpath:x,exports:He.exports,base:be?(0,gm.pathToFileURL)(ue.fromPortablePath(be)):null,conditions:Qe});return ue.toPortablePath((0,gm.fileURLToPath)(w))}catch(w){throw $i("EXPORTS_RESOLUTION_FAILED",w.message,{unqualifiedPath:au(Re),locator:_e,pkgJson:He,subpath:au(x),conditions:Qe},w.code)}}function pe(Re,Qe,{extensions:be}){let _e;try{Qe.push(Re),_e=e.fakeFs.statSync(Re)}catch{}if(_e&&!_e.isDirectory())return e.fakeFs.realpathSync(Re);if(_e&&_e.isDirectory()){let Te;try{Te=JSON.parse(e.fakeFs.readFileSync(K.join(Re,dr.manifest),"utf8"))}catch{}let Je;if(Te&&Te.main&&(Je=K.resolve(Re,Te.main)),Je&&Je!==Re){let He=pe(Je,Qe,{extensions:be});if(He!==null)return He}}for(let Te=0,Je=be.length;Te<Je;Te++){let He=`${Re}${be[Te]}`;if(Qe.push(He),e.fakeFs.existsSync(He))return He}if(_e&&_e.isDirectory())for(let Te=0,Je=be.length;Te<Je;Te++){let He=K.format({dir:Re,name:"index",ext:be[Te]});if(Qe.push(He),e.fakeFs.existsSync(He))return He}return null}function Ae(Re){let Qe=new rp.Module(Re,null);return Qe.filename=Re,Qe.paths=rp.Module._nodeModulePaths(Re),Qe}function ye(Re,Qe){return Qe.endsWith("/")&&(Qe=K.join(Qe,"internal.js")),rp.Module._resolveFilename(ue.fromPortablePath(Re),Ae(ue.fromPortablePath(Qe)),!1,{plugnplay:!1})}function ae(Re){if(I===null)return!1;let Qe=K.contains(t.basePath,Re);return Qe===null?!1:!!I.test(Qe.replace(/\/$/,""))}let we={std:3,resolveVirtual:1,getAllLocators:1},Pe=p;function g({name:Re,reference:Qe}){let be=v.get(Re);if(!be)return null;let _e=be.get(Qe);return _e||null}function Ee({name:Re,reference:Qe}){let be=[];for(let[_e,Te]of v)if(_e!==null)for(let[Je,He]of Te)Je===null||He.packageDependencies.get(Re)!==Qe||_e===Re&&Je===Qe||be.push({name:_e,reference:Je});return be}function De(Re,Qe){let be=new Map,_e=new Set,Te=He=>{let x=JSON.stringify(He.name);if(_e.has(x))return;_e.add(x);let w=Ee(He);for(let S of w)if(U(S).packagePeers.has(Re))Te(S);else{let F=be.get(S.name);typeof F>"u"&&be.set(S.name,F=new Set),F.add(S.reference)}};Te(Qe);let Je=[];for(let He of[...be.keys()].sort())for(let x of[...be.get(He)].sort())Je.push({name:He,reference:x});return Je}function ce(Re,{resolveIgnored:Qe=!1,includeDiscardFromLookup:be=!1}={}){if(ae(Re)&&!Qe)return null;let _e=K.relative(t.basePath,Re);_e.match(n)||(_e=`./${_e}`),_e.endsWith("/")||(_e=`${_e}/`);do{let Te=b.get(_e);if(typeof Te>"u"||Te.discardFromLookup&&!be){_e=_e.substring(0,_e.lastIndexOf("/",_e.length-2)+1);continue}return Te.locator}while(_e!=="");return null}function ne(Re){try{return e.fakeFs.readFileSync(ue.toPortablePath(Re),"utf8")}catch(Qe){if(Qe.code==="ENOENT")return;throw Qe}}function ee(Re,Qe,{considerBuiltins:be=!0}={}){if(Re.startsWith("#"))throw new Error("resolveToUnqualified can not handle private import mappings");if(Re==="pnpapi")return ue.toPortablePath(e.pnpapiResolution);if(be&&(0,rp.isBuiltin)(Re))return null;let _e=au(Re),Te=Qe&&au(Qe);if(Qe&&ae(Qe)&&(!K.isAbsolute(Re)||ce(Re)===null)){let x=ye(Re,Qe);if(x===!1)throw $i("BUILTIN_NODE_RESOLUTION_FAILED",`The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer was explicitely ignored by the regexp) + +Require request: "${_e}" +Required by: ${Te} +`,{request:_e,issuer:Te});return ue.toPortablePath(x)}let Je,He=Re.match(a);if(He){if(!Qe)throw $i("API_ERROR","The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute",{request:_e,issuer:Te});let[,x,w]=He,S=ce(Qe);if(!S){let Ne=ye(Re,Qe);if(Ne===!1)throw $i("BUILTIN_NODE_RESOLUTION_FAILED",`The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer doesn't seem to be part of the Yarn-managed dependency tree). + +Require path: "${_e}" +Required by: ${Te} +`,{request:_e,issuer:Te});return ue.toPortablePath(Ne)}let F=U(S).packageDependencies.get(x),z=null;if(F==null&&S.name!==null){let Ne=t.fallbackExclusionList.get(S.name);if(!Ne||!Ne.has(S.reference)){for(let dt=0,jt=h.length;dt<jt;++dt){let xt=U(h[dt]).packageDependencies.get(x);if(xt!=null){r?z=xt:F=xt;break}}if(t.enableTopLevelFallback&&F==null&&z===null){let dt=t.fallbackPool.get(x);dt!=null&&(z=dt)}}}let X=null;if(F===null)if(J(S))X=$i("MISSING_PEER_DEPENDENCY",`Your application tried to access ${x} (a peer dependency); this isn't allowed as there is no ancestor to satisfy the requirement. Use a devDependency if needed. + +Required package: ${x}${x!==_e?` (via "${_e}")`:""} +Required by: ${Te} +`,{request:_e,issuer:Te,dependencyName:x});else{let Ne=De(x,S);Ne.every(ot=>J(ot))?X=$i("MISSING_PEER_DEPENDENCY",`${S.name} tried to access ${x} (a peer dependency) but it isn't provided by your application; this makes the require call ambiguous and unsound. + +Required package: ${x}${x!==_e?` (via "${_e}")`:""} +Required by: ${S.name}@${S.reference} (via ${Te}) +${Ne.map(ot=>`Ancestor breaking the chain: ${ot.name}@${ot.reference} +`).join("")} +`,{request:_e,issuer:Te,issuerLocator:Object.assign({},S),dependencyName:x,brokenAncestors:Ne}):X=$i("MISSING_PEER_DEPENDENCY",`${S.name} tried to access ${x} (a peer dependency) but it isn't provided by its ancestors; this makes the require call ambiguous and unsound. + +Required package: ${x}${x!==_e?` (via "${_e}")`:""} +Required by: ${S.name}@${S.reference} (via ${Te}) + +${Ne.map(ot=>`Ancestor breaking the chain: ${ot.name}@${ot.reference} +`).join("")} +`,{request:_e,issuer:Te,issuerLocator:Object.assign({},S),dependencyName:x,brokenAncestors:Ne})}else F===void 0&&(!be&&(0,rp.isBuiltin)(Re)?J(S)?X=$i("UNDECLARED_DEPENDENCY",`Your application tried to access ${x}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${x} isn't otherwise declared in your dependencies, this makes the require call ambiguous and unsound. + +Required package: ${x}${x!==_e?` (via "${_e}")`:""} +Required by: ${Te} +`,{request:_e,issuer:Te,dependencyName:x}):X=$i("UNDECLARED_DEPENDENCY",`${S.name} tried to access ${x}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${x} isn't otherwise declared in ${S.name}'s dependencies, this makes the require call ambiguous and unsound. + +Required package: ${x}${x!==_e?` (via "${_e}")`:""} +Required by: ${Te} +`,{request:_e,issuer:Te,issuerLocator:Object.assign({},S),dependencyName:x}):J(S)?X=$i("UNDECLARED_DEPENDENCY",`Your application tried to access ${x}, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound. + +Required package: ${x}${x!==_e?` (via "${_e}")`:""} +Required by: ${Te} +`,{request:_e,issuer:Te,dependencyName:x}):X=$i("UNDECLARED_DEPENDENCY",`${S.name} tried to access ${x}, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound. + +Required package: ${x}${x!==_e?` (via "${_e}")`:""} +Required by: ${S.name}@${S.reference} (via ${Te}) +`,{request:_e,issuer:Te,issuerLocator:Object.assign({},S),dependencyName:x}));if(F==null){if(z===null||X===null)throw X||new Error("Assertion failed: Expected an error to have been set");F=z;let Ne=X.message.replace(/\n.*/g,"");X.message=Ne,!E.has(Ne)&&o!==0&&(E.add(Ne),process.emitWarning(X))}let Z=Array.isArray(F)?{name:F[0],reference:F[1]}:{name:x,reference:F},ie=U(Z);if(!ie.packageLocation)throw $i("MISSING_DEPENDENCY",`A dependency seems valid but didn't get installed for some reason. This might be caused by a partial install, such as dev vs prod. + +Required package: ${Z.name}@${Z.reference}${Z.name!==_e?` (via "${_e}")`:""} +Required by: ${S.name}@${S.reference} (via ${Te}) +`,{request:_e,issuer:Te,dependencyLocator:Object.assign({},Z)});let Se=ie.packageLocation;w?Je=K.join(Se,w):Je=Se}else if(K.isAbsolute(Re))Je=K.normalize(Re);else{if(!Qe)throw $i("API_ERROR","The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute",{request:_e,issuer:Te});let x=K.resolve(Qe);Qe.match(u)?Je=K.normalize(K.join(x,Re)):Je=K.normalize(K.join(K.dirname(x),Re))}return K.normalize(Je)}function Ie(Re,Qe,be=te,_e){if(n.test(Re))return Qe;let Te=le(Qe,be,_e);return Te?K.normalize(Te):Qe}function ke(Re,{extensions:Qe=Object.keys(rp.Module._extensions)}={}){let be=[],_e=pe(Re,be,{extensions:Qe});if(_e)return K.normalize(_e);{ZIe(be.map(He=>ue.fromPortablePath(He)));let Te=au(Re),Je=ce(Re);if(Je){let{packageLocation:He}=U(Je),x=!0;try{e.fakeFs.accessSync(He)}catch(w){if(w?.code==="ENOENT")x=!1;else{let S=(w?.message??w??"empty exception thrown").replace(/^[A-Z]/,y=>y.toLowerCase());throw $i("QUALIFIED_PATH_RESOLUTION_FAILED",`Required package exists but could not be accessed (${S}). + +Missing package: ${Je.name}@${Je.reference} +Expected package location: ${au(He)} +`,{unqualifiedPath:Te,extensions:Qe})}}if(!x){let w=He.includes("/unplugged/")?"Required unplugged package missing from disk. This may happen when switching branches without running installs (unplugged packages must be fully materialized on disk to work).":"Required package missing from disk. If you keep your packages inside your repository then restarting the Node process may be enough. Otherwise, try to run an install first.";throw $i("QUALIFIED_PATH_RESOLUTION_FAILED",`${w} + +Missing package: ${Je.name}@${Je.reference} +Expected package location: ${au(He)} +`,{unqualifiedPath:Te,extensions:Qe})}}throw $i("QUALIFIED_PATH_RESOLUTION_FAILED",`Qualified path resolution failed: we looked for the following paths, but none could be accessed. + +Source path: ${Te} +${be.map(He=>`Not found: ${au(He)} +`).join("")}`,{unqualifiedPath:Te,extensions:Qe})}}function ht(Re,Qe,be){if(!Qe)throw new Error("Assertion failed: An issuer is required to resolve private import mappings");let _e=YIe({name:Re,base:(0,gm.pathToFileURL)(ue.fromPortablePath(Qe)),conditions:be.conditions??te,readFileSyncFn:ne});if(_e instanceof URL)return ke(ue.toPortablePath((0,gm.fileURLToPath)(_e)),{extensions:be.extensions});if(_e.startsWith("#"))throw new Error("Mapping from one private import to another isn't allowed");return H(_e,Qe,be)}function H(Re,Qe,be={}){try{if(Re.startsWith("#"))return ht(Re,Qe,be);let{considerBuiltins:_e,extensions:Te,conditions:Je}=be,He=ee(Re,Qe,{considerBuiltins:_e});if(Re==="pnpapi")return He;if(He===null)return null;let x=()=>Qe!==null?ae(Qe):!1,w=(!_e||!(0,rp.isBuiltin)(Re))&&!x()?Ie(Re,He,Je,Qe):He;return ke(w,{extensions:Te})}catch(_e){throw Object.hasOwn(_e,"pnpCode")&&Object.assign(_e.data,{request:au(Re),issuer:Qe&&au(Qe)}),_e}}function lt(Re){let Qe=K.normalize(Re),be=mi.resolveVirtual(Qe);return be!==Qe?be:null}return{VERSIONS:we,topLevel:Pe,getLocator:(Re,Qe)=>Array.isArray(Qe)?{name:Qe[0],reference:Qe[1]}:{name:Re,reference:Qe},getDependencyTreeRoots:()=>[...t.dependencyTreeRoots],getAllLocators(){let Re=[];for(let[Qe,be]of v)for(let _e of be.keys())Qe!==null&&_e!==null&&Re.push({name:Qe,reference:_e});return Re},getPackageInformation:Re=>{let Qe=g(Re);if(Qe===null)return null;let be=ue.fromPortablePath(Qe.packageLocation);return{...Qe,packageLocation:be}},findPackageLocator:Re=>ce(ue.toPortablePath(Re)),resolveToUnqualified:L("resolveToUnqualified",(Re,Qe,be)=>{let _e=Qe!==null?ue.toPortablePath(Qe):null,Te=ee(ue.toPortablePath(Re),_e,be);return Te===null?null:ue.fromPortablePath(Te)}),resolveUnqualified:L("resolveUnqualified",(Re,Qe)=>ue.fromPortablePath(ke(ue.toPortablePath(Re),Qe))),resolveRequest:L("resolveRequest",(Re,Qe,be)=>{let _e=Qe!==null?ue.toPortablePath(Qe):null,Te=H(ue.toPortablePath(Re),_e,be);return Te===null?null:ue.fromPortablePath(Te)}),resolveVirtual:L("resolveVirtual",Re=>{let Qe=lt(ue.toPortablePath(Re));return Qe!==null?ue.fromPortablePath(Qe):null})}}Pt();var $Ie=(t,e,r)=>{let o=XB(t),a=Yj(o,{basePath:e}),n=ue.join(e,dr.pnpCjs);return rq(a,{fakeFs:r,pnpapiResolution:n})};var iq=$e(t1e());qt();var mA={};Kt(mA,{checkManifestCompatibility:()=>r1e,extractBuildRequest:()=>vQ,getExtractHint:()=>sq,hasBindingGyp:()=>oq});Ye();Pt();function r1e(t){return W.isPackageCompatible(t,Ji.getArchitectureSet())}function vQ(t,e,r,{configuration:o}){let a=[];for(let n of["preinstall","install","postinstall"])e.manifest.scripts.has(n)&&a.push({type:0,script:n});return!e.manifest.scripts.has("install")&&e.misc.hasBindingGyp&&a.push({type:1,script:"node-gyp rebuild"}),a.length===0?null:t.linkType!=="HARD"?{skipped:!0,explain:n=>n.reportWarningOnce(6,`${W.prettyLocator(o,t)} lists build scripts, but is referenced through a soft link. Soft links don't support build scripts, so they'll be ignored.`)}:r&&r.built===!1?{skipped:!0,explain:n=>n.reportInfoOnce(5,`${W.prettyLocator(o,t)} lists build scripts, but its build has been explicitly disabled through configuration.`)}:!o.get("enableScripts")&&!r.built?{skipped:!0,explain:n=>n.reportWarningOnce(4,`${W.prettyLocator(o,t)} lists build scripts, but all build scripts have been disabled.`)}:r1e(t)?{skipped:!1,directives:a}:{skipped:!0,explain:n=>n.reportWarningOnce(76,`${W.prettyLocator(o,t)} The ${Ji.getArchitectureName()} architecture is incompatible with this package, build skipped.`)}}var VIt=new Set([".exe",".bin",".h",".hh",".hpp",".c",".cc",".cpp",".java",".jar",".node"]);function sq(t){return t.packageFs.getExtractHint({relevantExtensions:VIt})}function oq(t){let e=K.join(t.prefixPath,"binding.gyp");return t.packageFs.existsSync(e)}var av={};Kt(av,{getUnpluggedPath:()=>ov});Ye();Pt();function ov(t,{configuration:e}){return K.resolve(e.get("pnpUnpluggedFolder"),W.slugifyLocator(t))}var KIt=new Set([W.makeIdent(null,"open").identHash,W.makeIdent(null,"opn").identHash]),P0=class{constructor(){this.mode="strict";this.pnpCache=new Map}getCustomDataKey(){return JSON.stringify({name:"PnpLinker",version:2})}supportsPackage(e,r){return this.isEnabled(r)}async findPackageLocation(e,r){if(!this.isEnabled(r))throw new Error("Assertion failed: Expected the PnP linker to be enabled");let o=S0(r.project).cjs;if(!oe.existsSync(o))throw new it(`The project in ${de.pretty(r.project.configuration,`${r.project.cwd}/package.json`,de.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let a=je.getFactoryWithDefault(this.pnpCache,o,()=>je.dynamicRequire(o,{cachingStrategy:je.CachingStrategy.FsTime})),n={name:W.stringifyIdent(e),reference:e.reference},u=a.getPackageInformation(n);if(!u)throw new it(`Couldn't find ${W.prettyLocator(r.project.configuration,e)} in the currently installed PnP map - running an install might help`);return ue.toPortablePath(u.packageLocation)}async findPackageLocator(e,r){if(!this.isEnabled(r))return null;let o=S0(r.project).cjs;if(!oe.existsSync(o))return null;let n=je.getFactoryWithDefault(this.pnpCache,o,()=>je.dynamicRequire(o,{cachingStrategy:je.CachingStrategy.FsTime})).findPackageLocator(ue.fromPortablePath(e));return n?W.makeLocator(W.parseIdent(n.name),n.reference):null}makeInstaller(e){return new dm(e)}isEnabled(e){return!(e.project.configuration.get("nodeLinker")!=="pnp"||e.project.configuration.get("pnpMode")!==this.mode)}},dm=class{constructor(e){this.opts=e;this.mode="strict";this.asyncActions=new je.AsyncActions(10);this.packageRegistry=new Map;this.virtualTemplates=new Map;this.isESMLoaderRequired=!1;this.customData={store:new Map};this.unpluggedPaths=new Set;this.opts=e}attachCustomData(e){this.customData=e}async installPackage(e,r,o){let a=W.stringifyIdent(e),n=e.reference,u=!!this.opts.project.tryWorkspaceByLocator(e),A=W.isVirtualLocator(e),p=e.peerDependencies.size>0&&!A,h=!p&&!u,E=!p&&e.linkType!=="SOFT",I,v;if(h||E){let te=A?W.devirtualizeLocator(e):e;I=this.customData.store.get(te.locatorHash),typeof I>"u"&&(I=await JIt(r),e.linkType==="HARD"&&this.customData.store.set(te.locatorHash,I)),I.manifest.type==="module"&&(this.isESMLoaderRequired=!0),v=this.opts.project.getDependencyMeta(te,e.version)}let b=h?vQ(e,I,v,{configuration:this.opts.project.configuration}):null,C=E?await this.unplugPackageIfNeeded(e,I,r,v,o):r.packageFs;if(K.isAbsolute(r.prefixPath))throw new Error(`Assertion failed: Expected the prefix path (${r.prefixPath}) to be relative to the parent`);let T=K.resolve(C.getRealPath(),r.prefixPath),L=aq(this.opts.project.cwd,T),U=new Map,J=new Set;if(A){for(let te of e.peerDependencies.values())U.set(W.stringifyIdent(te),null),J.add(W.stringifyIdent(te));if(!u){let te=W.devirtualizeLocator(e);this.virtualTemplates.set(te.locatorHash,{location:aq(this.opts.project.cwd,mi.resolveVirtual(T)),locator:te})}}return je.getMapWithDefault(this.packageRegistry,a).set(n,{packageLocation:L,packageDependencies:U,packagePeers:J,linkType:e.linkType,discardFromLookup:r.discardFromLookup||!1}),{packageLocation:T,buildRequest:b}}async attachInternalDependencies(e,r){let o=this.getPackageInformation(e);for(let[a,n]of r){let u=W.areIdentsEqual(a,n)?n.reference:[W.stringifyIdent(n),n.reference];o.packageDependencies.set(W.stringifyIdent(a),u)}}async attachExternalDependents(e,r){for(let o of r)this.getDiskInformation(o).packageDependencies.set(W.stringifyIdent(e),e.reference)}async finalizeInstall(){if(this.opts.project.configuration.get("pnpMode")!==this.mode)return;let e=S0(this.opts.project);if(this.isEsmEnabled()||await oe.removePromise(e.esmLoader),this.opts.project.configuration.get("nodeLinker")!=="pnp"){await oe.removePromise(e.cjs),await oe.removePromise(e.data),await oe.removePromise(e.esmLoader),await oe.removePromise(this.opts.project.configuration.get("pnpUnpluggedFolder"));return}for(let{locator:E,location:I}of this.virtualTemplates.values())je.getMapWithDefault(this.packageRegistry,W.stringifyIdent(E)).set(E.reference,{packageLocation:I,packageDependencies:new Map,packagePeers:new Set,linkType:"SOFT",discardFromLookup:!1});this.packageRegistry.set(null,new Map([[null,this.getPackageInformation(this.opts.project.topLevelWorkspace.anchoredLocator)]]));let r=this.opts.project.configuration.get("pnpFallbackMode"),o=this.opts.project.workspaces.map(({anchoredLocator:E})=>({name:W.stringifyIdent(E),reference:E.reference})),a=r!=="none",n=[],u=new Map,A=je.buildIgnorePattern([".yarn/sdks/**",...this.opts.project.configuration.get("pnpIgnorePatterns")]),p=this.packageRegistry,h=this.opts.project.configuration.get("pnpShebang");if(r==="dependencies-only")for(let E of this.opts.project.storedPackages.values())this.opts.project.tryWorkspaceByLocator(E)&&n.push({name:W.stringifyIdent(E),reference:E.reference});return await this.asyncActions.wait(),await this.finalizeInstallWithPnp({dependencyTreeRoots:o,enableTopLevelFallback:a,fallbackExclusionList:n,fallbackPool:u,ignorePattern:A,packageRegistry:p,shebang:h}),{customData:this.customData}}async transformPnpSettings(e){}isEsmEnabled(){if(this.opts.project.configuration.sources.has("pnpEnableEsmLoader"))return this.opts.project.configuration.get("pnpEnableEsmLoader");if(this.isESMLoaderRequired)return!0;for(let e of this.opts.project.workspaces)if(e.manifest.type==="module")return!0;return!1}async finalizeInstallWithPnp(e){let r=S0(this.opts.project),o=await this.locateNodeModules(e.ignorePattern);if(o.length>0){this.opts.report.reportWarning(31,"One or more node_modules have been detected and will be removed. This operation may take some time.");for(let n of o)await oe.removePromise(n)}if(await this.transformPnpSettings(e),this.opts.project.configuration.get("pnpEnableInlining")){let n=bIe(e);await oe.changeFilePromise(r.cjs,n,{automaticNewlines:!0,mode:493}),await oe.removePromise(r.data)}else{let{dataFile:n,loaderFile:u}=kIe(e);await oe.changeFilePromise(r.cjs,u,{automaticNewlines:!0,mode:493}),await oe.changeFilePromise(r.data,n,{automaticNewlines:!0,mode:420})}this.isEsmEnabled()&&(this.opts.report.reportWarning(0,"ESM support for PnP uses the experimental loader API and is therefore experimental"),await oe.changeFilePromise(r.esmLoader,(0,iq.default)(),{automaticNewlines:!0,mode:420}));let a=this.opts.project.configuration.get("pnpUnpluggedFolder");if(this.unpluggedPaths.size===0)await oe.removePromise(a);else for(let n of await oe.readdirPromise(a)){let u=K.resolve(a,n);this.unpluggedPaths.has(u)||await oe.removePromise(u)}}async locateNodeModules(e){let r=[],o=e?new RegExp(e):null;for(let a of this.opts.project.workspaces){let n=K.join(a.cwd,"node_modules");if(o&&o.test(K.relative(this.opts.project.cwd,a.cwd))||!oe.existsSync(n))continue;let u=await oe.readdirPromise(n,{withFileTypes:!0}),A=u.filter(p=>!p.isDirectory()||p.name===".bin"||!p.name.startsWith("."));if(A.length===u.length)r.push(n);else for(let p of A)r.push(K.join(n,p.name))}return r}async unplugPackageIfNeeded(e,r,o,a,n){return this.shouldBeUnplugged(e,r,a)?this.unplugPackage(e,o,n):o.packageFs}shouldBeUnplugged(e,r,o){return typeof o.unplugged<"u"?o.unplugged:KIt.has(e.identHash)||e.conditions!=null?!0:r.manifest.preferUnplugged!==null?r.manifest.preferUnplugged:!!(vQ(e,r,o,{configuration:this.opts.project.configuration})?.skipped===!1||r.misc.extractHint)}async unplugPackage(e,r,o){let a=ov(e,{configuration:this.opts.project.configuration});return this.opts.project.disabledLocators.has(e.locatorHash)?new Uu(a,{baseFs:r.packageFs,pathUtils:K}):(this.unpluggedPaths.add(a),o.holdFetchResult(this.asyncActions.set(e.locatorHash,async()=>{let n=K.join(a,r.prefixPath,".ready");await oe.existsPromise(n)||(this.opts.project.storedBuildState.delete(e.locatorHash),await oe.mkdirPromise(a,{recursive:!0}),await oe.copyPromise(a,Bt.dot,{baseFs:r.packageFs,overwrite:!1}),await oe.writeFilePromise(n,""))})),new gn(a))}getPackageInformation(e){let r=W.stringifyIdent(e),o=e.reference,a=this.packageRegistry.get(r);if(!a)throw new Error(`Assertion failed: The package information store should have been available (for ${W.prettyIdent(this.opts.project.configuration,e)})`);let n=a.get(o);if(!n)throw new Error(`Assertion failed: The package information should have been available (for ${W.prettyLocator(this.opts.project.configuration,e)})`);return n}getDiskInformation(e){let r=je.getMapWithDefault(this.packageRegistry,"@@disk"),o=aq(this.opts.project.cwd,e);return je.getFactoryWithDefault(r,o,()=>({packageLocation:o,packageDependencies:new Map,packagePeers:new Set,linkType:"SOFT",discardFromLookup:!1}))}};function aq(t,e){let r=K.relative(t,e);return r.match(/^\.{0,2}\//)||(r=`./${r}`),r.replace(/\/?$/,"/")}async function JIt(t){let e=await Mt.tryFind(t.prefixPath,{baseFs:t.packageFs})??new Mt,r=new Set(["preinstall","install","postinstall"]);for(let o of e.scripts.keys())r.has(o)||e.scripts.delete(o);return{manifest:{scripts:e.scripts,preferUnplugged:e.preferUnplugged,type:e.type},misc:{extractHint:sq(t),hasBindingGyp:oq(t)}}}Ye();Ye();qt();var n1e=$e(Zo());var x0=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("-A,--all",!1,{description:"Unplug direct dependencies from the entire project"});this.recursive=ge.Boolean("-R,--recursive",!1,{description:"Unplug both direct and transitive dependencies"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.patterns=ge.Rest()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n=await Lr.find(r);if(!a)throw new rr(o.cwd,this.context.cwd);if(r.get("nodeLinker")!=="pnp")throw new it("This command can only be used if the `nodeLinker` option is set to `pnp`");await o.restoreInstallState();let u=new Set(this.patterns),A=this.patterns.map(b=>{let C=W.parseDescriptor(b),T=C.range!=="unknown"?C:W.makeDescriptor(C,"*");if(!kr.validRange(T.range))throw new it(`The range of the descriptor patterns must be a valid semver range (${W.prettyDescriptor(r,T)})`);return L=>{let U=W.stringifyIdent(L);return!n1e.default.isMatch(U,W.stringifyIdent(T))||L.version&&!kr.satisfiesWithPrereleases(L.version,T.range)?!1:(u.delete(b),!0)}}),p=()=>{let b=[];for(let C of o.storedPackages.values())!o.tryWorkspaceByLocator(C)&&!W.isVirtualLocator(C)&&A.some(T=>T(C))&&b.push(C);return b},h=b=>{let C=new Set,T=[],L=(U,J)=>{if(C.has(U.locatorHash))return;let te=!!o.tryWorkspaceByLocator(U);if(!(J>0&&!this.recursive&&te)&&(C.add(U.locatorHash),!o.tryWorkspaceByLocator(U)&&A.some(le=>le(U))&&T.push(U),!(J>0&&!this.recursive)))for(let le of U.dependencies.values()){let pe=o.storedResolutions.get(le.descriptorHash);if(!pe)throw new Error("Assertion failed: The resolution should have been registered");let Ae=o.storedPackages.get(pe);if(!Ae)throw new Error("Assertion failed: The package should have been registered");L(Ae,J+1)}};for(let U of b)L(U.anchoredPackage,0);return T},E,I;if(this.all&&this.recursive?(E=p(),I="the project"):this.all?(E=h(o.workspaces),I="any workspace"):(E=h([a]),I="this workspace"),u.size>1)throw new it(`Patterns ${de.prettyList(r,u,de.Type.CODE)} don't match any packages referenced by ${I}`);if(u.size>0)throw new it(`Pattern ${de.prettyList(r,u,de.Type.CODE)} doesn't match any packages referenced by ${I}`);E=je.sortMap(E,b=>W.stringifyLocator(b));let v=await Nt.start({configuration:r,stdout:this.context.stdout,json:this.json},async b=>{for(let C of E){let T=C.version??"unknown",L=o.topLevelWorkspace.manifest.ensureDependencyMeta(W.makeDescriptor(C,T));L.unplugged=!0,b.reportInfo(0,`Will unpack ${W.prettyLocator(r,C)} to ${de.pretty(r,ov(C,{configuration:r}),de.Type.PATH)}`),b.reportJson({locator:W.stringifyLocator(C),version:T})}await o.topLevelWorkspace.persistManifest(),this.json||b.reportSeparator()});return v.hasErrors()?v.exitCode():await o.installWithNewReport({json:this.json,stdout:this.context.stdout},{cache:n})}};x0.paths=[["unplug"]],x0.usage=nt.Usage({description:"force the unpacking of a list of packages",details:"\n This command will add the selectors matching the specified patterns to the list of packages that must be unplugged when installed.\n\n A package being unplugged means that instead of being referenced directly through its archive, it will be unpacked at install time in the directory configured via `pnpUnpluggedFolder`. Note that unpacking packages this way is generally not recommended because it'll make it harder to store your packages within the repository. However, it's a good approach to quickly and safely debug some packages, and can even sometimes be required depending on the context (for example when the package contains shellscripts).\n\n Running the command will set a persistent flag inside your top-level `package.json`, in the `dependenciesMeta` field. As such, to undo its effects, you'll need to revert the changes made to the manifest and run `yarn install` to apply the modification.\n\n By default, only direct dependencies from the current workspace are affected. If `-A,--all` is set, direct dependencies from the entire project are affected. Using the `-R,--recursive` flag will affect transitive dependencies as well as direct ones.\n\n This command accepts glob patterns inside the scope and name components (not the range). Make sure to escape the patterns to prevent your own shell from trying to expand them.\n ",examples:[["Unplug the lodash dependency from the active workspace","yarn unplug lodash"],["Unplug all instances of lodash referenced by any workspace","yarn unplug lodash -A"],["Unplug all instances of lodash referenced by the active workspace and its dependencies","yarn unplug lodash -R"],["Unplug all instances of lodash, anywhere","yarn unplug lodash -AR"],["Unplug one specific version of lodash","yarn unplug lodash@1.2.3"],["Unplug all packages with the `@babel` scope","yarn unplug '@babel/*'"],["Unplug all packages (only for testing, not recommended)","yarn unplug -R '*'"]]});var S0=t=>({cjs:K.join(t.cwd,dr.pnpCjs),data:K.join(t.cwd,dr.pnpData),esmLoader:K.join(t.cwd,dr.pnpEsmLoader)}),s1e=t=>/\s/.test(t)?JSON.stringify(t):t;async function zIt(t,e,r){let o=/\s*--require\s+\S*\.pnp\.c?js\s*/g,a=/\s*--experimental-loader\s+\S*\.pnp\.loader\.mjs\s*/,n=(e.NODE_OPTIONS??"").replace(o," ").replace(a," ").trim();if(t.configuration.get("nodeLinker")!=="pnp"){e.NODE_OPTIONS=n;return}let u=S0(t),A=`--require ${s1e(ue.fromPortablePath(u.cjs))}`;oe.existsSync(u.esmLoader)&&(A=`${A} --experimental-loader ${(0,i1e.pathToFileURL)(ue.fromPortablePath(u.esmLoader)).href}`),oe.existsSync(u.cjs)&&(e.NODE_OPTIONS=n?`${A} ${n}`:A)}async function XIt(t,e){let r=S0(t);e(r.cjs),e(r.data),e(r.esmLoader),e(t.configuration.get("pnpUnpluggedFolder"))}var ZIt={hooks:{populateYarnPaths:XIt,setupScriptEnvironment:zIt},configuration:{nodeLinker:{description:'The linker used for installing Node packages, one of: "pnp", "pnpm", or "node-modules"',type:"STRING",default:"pnp"},winLinkType:{description:"Whether Yarn should use Windows Junctions or symlinks when creating links on Windows.",type:"STRING",values:["junctions","symlinks"],default:"junctions"},pnpMode:{description:"If 'strict', generates standard PnP maps. If 'loose', merges them with the n_m resolution.",type:"STRING",default:"strict"},pnpShebang:{description:"String to prepend to the generated PnP script",type:"STRING",default:"#!/usr/bin/env node"},pnpIgnorePatterns:{description:"Array of glob patterns; files matching them will use the classic resolution",type:"STRING",default:[],isArray:!0},pnpEnableEsmLoader:{description:"If true, Yarn will generate an ESM loader (`.pnp.loader.mjs`). If this is not explicitly set Yarn tries to automatically detect whether ESM support is required.",type:"BOOLEAN",default:!1},pnpEnableInlining:{description:"If true, the PnP data will be inlined along with the generated loader",type:"BOOLEAN",default:!0},pnpFallbackMode:{description:"If true, the generated PnP loader will follow the top-level fallback rule",type:"STRING",default:"dependencies-only"},pnpUnpluggedFolder:{description:"Folder where the unplugged packages must be stored",type:"ABSOLUTE_PATH",default:"./.yarn/unplugged"}},linkers:[P0],commands:[x0]},$It=ZIt;var p1e=$e(u1e());qt();var gq=$e(Be("crypto")),h1e=$e(Be("fs")),g1e=1,Pi="node_modules",DQ=".bin",d1e=".yarn-state.yml",d1t=1e3,dq=(o=>(o.CLASSIC="classic",o.HARDLINKS_LOCAL="hardlinks-local",o.HARDLINKS_GLOBAL="hardlinks-global",o))(dq||{}),lv=class{constructor(){this.installStateCache=new Map}getCustomDataKey(){return JSON.stringify({name:"NodeModulesLinker",version:3})}supportsPackage(e,r){return this.isEnabled(r)}async findPackageLocation(e,r){if(!this.isEnabled(r))throw new Error("Assertion failed: Expected the node-modules linker to be enabled");let o=r.project.tryWorkspaceByLocator(e);if(o)return o.cwd;let a=await je.getFactoryWithDefault(this.installStateCache,r.project.cwd,async()=>await hq(r.project,{unrollAliases:!0}));if(a===null)throw new it("Couldn't find the node_modules state file - running an install might help (findPackageLocation)");let n=a.locatorMap.get(W.stringifyLocator(e));if(!n){let p=new it(`Couldn't find ${W.prettyLocator(r.project.configuration,e)} in the currently installed node_modules map - running an install might help`);throw p.code="LOCATOR_NOT_INSTALLED",p}let u=n.locations.sort((p,h)=>p.split(K.sep).length-h.split(K.sep).length),A=K.join(r.project.configuration.startingCwd,Pi);return u.find(p=>K.contains(A,p))||n.locations[0]}async findPackageLocator(e,r){if(!this.isEnabled(r))return null;let o=await je.getFactoryWithDefault(this.installStateCache,r.project.cwd,async()=>await hq(r.project,{unrollAliases:!0}));if(o===null)return null;let{locationRoot:a,segments:n}=PQ(K.resolve(e),{skipPrefix:r.project.cwd}),u=o.locationTree.get(a);if(!u)return null;let A=u.locator;for(let p of n){if(u=u.children.get(p),!u)break;A=u.locator||A}return W.parseLocator(A)}makeInstaller(e){return new pq(e)}isEnabled(e){return e.project.configuration.get("nodeLinker")==="node-modules"}},pq=class{constructor(e){this.opts=e;this.localStore=new Map;this.realLocatorChecksums=new Map;this.customData={store:new Map}}attachCustomData(e){this.customData=e}async installPackage(e,r){let o=K.resolve(r.packageFs.getRealPath(),r.prefixPath),a=this.customData.store.get(e.locatorHash);if(typeof a>"u"&&(a=await m1t(e,r),e.linkType==="HARD"&&this.customData.store.set(e.locatorHash,a)),!W.isPackageCompatible(e,this.opts.project.configuration.getSupportedArchitectures()))return{packageLocation:null,buildRequest:null};let n=new Map,u=new Set;n.has(W.stringifyIdent(e))||n.set(W.stringifyIdent(e),e.reference);let A=e;if(W.isVirtualLocator(e)){A=W.devirtualizeLocator(e);for(let E of e.peerDependencies.values())n.set(W.stringifyIdent(E),null),u.add(W.stringifyIdent(E))}let p={packageLocation:`${ue.fromPortablePath(o)}/`,packageDependencies:n,packagePeers:u,linkType:e.linkType,discardFromLookup:r.discardFromLookup??!1};this.localStore.set(e.locatorHash,{pkg:e,customPackageData:a,dependencyMeta:this.opts.project.getDependencyMeta(e,e.version),pnpNode:p});let h=r.checksum?r.checksum.substring(r.checksum.indexOf("/")+1):null;return this.realLocatorChecksums.set(A.locatorHash,h),{packageLocation:o,buildRequest:null}}async attachInternalDependencies(e,r){let o=this.localStore.get(e.locatorHash);if(typeof o>"u")throw new Error("Assertion failed: Expected information object to have been registered");for(let[a,n]of r){let u=W.areIdentsEqual(a,n)?n.reference:[W.stringifyIdent(n),n.reference];o.pnpNode.packageDependencies.set(W.stringifyIdent(a),u)}}async attachExternalDependents(e,r){throw new Error("External dependencies haven't been implemented for the node-modules linker")}async finalizeInstall(){if(this.opts.project.configuration.get("nodeLinker")!=="node-modules")return;let e=new mi({baseFs:new Jl({maxOpenFiles:80,readOnlyArchives:!0})}),r=await hq(this.opts.project),o=this.opts.project.configuration.get("nmMode");(r===null||o!==r.nmMode)&&(this.opts.project.storedBuildState.clear(),r={locatorMap:new Map,binSymlinks:new Map,locationTree:new Map,nmMode:o,mtimeMs:0});let a=new Map(this.opts.project.workspaces.map(v=>{let b=this.opts.project.configuration.get("nmHoistingLimits");try{b=je.validateEnum(KB,v.manifest.installConfig?.hoistingLimits??b)}catch{let T=W.prettyWorkspace(this.opts.project.configuration,v);this.opts.report.reportWarning(57,`${T}: Invalid 'installConfig.hoistingLimits' value. Expected one of ${Object.values(KB).join(", ")}, using default: "${b}"`)}return[v.relativeCwd,b]})),n=new Map(this.opts.project.workspaces.map(v=>{let b=this.opts.project.configuration.get("nmSelfReferences");return b=v.manifest.installConfig?.selfReferences??b,[v.relativeCwd,b]})),u={VERSIONS:{std:1},topLevel:{name:null,reference:null},getLocator:(v,b)=>Array.isArray(b)?{name:b[0],reference:b[1]}:{name:v,reference:b},getDependencyTreeRoots:()=>this.opts.project.workspaces.map(v=>{let b=v.anchoredLocator;return{name:W.stringifyIdent(b),reference:b.reference}}),getPackageInformation:v=>{let b=v.reference===null?this.opts.project.topLevelWorkspace.anchoredLocator:W.makeLocator(W.parseIdent(v.name),v.reference),C=this.localStore.get(b.locatorHash);if(typeof C>"u")throw new Error("Assertion failed: Expected the package reference to have been registered");return C.pnpNode},findPackageLocator:v=>{let b=this.opts.project.tryWorkspaceByCwd(ue.toPortablePath(v));if(b!==null){let C=b.anchoredLocator;return{name:W.stringifyIdent(C),reference:C.reference}}throw new Error("Assertion failed: Unimplemented")},resolveToUnqualified:()=>{throw new Error("Assertion failed: Unimplemented")},resolveUnqualified:()=>{throw new Error("Assertion failed: Unimplemented")},resolveRequest:()=>{throw new Error("Assertion failed: Unimplemented")},resolveVirtual:v=>ue.fromPortablePath(mi.resolveVirtual(ue.toPortablePath(v)))},{tree:A,errors:p,preserveSymlinksRequired:h}=JB(u,{pnpifyFs:!1,validateExternalSoftLinks:!0,hoistingLimitsByCwd:a,project:this.opts.project,selfReferencesByCwd:n});if(!A){for(let{messageName:v,text:b}of p)this.opts.report.reportError(v,b);return}let E=qj(A);await B1t(r,E,{baseFs:e,project:this.opts.project,report:this.opts.report,realLocatorChecksums:this.realLocatorChecksums,loadManifest:async v=>{let b=W.parseLocator(v),C=this.localStore.get(b.locatorHash);if(typeof C>"u")throw new Error("Assertion failed: Expected the slot to exist");return C.customPackageData.manifest}});let I=[];for(let[v,b]of E.entries()){if(C1e(v))continue;let C=W.parseLocator(v),T=this.localStore.get(C.locatorHash);if(typeof T>"u")throw new Error("Assertion failed: Expected the slot to exist");if(this.opts.project.tryWorkspaceByLocator(T.pkg))continue;let L=mA.extractBuildRequest(T.pkg,T.customPackageData,T.dependencyMeta,{configuration:this.opts.project.configuration});!L||I.push({buildLocations:b.locations,locator:C,buildRequest:L})}return h&&this.opts.report.reportWarning(72,`The application uses portals and that's why ${de.pretty(this.opts.project.configuration,"--preserve-symlinks",de.Type.CODE)} Node option is required for launching it`),{customData:this.customData,records:I}}};async function m1t(t,e){let r=await Mt.tryFind(e.prefixPath,{baseFs:e.packageFs})??new Mt,o=new Set(["preinstall","install","postinstall"]);for(let a of r.scripts.keys())o.has(a)||r.scripts.delete(a);return{manifest:{bin:r.bin,scripts:r.scripts},misc:{hasBindingGyp:mA.hasBindingGyp(e)}}}async function y1t(t,e,r,o,{installChangedByUser:a}){let n="";n+=`# Warning: This file is automatically generated. Removing it is fine, but will +`,n+=`# cause your node_modules installation to become invalidated. +`,n+=` +`,n+=`__metadata: +`,n+=` version: ${g1e} +`,n+=` nmMode: ${o.value} +`;let u=Array.from(e.keys()).sort(),A=W.stringifyLocator(t.topLevelWorkspace.anchoredLocator);for(let E of u){let I=e.get(E);n+=` +`,n+=`${JSON.stringify(E)}: +`,n+=` locations: +`;for(let v of I.locations){let b=K.contains(t.cwd,v);if(b===null)throw new Error(`Assertion failed: Expected the path to be within the project (${v})`);n+=` - ${JSON.stringify(b)} +`}if(I.aliases.length>0){n+=` aliases: +`;for(let v of I.aliases)n+=` - ${JSON.stringify(v)} +`}if(E===A&&r.size>0){n+=` bin: +`;for(let[v,b]of r){let C=K.contains(t.cwd,v);if(C===null)throw new Error(`Assertion failed: Expected the path to be within the project (${v})`);n+=` ${JSON.stringify(C)}: +`;for(let[T,L]of b){let U=K.relative(K.join(v,Pi),L);n+=` ${JSON.stringify(T)}: ${JSON.stringify(U)} +`}}}}let p=t.cwd,h=K.join(p,Pi,d1e);a&&await oe.removePromise(h),await oe.changeFilePromise(h,n,{automaticNewlines:!0})}async function hq(t,{unrollAliases:e=!1}={}){let r=t.cwd,o=K.join(r,Pi,d1e),a;try{a=await oe.statPromise(o)}catch{}if(!a)return null;let n=Vi(await oe.readFilePromise(o,"utf8"));if(n.__metadata.version>g1e)return null;let u=n.__metadata.nmMode||"classic",A=new Map,p=new Map;delete n.__metadata;for(let[h,E]of Object.entries(n)){let I=E.locations.map(b=>K.join(r,b)),v=E.bin;if(v)for(let[b,C]of Object.entries(v)){let T=K.join(r,ue.toPortablePath(b)),L=je.getMapWithDefault(p,T);for(let[U,J]of Object.entries(C))L.set(U,ue.toPortablePath([T,Pi,J].join(K.sep)))}if(A.set(h,{target:Bt.dot,linkType:"HARD",locations:I,aliases:E.aliases||[]}),e&&E.aliases)for(let b of E.aliases){let{scope:C,name:T}=W.parseLocator(h),L=W.makeLocator(W.makeIdent(C,T),b),U=W.stringifyLocator(L);A.set(U,{target:Bt.dot,linkType:"HARD",locations:I,aliases:[]})}}return{locatorMap:A,binSymlinks:p,locationTree:m1e(A,{skipPrefix:t.cwd}),nmMode:u,mtimeMs:a.mtimeMs}}var YC=async(t,e)=>{if(t.split(K.sep).indexOf(Pi)<0)throw new Error(`Assertion failed: trying to remove dir that doesn't contain node_modules: ${t}`);try{if(!e.innerLoop){let o=e.allowSymlink?await oe.statPromise(t):await oe.lstatPromise(t);if(e.allowSymlink&&!o.isDirectory()||!e.allowSymlink&&o.isSymbolicLink()){await oe.unlinkPromise(t);return}}let r=await oe.readdirPromise(t,{withFileTypes:!0});for(let o of r){let a=K.join(t,o.name);o.isDirectory()?(o.name!==Pi||e&&e.innerLoop)&&await YC(a,{innerLoop:!0,contentsOnly:!1}):await oe.unlinkPromise(a)}e.contentsOnly||await oe.rmdirPromise(t)}catch(r){if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw r}},A1e=4,PQ=(t,{skipPrefix:e})=>{let r=K.contains(e,t);if(r===null)throw new Error(`Assertion failed: Writing attempt prevented to ${t} which is outside project root: ${e}`);let o=r.split(K.sep).filter(p=>p!==""),a=o.indexOf(Pi),n=o.slice(0,a).join(K.sep),u=K.join(e,n),A=o.slice(a);return{locationRoot:u,segments:A}},m1e=(t,{skipPrefix:e})=>{let r=new Map;if(t===null)return r;let o=()=>({children:new Map,linkType:"HARD"});for(let[a,n]of t.entries()){if(n.linkType==="SOFT"&&K.contains(e,n.target)!==null){let A=je.getFactoryWithDefault(r,n.target,o);A.locator=a,A.linkType=n.linkType}for(let u of n.locations){let{locationRoot:A,segments:p}=PQ(u,{skipPrefix:e}),h=je.getFactoryWithDefault(r,A,o);for(let E=0;E<p.length;++E){let I=p[E];if(I!=="."){let v=je.getFactoryWithDefault(h.children,I,o);h.children.set(I,v),h=v}E===p.length-1&&(h.locator=a,h.linkType=n.linkType)}}}return r},mq=async(t,e,r)=>{if(process.platform==="win32"&&r==="junctions"){let o;try{o=await oe.lstatPromise(t)}catch{}if(!o||o.isDirectory()){await oe.symlinkPromise(t,e,"junction");return}}await oe.symlinkPromise(K.relative(K.dirname(e),t),e)};async function y1e(t,e,r){let o=K.join(t,`${gq.default.randomBytes(16).toString("hex")}.tmp`);try{await oe.writeFilePromise(o,r);try{await oe.linkPromise(o,e)}catch{}}finally{await oe.unlinkPromise(o)}}async function E1t({srcPath:t,dstPath:e,entry:r,globalHardlinksStore:o,baseFs:a,nmMode:n}){if(r.kind===E1e.FILE){if(n.value==="hardlinks-global"&&o&&r.digest){let A=K.join(o,r.digest.substring(0,2),`${r.digest.substring(2)}.dat`),p;try{let h=await oe.statPromise(A);if(h&&(!r.mtimeMs||h.mtimeMs>r.mtimeMs||h.mtimeMs<r.mtimeMs-d1t))if(await wn.checksumFile(A,{baseFs:oe,algorithm:"sha1"})!==r.digest){let I=K.join(o,`${gq.default.randomBytes(16).toString("hex")}.tmp`);await oe.renamePromise(A,I);let v=await a.readFilePromise(t);await oe.writeFilePromise(I,v);try{await oe.linkPromise(I,A),r.mtimeMs=new Date().getTime(),await oe.unlinkPromise(I)}catch{}}else r.mtimeMs||(r.mtimeMs=Math.ceil(h.mtimeMs));await oe.linkPromise(A,e),p=!0}catch{p=!1}if(!p){let h=await a.readFilePromise(t);await y1e(o,A,h),r.mtimeMs=new Date().getTime();try{await oe.linkPromise(A,e)}catch(E){E&&E.code&&E.code=="EXDEV"&&(n.value="hardlinks-local",await a.copyFilePromise(t,e))}}}else await a.copyFilePromise(t,e);let u=r.mode&511;u!==420&&await oe.chmodPromise(e,u)}}var E1e=(o=>(o.FILE="file",o.DIRECTORY="directory",o.SYMLINK="symlink",o))(E1e||{}),C1t=async(t,e,{baseFs:r,globalHardlinksStore:o,nmMode:a,windowsLinkType:n,packageChecksum:u})=>{await oe.mkdirPromise(t,{recursive:!0});let A=async(E=Bt.dot)=>{let I=K.join(e,E),v=await r.readdirPromise(I,{withFileTypes:!0}),b=new Map;for(let C of v){let T=K.join(E,C.name),L,U=K.join(I,C.name);if(C.isFile()){if(L={kind:"file",mode:(await r.lstatPromise(U)).mode},a.value==="hardlinks-global"){let J=await wn.checksumFile(U,{baseFs:r,algorithm:"sha1"});L.digest=J}}else if(C.isDirectory())L={kind:"directory"};else if(C.isSymbolicLink())L={kind:"symlink",symlinkTo:await r.readlinkPromise(U)};else throw new Error(`Unsupported file type (file: ${U}, mode: 0o${await r.statSync(U).mode.toString(8).padStart(6,"0")})`);if(b.set(T,L),C.isDirectory()&&T!==Pi){let J=await A(T);for(let[te,le]of J)b.set(te,le)}}return b},p;if(a.value==="hardlinks-global"&&o&&u){let E=K.join(o,u.substring(0,2),`${u.substring(2)}.json`);try{p=new Map(Object.entries(JSON.parse(await oe.readFilePromise(E,"utf8"))))}catch{p=await A()}}else p=await A();let h=!1;for(let[E,I]of p){let v=K.join(e,E),b=K.join(t,E);if(I.kind==="directory")await oe.mkdirPromise(b,{recursive:!0});else if(I.kind==="file"){let C=I.mtimeMs;await E1t({srcPath:v,dstPath:b,entry:I,nmMode:a,baseFs:r,globalHardlinksStore:o}),I.mtimeMs!==C&&(h=!0)}else I.kind==="symlink"&&await mq(K.resolve(K.dirname(b),I.symlinkTo),b,n)}if(a.value==="hardlinks-global"&&o&&h&&u){let E=K.join(o,u.substring(0,2),`${u.substring(2)}.json`);await oe.removePromise(E),await y1e(o,E,Buffer.from(JSON.stringify(Object.fromEntries(p))))}};function w1t(t,e,r,o){let a=new Map,n=new Map,u=new Map,A=!1,p=(h,E,I,v,b)=>{let C=!0,T=K.join(h,E),L=new Set;if(E===Pi||E.startsWith("@")){let J;try{J=oe.statSync(T)}catch{}C=!!J,J?J.mtimeMs>r?(A=!0,L=new Set(oe.readdirSync(T))):L=new Set(I.children.get(E).children.keys()):A=!0;let te=e.get(h);if(te){let le=K.join(h,Pi,DQ),pe;try{pe=oe.statSync(le)}catch{}if(!pe)A=!0;else if(pe.mtimeMs>r){A=!0;let Ae=new Set(oe.readdirSync(le)),ye=new Map;n.set(h,ye);for(let[ae,we]of te)Ae.has(ae)&&ye.set(ae,we)}else n.set(h,te)}}else C=b.has(E);let U=I.children.get(E);if(C){let{linkType:J,locator:te}=U,le={children:new Map,linkType:J,locator:te};if(v.children.set(E,le),te){let pe=je.getSetWithDefault(u,te);pe.add(T),u.set(te,pe)}for(let pe of U.children.keys())p(T,pe,U,le,L)}else U.locator&&o.storedBuildState.delete(W.parseLocator(U.locator).locatorHash)};for(let[h,E]of t){let{linkType:I,locator:v}=E,b={children:new Map,linkType:I,locator:v};if(a.set(h,b),v){let C=je.getSetWithDefault(u,E.locator);C.add(h),u.set(E.locator,C)}E.children.has(Pi)&&p(h,Pi,E,b,new Set)}return{locationTree:a,binSymlinks:n,locatorLocations:u,installChangedByUser:A}}function C1e(t){let e=W.parseDescriptor(t);return W.isVirtualDescriptor(e)&&(e=W.devirtualizeDescriptor(e)),e.range.startsWith("link:")}async function I1t(t,e,r,{loadManifest:o}){let a=new Map;for(let[A,{locations:p}]of t){let h=C1e(A)?null:await o(A,p[0]),E=new Map;if(h)for(let[I,v]of h.bin){let b=K.join(p[0],v);v!==""&&oe.existsSync(b)&&E.set(I,v)}a.set(A,E)}let n=new Map,u=(A,p,h)=>{let E=new Map,I=K.contains(r,A);if(h.locator&&I!==null){let v=a.get(h.locator);for(let[b,C]of v){let T=K.join(A,ue.toPortablePath(C));E.set(b,T)}for(let[b,C]of h.children){let T=K.join(A,b),L=u(T,T,C);L.size>0&&n.set(A,new Map([...n.get(A)||new Map,...L]))}}else for(let[v,b]of h.children){let C=u(K.join(A,v),p,b);for(let[T,L]of C)E.set(T,L)}return E};for(let[A,p]of e){let h=u(A,A,p);h.size>0&&n.set(A,new Map([...n.get(A)||new Map,...h]))}return n}var f1e=(t,e)=>{if(!t||!e)return t===e;let r=W.parseLocator(t);W.isVirtualLocator(r)&&(r=W.devirtualizeLocator(r));let o=W.parseLocator(e);return W.isVirtualLocator(o)&&(o=W.devirtualizeLocator(o)),W.areLocatorsEqual(r,o)};function yq(t){return K.join(t.get("globalFolder"),"store")}async function B1t(t,e,{baseFs:r,project:o,report:a,loadManifest:n,realLocatorChecksums:u}){let A=K.join(o.cwd,Pi),{locationTree:p,binSymlinks:h,locatorLocations:E,installChangedByUser:I}=w1t(t.locationTree,t.binSymlinks,t.mtimeMs,o),v=m1e(e,{skipPrefix:o.cwd}),b=[],C=async({srcDir:we,dstDir:Pe,linkType:g,globalHardlinksStore:Ee,nmMode:De,windowsLinkType:ce,packageChecksum:ne})=>{let ee=(async()=>{try{g==="SOFT"?(await oe.mkdirPromise(K.dirname(Pe),{recursive:!0}),await mq(K.resolve(we),Pe,ce)):await C1t(Pe,we,{baseFs:r,globalHardlinksStore:Ee,nmMode:De,windowsLinkType:ce,packageChecksum:ne})}catch(Ie){throw Ie.message=`While persisting ${we} -> ${Pe} ${Ie.message}`,Ie}finally{le.tick()}})().then(()=>b.splice(b.indexOf(ee),1));b.push(ee),b.length>A1e&&await Promise.race(b)},T=async(we,Pe,g)=>{let Ee=(async()=>{let De=async(ce,ne,ee)=>{try{ee.innerLoop||await oe.mkdirPromise(ne,{recursive:!0});let Ie=await oe.readdirPromise(ce,{withFileTypes:!0});for(let ke of Ie){if(!ee.innerLoop&&ke.name===DQ)continue;let ht=K.join(ce,ke.name),H=K.join(ne,ke.name);ke.isDirectory()?(ke.name!==Pi||ee&&ee.innerLoop)&&(await oe.mkdirPromise(H,{recursive:!0}),await De(ht,H,{...ee,innerLoop:!0})):ye.value==="hardlinks-local"||ye.value==="hardlinks-global"?await oe.linkPromise(ht,H):await oe.copyFilePromise(ht,H,h1e.default.constants.COPYFILE_FICLONE)}}catch(Ie){throw ee.innerLoop||(Ie.message=`While cloning ${ce} -> ${ne} ${Ie.message}`),Ie}finally{ee.innerLoop||le.tick()}};await De(we,Pe,g)})().then(()=>b.splice(b.indexOf(Ee),1));b.push(Ee),b.length>A1e&&await Promise.race(b)},L=async(we,Pe,g)=>{if(g)for(let[Ee,De]of Pe.children){let ce=g.children.get(Ee);await L(K.join(we,Ee),De,ce)}else{Pe.children.has(Pi)&&await YC(K.join(we,Pi),{contentsOnly:!1});let Ee=K.basename(we)===Pi&&v.has(K.join(K.dirname(we),K.sep));await YC(we,{contentsOnly:we===A,allowSymlink:Ee})}};for(let[we,Pe]of p){let g=v.get(we);for(let[Ee,De]of Pe.children){if(Ee===".")continue;let ce=g&&g.children.get(Ee),ne=K.join(we,Ee);await L(ne,De,ce)}}let U=async(we,Pe,g)=>{if(g){f1e(Pe.locator,g.locator)||await YC(we,{contentsOnly:Pe.linkType==="HARD"});for(let[Ee,De]of Pe.children){let ce=g.children.get(Ee);await U(K.join(we,Ee),De,ce)}}else{Pe.children.has(Pi)&&await YC(K.join(we,Pi),{contentsOnly:!0});let Ee=K.basename(we)===Pi&&v.has(K.join(K.dirname(we),K.sep));await YC(we,{contentsOnly:Pe.linkType==="HARD",allowSymlink:Ee})}};for(let[we,Pe]of v){let g=p.get(we);for(let[Ee,De]of Pe.children){if(Ee===".")continue;let ce=g&&g.children.get(Ee);await U(K.join(we,Ee),De,ce)}}let J=new Map,te=[];for(let[we,Pe]of E)for(let g of Pe){let{locationRoot:Ee,segments:De}=PQ(g,{skipPrefix:o.cwd}),ce=v.get(Ee),ne=Ee;if(ce){for(let ee of De)if(ne=K.join(ne,ee),ce=ce.children.get(ee),!ce)break;if(ce){let ee=f1e(ce.locator,we),Ie=e.get(ce.locator),ke=Ie.target,ht=ne,H=Ie.linkType;if(ee)J.has(ke)||J.set(ke,ht);else if(ke!==ht){let lt=W.parseLocator(ce.locator);W.isVirtualLocator(lt)&&(lt=W.devirtualizeLocator(lt)),te.push({srcDir:ke,dstDir:ht,linkType:H,realLocatorHash:lt.locatorHash})}}}}for(let[we,{locations:Pe}]of e.entries())for(let g of Pe){let{locationRoot:Ee,segments:De}=PQ(g,{skipPrefix:o.cwd}),ce=p.get(Ee),ne=v.get(Ee),ee=Ee,Ie=e.get(we),ke=W.parseLocator(we);W.isVirtualLocator(ke)&&(ke=W.devirtualizeLocator(ke));let ht=ke.locatorHash,H=Ie.target,lt=g;if(H===lt)continue;let Re=Ie.linkType;for(let Qe of De)ne=ne.children.get(Qe);if(!ce)te.push({srcDir:H,dstDir:lt,linkType:Re,realLocatorHash:ht});else for(let Qe of De)if(ee=K.join(ee,Qe),ce=ce.children.get(Qe),!ce){te.push({srcDir:H,dstDir:lt,linkType:Re,realLocatorHash:ht});break}}let le=Xs.progressViaCounter(te.length),pe=a.reportProgress(le),Ae=o.configuration.get("nmMode"),ye={value:Ae},ae=o.configuration.get("winLinkType");try{let we=ye.value==="hardlinks-global"?`${yq(o.configuration)}/v1`:null;if(we&&!await oe.existsPromise(we)){await oe.mkdirpPromise(we);for(let g=0;g<256;g++)await oe.mkdirPromise(K.join(we,g.toString(16).padStart(2,"0")))}for(let g of te)(g.linkType==="SOFT"||!J.has(g.srcDir))&&(J.set(g.srcDir,g.dstDir),await C({...g,globalHardlinksStore:we,nmMode:ye,windowsLinkType:ae,packageChecksum:u.get(g.realLocatorHash)||null}));await Promise.all(b),b.length=0;for(let g of te){let Ee=J.get(g.srcDir);g.linkType!=="SOFT"&&g.dstDir!==Ee&&await T(Ee,g.dstDir,{nmMode:ye})}await Promise.all(b),await oe.mkdirPromise(A,{recursive:!0});let Pe=await I1t(e,v,o.cwd,{loadManifest:n});await v1t(h,Pe,o.cwd,ae),await y1t(o,e,Pe,ye,{installChangedByUser:I}),Ae=="hardlinks-global"&&ye.value=="hardlinks-local"&&a.reportWarningOnce(74,"'nmMode' has been downgraded to 'hardlinks-local' due to global cache and install folder being on different devices")}finally{pe.stop()}}async function v1t(t,e,r,o){for(let a of t.keys()){if(K.contains(r,a)===null)throw new Error(`Assertion failed. Excepted bin symlink location to be inside project dir, instead it was at ${a}`);if(!e.has(a)){let n=K.join(a,Pi,DQ);await oe.removePromise(n)}}for(let[a,n]of e){if(K.contains(r,a)===null)throw new Error(`Assertion failed. Excepted bin symlink location to be inside project dir, instead it was at ${a}`);let u=K.join(a,Pi,DQ),A=t.get(a)||new Map;await oe.mkdirPromise(u,{recursive:!0});for(let p of A.keys())n.has(p)||(await oe.removePromise(K.join(u,p)),process.platform==="win32"&&await oe.removePromise(K.join(u,`${p}.cmd`)));for(let[p,h]of n){let E=A.get(p),I=K.join(u,p);E!==h&&(process.platform==="win32"?await(0,p1e.default)(ue.fromPortablePath(h),ue.fromPortablePath(I),{createPwshFile:!1}):(await oe.removePromise(I),await mq(h,I,o),K.contains(r,await oe.realpathPromise(h))!==null&&await oe.chmodPromise(h,493)))}}}Ye();Pt();nA();var cv=class extends P0{constructor(){super(...arguments);this.mode="loose"}makeInstaller(r){return new Eq(r)}},Eq=class extends dm{constructor(){super(...arguments);this.mode="loose"}async transformPnpSettings(r){let o=new mi({baseFs:new Jl({maxOpenFiles:80,readOnlyArchives:!0})}),a=$Ie(r,this.opts.project.cwd,o),{tree:n,errors:u}=JB(a,{pnpifyFs:!1,project:this.opts.project});if(!n){for(let{messageName:I,text:v}of u)this.opts.report.reportError(I,v);return}let A=new Map;r.fallbackPool=A;let p=(I,v)=>{let b=W.parseLocator(v.locator),C=W.stringifyIdent(b);C===I?A.set(I,b.reference):A.set(I,[C,b.reference])},h=K.join(this.opts.project.cwd,dr.nodeModules),E=n.get(h);if(!(typeof E>"u")){if("target"in E)throw new Error("Assertion failed: Expected the root junction point to be a directory");for(let I of E.dirList){let v=K.join(h,I),b=n.get(v);if(typeof b>"u")throw new Error("Assertion failed: Expected the child to have been registered");if("target"in b)p(I,b);else for(let C of b.dirList){let T=K.join(v,C),L=n.get(T);if(typeof L>"u")throw new Error("Assertion failed: Expected the subchild to have been registered");if("target"in L)p(`${I}/${C}`,L);else throw new Error("Assertion failed: Expected the leaf junction to be a package")}}}}};var D1t={hooks:{cleanGlobalArtifacts:async t=>{let e=yq(t);await oe.removePromise(e)}},configuration:{nmHoistingLimits:{description:"Prevents packages to be hoisted past specific levels",type:"STRING",values:["workspaces","dependencies","none"],default:"none"},nmMode:{description:"Defines in which measure Yarn must use hardlinks and symlinks when generated `node_modules` directories.",type:"STRING",values:["classic","hardlinks-local","hardlinks-global"],default:"classic"},nmSelfReferences:{description:"Defines whether the linker should generate self-referencing symlinks for workspaces.",type:"BOOLEAN",default:!0}},linkers:[lv,cv]},P1t=D1t;var EG={};Kt(EG,{NpmHttpFetcher:()=>fv,NpmRemapResolver:()=>pv,NpmSemverFetcher:()=>dl,NpmSemverResolver:()=>hv,NpmTagResolver:()=>gv,default:()=>Ovt,npmConfigUtils:()=>Zn,npmHttpUtils:()=>on,npmPublishUtils:()=>sw});Ye();var x1e=$e(zn());var Wn="npm:";var on={};Kt(on,{AuthType:()=>P1e,customPackageError:()=>mm,del:()=>N1t,get:()=>ym,getIdentUrl:()=>SQ,getPackageMetadata:()=>KC,handleInvalidAuthenticationError:()=>b0,post:()=>T1t,put:()=>R1t});Ye();Ye();Pt();var Bq=$e(A2()),v1e=$e(S_()),D1e=$e(zn()),vq=Be("url");var Zn={};Kt(Zn,{RegistryType:()=>w1e,getAuditRegistry:()=>S1t,getAuthConfiguration:()=>Iq,getDefaultRegistry:()=>uv,getPublishRegistry:()=>x1t,getRegistryConfiguration:()=>I1e,getScopeConfiguration:()=>wq,getScopeRegistry:()=>WC,normalizeRegistry:()=>oc});var w1e=(o=>(o.AUDIT_REGISTRY="npmAuditRegistry",o.FETCH_REGISTRY="npmRegistryServer",o.PUBLISH_REGISTRY="npmPublishRegistry",o))(w1e||{});function oc(t){return t.replace(/\/$/,"")}function S1t({configuration:t}){return uv({configuration:t,type:"npmAuditRegistry"})}function x1t(t,{configuration:e}){return t.publishConfig?.registry?oc(t.publishConfig.registry):t.name?WC(t.name.scope,{configuration:e,type:"npmPublishRegistry"}):uv({configuration:e,type:"npmPublishRegistry"})}function WC(t,{configuration:e,type:r="npmRegistryServer"}){let o=wq(t,{configuration:e});if(o===null)return uv({configuration:e,type:r});let a=o.get(r);return a===null?uv({configuration:e,type:r}):oc(a)}function uv({configuration:t,type:e="npmRegistryServer"}){let r=t.get(e);return oc(r!==null?r:t.get("npmRegistryServer"))}function I1e(t,{configuration:e}){let r=e.get("npmRegistries"),o=oc(t),a=r.get(o);if(typeof a<"u")return a;let n=r.get(o.replace(/^[a-z]+:/,""));return typeof n<"u"?n:null}function wq(t,{configuration:e}){if(t===null)return null;let o=e.get("npmScopes").get(t);return o||null}function Iq(t,{configuration:e,ident:r}){let o=r&&wq(r.scope,{configuration:e});return o?.get("npmAuthIdent")||o?.get("npmAuthToken")?o:I1e(t,{configuration:e})||e}var P1e=(a=>(a[a.NO_AUTH=0]="NO_AUTH",a[a.BEST_EFFORT=1]="BEST_EFFORT",a[a.CONFIGURATION=2]="CONFIGURATION",a[a.ALWAYS_AUTH=3]="ALWAYS_AUTH",a))(P1e||{});async function b0(t,{attemptedAs:e,registry:r,headers:o,configuration:a}){if(bQ(t))throw new zt(41,"Invalid OTP token");if(t.originalError?.name==="HTTPError"&&t.originalError?.response.statusCode===401)throw new zt(41,`Invalid authentication (${typeof e!="string"?`as ${await M1t(r,o,{configuration:a})}`:`attempted as ${e}`})`)}function mm(t,e){let r=t.response?.statusCode;return r?r===404?"Package not found":r>=500&&r<600?`The registry appears to be down (using a ${de.applyHyperlink(e,"local cache","https://yarnpkg.com/advanced/lexicon#local-cache")} might have protected you against such outages)`:null:null}function SQ(t){return t.scope?`/@${t.scope}%2f${t.name}`:`/${t.name}`}var B1e=new Map;async function KC(t,{cache:e,project:r,registry:o,headers:a,version:n,...u}){return await je.getFactoryWithDefault(B1e,t.identHash,async()=>{let{configuration:A}=r;o=Av(A,{ident:t,registry:o});let p=Q1t(A,o),h=K.join(p,`${W.slugifyIdent(t)}.json`),E=null;if(!r.lockfileNeedsRefresh){try{E=await oe.readJsonPromise(h)}catch{}if(E){if(typeof n<"u"&&typeof E.metadata.versions[n]<"u")return E.metadata;if(A.get("enableOfflineMode")){let I=structuredClone(E.metadata),v=new Set;if(e){for(let C of Object.keys(I.versions)){let T=W.makeLocator(t,`npm:${C}`),L=e.getLocatorMirrorPath(T);(!L||!oe.existsSync(L))&&(delete I.versions[C],v.add(C))}let b=I["dist-tags"].latest;if(v.has(b)){let C=Object.keys(E.metadata.versions).sort(D1e.default.compare),T=C.indexOf(b);for(;v.has(C[T])&&T>=0;)T-=1;T>=0?I["dist-tags"].latest=C[T]:delete I["dist-tags"].latest}}return I}}}return await ym(SQ(t),{...u,customErrorMessage:mm,configuration:A,registry:o,ident:t,headers:{...a,["If-None-Match"]:E?.etag,["If-Modified-Since"]:E?.lastModified},wrapNetworkRequest:async I=>async()=>{let v=await I();if(v.statusCode===304){if(E===null)throw new Error("Assertion failed: cachedMetadata should not be null");return{...v,body:E.metadata}}let b=b1t(JSON.parse(v.body.toString()));B1e.set(t.identHash,b);let C={metadata:b,etag:v.headers.etag,lastModified:v.headers["last-modified"]},T=`${h}-${process.pid}.tmp`;return await oe.mkdirPromise(p,{recursive:!0}),await oe.writeJsonPromise(T,C,{compact:!0}),await oe.renamePromise(T,h),{...v,body:b}}})})}var S1e=["name","dist.tarball","bin","scripts","os","cpu","libc","dependencies","dependenciesMeta","optionalDependencies","peerDependencies","peerDependenciesMeta","deprecated"];function b1t(t){return{"dist-tags":t["dist-tags"],versions:Object.fromEntries(Object.entries(t.versions).map(([e,r])=>[e,(0,v1e.default)(r,S1e)]))}}var k1t=wn.makeHash(...S1e).slice(0,6);function Q1t(t,e){let r=F1t(t),o=new vq.URL(e);return K.join(r,k1t,o.hostname)}function F1t(t){return K.join(t.get("globalFolder"),"metadata/npm")}async function ym(t,{configuration:e,headers:r,ident:o,authType:a,registry:n,...u}){n=Av(e,{ident:o,registry:n}),o&&o.scope&&typeof a>"u"&&(a=1);let A=await xQ(n,{authType:a,configuration:e,ident:o});A&&(r={...r,authorization:A});try{return await rn.get(t.charAt(0)==="/"?`${n}${t}`:t,{configuration:e,headers:r,...u})}catch(p){throw await b0(p,{registry:n,configuration:e,headers:r}),p}}async function T1t(t,e,{attemptedAs:r,configuration:o,headers:a,ident:n,authType:u=3,registry:A,otp:p,...h}){A=Av(o,{ident:n,registry:A});let E=await xQ(A,{authType:u,configuration:o,ident:n});E&&(a={...a,authorization:E}),p&&(a={...a,...VC(p)});try{return await rn.post(A+t,e,{configuration:o,headers:a,...h})}catch(I){if(!bQ(I)||p)throw await b0(I,{attemptedAs:r,registry:A,configuration:o,headers:a}),I;p=await Dq(I,{configuration:o});let v={...a,...VC(p)};try{return await rn.post(`${A}${t}`,e,{configuration:o,headers:v,...h})}catch(b){throw await b0(b,{attemptedAs:r,registry:A,configuration:o,headers:a}),b}}}async function R1t(t,e,{attemptedAs:r,configuration:o,headers:a,ident:n,authType:u=3,registry:A,otp:p,...h}){A=Av(o,{ident:n,registry:A});let E=await xQ(A,{authType:u,configuration:o,ident:n});E&&(a={...a,authorization:E}),p&&(a={...a,...VC(p)});try{return await rn.put(A+t,e,{configuration:o,headers:a,...h})}catch(I){if(!bQ(I))throw await b0(I,{attemptedAs:r,registry:A,configuration:o,headers:a}),I;p=await Dq(I,{configuration:o});let v={...a,...VC(p)};try{return await rn.put(`${A}${t}`,e,{configuration:o,headers:v,...h})}catch(b){throw await b0(b,{attemptedAs:r,registry:A,configuration:o,headers:a}),b}}}async function N1t(t,{attemptedAs:e,configuration:r,headers:o,ident:a,authType:n=3,registry:u,otp:A,...p}){u=Av(r,{ident:a,registry:u});let h=await xQ(u,{authType:n,configuration:r,ident:a});h&&(o={...o,authorization:h}),A&&(o={...o,...VC(A)});try{return await rn.del(u+t,{configuration:r,headers:o,...p})}catch(E){if(!bQ(E)||A)throw await b0(E,{attemptedAs:e,registry:u,configuration:r,headers:o}),E;A=await Dq(E,{configuration:r});let I={...o,...VC(A)};try{return await rn.del(`${u}${t}`,{configuration:r,headers:I,...p})}catch(v){throw await b0(v,{attemptedAs:e,registry:u,configuration:r,headers:o}),v}}}function Av(t,{ident:e,registry:r}){if(typeof r>"u"&&e)return WC(e.scope,{configuration:t});if(typeof r!="string")throw new Error("Assertion failed: The registry should be a string");return oc(r)}async function xQ(t,{authType:e=2,configuration:r,ident:o}){let a=Iq(t,{configuration:r,ident:o}),n=L1t(a,e);if(!n)return null;let u=await r.reduceHook(A=>A.getNpmAuthenticationHeader,void 0,t,{configuration:r,ident:o});if(u)return u;if(a.get("npmAuthToken"))return`Bearer ${a.get("npmAuthToken")}`;if(a.get("npmAuthIdent")){let A=a.get("npmAuthIdent");return A.includes(":")?`Basic ${Buffer.from(A).toString("base64")}`:`Basic ${A}`}if(n&&e!==1)throw new zt(33,"No authentication configured for request");return null}function L1t(t,e){switch(e){case 2:return t.get("npmAlwaysAuth");case 1:case 3:return!0;case 0:return!1;default:throw new Error("Unreachable")}}async function M1t(t,e,{configuration:r}){if(typeof e>"u"||typeof e.authorization>"u")return"an anonymous user";try{return(await rn.get(new vq.URL(`${t}/-/whoami`).href,{configuration:r,headers:e,jsonResponse:!0})).username??"an unknown user"}catch{return"an unknown user"}}async function Dq(t,{configuration:e}){let r=t.originalError?.response.headers["npm-notice"];if(r&&(await Nt.start({configuration:e,stdout:process.stdout,includeFooter:!1},async a=>{if(a.reportInfo(0,r.replace(/(https?:\/\/\S+)/g,de.pretty(e,"$1",de.Type.URL))),!process.env.YARN_IS_TEST_ENV){let n=r.match(/open (https?:\/\/\S+)/i);if(n&&Ji.openUrl){let{openNow:u}=await(0,Bq.prompt)({type:"confirm",name:"openNow",message:"Do you want to try to open this url now?",required:!0,initial:!0,onCancel:()=>process.exit(130)});u&&(await Ji.openUrl(n[1])||(a.reportSeparator(),a.reportWarning(0,"We failed to automatically open the url; you'll have to open it yourself in your browser of choice.")))}}}),process.stdout.write(` +`)),process.env.YARN_IS_TEST_ENV)return process.env.YARN_INJECT_NPM_2FA_TOKEN||"";let{otp:o}=await(0,Bq.prompt)({type:"password",name:"otp",message:"One-time password:",required:!0,onCancel:()=>process.exit(130)});return process.stdout.write(` +`),o}function bQ(t){if(t.originalError?.name!=="HTTPError")return!1;try{return(t.originalError?.response.headers["www-authenticate"].split(/,\s*/).map(r=>r.toLowerCase())).includes("otp")}catch{return!1}}function VC(t){return{["npm-otp"]:t}}var fv=class{supports(e,r){if(!e.reference.startsWith(Wn))return!1;let{selector:o,params:a}=W.parseRange(e.reference);return!(!x1e.default.valid(o)||a===null||typeof a.__archiveUrl!="string")}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${W.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the remote server`),loader:()=>this.fetchFromNetwork(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:W.getIdentVendorPath(e),checksum:u}}async fetchFromNetwork(e,r){let{params:o}=W.parseRange(e.reference);if(o===null||typeof o.__archiveUrl!="string")throw new Error("Assertion failed: The archiveUrl querystring parameter should have been available");let a=await ym(o.__archiveUrl,{customErrorMessage:mm,configuration:r.project.configuration,ident:e});return await Xi.convertToZip(a,{configuration:r.project.configuration,prefixPath:W.getIdentVendorPath(e),stripComponents:1})}};Ye();var pv=class{supportsDescriptor(e,r){return!(!e.range.startsWith(Wn)||!W.tryParseDescriptor(e.range.slice(Wn.length),!0))}supportsLocator(e,r){return!1}shouldPersistResolution(e,r){throw new Error("Unreachable")}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){let o=r.project.configuration.normalizeDependency(W.parseDescriptor(e.range.slice(Wn.length),!0));return r.resolver.getResolutionDependencies(o,r)}async getCandidates(e,r,o){let a=o.project.configuration.normalizeDependency(W.parseDescriptor(e.range.slice(Wn.length),!0));return await o.resolver.getCandidates(a,r,o)}async getSatisfying(e,r,o,a){let n=a.project.configuration.normalizeDependency(W.parseDescriptor(e.range.slice(Wn.length),!0));return a.resolver.getSatisfying(n,r,o,a)}resolve(e,r){throw new Error("Unreachable")}};Ye();Ye();var b1e=$e(zn()),k1e=Be("url");var dl=class{supports(e,r){if(!e.reference.startsWith(Wn))return!1;let o=new k1e.URL(e.reference);return!(!b1e.default.valid(o.pathname)||o.searchParams.has("__archiveUrl"))}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${W.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the remote registry`),loader:()=>this.fetchFromNetwork(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:W.getIdentVendorPath(e),checksum:u}}async fetchFromNetwork(e,r){let o;try{o=await ym(dl.getLocatorUrl(e),{customErrorMessage:mm,configuration:r.project.configuration,ident:e})}catch{o=await ym(dl.getLocatorUrl(e).replace(/%2f/g,"/"),{customErrorMessage:mm,configuration:r.project.configuration,ident:e})}return await Xi.convertToZip(o,{configuration:r.project.configuration,prefixPath:W.getIdentVendorPath(e),stripComponents:1})}static isConventionalTarballUrl(e,r,{configuration:o}){let a=WC(e.scope,{configuration:o}),n=dl.getLocatorUrl(e);return r=r.replace(/^https?:(\/\/(?:[^/]+\.)?npmjs.org(?:$|\/))/,"https:$1"),a=a.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"),r=r.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"),r===a+n||r===a+n.replace(/%2f/g,"/")}static getLocatorUrl(e){let r=kr.clean(e.reference.slice(Wn.length));if(r===null)throw new zt(10,"The npm semver resolver got selected, but the version isn't semver");return`${SQ(e)}/-/${e.name}-${r}.tgz`}};Ye();Ye();Ye();var Pq=$e(zn());var kQ=W.makeIdent(null,"node-gyp"),O1t=/\b(node-gyp|prebuild-install)\b/,hv=class{supportsDescriptor(e,r){return e.range.startsWith(Wn)?!!kr.validRange(e.range.slice(Wn.length)):!1}supportsLocator(e,r){if(!e.reference.startsWith(Wn))return!1;let{selector:o}=W.parseRange(e.reference);return!!Pq.default.valid(o)}shouldPersistResolution(e,r){return!0}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){let a=kr.validRange(e.range.slice(Wn.length));if(a===null)throw new Error(`Expected a valid range, got ${e.range.slice(Wn.length)}`);let n=await KC(e,{cache:o.fetchOptions?.cache,project:o.project,version:Pq.default.valid(a.raw)?a.raw:void 0}),u=je.mapAndFilter(Object.keys(n.versions),h=>{try{let E=new kr.SemVer(h);if(a.test(E))return E}catch{}return je.mapAndFilter.skip}),A=u.filter(h=>!n.versions[h.raw].deprecated),p=A.length>0?A:u;return p.sort((h,E)=>-h.compare(E)),p.map(h=>{let E=W.makeLocator(e,`${Wn}${h.raw}`),I=n.versions[h.raw].dist.tarball;return dl.isConventionalTarballUrl(E,I,{configuration:o.project.configuration})?E:W.bindLocator(E,{__archiveUrl:I})})}async getSatisfying(e,r,o,a){let n=kr.validRange(e.range.slice(Wn.length));if(n===null)throw new Error(`Expected a valid range, got ${e.range.slice(Wn.length)}`);return{locators:je.mapAndFilter(o,p=>{if(p.identHash!==e.identHash)return je.mapAndFilter.skip;let h=W.tryParseRange(p.reference,{requireProtocol:Wn});if(!h)return je.mapAndFilter.skip;let E=new kr.SemVer(h.selector);return n.test(E)?{locator:p,version:E}:je.mapAndFilter.skip}).sort((p,h)=>-p.version.compare(h.version)).map(({locator:p})=>p),sorted:!0}}async resolve(e,r){let{selector:o}=W.parseRange(e.reference),a=kr.clean(o);if(a===null)throw new zt(10,"The npm semver resolver got selected, but the version isn't semver");let n=await KC(e,{cache:r.fetchOptions?.cache,project:r.project,version:a});if(!Object.hasOwn(n,"versions"))throw new zt(15,'Registry returned invalid data for - missing "versions" field');if(!Object.hasOwn(n.versions,a))throw new zt(16,`Registry failed to return reference "${a}"`);let u=new Mt;if(u.load(n.versions[a]),!u.dependencies.has(kQ.identHash)&&!u.peerDependencies.has(kQ.identHash)){for(let A of u.scripts.values())if(A.match(O1t)){u.dependencies.set(kQ.identHash,W.makeDescriptor(kQ,"latest"));break}}return{...e,version:a,languageName:"node",linkType:"HARD",conditions:u.getConditions(),dependencies:r.project.configuration.normalizeDependencyMap(u.dependencies),peerDependencies:u.peerDependencies,dependenciesMeta:u.dependenciesMeta,peerDependenciesMeta:u.peerDependenciesMeta,bin:u.bin}}};Ye();Ye();var Q1e=$e(zn());var gv=class{supportsDescriptor(e,r){return!(!e.range.startsWith(Wn)||!QE.test(e.range.slice(Wn.length)))}supportsLocator(e,r){return!1}shouldPersistResolution(e,r){throw new Error("Unreachable")}bindDescriptor(e,r,o){return e}getResolutionDependencies(e,r){return{}}async getCandidates(e,r,o){let a=e.range.slice(Wn.length),n=await KC(e,{cache:o.fetchOptions?.cache,project:o.project});if(!Object.hasOwn(n,"dist-tags"))throw new zt(15,'Registry returned invalid data - missing "dist-tags" field');let u=n["dist-tags"];if(!Object.hasOwn(u,a))throw new zt(16,`Registry failed to return tag "${a}"`);let A=u[a],p=W.makeLocator(e,`${Wn}${A}`),h=n.versions[A].dist.tarball;return dl.isConventionalTarballUrl(p,h,{configuration:o.project.configuration})?[p]:[W.bindLocator(p,{__archiveUrl:h})]}async getSatisfying(e,r,o,a){let n=[];for(let u of o){if(u.identHash!==e.identHash)continue;let A=W.tryParseRange(u.reference,{requireProtocol:Wn});if(!(!A||!Q1e.default.valid(A.selector))){if(A.params?.__archiveUrl){let p=W.makeRange({protocol:Wn,selector:A.selector,source:null,params:null}),[h]=await a.resolver.getCandidates(W.makeDescriptor(e,p),r,a);if(u.reference!==h.reference)continue}n.push(u)}}return{locators:n,sorted:!1}}async resolve(e,r){throw new Error("Unreachable")}};var sw={};Kt(sw,{getGitHead:()=>Lvt,getPublishAccess:()=>wBe,getReadmeContent:()=>IBe,makePublishBody:()=>Nvt});Ye();Ye();Pt();var hG={};Kt(hG,{PackCommand:()=>O0,default:()=>mvt,packUtils:()=>CA});Ye();Ye();Ye();Pt();qt();var CA={};Kt(CA,{genPackList:()=>$Q,genPackStream:()=>pG,genPackageManifest:()=>lBe,hasPackScripts:()=>AG,prepareForPack:()=>fG});Ye();Pt();var uG=$e(Zo()),oBe=$e(rBe()),aBe=Be("zlib"),ovt=["/package.json","/readme","/readme.*","/license","/license.*","/licence","/licence.*","/changelog","/changelog.*"],avt=["/package.tgz",".github",".git",".hg","node_modules",".npmignore",".gitignore",".#*",".DS_Store"];async function AG(t){return!!(un.hasWorkspaceScript(t,"prepack")||un.hasWorkspaceScript(t,"postpack"))}async function fG(t,{report:e},r){await un.maybeExecuteWorkspaceLifecycleScript(t,"prepack",{report:e});try{let o=K.join(t.cwd,Mt.fileName);await oe.existsPromise(o)&&await t.manifest.loadFile(o,{baseFs:oe}),await r()}finally{await un.maybeExecuteWorkspaceLifecycleScript(t,"postpack",{report:e})}}async function pG(t,e){typeof e>"u"&&(e=await $Q(t));let r=new Set;for(let n of t.manifest.publishConfig?.executableFiles??new Set)r.add(K.normalize(n));for(let n of t.manifest.bin.values())r.add(K.normalize(n));let o=oBe.default.pack();process.nextTick(async()=>{for(let n of e){let u=K.normalize(n),A=K.resolve(t.cwd,u),p=K.join("package",u),h=await oe.lstatPromise(A),E={name:p,mtime:new Date(vi.SAFE_TIME*1e3)},I=r.has(u)?493:420,v,b,C=new Promise((L,U)=>{v=L,b=U}),T=L=>{L?b(L):v()};if(h.isFile()){let L;u==="package.json"?L=Buffer.from(JSON.stringify(await lBe(t),null,2)):L=await oe.readFilePromise(A),o.entry({...E,mode:I,type:"file"},L,T)}else h.isSymbolicLink()?o.entry({...E,mode:I,type:"symlink",linkname:await oe.readlinkPromise(A)},T):T(new Error(`Unsupported file type ${h.mode} for ${ue.fromPortablePath(u)}`));await C}o.finalize()});let a=(0,aBe.createGzip)();return o.pipe(a),a}async function lBe(t){let e=JSON.parse(JSON.stringify(t.manifest.raw));return await t.project.configuration.triggerHook(r=>r.beforeWorkspacePacking,t,e),e}async function $Q(t){let e=t.project,r=e.configuration,o={accept:[],reject:[]};for(let I of avt)o.reject.push(I);for(let I of ovt)o.accept.push(I);o.reject.push(r.get("rcFilename"));let a=I=>{if(I===null||!I.startsWith(`${t.cwd}/`))return;let v=K.relative(t.cwd,I),b=K.resolve(Bt.root,v);o.reject.push(b)};a(K.resolve(e.cwd,dr.lockfile)),a(r.get("cacheFolder")),a(r.get("globalFolder")),a(r.get("installStatePath")),a(r.get("virtualFolder")),a(r.get("yarnPath")),await r.triggerHook(I=>I.populateYarnPaths,e,I=>{a(I)});for(let I of e.workspaces){let v=K.relative(t.cwd,I.cwd);v!==""&&!v.match(/^(\.\.)?\//)&&o.reject.push(`/${v}`)}let n={accept:[],reject:[]},u=t.manifest.publishConfig?.main??t.manifest.main,A=t.manifest.publishConfig?.module??t.manifest.module,p=t.manifest.publishConfig?.browser??t.manifest.browser,h=t.manifest.publishConfig?.bin??t.manifest.bin;u!=null&&n.accept.push(K.resolve(Bt.root,u)),A!=null&&n.accept.push(K.resolve(Bt.root,A)),typeof p=="string"&&n.accept.push(K.resolve(Bt.root,p));for(let I of h.values())n.accept.push(K.resolve(Bt.root,I));if(p instanceof Map)for(let[I,v]of p.entries())n.accept.push(K.resolve(Bt.root,I)),typeof v=="string"&&n.accept.push(K.resolve(Bt.root,v));let E=t.manifest.files!==null;if(E){n.reject.push("/*");for(let I of t.manifest.files)cBe(n.accept,I,{cwd:Bt.root})}return await lvt(t.cwd,{hasExplicitFileList:E,globalList:o,ignoreList:n})}async function lvt(t,{hasExplicitFileList:e,globalList:r,ignoreList:o}){let a=[],n=new _u(t),u=[[Bt.root,[o]]];for(;u.length>0;){let[A,p]=u.pop(),h=await n.lstatPromise(A);if(!iBe(A,{globalList:r,ignoreLists:h.isDirectory()?null:p}))if(h.isDirectory()){let E=await n.readdirPromise(A),I=!1,v=!1;if(!e||A!==Bt.root)for(let T of E)I=I||T===".gitignore",v=v||T===".npmignore";let b=v?await nBe(n,A,".npmignore"):I?await nBe(n,A,".gitignore"):null,C=b!==null?[b].concat(p):p;iBe(A,{globalList:r,ignoreLists:p})&&(C=[...p,{accept:[],reject:["**/*"]}]);for(let T of E)u.push([K.resolve(A,T),C])}else(h.isFile()||h.isSymbolicLink())&&a.push(K.relative(Bt.root,A))}return a.sort()}async function nBe(t,e,r){let o={accept:[],reject:[]},a=await t.readFilePromise(K.join(e,r),"utf8");for(let n of a.split(/\n/g))cBe(o.reject,n,{cwd:e});return o}function cvt(t,{cwd:e}){let r=t[0]==="!";return r&&(t=t.slice(1)),t.match(/\.{0,1}\//)&&(t=K.resolve(e,t)),r&&(t=`!${t}`),t}function cBe(t,e,{cwd:r}){let o=e.trim();o===""||o[0]==="#"||t.push(cvt(o,{cwd:r}))}function iBe(t,{globalList:e,ignoreLists:r}){let o=ZQ(t,e.accept);if(o!==0)return o===2;let a=ZQ(t,e.reject);if(a!==0)return a===1;if(r!==null)for(let n of r){let u=ZQ(t,n.accept);if(u!==0)return u===2;let A=ZQ(t,n.reject);if(A!==0)return A===1}return!1}function ZQ(t,e){let r=e,o=[];for(let a=0;a<e.length;++a)e[a][0]!=="!"?r!==e&&r.push(e[a]):(r===e&&(r=e.slice(0,a)),o.push(e[a].slice(1)));return sBe(t,o)?2:sBe(t,r)?1:0}function sBe(t,e){let r=e,o=[];for(let a=0;a<e.length;++a)e[a].includes("/")?r!==e&&r.push(e[a]):(r===e&&(r=e.slice(0,a)),o.push(e[a]));return!!(uG.default.isMatch(t,r,{dot:!0,nocase:!0})||uG.default.isMatch(t,o,{dot:!0,basename:!0,nocase:!0}))}var O0=class extends ut{constructor(){super(...arguments);this.installIfNeeded=ge.Boolean("--install-if-needed",!1,{description:"Run a preliminary `yarn install` if the package contains build scripts"});this.dryRun=ge.Boolean("-n,--dry-run",!1,{description:"Print the file paths without actually generating the package archive"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.out=ge.String("-o,--out",{description:"Create the archive at the specified path"});this.filename=ge.String("--filename",{hidden:!0})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd);if(!a)throw new rr(o.cwd,this.context.cwd);await AG(a)&&(this.installIfNeeded?await o.install({cache:await Lr.find(r),report:new Qi}):await o.restoreInstallState());let n=this.out??this.filename,u=typeof n<"u"?K.resolve(this.context.cwd,uvt(n,{workspace:a})):K.resolve(a.cwd,"package.tgz");return(await Nt.start({configuration:r,stdout:this.context.stdout,json:this.json},async p=>{await fG(a,{report:p},async()=>{p.reportJson({base:ue.fromPortablePath(a.cwd)});let h=await $Q(a);for(let E of h)p.reportInfo(null,ue.fromPortablePath(E)),p.reportJson({location:ue.fromPortablePath(E)});if(!this.dryRun){let E=await pG(a,h),I=oe.createWriteStream(u);E.pipe(I),await new Promise(v=>{I.on("finish",v)})}}),this.dryRun||(p.reportInfo(0,`Package archive generated in ${de.pretty(r,u,de.Type.PATH)}`),p.reportJson({output:ue.fromPortablePath(u)}))})).exitCode()}};O0.paths=[["pack"]],O0.usage=nt.Usage({description:"generate a tarball from the active workspace",details:"\n This command will turn the active workspace into a compressed archive suitable for publishing. The archive will by default be stored at the root of the workspace (`package.tgz`).\n\n If the `-o,---out` is set the archive will be created at the specified path. The `%s` and `%v` variables can be used within the path and will be respectively replaced by the package name and version.\n ",examples:[["Create an archive from the active workspace","yarn pack"],["List the files that would be made part of the workspace's archive","yarn pack --dry-run"],["Name and output the archive in a dedicated folder","yarn pack --out /artifacts/%s-%v.tgz"]]});function uvt(t,{workspace:e}){let r=t.replace("%s",Avt(e)).replace("%v",fvt(e));return ue.toPortablePath(r)}function Avt(t){return t.manifest.name!==null?W.slugifyIdent(t.manifest.name):"package"}function fvt(t){return t.manifest.version!==null?t.manifest.version:"unknown"}var pvt=["dependencies","devDependencies","peerDependencies"],hvt="workspace:",gvt=(t,e)=>{e.publishConfig&&(e.publishConfig.type&&(e.type=e.publishConfig.type),e.publishConfig.main&&(e.main=e.publishConfig.main),e.publishConfig.browser&&(e.browser=e.publishConfig.browser),e.publishConfig.module&&(e.module=e.publishConfig.module),e.publishConfig.exports&&(e.exports=e.publishConfig.exports),e.publishConfig.imports&&(e.imports=e.publishConfig.imports),e.publishConfig.bin&&(e.bin=e.publishConfig.bin));let r=t.project;for(let o of pvt)for(let a of t.manifest.getForScope(o).values()){let n=r.tryWorkspaceByDescriptor(a),u=W.parseRange(a.range);if(u.protocol===hvt)if(n===null){if(r.tryWorkspaceByIdent(a)===null)throw new zt(21,`${W.prettyDescriptor(r.configuration,a)}: No local workspace found for this range`)}else{let A;W.areDescriptorsEqual(a,n.anchoredDescriptor)||u.selector==="*"?A=n.manifest.version??"0.0.0":u.selector==="~"||u.selector==="^"?A=`${u.selector}${n.manifest.version??"0.0.0"}`:A=u.selector;let p=o==="dependencies"?W.makeDescriptor(a,"unknown"):null,h=p!==null&&t.manifest.ensureDependencyMeta(p).optional?"optionalDependencies":o;e[h][W.stringifyIdent(a)]=A}}},dvt={hooks:{beforeWorkspacePacking:gvt},commands:[O0]},mvt=dvt;var yBe=Be("crypto"),EBe=$e(mBe()),CBe=Be("url");async function Nvt(t,e,{access:r,tag:o,registry:a,gitHead:n}){let u=t.manifest.name,A=t.manifest.version,p=W.stringifyIdent(u),h=(0,yBe.createHash)("sha1").update(e).digest("hex"),E=EBe.default.fromData(e).toString(),I=r??wBe(t,u),v=await IBe(t),b=await CA.genPackageManifest(t),C=`${p}-${A}.tgz`,T=new CBe.URL(`${oc(a)}/${p}/-/${C}`);return{_id:p,_attachments:{[C]:{content_type:"application/octet-stream",data:e.toString("base64"),length:e.length}},name:p,access:I,["dist-tags"]:{[o]:A},versions:{[A]:{...b,_id:`${p}@${A}`,name:p,version:A,gitHead:n,dist:{shasum:h,integrity:E,tarball:T.toString()}}},readme:v}}async function Lvt(t){try{let{stdout:e}=await Ur.execvp("git",["rev-parse","--revs-only","HEAD"],{cwd:t});return e.trim()===""?void 0:e.trim()}catch{return}}function wBe(t,e){let r=t.project.configuration;return t.manifest.publishConfig&&typeof t.manifest.publishConfig.access=="string"?t.manifest.publishConfig.access:r.get("npmPublishAccess")!==null?r.get("npmPublishAccess"):e.scope?"restricted":"public"}async function IBe(t){let e=ue.toPortablePath(`${t.cwd}/README.md`),r=t.manifest.name,a=`# ${W.stringifyIdent(r)} +`;try{a=await oe.readFilePromise(e,"utf8")}catch(n){if(n.code==="ENOENT")return a;throw n}return a}var yG={npmAlwaysAuth:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:"BOOLEAN",default:!1},npmAuthIdent:{description:"Authentication identity for the npm registry (_auth in npm and yarn v1)",type:"SECRET",default:null},npmAuthToken:{description:"Authentication token for the npm registry (_authToken in npm and yarn v1)",type:"SECRET",default:null}},BBe={npmAuditRegistry:{description:"Registry to query for audit reports",type:"STRING",default:null},npmPublishRegistry:{description:"Registry to push packages to",type:"STRING",default:null},npmRegistryServer:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:"STRING",default:"https://registry.yarnpkg.com"}},Mvt={configuration:{...yG,...BBe,npmScopes:{description:"Settings per package scope",type:"MAP",valueDefinition:{description:"",type:"SHAPE",properties:{...yG,...BBe}}},npmRegistries:{description:"Settings per registry",type:"MAP",normalizeKeys:oc,valueDefinition:{description:"",type:"SHAPE",properties:{...yG}}}},fetchers:[fv,dl],resolvers:[pv,hv,gv]},Ovt=Mvt;var xG={};Kt(xG,{NpmAuditCommand:()=>_0,NpmInfoCommand:()=>H0,NpmLoginCommand:()=>j0,NpmLogoutCommand:()=>q0,NpmPublishCommand:()=>G0,NpmTagAddCommand:()=>W0,NpmTagListCommand:()=>Y0,NpmTagRemoveCommand:()=>V0,NpmWhoamiCommand:()=>K0,default:()=>Gvt,npmAuditTypes:()=>Tv,npmAuditUtils:()=>eF});Ye();Ye();qt();var vG=$e(Zo());Za();var Tv={};Kt(Tv,{Environment:()=>Qv,Severity:()=>Fv});var Qv=(o=>(o.All="all",o.Production="production",o.Development="development",o))(Qv||{}),Fv=(n=>(n.Info="info",n.Low="low",n.Moderate="moderate",n.High="high",n.Critical="critical",n))(Fv||{});var eF={};Kt(eF,{allSeverities:()=>ow,getPackages:()=>BG,getReportTree:()=>wG,getSeverityInclusions:()=>CG,getTopLevelDependencies:()=>IG});Ye();var vBe=$e(zn());var ow=["info","low","moderate","high","critical"];function CG(t){if(typeof t>"u")return new Set(ow);let e=ow.indexOf(t),r=ow.slice(e);return new Set(r)}function wG(t){let e={},r={children:e};for(let[o,a]of je.sortMap(Object.entries(t),n=>n[0]))for(let n of je.sortMap(a,u=>`${u.id}`))e[`${o}/${n.id}`]={value:de.tuple(de.Type.IDENT,W.parseIdent(o)),children:{ID:typeof n.id<"u"&&{label:"ID",value:de.tuple(de.Type.ID,n.id)},Issue:{label:"Issue",value:de.tuple(de.Type.NO_HINT,n.title)},URL:typeof n.url<"u"&&{label:"URL",value:de.tuple(de.Type.URL,n.url)},Severity:{label:"Severity",value:de.tuple(de.Type.NO_HINT,n.severity)},["Vulnerable Versions"]:{label:"Vulnerable Versions",value:de.tuple(de.Type.RANGE,n.vulnerable_versions)},["Tree Versions"]:{label:"Tree Versions",children:[...n.versions].sort(vBe.default.compare).map(u=>({value:de.tuple(de.Type.REFERENCE,u)}))},Dependents:{label:"Dependents",children:je.sortMap(n.dependents,u=>W.stringifyLocator(u)).map(u=>({value:de.tuple(de.Type.LOCATOR,u)}))}}};return r}function IG(t,e,{all:r,environment:o}){let a=[],n=r?t.workspaces:[e],u=["all","production"].includes(o),A=["all","development"].includes(o);for(let p of n)for(let h of p.anchoredPackage.dependencies.values())(p.manifest.devDependencies.has(h.identHash)?!A:!u)||a.push({workspace:p,dependency:h});return a}function BG(t,e,{recursive:r}){let o=new Map,a=new Set,n=[],u=(A,p)=>{let h=t.storedResolutions.get(p.descriptorHash);if(typeof h>"u")throw new Error("Assertion failed: The resolution should have been registered");if(!a.has(h))a.add(h);else return;let E=t.storedPackages.get(h);if(typeof E>"u")throw new Error("Assertion failed: The package should have been registered");if(W.ensureDevirtualizedLocator(E).reference.startsWith("npm:")&&E.version!==null){let v=W.stringifyIdent(E),b=je.getMapWithDefault(o,v);je.getArrayWithDefault(b,E.version).push(A)}if(r)for(let v of E.dependencies.values())n.push([E,v])};for(let{workspace:A,dependency:p}of e)n.push([A.anchoredLocator,p]);for(;n.length>0;){let[A,p]=n.shift();u(A,p)}return o}var _0=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("-A,--all",!1,{description:"Audit dependencies from all workspaces"});this.recursive=ge.Boolean("-R,--recursive",!1,{description:"Audit transitive dependencies as well"});this.environment=ge.String("--environment","all",{description:"Which environments to cover",validator:Vs(Qv)});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.noDeprecations=ge.Boolean("--no-deprecations",!1,{description:"Don't warn about deprecated packages"});this.severity=ge.String("--severity","info",{description:"Minimal severity requested for packages to be displayed",validator:Vs(Fv)});this.excludes=ge.Array("--exclude",[],{description:"Array of glob patterns of packages to exclude from audit"});this.ignores=ge.Array("--ignore",[],{description:"Array of glob patterns of advisory ID's to ignore in the audit report"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd);if(!a)throw new rr(o.cwd,this.context.cwd);await o.restoreInstallState();let n=IG(o,a,{all:this.all,environment:this.environment}),u=BG(o,n,{recursive:this.recursive}),A=Array.from(new Set([...r.get("npmAuditExcludePackages"),...this.excludes])),p=Object.create(null);for(let[L,U]of u)A.some(J=>vG.default.isMatch(L,J))||(p[L]=[...U.keys()]);let h=Zn.getAuditRegistry({configuration:r}),E,I=await AA.start({configuration:r,stdout:this.context.stdout},async()=>{let L=on.post("/-/npm/v1/security/advisories/bulk",p,{authType:on.AuthType.BEST_EFFORT,configuration:r,jsonResponse:!0,registry:h}),U=this.noDeprecations?[]:await Promise.all(Array.from(Object.entries(p),async([te,le])=>{let pe=await on.getPackageMetadata(W.parseIdent(te),{project:o});return je.mapAndFilter(le,Ae=>{let{deprecated:ye}=pe.versions[Ae];return ye?[te,Ae,ye]:je.mapAndFilter.skip})})),J=await L;for(let[te,le,pe]of U.flat(1))Object.hasOwn(J,te)&&J[te].some(Ae=>kr.satisfiesWithPrereleases(le,Ae.vulnerable_versions))||(J[te]??=[],J[te].push({id:`${te} (deprecation)`,title:pe.trim()||"This package has been deprecated.",severity:"moderate",vulnerable_versions:le}));E=J});if(I.hasErrors())return I.exitCode();let v=CG(this.severity),b=Array.from(new Set([...r.get("npmAuditIgnoreAdvisories"),...this.ignores])),C=Object.create(null);for(let[L,U]of Object.entries(E)){let J=U.filter(te=>!vG.default.isMatch(`${te.id}`,b)&&v.has(te.severity));J.length>0&&(C[L]=J.map(te=>{let le=u.get(L);if(typeof le>"u")throw new Error("Assertion failed: Expected the registry to only return packages that were requested");let pe=[...le.keys()].filter(ye=>kr.satisfiesWithPrereleases(ye,te.vulnerable_versions)),Ae=new Map;for(let ye of pe)for(let ae of le.get(ye))Ae.set(ae.locatorHash,ae);return{...te,versions:pe,dependents:[...Ae.values()]}}))}let T=Object.keys(C).length>0;return T?($s.emitTree(wG(C),{configuration:r,json:this.json,stdout:this.context.stdout,separators:2}),1):(await Nt.start({configuration:r,includeFooter:!1,json:this.json,stdout:this.context.stdout},async L=>{L.reportInfo(1,"No audit suggestions")}),T?1:0)}};_0.paths=[["npm","audit"]],_0.usage=nt.Usage({description:"perform a vulnerability audit against the installed packages",details:` + This command checks for known security reports on the packages you use. The reports are by default extracted from the npm registry, and may or may not be relevant to your actual program (not all vulnerabilities affect all code paths). + + For consistency with our other commands the default is to only check the direct dependencies for the active workspace. To extend this search to all workspaces, use \`-A,--all\`. To extend this search to both direct and transitive dependencies, use \`-R,--recursive\`. + + Applying the \`--severity\` flag will limit the audit table to vulnerabilities of the corresponding severity and above. Valid values are ${ow.map(r=>`\`${r}\``).join(", ")}. + + If the \`--json\` flag is set, Yarn will print the output exactly as received from the registry. Regardless of this flag, the process will exit with a non-zero exit code if a report is found for the selected packages. + + If certain packages produce false positives for a particular environment, the \`--exclude\` flag can be used to exclude any number of packages from the audit. This can also be set in the configuration file with the \`npmAuditExcludePackages\` option. + + If particular advisories are needed to be ignored, the \`--ignore\` flag can be used with Advisory ID's to ignore any number of advisories in the audit report. This can also be set in the configuration file with the \`npmAuditIgnoreAdvisories\` option. + + To understand the dependency tree requiring vulnerable packages, check the raw report with the \`--json\` flag or use \`yarn why package\` to get more information as to who depends on them. + `,examples:[["Checks for known security issues with the installed packages. The output is a list of known issues.","yarn npm audit"],["Audit dependencies in all workspaces","yarn npm audit --all"],["Limit auditing to `dependencies` (excludes `devDependencies`)","yarn npm audit --environment production"],["Show audit report as valid JSON","yarn npm audit --json"],["Audit all direct and transitive dependencies","yarn npm audit --recursive"],["Output moderate (or more severe) vulnerabilities","yarn npm audit --severity moderate"],["Exclude certain packages","yarn npm audit --exclude package1 --exclude package2"],["Ignore specific advisories","yarn npm audit --ignore 1234567 --ignore 7654321"]]});Ye();Ye();Pt();qt();var DG=$e(zn()),PG=Be("util"),H0=class extends ut{constructor(){super(...arguments);this.fields=ge.String("-f,--fields",{description:"A comma-separated list of manifest fields that should be displayed"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.packages=ge.Rest()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o}=await St.find(r,this.context.cwd),a=typeof this.fields<"u"?new Set(["name",...this.fields.split(/\s*,\s*/)]):null,n=[],u=!1,A=await Nt.start({configuration:r,includeFooter:!1,json:this.json,stdout:this.context.stdout},async p=>{for(let h of this.packages){let E;if(h==="."){let le=o.topLevelWorkspace;if(!le.manifest.name)throw new it(`Missing ${de.pretty(r,"name",de.Type.CODE)} field in ${ue.fromPortablePath(K.join(le.cwd,dr.manifest))}`);E=W.makeDescriptor(le.manifest.name,"unknown")}else E=W.parseDescriptor(h);let I=on.getIdentUrl(E),v=SG(await on.get(I,{configuration:r,ident:E,jsonResponse:!0,customErrorMessage:on.customPackageError})),b=Object.keys(v.versions).sort(DG.default.compareLoose),T=v["dist-tags"].latest||b[b.length-1],L=kr.validRange(E.range);if(L){let le=DG.default.maxSatisfying(b,L);le!==null?T=le:(p.reportWarning(0,`Unmet range ${W.prettyRange(r,E.range)}; falling back to the latest version`),u=!0)}else Object.hasOwn(v["dist-tags"],E.range)?T=v["dist-tags"][E.range]:E.range!=="unknown"&&(p.reportWarning(0,`Unknown tag ${W.prettyRange(r,E.range)}; falling back to the latest version`),u=!0);let U=v.versions[T],J={...v,...U,version:T,versions:b},te;if(a!==null){te={};for(let le of a){let pe=J[le];if(typeof pe<"u")te[le]=pe;else{p.reportWarning(1,`The ${de.pretty(r,le,de.Type.CODE)} field doesn't exist inside ${W.prettyIdent(r,E)}'s information`),u=!0;continue}}}else this.json||(delete J.dist,delete J.readme,delete J.users),te=J;p.reportJson(te),this.json||n.push(te)}});PG.inspect.styles.name="cyan";for(let p of n)(p!==n[0]||u)&&this.context.stdout.write(` +`),this.context.stdout.write(`${(0,PG.inspect)(p,{depth:1/0,colors:!0,compact:!1})} +`);return A.exitCode()}};H0.paths=[["npm","info"]],H0.usage=nt.Usage({category:"Npm-related commands",description:"show information about a package",details:"\n This command fetches information about a package from the npm registry and prints it in a tree format.\n\n The package does not have to be installed locally, but needs to have been published (in particular, local changes will be ignored even for workspaces).\n\n Append `@<range>` to the package argument to provide information specific to the latest version that satisfies the range or to the corresponding tagged version. If the range is invalid or if there is no version satisfying the range, the command will print a warning and fall back to the latest version.\n\n If the `-f,--fields` option is set, it's a comma-separated list of fields which will be used to only display part of the package information.\n\n By default, this command won't return the `dist`, `readme`, and `users` fields, since they are often very long. To explicitly request those fields, explicitly list them with the `--fields` flag or request the output in JSON mode.\n ",examples:[["Show all available information about react (except the `dist`, `readme`, and `users` fields)","yarn npm info react"],["Show all available information about react as valid JSON (including the `dist`, `readme`, and `users` fields)","yarn npm info react --json"],["Show all available information about react@16.12.0","yarn npm info react@16.12.0"],["Show all available information about react@next","yarn npm info react@next"],["Show the description of react","yarn npm info react --fields description"],["Show all available versions of react","yarn npm info react --fields versions"],["Show the readme of react","yarn npm info react --fields readme"],["Show a few fields of react","yarn npm info react --fields homepage,repository"]]});function SG(t){if(Array.isArray(t)){let e=[];for(let r of t)r=SG(r),r&&e.push(r);return e}else if(typeof t=="object"&&t!==null){let e={};for(let r of Object.keys(t)){if(r.startsWith("_"))continue;let o=SG(t[r]);o&&(e[r]=o)}return e}else return t||null}Ye();Ye();qt();var DBe=$e(A2()),j0=class extends ut{constructor(){super(...arguments);this.scope=ge.String("-s,--scope",{description:"Login to the registry configured for a given scope"});this.publish=ge.Boolean("--publish",!1,{description:"Login to the publish registry"});this.alwaysAuth=ge.Boolean("--always-auth",{description:"Set the npmAlwaysAuth configuration"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),o=await tF({configuration:r,cwd:this.context.cwd,publish:this.publish,scope:this.scope});return(await Nt.start({configuration:r,stdout:this.context.stdout,includeFooter:!1},async n=>{let u=await _vt({configuration:r,registry:o,report:n,stdin:this.context.stdin,stdout:this.context.stdout}),A=`/-/user/org.couchdb.user:${encodeURIComponent(u.name)}`,p=await on.put(A,u,{attemptedAs:u.name,configuration:r,registry:o,jsonResponse:!0,authType:on.AuthType.NO_AUTH});return await Uvt(o,p.token,{alwaysAuth:this.alwaysAuth,scope:this.scope}),n.reportInfo(0,"Successfully logged in")})).exitCode()}};j0.paths=[["npm","login"]],j0.usage=nt.Usage({category:"Npm-related commands",description:"store new login info to access the npm registry",details:"\n This command will ask you for your username, password, and 2FA One-Time-Password (when it applies). It will then modify your local configuration (in your home folder, never in the project itself) to reference the new tokens thus generated.\n\n Adding the `-s,--scope` flag will cause the authentication to be done against whatever registry is configured for the associated scope (see also `npmScopes`).\n\n Adding the `--publish` flag will cause the authentication to be done against the registry used when publishing the package (see also `publishConfig.registry` and `npmPublishRegistry`).\n ",examples:[["Login to the default registry","yarn npm login"],["Login to the registry linked to the @my-scope registry","yarn npm login --scope my-scope"],["Login to the publish registry for the current package","yarn npm login --publish"]]});async function tF({scope:t,publish:e,configuration:r,cwd:o}){return t&&e?Zn.getScopeRegistry(t,{configuration:r,type:Zn.RegistryType.PUBLISH_REGISTRY}):t?Zn.getScopeRegistry(t,{configuration:r}):e?Zn.getPublishRegistry((await AC(r,o)).manifest,{configuration:r}):Zn.getDefaultRegistry({configuration:r})}async function Uvt(t,e,{alwaysAuth:r,scope:o}){let a=u=>A=>{let p=je.isIndexableObject(A)?A:{},h=p[u],E=je.isIndexableObject(h)?h:{};return{...p,[u]:{...E,...r!==void 0?{npmAlwaysAuth:r}:{},npmAuthToken:e}}},n=o?{npmScopes:a(o)}:{npmRegistries:a(t)};return await Ve.updateHomeConfiguration(n)}async function _vt({configuration:t,registry:e,report:r,stdin:o,stdout:a}){r.reportInfo(0,`Logging in to ${de.pretty(t,e,de.Type.URL)}`);let n=!1;if(e.match(/^https:\/\/npm\.pkg\.github\.com(\/|$)/)&&(r.reportInfo(0,"You seem to be using the GitHub Package Registry. Tokens must be generated with the 'repo', 'write:packages', and 'read:packages' permissions."),n=!0),r.reportSeparator(),t.env.YARN_IS_TEST_ENV)return{name:t.env.YARN_INJECT_NPM_USER||"",password:t.env.YARN_INJECT_NPM_PASSWORD||""};let{username:u,password:A}=await(0,DBe.prompt)([{type:"input",name:"username",message:"Username:",required:!0,onCancel:()=>process.exit(130),stdin:o,stdout:a},{type:"password",name:"password",message:n?"Token:":"Password:",required:!0,onCancel:()=>process.exit(130),stdin:o,stdout:a}]);return r.reportSeparator(),{name:u,password:A}}Ye();Ye();qt();var aw=new Set(["npmAuthIdent","npmAuthToken"]),q0=class extends ut{constructor(){super(...arguments);this.scope=ge.String("-s,--scope",{description:"Logout of the registry configured for a given scope"});this.publish=ge.Boolean("--publish",!1,{description:"Logout of the publish registry"});this.all=ge.Boolean("-A,--all",!1,{description:"Logout of all registries"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),o=async()=>{let n=await tF({configuration:r,cwd:this.context.cwd,publish:this.publish,scope:this.scope}),u=await Ve.find(this.context.cwd,this.context.plugins),A=W.makeIdent(this.scope??null,"pkg");return!Zn.getAuthConfiguration(n,{configuration:u,ident:A}).get("npmAuthToken")};return(await Nt.start({configuration:r,stdout:this.context.stdout},async n=>{if(this.all&&(await jvt(),n.reportInfo(0,"Successfully logged out from everything")),this.scope){await PBe("npmScopes",this.scope),await o()?n.reportInfo(0,`Successfully logged out from ${this.scope}`):n.reportWarning(0,"Scope authentication settings removed, but some other ones settings still apply to it");return}let u=await tF({configuration:r,cwd:this.context.cwd,publish:this.publish});await PBe("npmRegistries",u),await o()?n.reportInfo(0,`Successfully logged out from ${u}`):n.reportWarning(0,"Registry authentication settings removed, but some other ones settings still apply to it")})).exitCode()}};q0.paths=[["npm","logout"]],q0.usage=nt.Usage({category:"Npm-related commands",description:"logout of the npm registry",details:"\n This command will log you out by modifying your local configuration (in your home folder, never in the project itself) to delete all credentials linked to a registry.\n\n Adding the `-s,--scope` flag will cause the deletion to be done against whatever registry is configured for the associated scope (see also `npmScopes`).\n\n Adding the `--publish` flag will cause the deletion to be done against the registry used when publishing the package (see also `publishConfig.registry` and `npmPublishRegistry`).\n\n Adding the `-A,--all` flag will cause the deletion to be done against all registries and scopes.\n ",examples:[["Logout of the default registry","yarn npm logout"],["Logout of the @my-scope scope","yarn npm logout --scope my-scope"],["Logout of the publish registry for the current package","yarn npm logout --publish"],["Logout of all registries","yarn npm logout --all"]]});function Hvt(t,e){let r=t[e];if(!je.isIndexableObject(r))return!1;let o=new Set(Object.keys(r));if([...aw].every(n=>!o.has(n)))return!1;for(let n of aw)o.delete(n);if(o.size===0)return t[e]=void 0,!0;let a={...r};for(let n of aw)delete a[n];return t[e]=a,!0}async function jvt(){let t=e=>{let r=!1,o=je.isIndexableObject(e)?{...e}:{};o.npmAuthToken&&(delete o.npmAuthToken,r=!0);for(let a of Object.keys(o))Hvt(o,a)&&(r=!0);if(Object.keys(o).length!==0)return r?o:e};return await Ve.updateHomeConfiguration({npmRegistries:t,npmScopes:t})}async function PBe(t,e){return await Ve.updateHomeConfiguration({[t]:r=>{let o=je.isIndexableObject(r)?r:{};if(!Object.hasOwn(o,e))return r;let a=o[e],n=je.isIndexableObject(a)?a:{},u=new Set(Object.keys(n));if([...aw].every(p=>!u.has(p)))return r;for(let p of aw)u.delete(p);if(u.size===0)return Object.keys(o).length===1?void 0:{...o,[e]:void 0};let A={};for(let p of aw)A[p]=void 0;return{...o,[e]:{...n,...A}}}})}Ye();qt();var G0=class extends ut{constructor(){super(...arguments);this.access=ge.String("--access",{description:"The access for the published package (public or restricted)"});this.tag=ge.String("--tag","latest",{description:"The tag on the registry that the package should be attached to"});this.tolerateRepublish=ge.Boolean("--tolerate-republish",!1,{description:"Warn and exit when republishing an already existing version of a package"});this.otp=ge.String("--otp",{description:"The OTP token to use with the command"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd);if(!a)throw new rr(o.cwd,this.context.cwd);if(a.manifest.private)throw new it("Private workspaces cannot be published");if(a.manifest.name===null||a.manifest.version===null)throw new it("Workspaces must have valid names and versions to be published on an external registry");await o.restoreInstallState();let n=a.manifest.name,u=a.manifest.version,A=Zn.getPublishRegistry(a.manifest,{configuration:r});return(await Nt.start({configuration:r,stdout:this.context.stdout},async h=>{if(this.tolerateRepublish)try{let E=await on.get(on.getIdentUrl(n),{configuration:r,registry:A,ident:n,jsonResponse:!0});if(!Object.hasOwn(E,"versions"))throw new zt(15,'Registry returned invalid data for - missing "versions" field');if(Object.hasOwn(E.versions,u)){h.reportWarning(0,`Registry already knows about version ${u}; skipping.`);return}}catch(E){if(E.originalError?.response?.statusCode!==404)throw E}await un.maybeExecuteWorkspaceLifecycleScript(a,"prepublish",{report:h}),await CA.prepareForPack(a,{report:h},async()=>{let E=await CA.genPackList(a);for(let T of E)h.reportInfo(null,T);let I=await CA.genPackStream(a,E),v=await je.bufferStream(I),b=await sw.getGitHead(a.cwd),C=await sw.makePublishBody(a,v,{access:this.access,tag:this.tag,registry:A,gitHead:b});await on.put(on.getIdentUrl(n),C,{configuration:r,registry:A,ident:n,otp:this.otp,jsonResponse:!0})}),h.reportInfo(0,"Package archive published")})).exitCode()}};G0.paths=[["npm","publish"]],G0.usage=nt.Usage({category:"Npm-related commands",description:"publish the active workspace to the npm registry",details:'\n This command will pack the active workspace into a fresh archive and upload it to the npm registry.\n\n The package will by default be attached to the `latest` tag on the registry, but this behavior can be overriden by using the `--tag` option.\n\n Note that for legacy reasons scoped packages are by default published with an access set to `restricted` (aka "private packages"). This requires you to register for a paid npm plan. In case you simply wish to publish a public scoped package to the registry (for free), just add the `--access public` flag. This behavior can be enabled by default through the `npmPublishAccess` settings.\n ',examples:[["Publish the active workspace","yarn npm publish"]]});Ye();qt();var SBe=$e(zn());Ye();Pt();qt();var Y0=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.package=ge.String({required:!1})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n;if(typeof this.package<"u")n=W.parseIdent(this.package);else{if(!a)throw new rr(o.cwd,this.context.cwd);if(!a.manifest.name)throw new it(`Missing 'name' field in ${ue.fromPortablePath(K.join(a.cwd,dr.manifest))}`);n=a.manifest.name}let u=await Rv(n,r),p={children:je.sortMap(Object.entries(u),([h])=>h).map(([h,E])=>({value:de.tuple(de.Type.RESOLUTION,{descriptor:W.makeDescriptor(n,h),locator:W.makeLocator(n,E)})}))};return $s.emitTree(p,{configuration:r,json:this.json,stdout:this.context.stdout})}};Y0.paths=[["npm","tag","list"]],Y0.usage=nt.Usage({category:"Npm-related commands",description:"list all dist-tags of a package",details:` + This command will list all tags of a package from the npm registry. + + If the package is not specified, Yarn will default to the current workspace. + `,examples:[["List all tags of package `my-pkg`","yarn npm tag list my-pkg"]]});async function Rv(t,e){let r=`/-/package${on.getIdentUrl(t)}/dist-tags`;return on.get(r,{configuration:e,ident:t,jsonResponse:!0,customErrorMessage:on.customPackageError})}var W0=class extends ut{constructor(){super(...arguments);this.package=ge.String();this.tag=ge.String()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd);if(!a)throw new rr(o.cwd,this.context.cwd);let n=W.parseDescriptor(this.package,!0),u=n.range;if(!SBe.default.valid(u))throw new it(`The range ${de.pretty(r,n.range,de.Type.RANGE)} must be a valid semver version`);let A=Zn.getPublishRegistry(a.manifest,{configuration:r}),p=de.pretty(r,n,de.Type.IDENT),h=de.pretty(r,u,de.Type.RANGE),E=de.pretty(r,this.tag,de.Type.CODE);return(await Nt.start({configuration:r,stdout:this.context.stdout},async v=>{let b=await Rv(n,r);Object.hasOwn(b,this.tag)&&b[this.tag]===u&&v.reportWarning(0,`Tag ${E} is already set to version ${h}`);let C=`/-/package${on.getIdentUrl(n)}/dist-tags/${encodeURIComponent(this.tag)}`;await on.put(C,u,{configuration:r,registry:A,ident:n,jsonRequest:!0,jsonResponse:!0}),v.reportInfo(0,`Tag ${E} added to version ${h} of package ${p}`)})).exitCode()}};W0.paths=[["npm","tag","add"]],W0.usage=nt.Usage({category:"Npm-related commands",description:"add a tag for a specific version of a package",details:` + This command will add a tag to the npm registry for a specific version of a package. If the tag already exists, it will be overwritten. + `,examples:[["Add a `beta` tag for version `2.3.4-beta.4` of package `my-pkg`","yarn npm tag add my-pkg@2.3.4-beta.4 beta"]]});Ye();qt();var V0=class extends ut{constructor(){super(...arguments);this.package=ge.String();this.tag=ge.String()}async execute(){if(this.tag==="latest")throw new it("The 'latest' tag cannot be removed.");let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd);if(!a)throw new rr(o.cwd,this.context.cwd);let n=W.parseIdent(this.package),u=Zn.getPublishRegistry(a.manifest,{configuration:r}),A=de.pretty(r,this.tag,de.Type.CODE),p=de.pretty(r,n,de.Type.IDENT),h=await Rv(n,r);if(!Object.hasOwn(h,this.tag))throw new it(`${A} is not a tag of package ${p}`);return(await Nt.start({configuration:r,stdout:this.context.stdout},async I=>{let v=`/-/package${on.getIdentUrl(n)}/dist-tags/${encodeURIComponent(this.tag)}`;await on.del(v,{configuration:r,registry:u,ident:n,jsonResponse:!0}),I.reportInfo(0,`Tag ${A} removed from package ${p}`)})).exitCode()}};V0.paths=[["npm","tag","remove"]],V0.usage=nt.Usage({category:"Npm-related commands",description:"remove a tag from a package",details:` + This command will remove a tag from a package from the npm registry. + `,examples:[["Remove the `beta` tag from package `my-pkg`","yarn npm tag remove my-pkg beta"]]});Ye();Ye();qt();var K0=class extends ut{constructor(){super(...arguments);this.scope=ge.String("-s,--scope",{description:"Print username for the registry configured for a given scope"});this.publish=ge.Boolean("--publish",!1,{description:"Print username for the publish registry"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),o;return this.scope&&this.publish?o=Zn.getScopeRegistry(this.scope,{configuration:r,type:Zn.RegistryType.PUBLISH_REGISTRY}):this.scope?o=Zn.getScopeRegistry(this.scope,{configuration:r}):this.publish?o=Zn.getPublishRegistry((await AC(r,this.context.cwd)).manifest,{configuration:r}):o=Zn.getDefaultRegistry({configuration:r}),(await Nt.start({configuration:r,stdout:this.context.stdout},async n=>{let u;try{u=await on.get("/-/whoami",{configuration:r,registry:o,authType:on.AuthType.ALWAYS_AUTH,jsonResponse:!0,ident:this.scope?W.makeIdent(this.scope,""):void 0})}catch(A){if(A.response?.statusCode===401||A.response?.statusCode===403){n.reportError(41,"Authentication failed - your credentials may have expired");return}else throw A}n.reportInfo(0,u.username)})).exitCode()}};K0.paths=[["npm","whoami"]],K0.usage=nt.Usage({category:"Npm-related commands",description:"display the name of the authenticated user",details:"\n Print the username associated with the current authentication settings to the standard output.\n\n When using `-s,--scope`, the username printed will be the one that matches the authentication settings of the registry associated with the given scope (those settings can be overriden using the `npmRegistries` map, and the registry associated with the scope is configured via the `npmScopes` map).\n\n When using `--publish`, the registry we'll select will by default be the one used when publishing packages (`publishConfig.registry` or `npmPublishRegistry` if available, otherwise we'll fallback to the regular `npmRegistryServer`).\n ",examples:[["Print username for the default registry","yarn npm whoami"],["Print username for the registry on a given scope","yarn npm whoami --scope company"]]});var qvt={configuration:{npmPublishAccess:{description:"Default access of the published packages",type:"STRING",default:null},npmAuditExcludePackages:{description:"Array of glob patterns of packages to exclude from npm audit",type:"STRING",default:[],isArray:!0},npmAuditIgnoreAdvisories:{description:"Array of glob patterns of advisory IDs to exclude from npm audit",type:"STRING",default:[],isArray:!0}},commands:[_0,H0,j0,q0,G0,W0,Y0,V0,K0]},Gvt=qvt;var NG={};Kt(NG,{PatchCommand:()=>X0,PatchCommitCommand:()=>z0,PatchFetcher:()=>Uv,PatchResolver:()=>_v,default:()=>lDt,patchUtils:()=>Dm});Ye();Ye();Pt();nA();var Dm={};Kt(Dm,{applyPatchFile:()=>nF,diffFolders:()=>TG,ensureUnpatchedDescriptor:()=>bG,ensureUnpatchedLocator:()=>sF,extractPackageToDisk:()=>FG,extractPatchFlags:()=>RBe,isParentRequired:()=>QG,isPatchDescriptor:()=>iF,isPatchLocator:()=>J0,loadPatchFiles:()=>Ov,makeDescriptor:()=>oF,makeLocator:()=>kG,makePatchHash:()=>RG,parseDescriptor:()=>Lv,parseLocator:()=>Mv,parsePatchFile:()=>Nv,unpatchDescriptor:()=>sDt,unpatchLocator:()=>oDt});Ye();Pt();Ye();Pt();var Yvt=/^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@.*/;function lw(t){return K.relative(Bt.root,K.resolve(Bt.root,ue.toPortablePath(t)))}function Wvt(t){let e=t.trim().match(Yvt);if(!e)throw new Error(`Bad header line: '${t}'`);return{original:{start:Math.max(Number(e[1]),1),length:Number(e[3]||1)},patched:{start:Math.max(Number(e[4]),1),length:Number(e[6]||1)}}}var Vvt=420,Kvt=493;var xBe=()=>({semverExclusivity:null,diffLineFromPath:null,diffLineToPath:null,oldMode:null,newMode:null,deletedFileMode:null,newFileMode:null,renameFrom:null,renameTo:null,beforeHash:null,afterHash:null,fromPath:null,toPath:null,hunks:null}),Jvt=t=>({header:Wvt(t),parts:[]}),zvt={["@"]:"header",["-"]:"deletion",["+"]:"insertion",[" "]:"context",["\\"]:"pragma",undefined:"context"};function Xvt(t){let e=[],r=xBe(),o="parsing header",a=null,n=null;function u(){a&&(n&&(a.parts.push(n),n=null),r.hunks.push(a),a=null)}function A(){u(),e.push(r),r=xBe()}for(let p=0;p<t.length;p++){let h=t[p];if(o==="parsing header")if(h.startsWith("@@"))o="parsing hunks",r.hunks=[],p-=1;else if(h.startsWith("diff --git ")){r&&r.diffLineFromPath&&A();let E=h.match(/^diff --git a\/(.*?) b\/(.*?)\s*$/);if(!E)throw new Error(`Bad diff line: ${h}`);r.diffLineFromPath=E[1],r.diffLineToPath=E[2]}else if(h.startsWith("old mode "))r.oldMode=h.slice(9).trim();else if(h.startsWith("new mode "))r.newMode=h.slice(9).trim();else if(h.startsWith("deleted file mode "))r.deletedFileMode=h.slice(18).trim();else if(h.startsWith("new file mode "))r.newFileMode=h.slice(14).trim();else if(h.startsWith("rename from "))r.renameFrom=h.slice(12).trim();else if(h.startsWith("rename to "))r.renameTo=h.slice(10).trim();else if(h.startsWith("index ")){let E=h.match(/(\w+)\.\.(\w+)/);if(!E)continue;r.beforeHash=E[1],r.afterHash=E[2]}else h.startsWith("semver exclusivity ")?r.semverExclusivity=h.slice(19).trim():h.startsWith("--- ")?r.fromPath=h.slice(6).trim():h.startsWith("+++ ")&&(r.toPath=h.slice(6).trim());else{let E=zvt[h[0]]||null;switch(E){case"header":u(),a=Jvt(h);break;case null:o="parsing header",A(),p-=1;break;case"pragma":{if(!h.startsWith("\\ No newline at end of file"))throw new Error(`Unrecognized pragma in patch file: ${h}`);if(!n)throw new Error("Bad parser state: No newline at EOF pragma encountered without context");n.noNewlineAtEndOfFile=!0}break;case"context":case"deletion":case"insertion":{if(!a)throw new Error("Bad parser state: Hunk lines encountered before hunk header");n&&n.type!==E&&(a.parts.push(n),n=null),n||(n={type:E,lines:[],noNewlineAtEndOfFile:!1}),n.lines.push(h.slice(1))}break;default:je.assertNever(E);break}}}A();for(let{hunks:p}of e)if(p)for(let h of p)$vt(h);return e}function Zvt(t){let e=[];for(let r of t){let{semverExclusivity:o,diffLineFromPath:a,diffLineToPath:n,oldMode:u,newMode:A,deletedFileMode:p,newFileMode:h,renameFrom:E,renameTo:I,beforeHash:v,afterHash:b,fromPath:C,toPath:T,hunks:L}=r,U=E?"rename":p?"file deletion":h?"file creation":L&&L.length>0?"patch":"mode change",J=null;switch(U){case"rename":{if(!E||!I)throw new Error("Bad parser state: rename from & to not given");e.push({type:"rename",semverExclusivity:o,fromPath:lw(E),toPath:lw(I)}),J=I}break;case"file deletion":{let te=a||C;if(!te)throw new Error("Bad parse state: no path given for file deletion");e.push({type:"file deletion",semverExclusivity:o,hunk:L&&L[0]||null,path:lw(te),mode:rF(p),hash:v})}break;case"file creation":{let te=n||T;if(!te)throw new Error("Bad parse state: no path given for file creation");e.push({type:"file creation",semverExclusivity:o,hunk:L&&L[0]||null,path:lw(te),mode:rF(h),hash:b})}break;case"patch":case"mode change":J=T||n;break;default:je.assertNever(U);break}J&&u&&A&&u!==A&&e.push({type:"mode change",semverExclusivity:o,path:lw(J),oldMode:rF(u),newMode:rF(A)}),J&&L&&L.length&&e.push({type:"patch",semverExclusivity:o,path:lw(J),hunks:L,beforeHash:v,afterHash:b})}if(e.length===0)throw new Error("Unable to parse patch file: No changes found. Make sure the patch is a valid UTF8 encoded string");return e}function rF(t){let e=parseInt(t,8)&511;if(e!==Vvt&&e!==Kvt)throw new Error(`Unexpected file mode string: ${t}`);return e}function Nv(t){let e=t.split(/\n/g);return e[e.length-1]===""&&e.pop(),Zvt(Xvt(e))}function $vt(t){let e=0,r=0;for(let{type:o,lines:a}of t.parts)switch(o){case"context":r+=a.length,e+=a.length;break;case"deletion":e+=a.length;break;case"insertion":r+=a.length;break;default:je.assertNever(o);break}if(e!==t.header.original.length||r!==t.header.patched.length){let o=a=>a<0?a:`+${a}`;throw new Error(`hunk header integrity check failed (expected @@ ${o(t.header.original.length)} ${o(t.header.patched.length)} @@, got @@ ${o(e)} ${o(r)} @@)`)}}Ye();Pt();var cw=class extends Error{constructor(r,o){super(`Cannot apply hunk #${r+1}`);this.hunk=o}};async function uw(t,e,r){let o=await t.lstatPromise(e),a=await r();typeof a<"u"&&(e=a),await t.lutimesPromise(e,o.atime,o.mtime)}async function nF(t,{baseFs:e=new Rn,dryRun:r=!1,version:o=null}={}){for(let a of t)if(!(a.semverExclusivity!==null&&o!==null&&!kr.satisfiesWithPrereleases(o,a.semverExclusivity)))switch(a.type){case"file deletion":if(r){if(!e.existsSync(a.path))throw new Error(`Trying to delete a file that doesn't exist: ${a.path}`)}else await uw(e,K.dirname(a.path),async()=>{await e.unlinkPromise(a.path)});break;case"rename":if(r){if(!e.existsSync(a.fromPath))throw new Error(`Trying to move a file that doesn't exist: ${a.fromPath}`)}else await uw(e,K.dirname(a.fromPath),async()=>{await uw(e,K.dirname(a.toPath),async()=>{await uw(e,a.fromPath,async()=>(await e.movePromise(a.fromPath,a.toPath),a.toPath))})});break;case"file creation":if(r){if(e.existsSync(a.path))throw new Error(`Trying to create a file that already exists: ${a.path}`)}else{let n=a.hunk?a.hunk.parts[0].lines.join(` +`)+(a.hunk.parts[0].noNewlineAtEndOfFile?"":` +`):"";await e.mkdirpPromise(K.dirname(a.path),{chmod:493,utimes:[vi.SAFE_TIME,vi.SAFE_TIME]}),await e.writeFilePromise(a.path,n,{mode:a.mode}),await e.utimesPromise(a.path,vi.SAFE_TIME,vi.SAFE_TIME)}break;case"patch":await uw(e,a.path,async()=>{await rDt(a,{baseFs:e,dryRun:r})});break;case"mode change":{let u=(await e.statPromise(a.path)).mode;if(bBe(a.newMode)!==bBe(u))continue;await uw(e,a.path,async()=>{await e.chmodPromise(a.path,a.newMode)})}break;default:je.assertNever(a);break}}function bBe(t){return(t&64)>0}function kBe(t){return t.replace(/\s+$/,"")}function tDt(t,e){return kBe(t)===kBe(e)}async function rDt({hunks:t,path:e},{baseFs:r,dryRun:o=!1}){let a=await r.statSync(e).mode,u=(await r.readFileSync(e,"utf8")).split(/\n/),A=[],p=0,h=0;for(let I of t){let v=Math.max(h,I.header.patched.start+p),b=Math.max(0,v-h),C=Math.max(0,u.length-v-I.header.original.length),T=Math.max(b,C),L=0,U=0,J=null;for(;L<=T;){if(L<=b&&(U=v-L,J=QBe(I,u,U),J!==null)){L=-L;break}if(L<=C&&(U=v+L,J=QBe(I,u,U),J!==null))break;L+=1}if(J===null)throw new cw(t.indexOf(I),I);A.push(J),p+=L,h=U+I.header.original.length}if(o)return;let E=0;for(let I of A)for(let v of I)switch(v.type){case"splice":{let b=v.index+E;u.splice(b,v.numToDelete,...v.linesToInsert),E+=v.linesToInsert.length-v.numToDelete}break;case"pop":u.pop();break;case"push":u.push(v.line);break;default:je.assertNever(v);break}await r.writeFilePromise(e,u.join(` +`),{mode:a})}function QBe(t,e,r){let o=[];for(let a of t.parts)switch(a.type){case"context":case"deletion":{for(let n of a.lines){let u=e[r];if(u==null||!tDt(u,n))return null;r+=1}a.type==="deletion"&&(o.push({type:"splice",index:r-a.lines.length,numToDelete:a.lines.length,linesToInsert:[]}),a.noNewlineAtEndOfFile&&o.push({type:"push",line:""}))}break;case"insertion":o.push({type:"splice",index:r,numToDelete:0,linesToInsert:a.lines}),a.noNewlineAtEndOfFile&&o.push({type:"pop"});break;default:je.assertNever(a.type);break}return o}var iDt=/^builtin<([^>]+)>$/;function Aw(t,e){let{protocol:r,source:o,selector:a,params:n}=W.parseRange(t);if(r!=="patch:")throw new Error("Invalid patch range");if(o===null)throw new Error("Patch locators must explicitly define their source");let u=a?a.split(/&/).map(E=>ue.toPortablePath(E)):[],A=n&&typeof n.locator=="string"?W.parseLocator(n.locator):null,p=n&&typeof n.version=="string"?n.version:null,h=e(o);return{parentLocator:A,sourceItem:h,patchPaths:u,sourceVersion:p}}function iF(t){return t.range.startsWith("patch:")}function J0(t){return t.reference.startsWith("patch:")}function Lv(t){let{sourceItem:e,...r}=Aw(t.range,W.parseDescriptor);return{...r,sourceDescriptor:e}}function Mv(t){let{sourceItem:e,...r}=Aw(t.reference,W.parseLocator);return{...r,sourceLocator:e}}function sDt(t){let{sourceItem:e}=Aw(t.range,W.parseDescriptor);return e}function oDt(t){let{sourceItem:e}=Aw(t.reference,W.parseLocator);return e}function bG(t){if(!iF(t))return t;let{sourceItem:e}=Aw(t.range,W.parseDescriptor);return e}function sF(t){if(!J0(t))return t;let{sourceItem:e}=Aw(t.reference,W.parseLocator);return e}function FBe({parentLocator:t,sourceItem:e,patchPaths:r,sourceVersion:o,patchHash:a},n){let u=t!==null?{locator:W.stringifyLocator(t)}:{},A=typeof o<"u"?{version:o}:{},p=typeof a<"u"?{hash:a}:{};return W.makeRange({protocol:"patch:",source:n(e),selector:r.join("&"),params:{...A,...p,...u}})}function oF(t,{parentLocator:e,sourceDescriptor:r,patchPaths:o}){return W.makeDescriptor(t,FBe({parentLocator:e,sourceItem:r,patchPaths:o},W.stringifyDescriptor))}function kG(t,{parentLocator:e,sourcePackage:r,patchPaths:o,patchHash:a}){return W.makeLocator(t,FBe({parentLocator:e,sourceItem:r,sourceVersion:r.version,patchPaths:o,patchHash:a},W.stringifyLocator))}function TBe({onAbsolute:t,onRelative:e,onProject:r,onBuiltin:o},a){let n=a.lastIndexOf("!");n!==-1&&(a=a.slice(n+1));let u=a.match(iDt);return u!==null?o(u[1]):a.startsWith("~/")?r(a.slice(2)):K.isAbsolute(a)?t(a):e(a)}function RBe(t){let e=t.lastIndexOf("!");return{optional:(e!==-1?new Set(t.slice(0,e).split(/!/)):new Set).has("optional")}}function QG(t){return TBe({onAbsolute:()=>!1,onRelative:()=>!0,onProject:()=>!1,onBuiltin:()=>!1},t)}async function Ov(t,e,r){let o=t!==null?await r.fetcher.fetch(t,r):null,a=o&&o.localPath?{packageFs:new gn(Bt.root),prefixPath:K.relative(Bt.root,o.localPath)}:o;o&&o!==a&&o.releaseFs&&o.releaseFs();let n=await je.releaseAfterUseAsync(async()=>await Promise.all(e.map(async u=>{let A=RBe(u),p=await TBe({onAbsolute:async h=>await oe.readFilePromise(h,"utf8"),onRelative:async h=>{if(a===null)throw new Error("Assertion failed: The parent locator should have been fetched");return await a.packageFs.readFilePromise(K.join(a.prefixPath,h),"utf8")},onProject:async h=>await oe.readFilePromise(K.join(r.project.cwd,h),"utf8"),onBuiltin:async h=>await r.project.configuration.firstHook(E=>E.getBuiltinPatch,r.project,h)},u);return{...A,source:p}})));for(let u of n)typeof u.source=="string"&&(u.source=u.source.replace(/\r\n?/g,` +`));return n}async function FG(t,{cache:e,project:r}){let o=r.storedPackages.get(t.locatorHash);if(typeof o>"u")throw new Error("Assertion failed: Expected the package to be registered");let a=sF(t),n=r.storedChecksums,u=new Qi,A=await oe.mktempPromise(),p=K.join(A,"source"),h=K.join(A,"user"),E=K.join(A,".yarn-patch.json"),I=r.configuration.makeFetcher(),v=[];try{let b,C;if(t.locatorHash===a.locatorHash){let T=await I.fetch(t,{cache:e,project:r,fetcher:I,checksums:n,report:u});v.push(()=>T.releaseFs?.()),b=T,C=T}else b=await I.fetch(t,{cache:e,project:r,fetcher:I,checksums:n,report:u}),v.push(()=>b.releaseFs?.()),C=await I.fetch(t,{cache:e,project:r,fetcher:I,checksums:n,report:u}),v.push(()=>C.releaseFs?.());await Promise.all([oe.copyPromise(p,b.prefixPath,{baseFs:b.packageFs}),oe.copyPromise(h,C.prefixPath,{baseFs:C.packageFs}),oe.writeJsonPromise(E,{locator:W.stringifyLocator(t),version:o.version})])}finally{for(let b of v)b()}return oe.detachTemp(A),h}async function TG(t,e){let r=ue.fromPortablePath(t).replace(/\\/g,"/"),o=ue.fromPortablePath(e).replace(/\\/g,"/"),{stdout:a,stderr:n}=await Ur.execvp("git",["-c","core.safecrlf=false","diff","--src-prefix=a/","--dst-prefix=b/","--ignore-cr-at-eol","--full-index","--no-index","--no-renames","--text",r,o],{cwd:ue.toPortablePath(process.cwd()),env:{...process.env,GIT_CONFIG_NOSYSTEM:"1",HOME:"",XDG_CONFIG_HOME:"",USERPROFILE:""}});if(n.length>0)throw new Error(`Unable to diff directories. Make sure you have a recent version of 'git' available in PATH. +The following error was reported by 'git': +${n}`);let u=r.startsWith("/")?A=>A.slice(1):A=>A;return a.replace(new RegExp(`(a|b)(${je.escapeRegExp(`/${u(r)}/`)})`,"g"),"$1/").replace(new RegExp(`(a|b)${je.escapeRegExp(`/${u(o)}/`)}`,"g"),"$1/").replace(new RegExp(je.escapeRegExp(`${r}/`),"g"),"").replace(new RegExp(je.escapeRegExp(`${o}/`),"g"),"")}function RG(t,e){let r=[];for(let{source:o}of t){if(o===null)continue;let a=Nv(o);for(let n of a){let{semverExclusivity:u,...A}=n;u!==null&&e!==null&&!kr.satisfiesWithPrereleases(e,u)||r.push(JSON.stringify(A))}}return wn.makeHash(`${3}`,...r).slice(0,6)}Ye();function NBe(t,{configuration:e,report:r}){for(let o of t.parts)for(let a of o.lines)switch(o.type){case"context":r.reportInfo(null,` ${de.pretty(e,a,"grey")}`);break;case"deletion":r.reportError(28,`- ${de.pretty(e,a,de.Type.REMOVED)}`);break;case"insertion":r.reportError(28,`+ ${de.pretty(e,a,de.Type.ADDED)}`);break;default:je.assertNever(o.type)}}var Uv=class{supports(e,r){return!!J0(e)}getLocalPath(e,r){return null}async fetch(e,r){let o=r.checksums.get(e.locatorHash)||null,[a,n,u]=await r.cache.fetchPackageFromCache(e,o,{onHit:()=>r.report.reportCacheHit(e),onMiss:()=>r.report.reportCacheMiss(e,`${W.prettyLocator(r.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.patchPackage(e,r),...r.cacheOptions});return{packageFs:a,releaseFs:n,prefixPath:W.getIdentVendorPath(e),localPath:this.getLocalPath(e,r),checksum:u}}async patchPackage(e,r){let{parentLocator:o,sourceLocator:a,sourceVersion:n,patchPaths:u}=Mv(e),A=await Ov(o,u,r),p=await oe.mktempPromise(),h=K.join(p,"current.zip"),E=await r.fetcher.fetch(a,r),I=W.getIdentVendorPath(e),v=new zi(h,{create:!0,level:r.project.configuration.get("compressionLevel")});await je.releaseAfterUseAsync(async()=>{await v.copyPromise(I,E.prefixPath,{baseFs:E.packageFs,stableSort:!0})},E.releaseFs),v.saveAndClose();for(let{source:b,optional:C}of A){if(b===null)continue;let T=new zi(h,{level:r.project.configuration.get("compressionLevel")}),L=new gn(K.resolve(Bt.root,I),{baseFs:T});try{await nF(Nv(b),{baseFs:L,version:n})}catch(U){if(!(U instanceof cw))throw U;let J=r.project.configuration.get("enableInlineHunks"),te=!J&&!C?" (set enableInlineHunks for details)":"",le=`${W.prettyLocator(r.project.configuration,e)}: ${U.message}${te}`,pe=Ae=>{!J||NBe(U.hunk,{configuration:r.project.configuration,report:Ae})};if(T.discardAndClose(),C){r.report.reportWarningOnce(66,le,{reportExtra:pe});continue}else throw new zt(66,le,pe)}T.saveAndClose()}return new zi(h,{level:r.project.configuration.get("compressionLevel")})}};Ye();var _v=class{supportsDescriptor(e,r){return!!iF(e)}supportsLocator(e,r){return!!J0(e)}shouldPersistResolution(e,r){return!1}bindDescriptor(e,r,o){let{patchPaths:a}=Lv(e);return a.every(n=>!QG(n))?e:W.bindDescriptor(e,{locator:W.stringifyLocator(r)})}getResolutionDependencies(e,r){let{sourceDescriptor:o}=Lv(e);return{sourceDescriptor:r.project.configuration.normalizeDependency(o)}}async getCandidates(e,r,o){if(!o.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{parentLocator:a,patchPaths:n}=Lv(e),u=await Ov(a,n,o.fetchOptions),A=r.sourceDescriptor;if(typeof A>"u")throw new Error("Assertion failed: The dependency should have been resolved");let p=RG(u,A.version);return[kG(e,{parentLocator:a,sourcePackage:A,patchPaths:n,patchHash:p})]}async getSatisfying(e,r,o,a){let[n]=await this.getCandidates(e,r,a);return{locators:o.filter(u=>u.locatorHash===n.locatorHash),sorted:!1}}async resolve(e,r){let{sourceLocator:o}=Mv(e);return{...await r.resolver.resolve(o,r),...e}}};Ye();Pt();qt();var z0=class extends ut{constructor(){super(...arguments);this.save=ge.Boolean("-s,--save",!1,{description:"Add the patch to your resolution entries"});this.patchFolder=ge.String()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd);if(!a)throw new rr(o.cwd,this.context.cwd);await o.restoreInstallState();let n=K.resolve(this.context.cwd,ue.toPortablePath(this.patchFolder)),u=K.join(n,"../source"),A=K.join(n,"../.yarn-patch.json");if(!oe.existsSync(u))throw new it("The argument folder didn't get created by 'yarn patch'");let p=await TG(u,n),h=await oe.readJsonPromise(A),E=W.parseLocator(h.locator,!0);if(!o.storedPackages.has(E.locatorHash))throw new it("No package found in the project for the given locator");if(!this.save){this.context.stdout.write(p);return}let I=r.get("patchFolder"),v=K.join(I,`${W.slugifyLocator(E)}.patch`);await oe.mkdirPromise(I,{recursive:!0}),await oe.writeFilePromise(v,p);let b=[],C=new Map;for(let T of o.storedPackages.values()){if(W.isVirtualLocator(T))continue;let L=T.dependencies.get(E.identHash);if(!L)continue;let U=W.ensureDevirtualizedDescriptor(L),J=bG(U),te=o.storedResolutions.get(J.descriptorHash);if(!te)throw new Error("Assertion failed: Expected the resolution to have been registered");if(!o.storedPackages.get(te))throw new Error("Assertion failed: Expected the package to have been registered");let pe=o.tryWorkspaceByLocator(T);if(pe)b.push(pe);else{let Ae=o.originalPackages.get(T.locatorHash);if(!Ae)throw new Error("Assertion failed: Expected the original package to have been registered");let ye=Ae.dependencies.get(L.identHash);if(!ye)throw new Error("Assertion failed: Expected the original dependency to have been registered");C.set(ye.descriptorHash,ye)}}for(let T of b)for(let L of Mt.hardDependencies){let U=T.manifest[L].get(E.identHash);if(!U)continue;let J=oF(U,{parentLocator:null,sourceDescriptor:W.convertLocatorToDescriptor(E),patchPaths:[K.join(dr.home,K.relative(o.cwd,v))]});T.manifest[L].set(U.identHash,J)}for(let T of C.values()){let L=oF(T,{parentLocator:null,sourceDescriptor:W.convertLocatorToDescriptor(E),patchPaths:[K.join(dr.home,K.relative(o.cwd,v))]});o.topLevelWorkspace.manifest.resolutions.push({pattern:{descriptor:{fullName:W.stringifyIdent(L),description:T.range}},reference:L.range})}await o.persist()}};z0.paths=[["patch-commit"]],z0.usage=nt.Usage({description:"generate a patch out of a directory",details:"\n By default, this will print a patchfile on stdout based on the diff between the folder passed in and the original version of the package. Such file is suitable for consumption with the `patch:` protocol.\n\n With the `-s,--save` option set, the patchfile won't be printed on stdout anymore and will instead be stored within a local file (by default kept within `.yarn/patches`, but configurable via the `patchFolder` setting). A `resolutions` entry will also be added to your top-level manifest, referencing the patched package via the `patch:` protocol.\n\n Note that only folders generated by `yarn patch` are accepted as valid input for `yarn patch-commit`.\n "});Ye();Pt();qt();var X0=class extends ut{constructor(){super(...arguments);this.update=ge.Boolean("-u,--update",!1,{description:"Reapply local patches that already apply to this packages"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.package=ge.String()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n=await Lr.find(r);if(!a)throw new rr(o.cwd,this.context.cwd);await o.restoreInstallState();let u=W.parseLocator(this.package);if(u.reference==="unknown"){let A=je.mapAndFilter([...o.storedPackages.values()],p=>p.identHash!==u.identHash?je.mapAndFilter.skip:W.isVirtualLocator(p)?je.mapAndFilter.skip:J0(p)!==this.update?je.mapAndFilter.skip:p);if(A.length===0)throw new it("No package found in the project for the given locator");if(A.length>1)throw new it(`Multiple candidate packages found; explicitly choose one of them (use \`yarn why <package>\` to get more information as to who depends on them): +${A.map(p=>` +- ${W.prettyLocator(r,p)}`).join("")}`);u=A[0]}if(!o.storedPackages.has(u.locatorHash))throw new it("No package found in the project for the given locator");await Nt.start({configuration:r,json:this.json,stdout:this.context.stdout},async A=>{let p=sF(u),h=await FG(u,{cache:n,project:o});A.reportJson({locator:W.stringifyLocator(p),path:ue.fromPortablePath(h)});let E=this.update?" along with its current modifications":"";A.reportInfo(0,`Package ${W.prettyLocator(r,p)} got extracted with success${E}!`),A.reportInfo(0,`You can now edit the following folder: ${de.pretty(r,ue.fromPortablePath(h),"magenta")}`),A.reportInfo(0,`Once you are done run ${de.pretty(r,`yarn patch-commit -s ${process.platform==="win32"?'"':""}${ue.fromPortablePath(h)}${process.platform==="win32"?'"':""}`,"cyan")} and Yarn will store a patchfile based on your changes.`)})}};X0.paths=[["patch"]],X0.usage=nt.Usage({description:"prepare a package for patching",details:"\n This command will cause a package to be extracted in a temporary directory intended to be editable at will.\n\n Once you're done with your changes, run `yarn patch-commit -s path` (with `path` being the temporary directory you received) to generate a patchfile and register it into your top-level manifest via the `patch:` protocol. Run `yarn patch-commit -h` for more details.\n\n Calling the command when you already have a patch won't import it by default (in other words, the default behavior is to reset existing patches). However, adding the `-u,--update` flag will import any current patch.\n "});var aDt={configuration:{enableInlineHunks:{description:"If true, the installs will print unmatched patch hunks",type:"BOOLEAN",default:!1},patchFolder:{description:"Folder where the patch files must be written",type:"ABSOLUTE_PATH",default:"./.yarn/patches"}},commands:[z0,X0],fetchers:[Uv],resolvers:[_v]},lDt=aDt;var OG={};Kt(OG,{PnpmLinker:()=>Hv,default:()=>pDt});Ye();Pt();qt();var Hv=class{getCustomDataKey(){return JSON.stringify({name:"PnpmLinker",version:3})}supportsPackage(e,r){return this.isEnabled(r)}async findPackageLocation(e,r){if(!this.isEnabled(r))throw new Error("Assertion failed: Expected the pnpm linker to be enabled");let o=this.getCustomDataKey(),a=r.project.linkersCustomData.get(o);if(!a)throw new it(`The project in ${de.pretty(r.project.configuration,`${r.project.cwd}/package.json`,de.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let n=a.pathsByLocator.get(e.locatorHash);if(typeof n>"u")throw new it(`Couldn't find ${W.prettyLocator(r.project.configuration,e)} in the currently installed pnpm map - running an install might help`);return n.packageLocation}async findPackageLocator(e,r){if(!this.isEnabled(r))return null;let o=this.getCustomDataKey(),a=r.project.linkersCustomData.get(o);if(!a)throw new it(`The project in ${de.pretty(r.project.configuration,`${r.project.cwd}/package.json`,de.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let n=e.match(/(^.*\/node_modules\/(@[^/]*\/)?[^/]+)(\/.*$)/);if(n){let p=a.locatorByPath.get(n[1]);if(p)return p}let u=e,A=e;do{A=u,u=K.dirname(A);let p=a.locatorByPath.get(A);if(p)return p}while(u!==A);return null}makeInstaller(e){return new LG(e)}isEnabled(e){return e.project.configuration.get("nodeLinker")==="pnpm"}},LG=class{constructor(e){this.opts=e;this.asyncActions=new je.AsyncActions(10);this.customData={pathsByLocator:new Map,locatorByPath:new Map};this.indexFolderPromise=PD(oe,{indexPath:K.join(e.project.configuration.get("globalFolder"),"index")})}attachCustomData(e){}async installPackage(e,r,o){switch(e.linkType){case"SOFT":return this.installPackageSoft(e,r,o);case"HARD":return this.installPackageHard(e,r,o)}throw new Error("Assertion failed: Unsupported package link type")}async installPackageSoft(e,r,o){let a=K.resolve(r.packageFs.getRealPath(),r.prefixPath),n=this.opts.project.tryWorkspaceByLocator(e)?K.join(a,dr.nodeModules):null;return this.customData.pathsByLocator.set(e.locatorHash,{packageLocation:a,dependenciesLocation:n}),{packageLocation:a,buildRequest:null}}async installPackageHard(e,r,o){let a=cDt(e,{project:this.opts.project}),n=a.packageLocation;this.customData.locatorByPath.set(n,W.stringifyLocator(e)),this.customData.pathsByLocator.set(e.locatorHash,a),o.holdFetchResult(this.asyncActions.set(e.locatorHash,async()=>{await oe.mkdirPromise(n,{recursive:!0}),await oe.copyPromise(n,r.prefixPath,{baseFs:r.packageFs,overwrite:!1,linkStrategy:{type:"HardlinkFromIndex",indexPath:await this.indexFolderPromise,autoRepair:!0}})}));let A=W.isVirtualLocator(e)?W.devirtualizeLocator(e):e,p={manifest:await Mt.tryFind(r.prefixPath,{baseFs:r.packageFs})??new Mt,misc:{hasBindingGyp:mA.hasBindingGyp(r)}},h=this.opts.project.getDependencyMeta(A,e.version),E=mA.extractBuildRequest(e,p,h,{configuration:this.opts.project.configuration});return{packageLocation:n,buildRequest:E}}async attachInternalDependencies(e,r){if(this.opts.project.configuration.get("nodeLinker")!=="pnpm"||!LBe(e,{project:this.opts.project}))return;let o=this.customData.pathsByLocator.get(e.locatorHash);if(typeof o>"u")throw new Error(`Assertion failed: Expected the package to have been registered (${W.stringifyLocator(e)})`);let{dependenciesLocation:a}=o;!a||this.asyncActions.reduce(e.locatorHash,async n=>{await oe.mkdirPromise(a,{recursive:!0});let u=await uDt(a),A=new Map(u),p=[n],h=(I,v)=>{let b=v;LBe(v,{project:this.opts.project})||(this.opts.report.reportWarningOnce(0,"The pnpm linker doesn't support providing different versions to workspaces' peer dependencies"),b=W.devirtualizeLocator(v));let C=this.customData.pathsByLocator.get(b.locatorHash);if(typeof C>"u")throw new Error(`Assertion failed: Expected the package to have been registered (${W.stringifyLocator(v)})`);let T=W.stringifyIdent(I),L=K.join(a,T),U=K.relative(K.dirname(L),C.packageLocation),J=A.get(T);A.delete(T),p.push(Promise.resolve().then(async()=>{if(J){if(J.isSymbolicLink()&&await oe.readlinkPromise(L)===U)return;await oe.removePromise(L)}await oe.mkdirpPromise(K.dirname(L)),process.platform=="win32"&&this.opts.project.configuration.get("winLinkType")==="junctions"?await oe.symlinkPromise(C.packageLocation,L,"junction"):await oe.symlinkPromise(U,L)}))},E=!1;for(let[I,v]of r)I.identHash===e.identHash&&(E=!0),h(I,v);!E&&!this.opts.project.tryWorkspaceByLocator(e)&&h(W.convertLocatorToDescriptor(e),e),p.push(ADt(a,A)),await Promise.all(p)})}async attachExternalDependents(e,r){throw new Error("External dependencies haven't been implemented for the pnpm linker")}async finalizeInstall(){let e=OBe(this.opts.project);if(this.opts.project.configuration.get("nodeLinker")!=="pnpm")await oe.removePromise(e);else{let r;try{r=new Set(await oe.readdirPromise(e))}catch{r=new Set}for(let{dependenciesLocation:o}of this.customData.pathsByLocator.values()){if(!o)continue;let a=K.contains(e,o);if(a===null)continue;let[n]=a.split(K.sep);r.delete(n)}await Promise.all([...r].map(async o=>{await oe.removePromise(K.join(e,o))}))}return await this.asyncActions.wait(),await MG(e),this.opts.project.configuration.get("nodeLinker")!=="node-modules"&&await MG(MBe(this.opts.project)),{customData:this.customData}}};function MBe(t){return K.join(t.cwd,dr.nodeModules)}function OBe(t){return K.join(MBe(t),".store")}function cDt(t,{project:e}){let r=W.slugifyLocator(t),o=OBe(e),a=K.join(o,r,"package"),n=K.join(o,r,dr.nodeModules);return{packageLocation:a,dependenciesLocation:n}}function LBe(t,{project:e}){return!W.isVirtualLocator(t)||!e.tryWorkspaceByLocator(t)}async function uDt(t){let e=new Map,r=[];try{r=await oe.readdirPromise(t,{withFileTypes:!0})}catch(o){if(o.code!=="ENOENT")throw o}try{for(let o of r)if(!o.name.startsWith("."))if(o.name.startsWith("@")){let a=await oe.readdirPromise(K.join(t,o.name),{withFileTypes:!0});if(a.length===0)e.set(o.name,o);else for(let n of a)e.set(`${o.name}/${n.name}`,n)}else e.set(o.name,o)}catch(o){if(o.code!=="ENOENT")throw o}return e}async function ADt(t,e){let r=[],o=new Set;for(let a of e.keys()){r.push(oe.removePromise(K.join(t,a)));let n=W.tryParseIdent(a)?.scope;n&&o.add(`@${n}`)}return Promise.all(r).then(()=>Promise.all([...o].map(a=>MG(K.join(t,a)))))}async function MG(t){try{await oe.rmdirPromise(t)}catch(e){if(e.code!=="ENOENT"&&e.code!=="ENOTEMPTY")throw e}}var fDt={linkers:[Hv]},pDt=fDt;var YG={};Kt(YG,{StageCommand:()=>Z0,default:()=>vDt,stageUtils:()=>lF});Ye();Pt();qt();Ye();Pt();var lF={};Kt(lF,{ActionType:()=>UG,checkConsensus:()=>aF,expandDirectory:()=>jG,findConsensus:()=>qG,findVcsRoot:()=>_G,genCommitMessage:()=>GG,getCommitPrefix:()=>UBe,isYarnFile:()=>HG});Pt();var UG=(n=>(n[n.CREATE=0]="CREATE",n[n.DELETE=1]="DELETE",n[n.ADD=2]="ADD",n[n.REMOVE=3]="REMOVE",n[n.MODIFY=4]="MODIFY",n))(UG||{});async function _G(t,{marker:e}){do if(!oe.existsSync(K.join(t,e)))t=K.dirname(t);else return t;while(t!=="/");return null}function HG(t,{roots:e,names:r}){if(r.has(K.basename(t)))return!0;do if(!e.has(t))t=K.dirname(t);else return!0;while(t!=="/");return!1}function jG(t){let e=[],r=[t];for(;r.length>0;){let o=r.pop(),a=oe.readdirSync(o);for(let n of a){let u=K.resolve(o,n);oe.lstatSync(u).isDirectory()?r.push(u):e.push(u)}}return e}function aF(t,e){let r=0,o=0;for(let a of t)a!=="wip"&&(e.test(a)?r+=1:o+=1);return r>=o}function qG(t){let e=aF(t,/^(\w\(\w+\):\s*)?\w+s/),r=aF(t,/^(\w\(\w+\):\s*)?[A-Z]/),o=aF(t,/^\w\(\w+\):/);return{useThirdPerson:e,useUpperCase:r,useComponent:o}}function UBe(t){return t.useComponent?"chore(yarn): ":""}var hDt=new Map([[0,"create"],[1,"delete"],[2,"add"],[3,"remove"],[4,"update"]]);function GG(t,e){let r=UBe(t),o=[],a=e.slice().sort((n,u)=>n[0]-u[0]);for(;a.length>0;){let[n,u]=a.shift(),A=hDt.get(n);t.useUpperCase&&o.length===0&&(A=`${A[0].toUpperCase()}${A.slice(1)}`),t.useThirdPerson&&(A+="s");let p=[u];for(;a.length>0&&a[0][0]===n;){let[,E]=a.shift();p.push(E)}p.sort();let h=p.shift();p.length===1?h+=" (and one other)":p.length>1&&(h+=` (and ${p.length} others)`),o.push(`${A} ${h}`)}return`${r}${o.join(", ")}`}var gDt="Commit generated via `yarn stage`",dDt=11;async function _Be(t){let{code:e,stdout:r}=await Ur.execvp("git",["log","-1","--pretty=format:%H"],{cwd:t});return e===0?r.trim():null}async function mDt(t,e){let r=[],o=e.filter(h=>K.basename(h.path)==="package.json");for(let{action:h,path:E}of o){let I=K.relative(t,E);if(h===4){let v=await _Be(t),{stdout:b}=await Ur.execvp("git",["show",`${v}:${I}`],{cwd:t,strict:!0}),C=await Mt.fromText(b),T=await Mt.fromFile(E),L=new Map([...T.dependencies,...T.devDependencies]),U=new Map([...C.dependencies,...C.devDependencies]);for(let[J,te]of U){let le=W.stringifyIdent(te),pe=L.get(J);pe?pe.range!==te.range&&r.push([4,`${le} to ${pe.range}`]):r.push([3,le])}for(let[J,te]of L)U.has(J)||r.push([2,W.stringifyIdent(te)])}else if(h===0){let v=await Mt.fromFile(E);v.name?r.push([0,W.stringifyIdent(v.name)]):r.push([0,"a package"])}else if(h===1){let v=await _Be(t),{stdout:b}=await Ur.execvp("git",["show",`${v}:${I}`],{cwd:t,strict:!0}),C=await Mt.fromText(b);C.name?r.push([1,W.stringifyIdent(C.name)]):r.push([1,"a package"])}else throw new Error("Assertion failed: Unsupported action type")}let{code:a,stdout:n}=await Ur.execvp("git",["log",`-${dDt}`,"--pretty=format:%s"],{cwd:t}),u=a===0?n.split(/\n/g).filter(h=>h!==""):[],A=qG(u);return GG(A,r)}var yDt={[0]:[" A ","?? "],[4]:[" M "],[1]:[" D "]},EDt={[0]:["A "],[4]:["M "],[1]:["D "]},HBe={async findRoot(t){return await _G(t,{marker:".git"})},async filterChanges(t,e,r,o){let{stdout:a}=await Ur.execvp("git",["status","-s"],{cwd:t,strict:!0}),n=a.toString().split(/\n/g),u=o?.staged?EDt:yDt;return[].concat(...n.map(p=>{if(p==="")return[];let h=p.slice(0,3),E=K.resolve(t,p.slice(3));if(!o?.staged&&h==="?? "&&p.endsWith("/"))return jG(E).map(I=>({action:0,path:I}));{let v=[0,4,1].find(b=>u[b].includes(h));return v!==void 0?[{action:v,path:E}]:[]}})).filter(p=>HG(p.path,{roots:e,names:r}))},async genCommitMessage(t,e){return await mDt(t,e)},async makeStage(t,e){let r=e.map(o=>ue.fromPortablePath(o.path));await Ur.execvp("git",["add","--",...r],{cwd:t,strict:!0})},async makeCommit(t,e,r){let o=e.map(a=>ue.fromPortablePath(a.path));await Ur.execvp("git",["add","-N","--",...o],{cwd:t,strict:!0}),await Ur.execvp("git",["commit","-m",`${r} + +${gDt} +`,"--",...o],{cwd:t,strict:!0})},async makeReset(t,e){let r=e.map(o=>ue.fromPortablePath(o.path));await Ur.execvp("git",["reset","HEAD","--",...r],{cwd:t,strict:!0})}};var CDt=[HBe],Z0=class extends ut{constructor(){super(...arguments);this.commit=ge.Boolean("-c,--commit",!1,{description:"Commit the staged files"});this.reset=ge.Boolean("-r,--reset",!1,{description:"Remove all files from the staging area"});this.dryRun=ge.Boolean("-n,--dry-run",!1,{description:"Print the commit message and the list of modified files without staging / committing"});this.update=ge.Boolean("-u,--update",!1,{hidden:!0})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o}=await St.find(r,this.context.cwd),{driver:a,root:n}=await wDt(o.cwd),u=[r.get("cacheFolder"),r.get("globalFolder"),r.get("virtualFolder"),r.get("yarnPath")];await r.triggerHook(I=>I.populateYarnPaths,o,I=>{u.push(I)});let A=new Set;for(let I of u)for(let v of IDt(n,I))A.add(v);let p=new Set([r.get("rcFilename"),dr.lockfile,dr.manifest]),h=await a.filterChanges(n,A,p),E=await a.genCommitMessage(n,h);if(this.dryRun)if(this.commit)this.context.stdout.write(`${E} +`);else for(let I of h)this.context.stdout.write(`${ue.fromPortablePath(I.path)} +`);else if(this.reset){let I=await a.filterChanges(n,A,p,{staged:!0});I.length===0?this.context.stdout.write("No staged changes found!"):await a.makeReset(n,I)}else h.length===0?this.context.stdout.write("No changes found!"):this.commit?await a.makeCommit(n,h,E):(await a.makeStage(n,h),this.context.stdout.write(E))}};Z0.paths=[["stage"]],Z0.usage=nt.Usage({description:"add all yarn files to your vcs",details:"\n This command will add to your staging area the files belonging to Yarn (typically any modified `package.json` and `.yarnrc.yml` files, but also linker-generated files, cache data, etc). It will take your ignore list into account, so the cache files won't be added if the cache is ignored in a `.gitignore` file (assuming you use Git).\n\n Running `--reset` will instead remove them from the staging area (the changes will still be there, but won't be committed until you stage them back).\n\n Since the staging area is a non-existent concept in Mercurial, Yarn will always create a new commit when running this command on Mercurial repositories. You can get this behavior when using Git by using the `--commit` flag which will directly create a commit.\n ",examples:[["Adds all modified project files to the staging area","yarn stage"],["Creates a new commit containing all modified project files","yarn stage --commit"]]});async function wDt(t){let e=null,r=null;for(let o of CDt)if((r=await o.findRoot(t))!==null){e=o;break}if(e===null||r===null)throw new it("No stage driver has been found for your current project");return{driver:e,root:r}}function IDt(t,e){let r=[];if(e===null)return r;for(;;){(e===t||e.startsWith(`${t}/`))&&r.push(e);let o;try{o=oe.statSync(e)}catch{break}if(o.isSymbolicLink())e=K.resolve(K.dirname(e),oe.readlinkSync(e));else break}return r}var BDt={commands:[Z0]},vDt=BDt;var WG={};Kt(WG,{default:()=>FDt});Ye();Ye();Pt();var GBe=$e(zn());Ye();var jBe=$e(ZH()),DDt="e8e1bd300d860104bb8c58453ffa1eb4",PDt="OFCNCOG2CU",qBe=async(t,e)=>{let r=W.stringifyIdent(t),a=SDt(e).initIndex("npm-search");try{return(await a.getObject(r,{attributesToRetrieve:["types"]})).types?.ts==="definitely-typed"}catch{return!1}},SDt=t=>(0,jBe.default)(PDt,DDt,{requester:{async send(r){try{let o=await rn.request(r.url,r.data||null,{configuration:t,headers:r.headers});return{content:o.body,isTimedOut:!1,status:o.statusCode}}catch(o){return{content:o.response.body,isTimedOut:!1,status:o.response.statusCode}}}}});var YBe=t=>t.scope?`${t.scope}__${t.name}`:`${t.name}`,xDt=async(t,e,r,o)=>{if(r.scope==="types")return;let{project:a}=t,{configuration:n}=a;if(!(n.get("tsEnableAutoTypes")??oe.existsSync(K.join(a.cwd,"tsconfig.json"))))return;let A=n.makeResolver(),p={project:a,resolver:A,report:new Qi};if(!await qBe(r,n))return;let E=YBe(r),I=W.parseRange(r.range).selector;if(!kr.validRange(I)){let L=n.normalizeDependency(r),U=await A.getCandidates(L,{},p);I=W.parseRange(U[0].reference).selector}let v=GBe.default.coerce(I);if(v===null)return;let b=`${zc.Modifier.CARET}${v.major}`,C=W.makeDescriptor(W.makeIdent("types",E),b),T=je.mapAndFind(a.workspaces,L=>{let U=L.manifest.dependencies.get(r.identHash)?.descriptorHash,J=L.manifest.devDependencies.get(r.identHash)?.descriptorHash;if(U!==r.descriptorHash&&J!==r.descriptorHash)return je.mapAndFind.skip;let te=[];for(let le of Mt.allDependencies){let pe=L.manifest[le].get(C.identHash);typeof pe>"u"||te.push([le,pe])}return te.length===0?je.mapAndFind.skip:te});if(typeof T<"u")for(let[L,U]of T)t.manifest[L].set(U.identHash,U);else{try{let L=n.normalizeDependency(C);if((await A.getCandidates(L,{},p)).length===0)return}catch{return}t.manifest[zc.Target.DEVELOPMENT].set(C.identHash,C)}},bDt=async(t,e,r)=>{if(r.scope==="types")return;let{project:o}=t,{configuration:a}=o;if(!(a.get("tsEnableAutoTypes")??oe.existsSync(K.join(o.cwd,"tsconfig.json"))))return;let u=YBe(r),A=W.makeIdent("types",u);for(let p of Mt.allDependencies)typeof t.manifest[p].get(A.identHash)>"u"||t.manifest[p].delete(A.identHash)},kDt=(t,e)=>{e.publishConfig&&e.publishConfig.typings&&(e.typings=e.publishConfig.typings),e.publishConfig&&e.publishConfig.types&&(e.types=e.publishConfig.types)},QDt={configuration:{tsEnableAutoTypes:{description:"Whether Yarn should auto-install @types/ dependencies on 'yarn add'",type:"BOOLEAN",isNullable:!0,default:null}},hooks:{afterWorkspaceDependencyAddition:xDt,afterWorkspaceDependencyRemoval:bDt,beforeWorkspacePacking:kDt}},FDt=QDt;var XG={};Kt(XG,{VersionApplyCommand:()=>$0,VersionCheckCommand:()=>eg,VersionCommand:()=>tg,default:()=>XDt,versionUtils:()=>gw});Ye();Ye();qt();var gw={};Kt(gw,{Decision:()=>pw,applyPrerelease:()=>XBe,applyReleases:()=>zG,applyStrategy:()=>uF,clearVersionFiles:()=>VG,getUndecidedDependentWorkspaces:()=>qv,getUndecidedWorkspaces:()=>cF,openVersionFile:()=>hw,requireMoreDecisions:()=>KDt,resolveVersionFiles:()=>jv,suggestStrategy:()=>JG,updateVersionFiles:()=>KG,validateReleaseDecision:()=>fw});Ye();Pt();Nl();qt();var zBe=$e(JBe()),BA=$e(zn()),VDt=/^(>=|[~^]|)(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?$/,pw=(u=>(u.UNDECIDED="undecided",u.DECLINE="decline",u.MAJOR="major",u.MINOR="minor",u.PATCH="patch",u.PRERELEASE="prerelease",u))(pw||{});function fw(t){let e=BA.default.valid(t);return e||je.validateEnum((0,zBe.default)(pw,"UNDECIDED"),t)}async function jv(t,{prerelease:e=null}={}){let r=new Map,o=t.configuration.get("deferredVersionFolder");if(!oe.existsSync(o))return r;let a=await oe.readdirPromise(o);for(let n of a){if(!n.endsWith(".yml"))continue;let u=K.join(o,n),A=await oe.readFilePromise(u,"utf8"),p=Vi(A);for(let[h,E]of Object.entries(p.releases||{})){if(E==="decline")continue;let I=W.parseIdent(h),v=t.tryWorkspaceByIdent(I);if(v===null)throw new Error(`Assertion failed: Expected a release definition file to only reference existing workspaces (${K.basename(u)} references ${h})`);if(v.manifest.version===null)throw new Error(`Assertion failed: Expected the workspace to have a version (${W.prettyLocator(t.configuration,v.anchoredLocator)})`);let b=v.manifest.raw.stableVersion??v.manifest.version,C=r.get(v),T=uF(b,fw(E));if(T===null)throw new Error(`Assertion failed: Expected ${b} to support being bumped via strategy ${E}`);let L=typeof C<"u"?BA.default.gt(T,C)?T:C:T;r.set(v,L)}}return e&&(r=new Map([...r].map(([n,u])=>[n,XBe(u,{current:n.manifest.version,prerelease:e})]))),r}async function VG(t){let e=t.configuration.get("deferredVersionFolder");!oe.existsSync(e)||await oe.removePromise(e)}async function KG(t,e){let r=new Set(e),o=t.configuration.get("deferredVersionFolder");if(!oe.existsSync(o))return;let a=await oe.readdirPromise(o);for(let n of a){if(!n.endsWith(".yml"))continue;let u=K.join(o,n),A=await oe.readFilePromise(u,"utf8"),p=Vi(A),h=p?.releases;if(!!h){for(let E of Object.keys(h)){let I=W.parseIdent(E),v=t.tryWorkspaceByIdent(I);(v===null||r.has(v))&&delete p.releases[E]}Object.keys(p.releases).length>0?await oe.changeFilePromise(u,Ba(new Ba.PreserveOrdering(p))):await oe.unlinkPromise(u)}}}async function hw(t,{allowEmpty:e=!1}={}){let r=t.configuration;if(r.projectCwd===null)throw new it("This command can only be run from within a Yarn project");let o=await ra.fetchRoot(r.projectCwd),a=o!==null?await ra.fetchBase(o,{baseRefs:r.get("changesetBaseRefs")}):null,n=o!==null?await ra.fetchChangedFiles(o,{base:a.hash,project:t}):[],u=r.get("deferredVersionFolder"),A=n.filter(b=>K.contains(u,b)!==null);if(A.length>1)throw new it(`Your current branch contains multiple versioning files; this isn't supported: +- ${A.map(b=>ue.fromPortablePath(b)).join(` +- `)}`);let p=new Set(je.mapAndFilter(n,b=>{let C=t.tryWorkspaceByFilePath(b);return C===null?je.mapAndFilter.skip:C}));if(A.length===0&&p.size===0&&!e)return null;let h=A.length===1?A[0]:K.join(u,`${wn.makeHash(Math.random().toString()).slice(0,8)}.yml`),E=oe.existsSync(h)?await oe.readFilePromise(h,"utf8"):"{}",I=Vi(E),v=new Map;for(let b of I.declined||[]){let C=W.parseIdent(b),T=t.getWorkspaceByIdent(C);v.set(T,"decline")}for(let[b,C]of Object.entries(I.releases||{})){let T=W.parseIdent(b),L=t.getWorkspaceByIdent(T);v.set(L,fw(C))}return{project:t,root:o,baseHash:a!==null?a.hash:null,baseTitle:a!==null?a.title:null,changedFiles:new Set(n),changedWorkspaces:p,releaseRoots:new Set([...p].filter(b=>b.manifest.version!==null)),releases:v,async saveAll(){let b={},C=[],T=[];for(let L of t.workspaces){if(L.manifest.version===null)continue;let U=W.stringifyIdent(L.anchoredLocator),J=v.get(L);J==="decline"?C.push(U):typeof J<"u"?b[U]=fw(J):p.has(L)&&T.push(U)}await oe.mkdirPromise(K.dirname(h),{recursive:!0}),await oe.changeFilePromise(h,Ba(new Ba.PreserveOrdering({releases:Object.keys(b).length>0?b:void 0,declined:C.length>0?C:void 0,undecided:T.length>0?T:void 0})))}}}function KDt(t){return cF(t).size>0||qv(t).length>0}function cF(t){let e=new Set;for(let r of t.changedWorkspaces)r.manifest.version!==null&&(t.releases.has(r)||e.add(r));return e}function qv(t,{include:e=new Set}={}){let r=[],o=new Map(je.mapAndFilter([...t.releases],([n,u])=>u==="decline"?je.mapAndFilter.skip:[n.anchoredLocator.locatorHash,n])),a=new Map(je.mapAndFilter([...t.releases],([n,u])=>u!=="decline"?je.mapAndFilter.skip:[n.anchoredLocator.locatorHash,n]));for(let n of t.project.workspaces)if(!(!e.has(n)&&(a.has(n.anchoredLocator.locatorHash)||o.has(n.anchoredLocator.locatorHash)))&&n.manifest.version!==null)for(let u of Mt.hardDependencies)for(let A of n.manifest.getForScope(u).values()){let p=t.project.tryWorkspaceByDescriptor(A);p!==null&&o.has(p.anchoredLocator.locatorHash)&&r.push([n,p])}return r}function JG(t,e){let r=BA.default.clean(e);for(let o of Object.values(pw))if(o!=="undecided"&&o!=="decline"&&BA.default.inc(t,o)===r)return o;return null}function uF(t,e){if(BA.default.valid(e))return e;if(t===null)throw new it(`Cannot apply the release strategy "${e}" unless the workspace already has a valid version`);if(!BA.default.valid(t))throw new it(`Cannot apply the release strategy "${e}" on a non-semver version (${t})`);let r=BA.default.inc(t,e);if(r===null)throw new it(`Cannot apply the release strategy "${e}" on the specified version (${t})`);return r}function zG(t,e,{report:r}){let o=new Map;for(let a of t.workspaces)for(let n of Mt.allDependencies)for(let u of a.manifest[n].values()){let A=t.tryWorkspaceByDescriptor(u);if(A===null||!e.has(A))continue;je.getArrayWithDefault(o,A).push([a,n,u.identHash])}for(let[a,n]of e){let u=a.manifest.version;a.manifest.version=n,BA.default.prerelease(n)===null?delete a.manifest.raw.stableVersion:a.manifest.raw.stableVersion||(a.manifest.raw.stableVersion=u);let A=a.manifest.name!==null?W.stringifyIdent(a.manifest.name):null;r.reportInfo(0,`${W.prettyLocator(t.configuration,a.anchoredLocator)}: Bumped to ${n}`),r.reportJson({cwd:ue.fromPortablePath(a.cwd),ident:A,oldVersion:u,newVersion:n});let p=o.get(a);if(!(typeof p>"u"))for(let[h,E,I]of p){let v=h.manifest[E].get(I);if(typeof v>"u")throw new Error("Assertion failed: The dependency should have existed");let b=v.range,C=!1;if(b.startsWith(Xn.protocol)&&(b=b.slice(Xn.protocol.length),C=!0,b===a.relativeCwd))continue;let T=b.match(VDt);if(!T){r.reportWarning(0,`Couldn't auto-upgrade range ${b} (in ${W.prettyLocator(t.configuration,h.anchoredLocator)})`);continue}let L=`${T[1]}${n}`;C&&(L=`${Xn.protocol}${L}`);let U=W.makeDescriptor(v,L);h.manifest[E].set(I,U)}}}var JDt=new Map([["%n",{extract:t=>t.length>=1?[t[0],t.slice(1)]:null,generate:(t=0)=>`${t+1}`}]]);function XBe(t,{current:e,prerelease:r}){let o=new BA.default.SemVer(e),a=o.prerelease.slice(),n=[];o.prerelease=[],o.format()!==t&&(a.length=0);let u=!0,A=r.split(/\./g);for(let p of A){let h=JDt.get(p);if(typeof h>"u")n.push(p),a[0]===p?a.shift():u=!1;else{let E=u?h.extract(a):null;E!==null&&typeof E[0]=="number"?(n.push(h.generate(E[0])),a=E[1]):(n.push(h.generate()),u=!1)}}return o.prerelease&&(o.prerelease=[]),`${t}-${n.join(".")}`}var $0=class extends ut{constructor(){super(...arguments);this.all=ge.Boolean("--all",!1,{description:"Apply the deferred version changes on all workspaces"});this.dryRun=ge.Boolean("--dry-run",!1,{description:"Print the versions without actually generating the package archive"});this.prerelease=ge.String("--prerelease",{description:"Add a prerelease identifier to new versions",tolerateBoolean:!0});this.recursive=ge.Boolean("-R,--recursive",{description:"Release the transitive workspaces as well"});this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n=await Lr.find(r);if(!a)throw new rr(o.cwd,this.context.cwd);await o.restoreInstallState({restoreResolutions:!1});let u=await Nt.start({configuration:r,json:this.json,stdout:this.context.stdout},async A=>{let p=this.prerelease?typeof this.prerelease!="boolean"?this.prerelease:"rc.%n":null,h=await jv(o,{prerelease:p}),E=new Map;if(this.all)E=h;else{let I=this.recursive?a.getRecursiveWorkspaceDependencies():[a];for(let v of I){let b=h.get(v);typeof b<"u"&&E.set(v,b)}}if(E.size===0){let I=h.size>0?" Did you want to add --all?":"";A.reportWarning(0,`The current workspace doesn't seem to require a version bump.${I}`);return}zG(o,E,{report:A}),this.dryRun||(p||(this.all?await VG(o):await KG(o,[...E.keys()])),A.reportSeparator())});return u.hasErrors()?u.exitCode():await o.installWithNewReport({json:this.json,stdout:this.context.stdout},{cache:n})}};$0.paths=[["version","apply"]],$0.usage=nt.Usage({category:"Release-related commands",description:"apply all the deferred version bumps at once",details:` + This command will apply the deferred version changes and remove their definitions from the repository. + + Note that if \`--prerelease\` is set, the given prerelease identifier (by default \`rc.%d\`) will be used on all new versions and the version definitions will be kept as-is. + + By default only the current workspace will be bumped, but you can configure this behavior by using one of: + + - \`--recursive\` to also apply the version bump on its dependencies + - \`--all\` to apply the version bump on all packages in the repository + + Note that this command will also update the \`workspace:\` references across all your local workspaces, thus ensuring that they keep referring to the same workspaces even after the version bump. + `,examples:[["Apply the version change to the local workspace","yarn version apply"],["Apply the version change to all the workspaces in the local workspace","yarn version apply --all"]]});Ye();Pt();qt();var AF=$e(zn());var eg=class extends ut{constructor(){super(...arguments);this.interactive=ge.Boolean("-i,--interactive",{description:"Open an interactive interface used to set version bumps"})}async execute(){return this.interactive?await this.executeInteractive():await this.executeStandard()}async executeInteractive(){SC(this.context);let{Gem:r}=await Promise.resolve().then(()=>(AQ(),Dj)),{ScrollableItems:o}=await Promise.resolve().then(()=>(gQ(),hQ)),{FocusRequest:a}=await Promise.resolve().then(()=>(Sj(),Xwe)),{useListInput:n}=await Promise.resolve().then(()=>(pQ(),Zwe)),{renderForm:u}=await Promise.resolve().then(()=>(EQ(),yQ)),{Box:A,Text:p}=await Promise.resolve().then(()=>$e(ic())),{default:h,useCallback:E,useState:I}=await Promise.resolve().then(()=>$e(sn())),v=await Ve.find(this.context.cwd,this.context.plugins),{project:b,workspace:C}=await St.find(v,this.context.cwd);if(!C)throw new rr(b.cwd,this.context.cwd);await b.restoreInstallState();let T=await hw(b);if(T===null||T.releaseRoots.size===0)return 0;if(T.root===null)throw new it("This command can only be run on Git repositories");let L=()=>h.createElement(A,{flexDirection:"row",paddingBottom:1},h.createElement(A,{flexDirection:"column",width:60},h.createElement(A,null,h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"<up>"),"/",h.createElement(p,{bold:!0,color:"cyanBright"},"<down>")," to select workspaces.")),h.createElement(A,null,h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"<left>"),"/",h.createElement(p,{bold:!0,color:"cyanBright"},"<right>")," to select release strategies."))),h.createElement(A,{flexDirection:"column"},h.createElement(A,{marginLeft:1},h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"<enter>")," to save.")),h.createElement(A,{marginLeft:1},h.createElement(p,null,"Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"<ctrl+c>")," to abort.")))),U=({workspace:ye,active:ae,decision:we,setDecision:Pe})=>{let g=ye.manifest.raw.stableVersion??ye.manifest.version;if(g===null)throw new Error(`Assertion failed: The version should have been set (${W.prettyLocator(v,ye.anchoredLocator)})`);if(AF.default.prerelease(g)!==null)throw new Error(`Assertion failed: Prerelease identifiers shouldn't be found (${g})`);let Ee=["undecided","decline","patch","minor","major"];n(we,Ee,{active:ae,minus:"left",plus:"right",set:Pe});let De=we==="undecided"?h.createElement(p,{color:"yellow"},g):we==="decline"?h.createElement(p,{color:"green"},g):h.createElement(p,null,h.createElement(p,{color:"magenta"},g)," \u2192 ",h.createElement(p,{color:"green"},AF.default.valid(we)?we:AF.default.inc(g,we)));return h.createElement(A,{flexDirection:"column"},h.createElement(A,null,h.createElement(p,null,W.prettyLocator(v,ye.anchoredLocator)," - ",De)),h.createElement(A,null,Ee.map(ce=>h.createElement(A,{key:ce,paddingLeft:2},h.createElement(p,null,h.createElement(r,{active:ce===we})," ",ce)))))},J=ye=>{let ae=new Set(T.releaseRoots),we=new Map([...ye].filter(([Pe])=>ae.has(Pe)));for(;;){let Pe=qv({project:T.project,releases:we}),g=!1;if(Pe.length>0){for(let[Ee]of Pe)if(!ae.has(Ee)){ae.add(Ee),g=!0;let De=ye.get(Ee);typeof De<"u"&&we.set(Ee,De)}}if(!g)break}return{relevantWorkspaces:ae,relevantReleases:we}},te=()=>{let[ye,ae]=I(()=>new Map(T.releases)),we=E((Pe,g)=>{let Ee=new Map(ye);g!=="undecided"?Ee.set(Pe,g):Ee.delete(Pe);let{relevantReleases:De}=J(Ee);ae(De)},[ye,ae]);return[ye,we]},le=({workspaces:ye,releases:ae})=>{let we=[];we.push(`${ye.size} total`);let Pe=0,g=0;for(let Ee of ye){let De=ae.get(Ee);typeof De>"u"?g+=1:De!=="decline"&&(Pe+=1)}return we.push(`${Pe} release${Pe===1?"":"s"}`),we.push(`${g} remaining`),h.createElement(p,{color:"yellow"},we.join(", "))},Ae=await u(({useSubmit:ye})=>{let[ae,we]=te();ye(ae);let{relevantWorkspaces:Pe}=J(ae),g=new Set([...Pe].filter(ne=>!T.releaseRoots.has(ne))),[Ee,De]=I(0),ce=E(ne=>{switch(ne){case a.BEFORE:De(Ee-1);break;case a.AFTER:De(Ee+1);break}},[Ee,De]);return h.createElement(A,{flexDirection:"column"},h.createElement(L,null),h.createElement(A,null,h.createElement(p,{wrap:"wrap"},"The following files have been modified in your local checkout.")),h.createElement(A,{flexDirection:"column",marginTop:1,paddingLeft:2},[...T.changedFiles].map(ne=>h.createElement(A,{key:ne},h.createElement(p,null,h.createElement(p,{color:"grey"},ue.fromPortablePath(T.root)),ue.sep,ue.relative(ue.fromPortablePath(T.root),ue.fromPortablePath(ne)))))),T.releaseRoots.size>0&&h.createElement(h.Fragment,null,h.createElement(A,{marginTop:1},h.createElement(p,{wrap:"wrap"},"Because of those files having been modified, the following workspaces may need to be released again (note that private workspaces are also shown here, because even though they won't be published, releasing them will allow us to flag their dependents for potential re-release):")),g.size>3?h.createElement(A,{marginTop:1},h.createElement(le,{workspaces:T.releaseRoots,releases:ae})):null,h.createElement(A,{marginTop:1,flexDirection:"column"},h.createElement(o,{active:Ee%2===0,radius:1,size:2,onFocusRequest:ce},[...T.releaseRoots].map(ne=>h.createElement(U,{key:ne.cwd,workspace:ne,decision:ae.get(ne)||"undecided",setDecision:ee=>we(ne,ee)}))))),g.size>0?h.createElement(h.Fragment,null,h.createElement(A,{marginTop:1},h.createElement(p,{wrap:"wrap"},"The following workspaces depend on other workspaces that have been marked for release, and thus may need to be released as well:")),h.createElement(A,null,h.createElement(p,null,"(Press ",h.createElement(p,{bold:!0,color:"cyanBright"},"<tab>")," to move the focus between the workspace groups.)")),g.size>5?h.createElement(A,{marginTop:1},h.createElement(le,{workspaces:g,releases:ae})):null,h.createElement(A,{marginTop:1,flexDirection:"column"},h.createElement(o,{active:Ee%2===1,radius:2,size:2,onFocusRequest:ce},[...g].map(ne=>h.createElement(U,{key:ne.cwd,workspace:ne,decision:ae.get(ne)||"undecided",setDecision:ee=>we(ne,ee)}))))):null)},{versionFile:T},{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});if(typeof Ae>"u")return 1;T.releases.clear();for(let[ye,ae]of Ae)T.releases.set(ye,ae);await T.saveAll()}async executeStandard(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd);if(!a)throw new rr(o.cwd,this.context.cwd);return await o.restoreInstallState(),(await Nt.start({configuration:r,stdout:this.context.stdout},async u=>{let A=await hw(o);if(A===null||A.releaseRoots.size===0)return;if(A.root===null)throw new it("This command can only be run on Git repositories");if(u.reportInfo(0,`Your PR was started right after ${de.pretty(r,A.baseHash.slice(0,7),"yellow")} ${de.pretty(r,A.baseTitle,"magenta")}`),A.changedFiles.size>0){u.reportInfo(0,"You have changed the following files since then:"),u.reportSeparator();for(let v of A.changedFiles)u.reportInfo(null,`${de.pretty(r,ue.fromPortablePath(A.root),"gray")}${ue.sep}${ue.relative(ue.fromPortablePath(A.root),ue.fromPortablePath(v))}`)}let p=!1,h=!1,E=cF(A);if(E.size>0){p||u.reportSeparator();for(let v of E)u.reportError(0,`${W.prettyLocator(r,v.anchoredLocator)} has been modified but doesn't have a release strategy attached`);p=!0}let I=qv(A);for(let[v,b]of I)h||u.reportSeparator(),u.reportError(0,`${W.prettyLocator(r,v.anchoredLocator)} doesn't have a release strategy attached, but depends on ${W.prettyWorkspace(r,b)} which is planned for release.`),h=!0;(p||h)&&(u.reportSeparator(),u.reportInfo(0,"This command detected that at least some workspaces have received modifications without explicit instructions as to how they had to be released (if needed)."),u.reportInfo(0,"To correct these errors, run `yarn version check --interactive` then follow the instructions."))})).exitCode()}};eg.paths=[["version","check"]],eg.usage=nt.Usage({category:"Release-related commands",description:"check that all the relevant packages have been bumped",details:"\n **Warning:** This command currently requires Git.\n\n This command will check that all the packages covered by the files listed in argument have been properly bumped or declined to bump.\n\n In the case of a bump, the check will also cover transitive packages - meaning that should `Foo` be bumped, a package `Bar` depending on `Foo` will require a decision as to whether `Bar` will need to be bumped. This check doesn't cross packages that have declined to bump.\n\n In case no arguments are passed to the function, the list of modified files will be generated by comparing the HEAD against `master`.\n ",examples:[["Check whether the modified packages need a bump","yarn version check"]]});Ye();qt();var fF=$e(zn());var tg=class extends ut{constructor(){super(...arguments);this.deferred=ge.Boolean("-d,--deferred",{description:"Prepare the version to be bumped during the next release cycle"});this.immediate=ge.Boolean("-i,--immediate",{description:"Bump the version immediately"});this.strategy=ge.String()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd);if(!a)throw new rr(o.cwd,this.context.cwd);let n=r.get("preferDeferredVersions");this.deferred&&(n=!0),this.immediate&&(n=!1);let u=fF.default.valid(this.strategy),A=this.strategy==="decline",p;if(u)if(a.manifest.version!==null){let E=JG(a.manifest.version,this.strategy);E!==null?p=E:p=this.strategy}else p=this.strategy;else{let E=a.manifest.version;if(!A){if(E===null)throw new it("Can't bump the version if there wasn't a version to begin with - use 0.0.0 as initial version then run the command again.");if(typeof E!="string"||!fF.default.valid(E))throw new it(`Can't bump the version (${E}) if it's not valid semver`)}p=fw(this.strategy)}if(!n){let I=(await jv(o)).get(a);if(typeof I<"u"&&p!=="decline"){let v=uF(a.manifest.version,p);if(fF.default.lt(v,I))throw new it(`Can't bump the version to one that would be lower than the current deferred one (${I})`)}}let h=await hw(o,{allowEmpty:!0});return h.releases.set(a,p),await h.saveAll(),n?0:await this.cli.run(["version","apply"])}};tg.paths=[["version"]],tg.usage=nt.Usage({category:"Release-related commands",description:"apply a new version to the current package",details:"\n This command will bump the version number for the given package, following the specified strategy:\n\n - If `major`, the first number from the semver range will be increased (`X.0.0`).\n - If `minor`, the second number from the semver range will be increased (`0.X.0`).\n - If `patch`, the third number from the semver range will be increased (`0.0.X`).\n - If prefixed by `pre` (`premajor`, ...), a `-0` suffix will be set (`0.0.0-0`).\n - If `prerelease`, the suffix will be increased (`0.0.0-X`); the third number from the semver range will also be increased if there was no suffix in the previous version.\n - If `decline`, the nonce will be increased for `yarn version check` to pass without version bump.\n - If a valid semver range, it will be used as new version.\n - If unspecified, Yarn will ask you for guidance.\n\n For more information about the `--deferred` flag, consult our documentation (https://yarnpkg.com/features/release-workflow#deferred-versioning).\n ",examples:[["Immediately bump the version to the next major","yarn version major"],["Prepare the version to be bumped to the next major","yarn version major --deferred"]]});var zDt={configuration:{deferredVersionFolder:{description:"Folder where are stored the versioning files",type:"ABSOLUTE_PATH",default:"./.yarn/versions"},preferDeferredVersions:{description:"If true, running `yarn version` will assume the `--deferred` flag unless `--immediate` is set",type:"BOOLEAN",default:!1}},commands:[$0,eg,tg]},XDt=zDt;var ZG={};Kt(ZG,{WorkspacesFocusCommand:()=>rg,WorkspacesForeachCommand:()=>op,default:()=>ePt});Ye();Ye();qt();var rg=class extends ut{constructor(){super(...arguments);this.json=ge.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.production=ge.Boolean("--production",!1,{description:"Only install regular dependencies by omitting dev dependencies"});this.all=ge.Boolean("-A,--all",!1,{description:"Install the entire project"});this.workspaces=ge.Rest()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd),n=await Lr.find(r);await o.restoreInstallState({restoreResolutions:!1});let u;if(this.all)u=new Set(o.workspaces);else if(this.workspaces.length===0){if(!a)throw new rr(o.cwd,this.context.cwd);u=new Set([a])}else u=new Set(this.workspaces.map(A=>o.getWorkspaceByIdent(W.parseIdent(A))));for(let A of u)for(let p of this.production?["dependencies"]:Mt.hardDependencies)for(let h of A.manifest.getForScope(p).values()){let E=o.tryWorkspaceByDescriptor(h);E!==null&&u.add(E)}for(let A of o.workspaces)u.has(A)?this.production&&A.manifest.devDependencies.clear():(A.manifest.installConfig=A.manifest.installConfig||{},A.manifest.installConfig.selfReferences=!1,A.manifest.dependencies.clear(),A.manifest.devDependencies.clear(),A.manifest.peerDependencies.clear(),A.manifest.scripts.clear());return await o.installWithNewReport({json:this.json,stdout:this.context.stdout},{cache:n,persistProject:!1})}};rg.paths=[["workspaces","focus"]],rg.usage=nt.Usage({category:"Workspace-related commands",description:"install a single workspace and its dependencies",details:"\n This command will run an install as if the specified workspaces (and all other workspaces they depend on) were the only ones in the project. If no workspaces are explicitly listed, the active one will be assumed.\n\n Note that this command is only very moderately useful when using zero-installs, since the cache will contain all the packages anyway - meaning that the only difference between a full install and a focused install would just be a few extra lines in the `.pnp.cjs` file, at the cost of introducing an extra complexity.\n\n If the `-A,--all` flag is set, the entire project will be installed. Combine with `--production` to replicate the old `yarn install --production`.\n "});Ye();Ye();Ye();qt();var dw=$e(Zo()),$Be=$e(nd());Za();var op=class extends ut{constructor(){super(...arguments);this.from=ge.Array("--from",{description:"An array of glob pattern idents or paths from which to base any recursion"});this.all=ge.Boolean("-A,--all",{description:"Run the command on all workspaces of a project"});this.recursive=ge.Boolean("-R,--recursive",{description:"Run the command on the current workspace and all of its recursive dependencies"});this.worktree=ge.Boolean("-W,--worktree",{description:"Run the command on all workspaces of the current worktree"});this.verbose=ge.Boolean("-v,--verbose",{description:"Prefix each output line with the name of the originating workspace"});this.parallel=ge.Boolean("-p,--parallel",!1,{description:"Run the commands in parallel"});this.interlaced=ge.Boolean("-i,--interlaced",!1,{description:"Print the output of commands in real-time instead of buffering it"});this.jobs=ge.String("-j,--jobs",{description:"The maximum number of parallel tasks that the execution will be limited to; or `unlimited`",validator:LR([Vs(["unlimited"]),oI(NR(),[OR(),MR(1)])])});this.topological=ge.Boolean("-t,--topological",!1,{description:"Run the command after all workspaces it depends on (regular) have finished"});this.topologicalDev=ge.Boolean("--topological-dev",!1,{description:"Run the command after all workspaces it depends on (regular + dev) have finished"});this.include=ge.Array("--include",[],{description:"An array of glob pattern idents or paths; only matching workspaces will be traversed"});this.exclude=ge.Array("--exclude",[],{description:"An array of glob pattern idents or paths; matching workspaces won't be traversed"});this.publicOnly=ge.Boolean("--no-private",{description:"Avoid running the command on private workspaces"});this.since=ge.String("--since",{description:"Only include workspaces that have been changed since the specified ref.",tolerateBoolean:!0});this.dryRun=ge.Boolean("-n,--dry-run",{description:"Print the commands that would be run, without actually running them"});this.commandName=ge.String();this.args=ge.Proxy()}async execute(){let r=await Ve.find(this.context.cwd,this.context.plugins),{project:o,workspace:a}=await St.find(r,this.context.cwd);if(!this.all&&!a)throw new rr(o.cwd,this.context.cwd);await o.restoreInstallState();let n=this.cli.process([this.commandName,...this.args]),u=n.path.length===1&&n.path[0]==="run"&&typeof n.scriptName<"u"?n.scriptName:null;if(n.path.length===0)throw new it("Invalid subcommand name for iteration - use the 'run' keyword if you wish to execute a script");let A=ae=>{!this.dryRun||this.context.stdout.write(`${ae} +`)},p=()=>{let ae=this.from.map(we=>dw.default.matcher(we));return o.workspaces.filter(we=>{let Pe=W.stringifyIdent(we.anchoredLocator),g=we.relativeCwd;return ae.some(Ee=>Ee(Pe)||Ee(g))})},h=[];if(this.since?(A("Option --since is set; selecting the changed workspaces as root for workspace selection"),h=Array.from(await ra.fetchChangedWorkspaces({ref:this.since,project:o}))):this.from?(A("Option --from is set; selecting the specified workspaces"),h=[...p()]):this.worktree?(A("Option --worktree is set; selecting the current workspace"),h=[a]):this.recursive?(A("Option --recursive is set; selecting the current workspace"),h=[a]):this.all&&(A("Option --all is set; selecting all workspaces"),h=[...o.workspaces]),this.dryRun&&!this.all){for(let ae of h)A(` +- ${ae.relativeCwd} + ${W.prettyLocator(r,ae.anchoredLocator)}`);h.length>0&&A("")}let E;if(this.recursive?this.since?(A("Option --recursive --since is set; recursively selecting all dependent workspaces"),E=new Set(h.map(ae=>[...ae.getRecursiveWorkspaceDependents()]).flat())):(A("Option --recursive is set; recursively selecting all transitive dependencies"),E=new Set(h.map(ae=>[...ae.getRecursiveWorkspaceDependencies()]).flat())):this.worktree?(A("Option --worktree is set; recursively selecting all nested workspaces"),E=new Set(h.map(ae=>[...ae.getRecursiveWorkspaceChildren()]).flat())):E=null,E!==null&&(h=[...new Set([...h,...E])],this.dryRun))for(let ae of E)A(` +- ${ae.relativeCwd} + ${W.prettyLocator(r,ae.anchoredLocator)}`);let I=[],v=!1;if(u?.includes(":")){for(let ae of o.workspaces)if(ae.manifest.scripts.has(u)&&(v=!v,v===!1))break}for(let ae of h){if(u&&!ae.manifest.scripts.has(u)&&!v&&!(await un.getWorkspaceAccessibleBinaries(ae)).has(u)){A(`Excluding ${ae.relativeCwd} because it doesn't have a "${u}" script`);continue}if(!(u===r.env.npm_lifecycle_event&&ae.cwd===a.cwd)){if(this.include.length>0&&!dw.default.isMatch(W.stringifyIdent(ae.anchoredLocator),this.include)&&!dw.default.isMatch(ae.relativeCwd,this.include)){A(`Excluding ${ae.relativeCwd} because it doesn't match the --include filter`);continue}if(this.exclude.length>0&&(dw.default.isMatch(W.stringifyIdent(ae.anchoredLocator),this.exclude)||dw.default.isMatch(ae.relativeCwd,this.exclude))){A(`Excluding ${ae.relativeCwd} because it matches the --include filter`);continue}if(this.publicOnly&&ae.manifest.private===!0){A(`Excluding ${ae.relativeCwd} because it's a private workspace and --no-private was set`);continue}I.push(ae)}}if(this.dryRun)return 0;let b=this.verbose??this.context.stdout.isTTY,C=this.parallel?this.jobs==="unlimited"?1/0:Number(this.jobs)||Math.ceil(Ji.availableParallelism()/2):1,T=C===1?!1:this.parallel,L=T?this.interlaced:!0,U=(0,$Be.default)(C),J=new Map,te=new Set,le=0,pe=null,Ae=!1,ye=await Nt.start({configuration:r,stdout:this.context.stdout,includePrefix:!1},async ae=>{let we=async(Pe,{commandIndex:g})=>{if(Ae)return-1;!T&&b&&g>1&&ae.reportSeparator();let Ee=ZDt(Pe,{configuration:r,verbose:b,commandIndex:g}),[De,ce]=ZBe(ae,{prefix:Ee,interlaced:L}),[ne,ee]=ZBe(ae,{prefix:Ee,interlaced:L});try{b&&ae.reportInfo(null,`${Ee} Process started`);let Ie=Date.now(),ke=await this.cli.run([this.commandName,...this.args],{cwd:Pe.cwd,stdout:De,stderr:ne})||0;De.end(),ne.end(),await ce,await ee;let ht=Date.now();if(b){let H=r.get("enableTimers")?`, completed in ${de.pretty(r,ht-Ie,de.Type.DURATION)}`:"";ae.reportInfo(null,`${Ee} Process exited (exit code ${ke})${H}`)}return ke===130&&(Ae=!0,pe=ke),ke}catch(Ie){throw De.end(),ne.end(),await ce,await ee,Ie}};for(let Pe of I)J.set(Pe.anchoredLocator.locatorHash,Pe);for(;J.size>0&&!ae.hasErrors();){let Pe=[];for(let[De,ce]of J){if(te.has(ce.anchoredDescriptor.descriptorHash))continue;let ne=!0;if(this.topological||this.topologicalDev){let ee=this.topologicalDev?new Map([...ce.manifest.dependencies,...ce.manifest.devDependencies]):ce.manifest.dependencies;for(let Ie of ee.values()){let ke=o.tryWorkspaceByDescriptor(Ie);if(ne=ke===null||!J.has(ke.anchoredLocator.locatorHash),!ne)break}}if(!!ne&&(te.add(ce.anchoredDescriptor.descriptorHash),Pe.push(U(async()=>{let ee=await we(ce,{commandIndex:++le});return J.delete(De),te.delete(ce.anchoredDescriptor.descriptorHash),ee})),!T))break}if(Pe.length===0){let De=Array.from(J.values()).map(ce=>W.prettyLocator(r,ce.anchoredLocator)).join(", ");ae.reportError(3,`Dependency cycle detected (${De})`);return}let Ee=(await Promise.all(Pe)).find(De=>De!==0);pe===null&&(pe=typeof Ee<"u"?1:pe),(this.topological||this.topologicalDev)&&typeof Ee<"u"&&ae.reportError(0,"The command failed for workspaces that are depended upon by other workspaces; can't satisfy the dependency graph")}});return pe!==null?pe:ye.exitCode()}};op.paths=[["workspaces","foreach"]],op.usage=nt.Usage({category:"Workspace-related commands",description:"run a command on all workspaces",details:"\n This command will run a given sub-command on current and all its descendant workspaces. Various flags can alter the exact behavior of the command:\n\n - If `-p,--parallel` is set, the commands will be ran in parallel; they'll by default be limited to a number of parallel tasks roughly equal to half your core number, but that can be overridden via `-j,--jobs`, or disabled by setting `-j unlimited`.\n\n - If `-p,--parallel` and `-i,--interlaced` are both set, Yarn will print the lines from the output as it receives them. If `-i,--interlaced` wasn't set, it would instead buffer the output from each process and print the resulting buffers only after their source processes have exited.\n\n - If `-t,--topological` is set, Yarn will only run the command after all workspaces that it depends on through the `dependencies` field have successfully finished executing. If `--topological-dev` is set, both the `dependencies` and `devDependencies` fields will be considered when figuring out the wait points.\n\n - If `-A,--all` is set, Yarn will run the command on all the workspaces of a project.\n\n - If `-R,--recursive` is set, Yarn will find workspaces to run the command on by recursively evaluating `dependencies` and `devDependencies` fields, instead of looking at the `workspaces` fields.\n\n - If `-W,--worktree` is set, Yarn will find workspaces to run the command on by looking at the current worktree.\n\n - If `--from` is set, Yarn will use the packages matching the 'from' glob as the starting point for any recursive search.\n\n - If `--since` is set, Yarn will only run the command on workspaces that have been modified since the specified ref. By default Yarn will use the refs specified by the `changesetBaseRefs` configuration option.\n\n - If `--dry-run` is set, Yarn will explain what it would do without actually doing anything.\n\n - The command may apply to only some workspaces through the use of `--include` which acts as a whitelist. The `--exclude` flag will do the opposite and will be a list of packages that mustn't execute the script. Both flags accept glob patterns (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n Adding the `-v,--verbose` flag (automatically enabled in interactive terminal environments) will cause Yarn to print more information; in particular the name of the workspace that generated the output will be printed at the front of each line.\n\n If the command is `run` and the script being run does not exist the child workspace will be skipped without error.\n ",examples:[["Publish all packages","yarn workspaces foreach -A npm publish --tolerate-republish"],["Run the build script on all descendant packages","yarn workspaces foreach -A run build"],["Run the build script on current and all descendant packages in parallel, building package dependencies first","yarn workspaces foreach -Apt run build"],["Run the build script on several packages and all their dependencies, building dependencies first","yarn workspaces foreach -Rpt --from '{workspace-a,workspace-b}' run build"]]}),op.schema=[lI("all",Gu.Forbids,["from","recursive","since","worktree"],{missingIf:"undefined"}),UR(["all","recursive","since","worktree"],{missingIf:"undefined"})];function ZBe(t,{prefix:e,interlaced:r}){let o=t.createStreamReporter(e),a=new je.DefaultStream;a.pipe(o,{end:!1}),a.on("finish",()=>{o.end()});let n=new Promise(A=>{o.on("finish",()=>{A(a.active)})});if(r)return[a,n];let u=new je.BufferStream;return u.pipe(a,{end:!1}),u.on("finish",()=>{a.end()}),[u,n]}function ZDt(t,{configuration:e,commandIndex:r,verbose:o}){if(!o)return null;let n=`[${W.stringifyIdent(t.anchoredLocator)}]:`,u=["#2E86AB","#A23B72","#F18F01","#C73E1D","#CCE2A3"],A=u[r%u.length];return de.pretty(e,n,A)}var $Dt={commands:[rg,op]},ePt=$Dt;var fC=()=>({modules:new Map([["@yarnpkg/cli",o2],["@yarnpkg/core",s2],["@yarnpkg/fslib",Vw],["@yarnpkg/libzip",x1],["@yarnpkg/parsers",tI],["@yarnpkg/shell",T1],["clipanion",pI],["semver",tPt],["typanion",Ko],["@yarnpkg/plugin-essentials",tH],["@yarnpkg/plugin-compat",oH],["@yarnpkg/plugin-constraints",BH],["@yarnpkg/plugin-dlx",vH],["@yarnpkg/plugin-exec",SH],["@yarnpkg/plugin-file",bH],["@yarnpkg/plugin-git",eH],["@yarnpkg/plugin-github",FH],["@yarnpkg/plugin-http",TH],["@yarnpkg/plugin-init",RH],["@yarnpkg/plugin-interactive-tools",Lj],["@yarnpkg/plugin-link",Mj],["@yarnpkg/plugin-nm",Cq],["@yarnpkg/plugin-npm",EG],["@yarnpkg/plugin-npm-cli",xG],["@yarnpkg/plugin-pack",hG],["@yarnpkg/plugin-patch",NG],["@yarnpkg/plugin-pnp",lq],["@yarnpkg/plugin-pnpm",OG],["@yarnpkg/plugin-stage",YG],["@yarnpkg/plugin-typescript",WG],["@yarnpkg/plugin-version",XG],["@yarnpkg/plugin-workspace-tools",ZG]]),plugins:new Set(["@yarnpkg/plugin-essentials","@yarnpkg/plugin-compat","@yarnpkg/plugin-constraints","@yarnpkg/plugin-dlx","@yarnpkg/plugin-exec","@yarnpkg/plugin-file","@yarnpkg/plugin-git","@yarnpkg/plugin-github","@yarnpkg/plugin-http","@yarnpkg/plugin-init","@yarnpkg/plugin-interactive-tools","@yarnpkg/plugin-link","@yarnpkg/plugin-nm","@yarnpkg/plugin-npm","@yarnpkg/plugin-npm-cli","@yarnpkg/plugin-pack","@yarnpkg/plugin-patch","@yarnpkg/plugin-pnp","@yarnpkg/plugin-pnpm","@yarnpkg/plugin-stage","@yarnpkg/plugin-typescript","@yarnpkg/plugin-version","@yarnpkg/plugin-workspace-tools"])});function rve({cwd:t,pluginConfiguration:e}){let r=new as({binaryLabel:"Yarn Package Manager",binaryName:"yarn",binaryVersion:tn??"<unknown>"});return Object.assign(r,{defaultContext:{...as.defaultContext,cwd:t,plugins:e,quiet:!1,stdin:process.stdin,stdout:process.stdout,stderr:process.stderr}})}function rPt(t){if(je.parseOptionalBoolean(process.env.YARN_IGNORE_NODE))return!0;let r=process.versions.node,o=">=18.12.0";if(kr.satisfiesWithPrereleases(r,o))return!0;let a=new it(`This tool requires a Node version compatible with ${o} (got ${r}). Upgrade Node, or set \`YARN_IGNORE_NODE=1\` in your environment.`);return as.defaultContext.stdout.write(t.error(a)),!1}async function nve({selfPath:t,pluginConfiguration:e}){return await Ve.find(ue.toPortablePath(process.cwd()),e,{strict:!1,usePathCheck:t})}function nPt(t,e,{yarnPath:r}){if(!oe.existsSync(r))return t.error(new Error(`The "yarn-path" option has been set, but the specified location doesn't exist (${r}).`)),1;process.on("SIGINT",()=>{});let o={stdio:"inherit",env:{...process.env,YARN_IGNORE_PATH:"1"}};try{(0,eve.execFileSync)(process.execPath,[ue.fromPortablePath(r),...e],o)}catch(a){return a.status??1}return 0}function iPt(t,e){let r=null,o=e;return e.length>=2&&e[0]==="--cwd"?(r=ue.toPortablePath(e[1]),o=e.slice(2)):e.length>=1&&e[0].startsWith("--cwd=")?(r=ue.toPortablePath(e[0].slice(6)),o=e.slice(1)):e[0]==="add"&&e[e.length-2]==="--cwd"&&(r=ue.toPortablePath(e[e.length-1]),o=e.slice(0,e.length-2)),t.defaultContext.cwd=r!==null?K.resolve(r):K.cwd(),o}function sPt(t,{configuration:e}){if(!e.get("enableTelemetry")||tve.isCI||!process.stdout.isTTY)return;Ve.telemetry=new cC(e,"puba9cdc10ec5790a2cf4969dd413a47270");let o=/^@yarnpkg\/plugin-(.*)$/;for(let a of e.plugins.keys())uC.has(a.match(o)?.[1]??"")&&Ve.telemetry?.reportPluginName(a);t.binaryVersion&&Ve.telemetry.reportVersion(t.binaryVersion)}function ive(t,{configuration:e}){for(let r of e.plugins.values())for(let o of r.commands||[])t.register(o)}async function oPt(t,e,{selfPath:r,pluginConfiguration:o}){if(!rPt(t))return 1;let a=await nve({selfPath:r,pluginConfiguration:o}),n=a.get("yarnPath"),u=a.get("ignorePath");if(n&&!u)return nPt(t,e,{yarnPath:n});delete process.env.YARN_IGNORE_PATH;let A=iPt(t,e);sPt(t,{configuration:a}),ive(t,{configuration:a});let p=t.process(A,t.defaultContext);return p.help||Ve.telemetry?.reportCommandName(p.path.join(" ")),await t.run(p,t.defaultContext)}async function the({cwd:t=K.cwd(),pluginConfiguration:e=fC()}={}){let r=rve({cwd:t,pluginConfiguration:e}),o=await nve({pluginConfiguration:e,selfPath:null});return ive(r,{configuration:o}),r}async function sk(t,{cwd:e=K.cwd(),selfPath:r,pluginConfiguration:o}){let a=rve({cwd:e,pluginConfiguration:o});try{process.exitCode=await oPt(a,t,{selfPath:r,pluginConfiguration:o})}catch(n){as.defaultContext.stdout.write(a.error(n)),process.exitCode=1}finally{await oe.rmtempPromise()}}sk(process.argv.slice(2),{cwd:K.cwd(),selfPath:ue.toPortablePath(ue.resolve(process.argv[1])),pluginConfiguration:fC()});})(); +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ +/*! + * buildToken + * Builds OAuth token prefix (helper function) + * + * @name buildToken + * @function + * @param {GitUrl} obj The parsed Git url object. + * @return {String} token prefix + */ +/*! + * fill-range <https://github.com/jonschlinkert/fill-range> + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Licensed under the MIT License. + */ +/*! + * is-extglob <https://github.com/jonschlinkert/is-extglob> + * + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. + */ +/*! + * is-glob <https://github.com/jonschlinkert/is-glob> + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ +/*! + * is-number <https://github.com/jonschlinkert/is-number> + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Released under the MIT License. + */ +/*! + * is-windows <https://github.com/jonschlinkert/is-windows> + * + * Copyright © 2015-2018, Jon Schlinkert. + * Released under the MIT License. + */ +/*! + * to-regex-range <https://github.com/micromatch/to-regex-range> + * + * Copyright (c) 2015-present, Jon Schlinkert. + * Released under the MIT License. + */ +/** + @license + Copyright (c) 2015, Rebecca Turner + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + */ +/** + @license + Copyright Joyent, Inc. and other Node contributors. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to permit + persons to whom the Software is furnished to do so, subject to the + following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +/** + @license + Copyright Node.js contributors. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +/** + @license + The MIT License (MIT) + + Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +/** @license React v0.18.0 + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v0.24.0 + * react-reconciler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/** @license React v16.13.1 + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ diff --git a/graphrag/docsite/.yarn/sdks/integrations.yml b/graphrag/docsite/.yarn/sdks/integrations.yml new file mode 100644 index 0000000000000000000000000000000000000000..aa9d0d0ad81a4dfefda7bee1ba2c691b51d7973f --- /dev/null +++ b/graphrag/docsite/.yarn/sdks/integrations.yml @@ -0,0 +1,5 @@ +# This file is automatically generated by @yarnpkg/sdks. +# Manual changes might be lost! + +integrations: + - vscode diff --git a/graphrag/docsite/.yarnrc.yml b/graphrag/docsite/.yarnrc.yml new file mode 100644 index 0000000000000000000000000000000000000000..42f1e2ebfa55205019c877bf78b5f478478d9af9 --- /dev/null +++ b/graphrag/docsite/.yarnrc.yml @@ -0,0 +1,7 @@ +compressionLevel: mixed + +enableGlobalCache: false + +nodeLinker: pnp + +yarnPath: .yarn/releases/yarn-4.0.2.cjs diff --git a/graphrag/docsite/_includes/page.css b/graphrag/docsite/_includes/page.css new file mode 100644 index 0000000000000000000000000000000000000000..416ac89e3d858dc13fb240963c01e4777ac4219c --- /dev/null +++ b/graphrag/docsite/_includes/page.css @@ -0,0 +1,115 @@ +html { + padding: 0; + margin: 0; +} + +body{ + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + padding: 0; + margin: 0; +} + +footer{ + width: 100%; + height: 32px; + font-size: 12px; + display: flex; + flex-direction: row; + justify-content: center; + gap: 18px; + align-items: center; + color: #5d5d5d; + background: #e9eaeb; + border-top: 1px solid #c4c5c6; +} + +#cookiesManager{ + cursor: pointer; + color: #485fc7; +} + +.page-content { + display: flex; + flex-direction: row; + margin: 0; + padding: 0; + overflow: scroll; + padding: 0; + margin: 0; +} + +header { + background-color: lightgrey; + height: 2%; + padding: 10px; +} + +nav { + padding: 1em; + min-width: 200px; +} + +main { + flex: 1; + padding: 0 5em 0 5em; +} + +.logotitle { + font-size: 1.5em; + font-weight: bold; + margin: 5px; +} + +.number { + all: unset; +} + +.tag.token { + all: unset; +} + +main ul { + list-style-type: disc; + padding-left: 30px; + margin-top: 10px; +} + +h1 { + font-size: 2rem; + margin-top: 10px; +} + +h2 { + font-size: 1.5rem; + margin-top: 10px; + font-weight: 500; +} + +h3 { + font-size: 1rem; + margin-top: 10px; + font-weight: 500; +} +p { + margin-top: 10px; +} + +/* Accessibility styling */ + +a { + color: #485fc7; + text-decoration: underline; +} + +.menu-list a { + text-decoration: none; +} + + +.token.comment, .token.prolog, .token.doctype, .token.cdata { + color: #8093a5; +} + +.token.property, .token.tag, .token.constant, .token.symbol, .token.deleted { + color: #ff36ab; +} \ No newline at end of file diff --git a/graphrag/docsite/_includes/page.njk b/graphrag/docsite/_includes/page.njk new file mode 100644 index 0000000000000000000000000000000000000000..b6f57bc96f9843c6012fffd41b376abda912a0f4 --- /dev/null +++ b/graphrag/docsite/_includes/page.njk @@ -0,0 +1,164 @@ +--- +title: GraphRAG +--- +{% set css %} +{% include "page.css" %} +{% endset %} + +{% macro link_to(url, text) %} +<a href="{{url}}"{% if page.url == url %} class="is-active" aria-current="page"{% endif %}>{{text}}</a> +{% endmacro %} + +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>{{ title }} + + + + + {% mermaid_js %} + {% initClipboardJS %} + + {% block js %} + + + {% endblock %} + + +
+ + GraphRAG +
+
+ + + + +
+

{{title}}

+ {{ content | safe }} +
+
+ + + \ No newline at end of file diff --git a/graphrag/docsite/data/operation_dulce/ABOUT.md b/graphrag/docsite/data/operation_dulce/ABOUT.md new file mode 100644 index 0000000000000000000000000000000000000000..272d3bf6368ef58a1425238ca22c1c36260080a6 --- /dev/null +++ b/graphrag/docsite/data/operation_dulce/ABOUT.md @@ -0,0 +1,3 @@ +# About + +This document (Operation Dulce) is an AI-generated science fiction novella, included here for the purposes of integration testing. \ No newline at end of file diff --git a/graphrag/docsite/data/operation_dulce/Operation Dulce v2 1 1.md b/graphrag/docsite/data/operation_dulce/Operation Dulce v2 1 1.md new file mode 100644 index 0000000000000000000000000000000000000000..95c9e3cd3af76b570f0550d69b2025d7cd6fafbb --- /dev/null +++ b/graphrag/docsite/data/operation_dulce/Operation Dulce v2 1 1.md @@ -0,0 +1,970 @@ +# Operation: Dulce + +## Chapter 1 + +The thrumming of monitors cast a stark contrast to the rigid silence enveloping the group. Agent Alex Mercer, unfailingly determined on paper, seemed dwarfed by the enormity of the sterile briefing room where Paranormal Military Squad's elite convened. With dulled eyes, he scanned the projectors outlining their impending odyssey into Operation: Dulce. + +“I assume, Agent Mercer, you’re not having second thoughts?” It was Taylor Cruz’s voice, laced with an edge that demanded attention. + +Alex flickered a strained smile, still thumbing his folder's corner. "Of course not, Agent Cruz. Just trying to soak in all the details." The compliance in his tone was unsettling, even to himself. + +Jordan Hayes, perched on the opposite side of the table, narrowed their eyes but offered a supportive nod. "Details are imperative. We’ll need your clear-headedness down there, Mercer." + +A comfortable silence, the kind that threaded between veterans of shared secrets, lingered briefly before Sam Rivera, never one to submit to quiet, added, "I’ve combed through the last transmission logs. If anyone can make sense of the anomalies, it’s going to be the two of you." + +Taylor snorted dismissively. “Focus, people. We have protocols for a reason. Speculation is counter-productive.” The words 'counter-productive' seemed to hang in the air, a tacit reprimand directed at Alex. + +Feeling the weight of his compliance conflicting with his natural inclination to leave no stone unturned, Alex straightened in his seat. "I agree, Agent Cruz. Protocol is paramount," he said, meeting Taylor's steely gaze. It was an affirmation, but beneath it lay layers of unspoken complexities that would undoubtedly unwind with time. + +Alex's submission, though seemingly complete, didn't escape Jordan, who tilted their head ever so slightly, their eyes revealing a spark of understanding. They knew well enough the struggle of aligning personal convictions with overarching missions. As everyone began to collect their binders and prepare for departure, a quiet resolve took form within Alex, galvanized by the groundwork laid by their interactions. He may have spoken in compliance, but his determination had merely taken a subtler form — one that wouldn't surrender so easily to the forthcoming shadows. + +\* + +Dr. Jordan Hayes shuffled a stack of papers, their eyes revealing a tinge of skepticism at Taylor Cruz's authoritarian performance. _Protocols_, Jordan thought, _are just the framework, the true challenges we're about to face lie well beyond the boundaries of any protocol._ They cleared their throat before speaking, tone cautious yet firm, "Let's remember, the unknown variables exceed the known. We should remain adaptive." + +A murmur of agreement echoed from Sam Rivera, who leaned forward, lacing their fingers together as if weaving a digital framework in the air before them, "Exactly, adaptability could be the key to interpreting the signal distortions and system malfunctions. We shouldn't discount the… erratic." + +Their words hung like an electric charge in the room, challenging Taylor's position with an inherent truth. Cruz’s jaw tightened almost imperceptibly, but the agent masked it with a small nod, conceding to the omnipresent threat of the unpredictable. + +Alex glanced at Jordan, who never looked back, their gaze fixed instead on a distant point, as if envisioning the immense dark corridors they were soon to navigate in Dulce. Jordan was not one to embrace fantastical theories, but the air of cautious calculation betrayed a mind bracing for confrontation with the inexplicable, an internal battle between the evidence of their research and the calculating skepticism that kept them alive in their field. + +The meeting adjourned with no further comments, the team members quietly retreading the paths to their personal preparations. Alex, trailing slightly behind, observed the others. _The cautious reserve Jordan wears like armor doesn't fool me_, he thought, _their analytical mind sees the patterns I do. And that's worth more than protocol. That's the connection we need to survive this._ + +As the agents dispersed into the labyrinth of the facility, lost in their thoughts and preparations, the base's halogen lights flickered, a brief and unnoticed harbingers of the darkness to come. + +\* + +A deserted corridor inside the facility stretched before Taylor Cruz, each footstep rhythmic and precise. Cruz, ambitious and meticulous, eyed the troops passing by with a sardonic tilt of the lips. Obedience—it was as much a tool as any weapon in the arsenal, and Cruz wielded it masterfully. To them, it was another step toward unfettered power within the dark bowels of the military complex. + +Inside a secluded equipment bay, Cruz began checking over gear with mechanical efficiency. They traced fingers over the sleek surface of an encrypted radio transmitter. "If protocols are maintained," said Cruz aloud, rehearsing the speech for their subordinates, "not only will we re-establish a line of communication with Dulce, but we shall also illuminate the darkest secrets it conceals." + +Agent Hayes appeared in the doorway, arms crossed and a knowing glint in their eyes. "You do understand," Jordan began, the words measured and probing, "that once we're in the depths, rank gives way to survival instincts. It's not about commands—it's empowerment through trust." + +The sentiment snagged on Cruz's armor of confidence, probing at the insecurities festering beneath. Taylor offered a brief nod, perhaps too curt, but enough to acknowledge Jordan's point without yielding ground. "Trust," Cruz mused, "or the illusion thereof, is just as potent." + +Silence claimed the space between them, steeped in the reality of the unknown dangers lurking in the shadows of the mission. Cruz diligently returned to the equipment, the act a clear dismissal. + +Not much later, Cruz stood alone, the hollow echo of the bay a stark reminder of the isolation that power often wrought. With each checked box, their resolve steeled further, a silent vow to usher their team through the abyss—whatever it might hold—and emerge enshrined in the respect they so deeply craved. + +## Chapter 2 + +Sam Rivera sat alone in a cramped office, the hum of a dozen servers murmuring a digital lullaby in the background. Surrounded by the glow of multiple screens, their eyes danced across lines of code and intercepted comm signals from Dulce — a kaleidoscope of data that their curious and isolated mind hungered to decrypt. + +To an outsider, it might have looked like obsession, this fervent quest for answers. But to Sam, it was a dance — a give and take with the mysteries of the universe. Their fingers paused over the keyboard as they leaned back in the chair, whispering to thin air, "What secrets are you hiding from us?" + +The stillness of the room broke with the unexpected arrival of Alex Mercer, whose encroaching shadow loomed over Sam's workspace. The cybersecurity expert craned their neck upwards, met by the ever-so-slight furrow in Alex's brow. "Got a minute, Rivera?" + +"Always," Sam said, a smile surfacing as they swiveled to face their mentor more directly. _He has that look — like something's not sitting right with him,_ they noted inwardly. + +Alex hesitated, weighing his words carefully. "Our tech is top-tier, but the silence from Dulce... It's not just technology that will see us through, it's intuition and... trust." His gaze pierced through the digital haze, trying to instill something more profound than advice. + +Sam regarded Alex for a moment, the sincerity in his voice resonating with their own unspoken desire to prove their worth. "Intuition," they mirrored thoughtfully. "I guess sometimes the numbers don't have all the answers." + +Their shared silence held a newfound understanding, a recognition that between the ones and zeros, it was their combined human insights that might prevail against the impossible. As Alex turned to leave, Sam's eyes drifted back to the screens, now seeing them not as barriers to isolate behind, but as windows into the vast and enigmatic challenge that awaited their team. + +Outside the office, the persistent buzz of activity in the facility belied the unease that gripped its inhabitants. A restlessness that nibbled on the edges of reality, as though forewarning of the threshold they were soon to cross — from the known into the realm of cosmic secrets and silent threats. + +\* + +Shadows played against the walls of the cramped underground meeting room, where Alex Mercer stood gazing at the concealed elevator that would deliver them into the bowels of Dulce base. The air was thick, every breath laced with the weight of impending confrontation, the kind one feels when stepping into a legend. Though armed with an array of advanced weaponry and gear, there was an unshakeable sense that they were delving into a conflict where the physical might be of little consequence. + +"I know what you're thinking," Jordan Hayes remarked, approaching Mercer. Their voice was low, a blend of confidence and hidden apprehension. "This feels like more than a rescue or reconnaissance mission, doesn't it?" + +Alex turned, his features a mask of uneasy resolve. "It's like we're being pulled into someone else’s game. Not just observers or participants, but... pawns." + +Jordan gave a short nod, their analytical mind colliding with the uncertain dynamics of this operation. "I've felt that way since the briefing. Like there's a layer we’re not seeing. And yet, we have no choice but to play along." Their eyes locked with Alex's, silently exchanging a vow to remain vigilant. + +"You two need to cut the philosophical chatter. We have positions to secure," Taylor Cruz interjected sharply, stepping into their exchange. The authority in Taylor's voice brooked no argument; it was their way of pulling everyone back to the now. + +Alex's response was measured, more assertive than moments ago. "Acknowledged, Agent Cruz," he replied, his voice steadier, mirroring the transformation brewing within. He gripped his rifle with a newfound firmness. "Let's proceed." + +As they congregated at the elevator, a tension palpable, Sam Rivera piped in with a tone of balanced levity, "Hope everyone’s brought their good luck charms. Something tells me we’re going to need all the help we can get." + +Their laughter served as a brief respite from the gravity of their mission, a shared moment that reinforced their common humanity amidst the unknowable. Then, as one, they stepped into the elevator. The doors closed with a silent hiss, and they descended into the darkness together, aware that when they returned, if they returned, none of them would be the same. + +\* + +The sense of foreboding hung heavier than the darkness that the artificial lights of the elevator shaft failed to fully penetrate. The team was descending into the earth, carrying with them not only the weight of their equipment but also the silent pressure of the invisible war they were about to fight—a war that seemed to edge away from physicality and into the unnervingly psychological. + +As they descended, Dr. Jordan Hayes couldn't help but muse over the layers of data that could wait below, now almost longing for the comfort of empirical evidence. _To think that this reluctance to accept other possibilities may have been my biggest blind spot,_ Jordan contemplated, feeling the hard shell of skepticism begin to crack. + +Alex caught Jordan's reflective gaze and leaned in, his voice barely a murmur over the hum of the elevator. "Once we're down there, keep that analytical edge sharp. You see through the mazes of the unexplained better than anyone." + +The compliment was unexpected and weighed differently than praise from others. This was an acknowledgment from someone who stood on the front lines of the unknown with eyes wide open. "Thank you, Alex," Jordan said, the words carrying a trace of newfound assertiveness. "You can count on me." + +The exchange was cut short by a shudder that ran through the elevator, subtle, but enough to make them instinctively hold their breaths. It wasn't the mechanical stutter of old gears but a vibration that seemed to emanate from the very walls of the shaft—a whisper of something that defied natural explanation. + +Cruz was the first to react, all business despite the shadow that crossed their expression. "Systems check. Now," they barked out, masking the moment of disquiet with swift command. + +Every agent checked their gear, sending confirmation signals through their comms, creating a chorus of electronic beeps that promised readiness. But there was an unspoken question among them: was their technology, their weaponry, their protocols sufficient for what awaited them or merely a fragile comfort? + +Against the gravity of the silence that was once again closing in, Sam's voice crackled through, only half-jest. "I'd laugh if we run into Martians playing poker down there—just to lighten the mood, you know?" + +Despite—or perhaps because of—the oddity of the moment, this elicited a round of chuckles, an audible release of tension that ran counterpoint to the undercurrent of anxiety coursing through the team. + +As the elevator came to a halting, eerie calm at the sub-level, the group stepped off, finding themselves at the threshold of Dulce's mysterious halls. They stood in a tight pack, sharing a cautious glance before fanning out into the unknown, each one acutely aware that the truth was inevitably intertwined with danger. + +Into the depths of Dulce, the team advanced, their silence now a shared testament to the camaraderie born of facing the abyss together—and the steel resolve to uncover whatever horrors lay hidden in its shadows. + +\* + +The weight of the thick metal door closing behind them reverberated through the concrete hallway, marking the final threshold between the familiar world above and the strangeness that lay beneath. Dulce base, a name that had been whispered in the wind-blown deserts above and in the shadowed corners of conspiracy forums, now a tangible cold reality that they could touch — and that touched them back with a chill. + +Like lambs led to an altar of alien deities, so did Agents Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera proceed, their movements measured, their senses heightened. The air was still, almost respectful of the gravity of their presence. Their torch beams sliced through the darkness, uncovering steel doors with warnings that spoke of top secrets and mortal dangers. + +Taylor Cruz, stepping firmly into the role of de facto leader, set a brisk pace. "Eyes sharp, people. Comms check, every thirty seconds," Taylor ordered, their voice echoing slightly before being swallowed by the surrounding silence. + +Sam, fiddling with a handheld device aimed at detecting electronic anomalies, offered a murmured "Copy that," their usual buoyancy dimmed by the oppressive atmosphere. + +It was Jordan Hayes who paused at an innocuous looking panel, nondescript amongst the gauntlet of secured doorways. "Mercer, Rivera, come see this," Jordan’s voice was marked with a rare hint of urgency. + +Alex joined Jordan's side, examining the panel which, at a mere glance, seemed just another part of the base's infrastructure. Yet, to the trained eye, it appeared out of place—a facade. + +Jordan explained their reasoning as Sam approached, instinctively understanding the significance of what lay beneath, "This panel is a recent addition — covering something they didn't want found." + +Before Alex could respond, the soft whir of an approaching drone cut through their muffled exchange. Taylor had looped back upon hearing the commotion. "Explanations later. We can't afford to attract..." Cruz’s voice trailed off as the small airborne device came into view, its sensors locked onto the group. + +Sam was the first to react, their tech-savvy mind already steps ahead. "I've got this," they declared, fingers flying over the controls of their own gadgetry to ward off the impending threat. + +The drone lingered, its scan seeming more curious than hostile. But within moments, courtesy of Sam's interference, the little sentinel drifted away, retreating into the shadows as if accepting a silent truce. The crew exhaled, a moment of collective relief palpable in the air. + +Cruz squared their shoulders, clearly ruffled but not conceding any ground. "Move out," they directed, a hint more forceful than before. "And Rivera, keep that trick handy." + +The team pressed onward, the quiet now filled with the soft beeps of regular comms checks, their pace undeterred by the confrontation. Yet, every agent held a renewed sense of wariness, their trust in one another deepening with the knowledge that the base—its technology, its secrets—was alive in a way they hadn't fully anticipated. + +As they converged upon a central hub, the imposing doors to the mainframe room stood ajar — an invitation or a trap, neither option comforting. Without a word, they fortified their resolve and stepped through the threshold, where the dim glow of operational LED lights and the distant hum of machinery hinted at Dulce’s still-beating heart. + +Solemnly, yet unmistakably together, they moved deeper into the heart of the enigma, ready to unmask the lifeforce of Dulce base or confront whatever existential threat lay in wait. It was in that unwavering march towards the unknown that their destinies were forever cemented to the legacy of Operation: Dulce. + +## Chapter 3 + +The thrumming of monitors cast a stark contrast to the rigid silence enveloping the group. Agent Alex Mercer, unfailingly determined on paper, seemed dwarfed by the enormity of the sterile briefing room where Paranormal Military Squad's elite convened. With dulled eyes, he scanned the projectors outlining their impending odyssey into Operation: Dulce. + +\* + +The cooling vents hummed in a monotonous drone, but it was the crackle of the comms system coming to life that cut through the lab’s tension. Dr. Jordan Hayes hovered over a table arrayed with alien technology, their fingers delicately probing the enigmatic circuitry retrieved from the crash site. Agent Alex Mercer watched, admiration blooming in silent solidarity for Jordan's deft touch and unspoken drive. + +Jordan, always composed, only allowed the faintest furrow of concentration to mar their brow. "What we understand about physics..." they muttered, trailing off as they realigned a translucent component. The device emitted a low pulse, causing Jordan to still. "Could be fundamentally changed by this." + +A calculated risk—that's what this was. And for a person of science, a gamble was worth the potential paradigm shift. + +"I’ve been thinking," Alex started, his eyes still fixed on the immediately tangible mystery before them. "About what’s at stake here. Not the mission parameters, but what this means for us—humanity." + +Jordan glanced up, meeting his eyes just long enough to convey the shared enormity of their situation; the career-defining glory and existential dread entwined. "The quest for understanding always comes at a price. We're standing on the precipice of knowledge that could either elevate us or condemn us." + +The charged air between them spiked as Taylor Cruz’s brusque tones sliced through their reverie. "Hayes, Mercer, this isn't philosophy hour. Focus on the task. We need actionable intel, not daydreams." + +With a sound of restrained acknowledgment, Jordan returned their gaze to the device, while Alex clenched his jaw, the buzz of frustration dull against the backdrop of Taylor's authoritarian certainty. It was this competitive undercurrent that kept him alert, the sense that his and Jordan's shared commitment to discovery was an unspoken rebellion against Cruz's narrowing vision of control and order. + +Then Taylor did something unexpected. They paused beside Jordan and, for a moment, observed the device with something akin to reverence. “If this tech can be understood..." Taylor said, their voice quieter, "It could change the game for us. For all of us.” + +The underlying dismissal earlier seemed to falter, replaced by a glimpse of reluctant respect for the gravity of what lay in their hands. Jordan looked up, and for a fleeting heartbeat, their eyes locked with Taylor's, a wordless clash of wills softening into an uneasy truce. + +It was a small transformation, barely perceptible, but one that Alex noted with an inward nod. They had all been brought here by different paths and for different reasons. Yet, beneath the veneer of duty, the enticement of the vast unknown pulled them inexorably together, coalescing their distinct desires into a shared pulse of anticipation. + +Marshaled back to the moment by the blink of lights and whir of machinery, they refocused their efforts, each movement sharpened by the knowledge that beyond understanding the unearthly artifacts, they might be piecing together the future of their species. + +\* + +Amidst the sterility of the briefing room, the liminal space between the facts laid out and the hidden truths, sat Sam Rivera, his demeanor an artful balance of focus and a casual disguise of his razor-sharp talent with technology. Across from him, Alex Mercer lingered in thought, the mental cogs turning as each file on Dulce stirred more than curiosity—it beckoned to a past both honored and burdensome. + +"You've been quiet, Sam," Alex noted, catching the younger man's contemplative gaze. "Your take on these signal inconsistencies?" + +There was a respect in Alex's tone, though a respectful distance remained—a gulf of experience and a hint of protective mentorship that stood between them. Sam nodded, recognizing the space afforded to him, and he couldn't help but feel the weight of expectation pressing upon his shoulders. It wasn't just the mission that was immense, it was the trust being placed in him. + +"The patterns are... off," Sam admitted, hesitant but driven. "If I'm right, what we're looking at isn't random—it's a structured anomaly. We need to be ready for anything." + +Alex's eyes brightened with a subtle approval that crossed the distance like a silent nod. "Good. Keen eyes will keep us ahead—or at least not blindsided," he said, affirming the belief that inscribed Sam's role as more than the tech personnel—he was to be a guiding intellect in the heart of uncertainty. + +Their exchange was cut short by Taylor Cruz's abrupt arrival, his gait brimming with a robust confidence that veiled the sharp undercurrents of his striving nature. "Time to gear up. Dulce waits for no one," Taylor announced, his voice carrying an iron resolve that knew the costs of hesitation—though whether the cost was calculated in human or career terms was an ambiguity he wore like a badge of honor. + +As Sam and Alex nodded in unison, the icy chasm of hierarchy and cryptic protocols seemed momentarily to bridge over with an understanding—this mission was convergence, a nexus point that would challenge each of their motives and strength. + +They filed out of the briefing room, their footsteps synchronized, a rhythm that spoke volumes of the unknown cadence they would soon march to within the base's veins. For Alex Mercer, the link with Sam Rivera, though distant, was now poised with a mutuality ready to be tested; for Taylor Cruz, the initiative pulsed like a heartbeat, anticipation thinly veiled behind a mask of duty. + +In the midst of the descent, they were each alone yet irrevocably joined, stepping closer towards the volatile embrace of Operation: Dulce. + +## Chapter 4 + +The corridors of the Dulce military base were as silent as a tomb and twice as chilling. Alex Mercer walked with a surety that belied his bubbling undercurrents of doubt. The briefing had been definitive, sturdy pillars of facts and protocols, yet as he ventured deeper, the ominous atmosphere gnawed at him—a stark reminder of how much remained unknown. + +Jordan Hayes trailed a few steps behind, their detached exterior breaking for a moment as they caught up to Alex. "What's on your mind?" Jordan asked, their astuteness cutting through the unspoken tension. + +Alex glanced back at them. This place was a puzzle, a treacherous labyrinth where the walls whispered secrets, and among them, he sensed a call to question, to challenge the narrative they'd been sold. "The silence here... It's almost as if the base is waiting for something—or someone." + +"Just stay sharp, Mercer," Jordan cautioned, yet their eyes lingered on the quietude around them, conceiving the same shadow of doubt that unsettled Alex. + +Before they could delve into further discussion, the distinctive click of a safety catch echoed in the hollow space. Both agents turned to find Taylor Cruz standing resolute, primed for combat. Taylor's gaze was scrutinizing and cold, a stark contrast to the growing unease that smoldered silently amongst the rest. + +"Chatter is a liability," Taylor snapped, with a commanding flair that bordered on tyrannical. "We move forward, eyes open, mouths shut." + +Alex felt the tight grip of compliance strangle his gut, a lesson learned under the hard tutelage of rank and order. But here, in the bowels of Dulce, those instincts began to wane, the imperative to adhere now conflicting with the pressing urgency to confront the shadows they were enmeshed in. + +Then, unexpectedly, the lights flickered, a power fluctuation—or a sign? Alex's hand instinctively went to his sidearm, his mindset shifting from soldier to skeptic. The base, with its unyielding coldness, had just given them their first nudge into the realm of the speculative, an invitation to peel back the veneer of reality. + +"We should consider all possibilities," Alex murmured, more to himself than the others, his voice a barely audible breath against the sterile air of the complex. + +Taylor's posture stiffened at the challenge, yet their response was uncharacteristically reserved, notable in its lack of rebuke. "Agreed. For now, keep moving. But stay vigilant." + +A surprise—an echo of agreement from the last person Alex expected it from. And there it was, the glimpse of a wrinkle in the unyielding fabric of command, a hint that perhaps they were all starting to sense the strangeness that permeated this place. + +Progressing with determined steps, the trio moved deeper, silently acknowledging the evolution of their predicament. It was a small yet transformative concession to the unknown forces at play, an acknowledgment from each agent that, despite their disparate goals and ideals, the true nature of the Dulce base was an enigma that would forge new paths through their convictions. + +As they reached the central communications hub, the truth that awaited them lurked in the shadows, its eyes unseen but felt by all. The walls didn't just whisper now; they spoke in tones only the brave—or the foolish—would dare to listen to. + +\* + +The subterranean silence of Dulce was an oppressive entity of its own, wrapping the team in a cloak of uneasiness as they pressed on through the dimly lit corridor. Jordan Hayes found themselves contemplating the ramifications of each step taken into this suspended world, where the sterile air seemed to mock the gravity of their predicament. The closer they got to the communication hub, the more Jordan's mind wandered toward the realm of the inexplicable. + +Beside Jordan, Alex Mercer moved forward with deliberation, his gaze scanning the heavy utility doors they passed—one of which was partially ajar, beckoning them with its darkness. "After you, Dr. Hayes," Alex said, gesturing toward the mysterious opening. A hint of shared understanding passed between them; knowledge was the guiding star of this mission as much as confrontation or recovery. + +Jordan peered inside, the beam from their flashlight slicing through the obscurity. The room beyond was a chaotic cascade of papers, overturned furniture, and the particular kind of disorder born from hasty evacuation—or something far more sinister. + +"It's like they vanished in the middle of something urgent," Alex murmured, his voice tight with a mix of concern and anticipation. He began to sift through the scattered reports, each page a potential clue to the enigmatic silence that shrouded Dulce. + +Behind them, Taylor watched with a disciplined patience, their authority the foundation upon which the operation was built. Their voice cut into the stillness, a reminder of their presence, "Time is not our ally here." + +Drawing back from momentary distraction, Jordan acknowledged the wisdom in Taylor's words, yet could feel the shift in their stance—from skeptical, reserved analyst, to a proactive agent within the narrative. "You're right; these documents may hold critical insights. Let's collect what we can and analyze them properly." + +From the darkened hollows of the room, shadows seemed to cast subtle judgment as Alex and Jordan worked together with heightened urgency. Taylor, for once, didn't intervene but instead surveyed the entrance, their mind anticipating the unknown variables that lay ahead. + +Unexpectedly, a soft hiss emanated from a neglected terminal on the desk. Jordan's head snapped up, their heart rate accelerating at the potential ramifications. Without a word, they moved to the machine, hands driven by the newfound conviction that knowledge was more than power—it was survival. + +As Jordan began to extract what data they could from the terminal, the first comprehensible communication from the depths of Dulce in far too long crackled through: an automated distress marker, looping endlessly without further context. It was a revelation, one that reverberated through the group, confirming their fears and igniting an even greater need to press on. + +Watching Jordan's dogged determination, Alex witnessed the minor transformation in his colleague unfold—a shift from doubt to action, a sliver of belief in the possibilities beyond their rational understanding. This forge of resolve amidst the alien echoes of Dulce not only bonded them closer as a team but compelled them forward with a sharpened edge of responsibility to the truth, wherever it would lead. + +As they collected their findings and regrouped, the base around them imperceptibly changed, the air charged with the vibration of secrets poised on the brink of revelation. And in that charged silence, the group moved on, each now carrying pieces of a puzzle that would soon converge into a picture of galactic significance. + +\* + +In the chill of the cramped server room, the hum of machinery was the backbone to a symphony of data streams coursing through the air. Dr. Jordan Hayes, nerves alight with the mission's mounting unknowns, patched into the last known coordinates of the unsent distress broadcast they had uncovered. They were so close to the core now – to the truth behind the blackout – it was almost tangible. + +Beside them stood Agent Alex Mercer, ever the soldier, yet with eyes that betrayed an intellect craving to understand the murk beneath the surface. "Any progress, Dr. Hayes?" Alex queried, his voice betraying a subtle urgency. + +"Getting there," Jordan replied, fingers dancing across the keyboard. "Whoever sent this was cut off mid-transmission. It's as if Dulce itself swallowed the message whole." + +Taylor Cruz closed in, their frame casting a long shadow over the duo, evoking an almost palpable wall between them and the forward momentum of their mission. "Time is against us," Taylor intoned, more statement than threat. "What we uncover here determines our next course of action." + +Alex acknowledged Taylor with a brisk nod, his stance firm. Yet inwardly, the tightening grip he felt from Taylor's words couldn't throttle the swell of his own investigative instinct. His soldier's obedience had begun to war with the advocate's zeal for unveiling the dark heart of Dulce's secrets. + +And then, the unexpected occurred. The screens flashed in unison, spilling a discordant stream of symbols and images that defied immediate analysis. Jordan's breath caught – this was the response they had been fishing for, an alien communication protocol resonating just at the edge of human comprehension. + +Each member of the team felt it: a shift in the room’s very atmosphere, like a veil being drawn from their perception. Alex and Jordan stood still, absorbed in the bewilderment of contact, while Taylor, despite their authority, hesitated – a minor betrayal that unease was creeping into even their disciplined heart. + +"Thoughts, Rivera?" Taylor rallied, seeking the counsel of Sam Rivera, whose eyes were wide with exhilaration. + +Sam stepped forward, breaking the spell of stillness. "It's like nothing I've ever seen before, but I think I can bridge our systems to communicate," they declared, a wisp of optimism braiding their voice. They set about adapting their gear to transmute the foreign signals into something the team could dissect, their actions a testament to the mentorship and belief instilled in them by Mercer and the team. + +Taylor observed them, a cold calculation behind their facade, as they weighed the worth of this anomaly. It was a crossroad that potentially led to either monumental breakthrough or unprecedented catastrophe. "Once you've established a line, document everything. We can't afford to miss any detail," Taylor ordered, the words sharper than intended. + +The connection was made, and with trembling anticipation, the team listened as the first garbled outputs began to emerge, their very essence promising insights that could alter the course of history. It was an enigmatic dance with the unknown, the pulse of Dulce no longer just a place, but a herald to an alien register the team had yet to decipher. + +Together, they stood at the precipice of understanding, where the faint glow of their monitors cast more than just light – it cast the shadow of burgeoning transformation. It was in this moment, in the grasp of an extraterrestrial tongue, that the team, bound by a hunger for knowledge and the raw edge of survival, found their mission reframed from a search for answers to the articulation of a question humankind had yet to fully ask. + +Silent in their commune with the inexplicable frequency, they realized they were not merely investigators; they had become liaisons on behalf of Earth, interpreters of a cosmic message that could redefine their very existence. The implications loomed large, but now, they would not face them alone – they would face them as a united front, wrought together by the very mysteries that once drove them apart. + +## Chapter 5 + +Dr. Jordan Hayes clutched the edge of the briefing room table, their fingers white-knuckled against the laminate surface, as an array of constellations rotated on the projector—charts and graphs bleeding across the stars. In the dim room, nebulas and dark matter seemed within arm's reach, tangible yet unfathomable. + +Sam Rivera leaned back against the wall, arms crossed, gaze darting between the swirling cosmos and the faces of their companions. A taut line of concentration etched their young features, a mingling of fervent curiosity with the nascent understanding of the high stakes for which they played. + +Jordan's voice broke the profound silence. "The patterns in the signal disruptions sync with none other than zenithal star alignments. It's as if... as if these 'meet and greets' were scheduled, predestined by celestial mechanics." + +The statement hung heavy, daring the occupants of the room to unravel its implications. Alex Mercer, his prior military resolve momentarily suspended, absorbed the hypothesis with a visible hunger. "It's like we're adhering to an appointment we never knew we had," he murmured, his heart a drumbeat in his chest. + +Taylor Cruz snorted—a sound that clattered against the high concepts like a tumbledown shack in a futurist cityscape. Folding their arms, they glanced between the agents, their apprehension clad in the contempt of practicality. "What we need are facts, not mystic conjecture." + +Alex pivoted on his heel, facing Taylor squarely, and his voice found its edge of steel. "This isn't mysticism, Cruz. It's a hypothesis based on observed phenomena as unpredictable as the place we're standing in." + +Taylor's gaze never wavered, yet the slight twitch at the corner of their mouth belied their taut composure. "If there's a semblance of truth to it, then it's critical intel. But remember, we're not astrologers—we're soldiers and scientists." + +Jordan met Taylor’s gaze with a curt nod, accepting the caution even as the crucible of their intellect smoldered with the fervor of cosmic discovery. Their eyes flicked to Sam, whose steady presence and ready tech affirmed a burgeoning dynamic—the makings of a sentinel, standing guard over the threshold of human understanding and cosmic reality. + +With the projector casting pallid light over their features, each agent became a silhouette of purpose, shadows pillared against the backdrop of an endless universe. The story they were embroiled in would soon demand they plunge into darkness to retrieve the light of knowledge—a light that could very well redraw the shape of their world. + +They left the briefing room with a shared silence, each pondering the vast weave of celestial intent and terrestrial response, sensing that the galactic appointment to which they'd unwittingly RSVP’d was more insistent—and more threatening—than any operation they’d faced before. + +\* + +As the Paranormal Military Squad team convened in the heart of the Dulce military complex, an air of bristling expectation clung to the walls of the underground sanctum. Alex Mercer’s brow furrowed while watching his companions—Jordan Hayes, diligently setting up their makeshift lab station, and Sam Rivera meticulously checking the communication relays they had restored. Taylor Cruz observed with hawk-like focus, yet to betray the strain that their command posed on them. + +The gravity of the mission had shifted, deepened; each member of the team felt its pull, tethered to the understanding that they were now part of a larger narrative—a cosmic play with Earth as a stage and the human race unwitting actors. + +Jordan paused, a tension creeping across their shoulders as they aligned the satellite data with the alien message that had been decoded. "The instructions in this message," Jordan started, the timbre of their voice betraying their usual composure. "They're coordinates and... a warning." + +Sam leaned in, their eyes widening behind the glow of their laptop screen. "A warning? Like, ‘stay away from’, or ‘beware of’...?" Their words trailed off, uncertainty a new companion in their lexicon. + +Alex exhaled slowly, his mind racing to connect the dots. "It doesn't matter which," he said, decisive yet contemplative. "What matters is we understand intent. Are we being warned out of concern, or are we stumbling upon a threat?" + +Cruz’s iron-clad facade momentarily cracked, a fleeting glimpse of vulnerability flashing through their eyes. "We need to know if this entails additional risk to the operation," they said, directing their gaze specifically at Alex. "Mercer, I rely on you to keep the team grounded. No one goes off-course." + +Their reminder seemed both a command and a plea—rooted in an understanding that each member of the team now faced the duality of their roles, protectors of earthly secrets and heralds of potentially devastating revelations. + +Sam's fingers stilled mid-type, their task forgotten as they absorbed the weight of the unfolding reality. "We're the first line of defense... or detection," they mused half to themselves, a growing sense of agency within the larger play they were cast into. + +Jordan returned to the data, more resolute in their actions. The warning, whether cautionary or dire, was a beacon they no longer could ignore; its light casting aside shadows of doubt and igniting a collective purpose within the team. + +Alex watched Jordan and Sam, feeling a brotherhood in their shared quest. As Cruz paced, poised on the cusp of decisions that would mark their career and perhaps the fate of many, Alex knew the narrative had changed. They were no longer mere operatives; they had become guardians of a threshold, keepers of a message from a realm beyond stars and stripes. This elevation in their mission could not be shackled by regulations and established protocols—it demanded a new perspective, a new resolve. + +Tension threaded through the dialogue of beeps and static as communications with Washington buzzed in the background. The team stood, a portentous air enveloping them. It was clear that the decisions they made in the ensuing hours could redefine humanity's place in the cosmos or condemn them to ignorance and potential peril. + +Their connection to the stars solidified, the group moved to address the crystallizing warning, shifting from passive recipients to active participants. Mercer’s latter instincts gained precedence— the team’s mandate had evolved, no longer solely to observe and report but to interact and prepare. A metamorphosis had begun, and Operation: Dulce hummed with the newfound frequency of their daring, a tone set not by the earthly hierarchies but by the pulsing symphony of the universe itself. + +\* + +The desert night loomed eerily still as echoes of hidden activity reverberated deep beneath the bleak sands of New Mexico. Diverting his gaze from the array of sensors before him, Jordan Hayes allowed a rare breath, deep and anxious. Turning to Alex Mercer's focused silhouette, the nocturnal landscape illuminated softly by makeshift floodlights, Jordan felt the syncopated tempo of apprehension and exhilaration jockey for primacy within. + +"The closer we get to unlocking these messages, the more I feel like we're peeling back layers of reality itself," Jordan confided, eyes not leaving the monitors that presented a constellation of data points. + +"Yes," Alex replied, his voice steady as he considered the implications of their discovery. "And we have to be ready for whatever we find beneath those layers. Whether it's a breakthrough or a Pandora's Box." + +Silence settled between them, broken only by the occasional buzz of communications equipment attempting to bridge terrestrial and extraterrestrial intelligences. Tense moments drifted by, laden with the expectant weight of near breakthrough, when a soft chime signaled an incoming transmission -- a rare sound that set every agent on high alert. + +Absent was the voice of Washington or Paranormal Military Squad command. Instead, a rhythmic series of pulses and tones filled the air, deliberately patterned, unmistakably non-human. + +Sam Rivera adjusted the sensitivity of the decoding equipment, their hands shaking with anticipation as much as focus. "I have it!" they announced, the signal transforming under their expertise into a sequence of visual symbols on the screen before them. + +Their shared excitement was palpable, a kinetic force resonating between the team members as they crowded around the display. + +"What does it say?" Taylor Cruz demanded, the urgency in his tone scraping against the newfound wonderment. + +Interpreting the alien syntax required not only decoding but intuition and empathy. The words that emerged upon the screen were at once coherent and enigmatic: "*Voyage. Convergence. Peril.*" + +The stark simplicity of the message struck them collectively, a chill breeze wafting through their resolve. + +Alex stepped forward, piecing together the cryptic communication with a growing sense of obligation. "It’s a call to action," he deduced, "or possibly a summons." + +Jordan's gaze met Alex’s, both understanding that this was no longer an investigation or mere extraction of hidden truths. This was humanity's unwitting enlistment into a galactic dialogue that defied boundaries of nation, creed, or protocol. + +Sam's eyes were aglow, not with fear, but with the profound acceptance of inevitability that comes with groundbreaking revelation. Moreover, within Taylor's stern exterior churned the seed of reluctant admiration for the unclassified, the uncharted realms they were approaching. + +Together, they accepted the pivot in their mission, readjusting their objectives from exploration to engagement, and from isolation to a communal outreach beyond the stars. As dawn's first light threatened the horizon, it became clear that they were no longer merely operatives of a clandestine governmental faction—they were delegates on behalf of Earth, embarking on a voyage orchestrated by destinies unrelated to the mere geopolitics of their world. + +Turning to each other, their silhouettes sketched against the coming dawn, the agents recognized the transformation within and amongst them. They were bound by more than duty—they were intricately woven into the fabric of an unfolding cosmic opera, one in which they had been granted an undeniable role. And as they set course for the coordinates that beckoned them like a distant siren's call, it was with a solemn dedication to not only uncover the mysteries ahead but to navigate the convergence, and the peril, as unified emissaries of a world on the cusp of a broader understanding. + +\* + +Beneath the hum of the fluorescent lights and the vigilance of silent monitors, Alex Mercer stood with his team in the threshold of the base's command center, their faces etched with the fatigue of hours spent unraveling galactic mysteries. Jordan Hayes broke the stillness with a delicate fusion of disbelief and resolve. "The signal..." they began, their tone deliberate, "it’s evolving. It’s not just sending a message—it’s responding to us." + +Taylor Cruz leaned over the console, their eyes narrowing with intrigue and a flicker of unease, studying the alternating patterns on the screen. "Responding? Like it’s alive?" Taylor asked, a question that bordered on the edge of wonder and alarm. + +Sam Rivera’s gaze was locked onto their interface, a digital orchestra at their fingertips. "It could be some form of advanced AI. Or something else entirely," they contributed, a note of exhilaration betraying the gravity of the situation. + +Alex paced before the terminal, absorbing the enormity of their predicament. Their mission—once rooted in the solid ground of military discipline and covert operations—had transcended into an encounter of unprecedented import. "We need to be cautious," he advised, his voice a low rumble of cautious strategy. "If this signal is intelligent, how we interact with it could dictate the outcome of this entire operation." + +Jordan met Alex's gaze with a nod, the weight of the responsibility shared and accepted. "We have protocols for first contact, but nothing for... this," Jordan admitted. The room was gripped with tension, each breath seemingly louder than the last. + +Then, with a sudden burst that filled the command center, the signal coalesced into a clear and distinct pattern which replicated and expanded, its complexity revealing the hand—or mind—of an intelligent architect. + +Taylor's instinct for command surged forth. "Prepare to record and analyze. Whatever it is, we need to understand it—" But their words were cut short as the signal surged, enveloping the room in a brief, blinding cascade of light. + +In that pulse of brilliance, a shared revelation coursed through the team. The signal had become a bridge, an extension of unknown consciousness reaching towards them, testing, communicating, searching. + +Alex stepped back from the light, feeling a profound change unravelling within him. The path forward would not be one of confrontation or conquest, but of connection and comprehension. + +Jordan turned to Alex and Taylor, seeing in their faces a reflection of the same metamorphosis taking place within themselves—a movement from observers to participants, from agents to ambassadors. + +With a collective breath, the team faced the kaleidoscope of lights. The alien signal, once a harbinger of enigma, was now a catalyst for transformation—a symphony of light and sound that echoed the beginnings of a new relationship between humanity and the alien unknown. + +And so, with deliberate steps, Alex Mercer led his team into the luminous fray. Science, protocol, and survival instinct harmonized within them, each member poised on the cusp of a new chapter in human history. + +They were no longer merely the instruments of Paranormal Military Squad's will—they were the vanguard of humankind’s first definitive leap into the cosmic community. + +With the last echoes of the signal resonating in the control room, they each embraced the sequencing of the transmission, the dance of extraterrestrial light that now wrote itself into their story. The chapter of Operation: Dulce drew to a close, but the narrative of their destiny had only just begun. + +## Chapter 6 + +\* + +The cool darkness of the command center at Dulce base was a stark contrast to the brewing storm outside, where the unforgiving New Mexico desert winds whispered of the hidden truths that lay buried deep beneath its surface. Dr. Jordan Hayes sat, their eyes fixed on the readout, the frenetic dance of symbols and numbers reflecting off their determined face. They were on the cusp of an epiphany, teetering between the widely accepted laws of physics and the promise of a new cosmic paradigm. + +Alex Mercer watched from across the room, noting the subtle shifts in Jordan’s posture that belied a developing readiness to embrace the unbelievable. “Find something?” Alex’s question, asked with a blend of curiosity and solidarity, bridged the gap between a command and a genuine query among equals. + +Jordan's response was slow, measured against the magnitude of their analysis. “This isn’t random static. It’s a pattern - a repeated sequence phasing in and out but distinctly artificial.” Jordan turned away from the screen, locking eyes with Alex. “This could change everything.” + +Sam Rivera leaned in, their eyes alight with the fires of revelation and a quenchless thirst for understanding. “A pattern means intention. Could it be a message?” + +A figure emerged from the doorway, casting a long shadow into the room - Taylor Cruz. “Intentions can be friendly, or hostile. We shouldn’t forget that,” said Taylor, bringing a dose of their usual pragmatism into the heart of discovery. + +Alex acknowledged Taylor’s caution with a nod, understanding the need to keep their feet grounded even as their spirits soared toward the unknown. “Then let’s be the first to find out which it is." + +The team gathered around the monitors, the soft tapping of Jordan's keystrokes now punctuated by the occasional crackle of Sam's radio equipment. The sound was almost ritualistic, a prelude to humanity’s potential first, knowing foray into a larger universe. + +Jordan’s fingers paused, suspended in mid-air. The signal had evolved, becoming a beacon that somehow felt less alien and more familiar. It was as if the complexities of their message were unfolding into something more accessible, more terrestrial. + +A hushed excitement swept through the room. The transformation suggested an awareness on the part of the unknown senders; a finesse that spoke volumes about their capabilities and perhaps their intentions. + +With the growing realization that they were engaging with an intelligence far exceeding their previous understanding, the team prepared to reach back across the cosmic divide. Prepared or not, they were no longer bystanders in this galactic narrative. They were active correspondents in an exchange that transcended galaxies and welcomed them into an expansive, possibly fraught, interstellar conversation. + +\* + +Inside the cavernous central hub of Dulce military base, Dr. Jordan Hayes stood in near-darkness, surrounded by a nest of cables and monitors that buzzed with silent, cryptic life. Jordan's eyes narrowed to focus on the sequences that danced across the screen—patterns that could unravel the cosmic enigma surrounding them. + +Alex Mercer approached with his characteristic stride, a signal of reliability in the chaos. "Status report, Dr. Hayes?" he inquired, his voice low, almost blending into the soundscape of beeping consoles and swirling fans. + +"We're on the brink of unravelling the signal's origin," Jordan replied, the weight of implications heavy in their tone. "There's intelligence behind it, a thought process alien to our own." + +As if summoned by their analysis, Taylor Cruz approached with authority radiating from every pore. "Understand this, we need to know if it's friend or foe. Don't get wrapped up in the existential—our lives may depend on the answers you provide." + +Sam Rivera, their hands adroitly adjusting a device to fine-tune the signal, chimed in with optimism undercut by anxious anticipation. "We're deciphering the comm encryption. Soon, we'll have a channel open—not just listening in, but speaking back." + +Alex nodded his understanding, his strategic mind processing the tactical implications while grappling with the more profound humanistic impact. "When we do, we'll tread carefully, communicate with purpose," he reassured the team. + +The operation had evolved rapidly, from a stealthy incursion into a clandestine labyrinth to an exchange with an extraterrestrial intellect. Their earlier trepidation transformed into determined focus, as they prepared to extend humanity’s hand into the vast unknown. + +An alert on one of the monitor stations snapped the team into alarm. The signal had not simply been waiting—it had been calculating. Now, it reached its crescendo, demanding their attention with a provocative urgency. + +Jordan's fingers raced over the keyboard, their eyes simultaneously interpreting data and sharing directives. "It’s a linguistic lock, a test of comprehension. We crack this, we establish dialogue." + +Taylor's presence was a beacon of steely resolve. "Then let’s solve it. This is what we trained for—the unknown." + +Alex and Sam exchanged a look that telegraphed their shared determination—this was not only the mission they had trained for; it was the mission they had been destined for. + +Together, the Paranormal Military Squad team leaned into the challenge, their minds honing in on the complex patterns with a singular goal: to unlock the conversation with an intelligence that had already begun to shift the foundations of what they knew, or thought they knew, about the universe. + +In a symphony of clicks and murmurs, they worked, knowing they were about to make a giant leap not just for themselves or Paranormal Military Squad, but for all of humanity. As the final pieces fell into place, Dulce's militaristic silence was shattered by the sound of intergalactic contact—by the sound of history being made. + +## Chapter 7 + +In the enclosed space of Dulce’s command center, the air was thick with anticipation, each team member poised to tread the razor's edge between scientific breakthrough and galactic peril. Dr. Jordan Hayes focused intently on the screen, their fingers tapping a staccato rhythm against the keyboard as lines of alien code cascaded down the monitor. + +Alex Mercer's steely gaze surveyed the room, stopping on each member of his team. "Thoughts?" he asked, echoing the unspoken tension. His question, while directed at the group, lingered on Jordan—acknowledging their expertise and inviting collaboration rather than dictating orders. + +Jordan’s brow furrowed, an indicator of the mental gymnastics being performed. "It's unprecedented," they finally said, their voice a testament to the gravity of the moment. "Behavioral algorithms... if we're right, this code could reveal extraterrestrial thought patterns." + +Before anyone could react, Taylor Cruz interjected with the assertiveness of someone accustomed to commandeering the discourse. "Then let’s ensure we’re deciphering it correctly," Taylor stated, their tone suggesting they were still battling to maintain control over an increasingly alien situation. + +Sam Rivera hovered near the mainframe, youthful energy barely contained under the surface. "What if it’s more than just a message? What if they’re trying to extend consciousness across the stars?" + +The room fell into a contemplative silence, broken only by the hum of electronic equipment and the distant thud of secured doors locking in rhythm. The weight of responsibility rested on each agent's shoulders—a heaviness palpable in the air they shared. + +Alex stepped forward, reaching a subtle decision, one dictated by foresight and the humanity nestled at the core of their mission. "We approach with the aim to understand, not to confront," he said, softening his military bearing into a more diplomatic stance. + +Jordan nodded, appreciating the leadership that Alex displayed in the face of the unknown, and turned back to the cryptic data. Here, before them all, was a tangible piece of evidence—proof of an extraterrestrial sentience that had outreached the bounds of their expectations. + +Taylor took a breath, simultaneously exuding a sense of preparedness and venturing into the unknown alongside their peers. "Then let’s do what Paranormal Military Squad does best—investigate and adapt," Taylor added, finding comfort in the familiar even as they stood on the cusp of an unprecedented alchemy of science and mystery. + +The team leaned into their respective roles, driven by the urgency of the assignment and the pull of an insatiable curiosity. Sam offered a grin that belied the tension, a youthfulness that reminded them all of the profound excitement nested within the terror of the unknown. + +Quietly but resolutely, they turned back to their instruments, each of them a sentinel on the threshold of a new reality. The once implicit lines of command were now woven into a shared tapestry of hierarchy and camaraderie. As they danced with the unknown, they were beacons of sentient endeavor, casting the light of human consciousness into the vast darkness that called to them. + +\* + +\* + +Dulce Base's cavernous darkness was pierced by the sharp luminescence of monitors, casting an electric glow onto the faces of those who dared to unearth its secrets. Dr. Jordan Hayes stood motionless, eyes glazed in concentration, their mind a nexus where terrestrial science battled with celestial unknowns. + +Alex Mercer watched from a slight distance, the weight of command tangible upon his shoulders, though lightened by the shared burden now held amongst them. "We could be on the frontier of a new kind of diplomacy," he mused aloud, giving voice to the moment's gravity. + +At those words, Jordan's trance broke. "If that's the case, then these communications," Jordan motioned to the stream of data, "are our olive branch across the cosmos." + +Taylor Cruz, who paced with restless energy, halted and faced the team—his stoicism marred by the erratic dance of lights reflected in his eyes. "An olive branch, or an invitation to a battlefield?" he posed, ever the strategist, his words laced with a hint of cynicism. + +Sam Rivera, nestled amongst an array of equipment, licked their lips—a mixture of nerves and anticipation palpable. "We're mapping out something incredible here. Whether it's peace or war, we're the cartographers." + +Silence enveloped them like the expanse of space itself, each member contemplating the chasms they might bridge—or the abysses into which they might unwittingly descend. + +Alex's demeanor assumed a quiet resolve—the profound knowledge that this mission was as much about navigating uncharted philosophical territories as it was about ensuring survival. "Whichever it proves to be, we'll face it. Prepared, unified." + +A nod passed between Jordan and Alex, a silent exchange of mutual respect and shared mission. Sam, buoyed by the weighty encounters of the mind and machinery, entered keystrokes with a fervor that seemed to bring them ever closer to the alien mind. + +They stood there, the Paranormal Military Squad team, not just as guardians of homeworld secrets or as soldiers of clandestine wars, but as humankind's chosen few at the fulcrum of history—a history that was now unfolding to the rhythm of otherworldly codes. + +Each revelation, each parsed symbol, inched them toward the line between the earthly and otherworldly. And as they stood on this precipice of cosmic negotiations, it was clear the ensuing dialogue would not just shape the future of Paranormal Military Squad—it could very well redefine the parameters of human existence. + +\* + +The hum of advanced computational systems tingling with cryptic transmissions framed the ambiance of Dulce's mainframe chamber. Jordan Hayes, fingers hovering over a console dense with blinking lights, furrowed their brow as sequences of alien data streamed across the screen. + +Alex materialized behind them, his presence a stable beacon amidst the technological whirlwind. "Look for patterns, anomalies. Anything that might resemble a handshake protocol in their communications," he directed, his voice a low thrum, reverberating with cautious optimism. + +Jordan cast a glance over their shoulder, acknowledging Alex's contribution with the shared understanding of colleagues who had transcended mere professional acquaintance. "I’m isolating sequences that seem to recur with more intention than static. If these are their ‘handshakes,’ then we might just be making first contact," they remarked, their focus returning to the screen with renewed vigor. + +From the other end of the room, where shadows married the artificial light, Sam's voice crackled through the static of nearby speakers, "Don't forget the anomalies we detected earlier. Each one could be a word, a sentence, or even a concept untranslatable to our current understandings." + +Resolute, Taylor Cruz stood at Jordan's other side, a stoic figure wrestling with the implications of their mission. "Keep pursuing this line," Taylor instructed, an undercurrent of intensity carried forth in their otherwise composed demeanor. "And remember, this isn't just about making contact; it's about securing knowledge for humanity." + +Alex offered a nod that spoke volumes, conveying his understanding of the stakes at play. Here, in this chamber of possibility, the team's actions would determine if humanity stood at the brink of a new age of understanding or the onset of an unprecedented threat. + +Every second thrummed with significance as Jordan and Sam worked in tandem, each keystroke a foray into the unknown. Taylor observed with a commander's scrutiny, the gravity of their role sustaining them against the waves of ambiguity breaking against their resolve. + +Pivotal moments come rarely in the course of human events but here, amidst the electronic symphony of a stalwart command center, lay the incepting notes of a cosmic overture. The harmony between human and alien, between Paranormal Military Squad and the vast reaches of space, began its first tentative measures, with each member of the team a vital instrument in a celestial ensemble yet to be fully heard. + +\* + +The crisp air within the mainframe room of Dulce base seemed to hum with unspoken possibilities. Jordan Hayes was the centerpiece of focus, their hands dancing methodically over the console as streams of otherworldly code cascaded down monitors, each flicker a potential key to the cosmic doors they were inching open. + +Alex Mercer watched, posture relaxed but eyes sharp. "Remember, this could be our first introduction, maybe even our first impression," he said, mindful of the gravity carried by each action they made henceforth. + +A hint of a smile touched Jordan's face, a small acknowledgment of the monumental task at hand. "Understood. I'm balancing the signal's syntax with our algorithms. If we're interpreting this correctly, it could be... well, an invitation." + +Into the electric tension of the chamber walked Taylor Cruz, their silhouette a sharp contrast against the cool lighting, radiating a presence that spoke of command and chilly tenacity. "An invitation, or a challenge?” Taylor questioned, the weight of their suspicion casting a different tint on the cascading data. + +Sam Rivera, in a corner arrayed with sophisticated equipment, piped up, their voice a buoyant note amidst the tentative atmosphere. "Either way, it's a connection. One that we're uniquely positioned to navigate," they remarked with an air of optimism threading through the uncertainty. + +Alex channeled the strengths of his team into the core of their approach, his leadership adapting to the contours of an unprecedented scenario. "Cautious and curious," he reflected aloud, shaping a strategy that balanced their thirst for comprehension with the prudence required in addressing the unknown. + +Jordan, hands momentarily at rest, looked up. The signal was more than a sequence of bits and commands—it was a riddle wrapped in the depths of space-time, and they were on the cusp of parsing its meaning. + +Taylor, hardly a step away, nodded in silent agreement. The implications of their findings might very well direct the course of human destiny from this point onward. + +Finding a tempo among themselves, the Dulce team was a confluence of ambition and acumen, each member intuitive to the beats of discovery. The chamber around them held untold stories, secrets coaxed from the stars, that now, led by Paranormal Military Squad's finest, began to unravel. + +The future in those moments was unwritten, a narrative scribed not in the dust of desert confines, but in the potential for interstellar diplomacy and understanding. As they prepared to script humanity's next chapter, the room seemed to pulse with the heartbeat of a story far greater than the sum of its parts. + +## Chapter 8 + +The grit of an earthbound dust storm contrasted sharply with the pristine sterility of the underground command center. Alex Mercer, eyes set with fervent determination, stood over Jordan Hayes, whose fingers danced across the keyboard with rapid purpose. Monitoring the progression of alien code unraveling before them, Mercer spoke with a tempered urgency, "Keep it steady, Jordan. We might be initiating the first true interspecies communication bridge here. It's all about finesse now." + +Taylor Cruz, the embodiment of military precision, surveyed the room with a calculated gaze from their vigil beside an array of glimmering screens. "Remember, these could be delicate negotiations -- or coded threats. Stay sharp," Cruz added, their voice cool as polished steel. + +Jordan, with a silent nod, recognized the gravity of both stances. Gravitating between scientific acuity and diplomatic caution, they replied, "The sequence is aligning—syncing with our comms. It's looking more and more like direct engagement." + +Amid the banks of electronic machinery, the thrumming pulse of an impending interspecies signal exchange, Sam Rivera interjected with a youthful zeal that cut through the weighty atmosphere, "It's not just an exchange. It's a... symphony. It's as if they're teaching us their language through modulation." + +A moment of profound silence swept over the team. The isolation of their location, deep within the top-secret labyrinth of Dulce, became suffused with an almost palpable sense of historical significance. + +"Then our response needs to be equally symphonic," Alex uttered, contemplating the awe-inspiring transmutation of their task from a simple recovery mission to a full-blown cosmic concerto. + +With a renewed sense of wonder tempered by caution, the Paranormal Military Squad team found themselves harmonizing a delicate balance between envoys and interpreters. The long shadow cast by their duty was now illuminated by the brilliant glow of otherworldly dialogue. + +In this carefully orchestrated march towards the unknown, each individual's expertise became critical notes in a larger melody. The narrative of human achievement, so often defined by solitary pursuits, now emerged as a collaborative opus, each member of the team a maestro in their right. + +The protocols of encounters, the mathematics of languages, and the poetics of connection all fused into a singular moment of convergence. The echo of their efforts reverberated back to them, not through the cavernous base's concrete walls, but from light-years away, in the form of a reply, intangible yet infinitely profound. + +\* + +Amidst the hum of the supercomputers and the faint static from the scrambled transmissions, Alex Mercer cast a thoughtful glance across the dimly lit room toward where Dr. Jordan Hayes was methodically adjusting the archaic dials of the decryption machine. "Any progress?" he asked, his tone conveying both impatience and the deep-seated respect born from countless shared challenges. + +Jordan did not look up, their gaze remained locked on the flickering lights that represented a dialogue suspended between worlds. Their fingers ceased their dance, hovering meditatively over the controls. "We might be on the cusp of a breakthrough," Jordan suggested. "The signal... it's evolved. It's reflexive now, responsive in a way that suggests sentience." + +Taylor Cruz's familiar sharp strides approached the two, breaking the rhythm of soft beeps. "Responsive is good, if it means understanding," Taylor said, head tilted as they peered at the encryption data scrolling by. "But remember, comprehension can bring revelation or conflict." + +Sam Rivera’s youthful voice permeated the tension, brimming with an excitement edged by the enormity of what they faced. "If it's truly sentient, we're not just cracking a code; we're learning how to converse with an entirely new form of consciousness," they chimed in, the weight of history not lost on the zealous astrotechnician. + +Alex nodded, his thoughts alighting on potential strategies for navigating the conversation they were cultivating with the unfathomable. "We need to keep that conversation going, echo its patterns, and speak its language," he resolved, knowing the delicate nature of their work merited every ounce of their collective acumen. + +The chamber now was a crucible, forging within it the future narrative of human contact with the unknown. Every signal pulse they sent out was an invitation for understanding, and every echo back a step closer to bridging the cosmic divide. And so, together, they stood - agents in Paranormal Military Squad's clandestine ranks, united by purpose, sculpting humanity’s first sonnets into the void. + +\* + +#### Knowledge graph updates + +- (Jordan Hayes, Interprets, Communications as cosmic diplomacy, Moderate) + +- (Taylor Cruz, Questions, Potential aggressiveness of alien intent, Minor) + +- (Sam Rivera, Expresses, Optimism about forming a connection, Minor) + +- (Alex Mercer, Adopts, Balanced strategy for contact, Moderate) + +- (Paranormal Military Squad team, Navigates, Beats of cosmic discovery, Moderate) + +- (Paranormal Military Squad team, Prepares, To script humanity's interstellar narrative, Major) + +## Chapter 9 + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +Dr. Jordan Hayes, whose hands had been steadfastly working the decryption algorithms, paused and looked up at Alex. "We're through the next layer of encryption," Jordan announced, a mixture of pride and gravitas in their tone. "It's communicating. It's... aware." + +A shadow momentarily clouded Alex's determined features—awareness implied so much more than mere intelligence. "Aware and reactive or aware and proactive?" he queried, his experience anticipating the pivotal importance of intention. + +"Unknown at this stage," Taylor Cruz interjected, looking up from a datasheet. "But I urge caution. We tread the line between breakthrough and disaster with each keystroke." + +Sam Rivera, ever the source of technological acumen, added their voice to the conversation. "The signal's adapting every time we interact with it. Like a conversation where both parties are learning each other's language in real time." + +Alex leaned in, rested a hand on Jordan's shoulder—a sign of companionship and an affirmation of trust. "Keep the communication channels open. But let no message, no pulse go unchecked. This could be our Rosetta Stone or our Tower of Babel." + +Silence fell over them, a momentary lull as each member of the team contemplated the historic weight of their task. Yet, it was impregnated with a tangible sense of excitement—a collective energy that thrummed through the air just as palpably as the electric current through the banks of machines surrounding them. + +They continued their work, squaring shoulders against the magnitude of their undertaking. The agents were standing not just at the precipice of a new chapter for Paranormal Military Squad but for all of humanity. For now, they communicated with powerful unknowns, but with each exchange, they were etching the first words of a dialogue that might forever alter humanity's place in the cosmos. + +\* + +\* + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +Dr. Jordan Hayes, whose hands had been steadfastly working the decryption algorithms, paused and looked up at Alex. "We're through the next layer of encryption," Jordan announced, a mixture of pride and gravitas in their tone. "It's communicating. It's... aware." + +A shadow momentarily clouded Alex's determined features—awareness implied so much more than mere intelligence. "Aware and reactive or aware and proactive?" he queried, his experience anticipating the pivotal importance of intention. + +"Unknown at this stage," Taylor Cruz interjected, looking up from a datasheet. "But I urge caution. We tread the line between breakthrough and disaster with each keystroke." + +Sam Rivera, ever the source of technological acumen, added their voice to the conversation. "The signal's adapting every time we interact with it. Like a conversation where both parties are learning each other's language in real time." + +Alex leaned in, rested a hand on Jordan's shoulder—a sign of companionship and an affirmation of trust. "Keep the communication channels open. But let no message, no pulse go unchecked. This could be our Rosetta Stone or our Tower of Babel." + +Silence fell over them, a momentary lull as each member of the team contemplated the historic weight of their task. Yet, it was impregnated with a tangible sense of excitement—a collective energy that thrummed through the air just as palpably as the electric current through the banks of machines surrounding them. + +They continued their work, squaring shoulders against the magnitude of their undertaking. The agents were standing not just at the precipice of a new chapter for Paranormal Military Squad but for all of humanity. For now, they communicated with powerful unknowns, but with each exchange, they were etching the first words of a dialogue that might forever alter humanity's place in the cosmos. + +\* + +Alex Mercer's eyes were fixed on the monitors, the reflected light casting an ethereal glow across his stoic face. The room buzzed with tension, a cacophony of low hums and electronic beeps that underscored the historic nature of their actions. He moved to where Dr. Jordan Hayes was immersed in their work, scrutinizing the alien code streaming rapidly down the terminal. + +"Find anything that might look like an entry point or a... digital handshake?" Alex asked, his voice steady, betraying none of the tension gripping his chest. + +Jordan looked up briefly, their expression weary yet intense, "Potentially. It's as if the code is anticipating our input, modifying itself in real-time. I've never seen anything like it." + +From across the room, Taylor Cruz's sharp voice cut through the hum. "Then it's learning or, possibly worse, baiting us. Proceed with extreme caution," they commanded, their firm stance reinforcing the gravity of the situation. + +Sam Rivera, surrounded by a cascade of screens and interfaces, added, "It's almost organic in its complexity. Any minute now, and I might have a way in." + +A slight nod was Alex's immediate response, his mind racing through the potential scenarios. "Everyone, stay alert. This could be the beginning of something profound." His seasoned eyes never left the unfolding drama on the monitors. + +The room fell silent, the air heavy with unspoken questions. Were they mere moments away from unlocking an otherworldly dialogue? Or was it a Pandora's box that, once opened, could not be closed? + +Alex moved closer to the main console, his fingers hovering over the command keys. With the precision of a maestro orchestrating a symphony, he communicated silently with Jordan – respectful of their expertise, aware that the next move could alter the course of human history. + +Jordan met his gaze, nodding sharply, and refocused on the task. The signal seemed to pulse with sentient curiosity, drawing them further into its intricate web. + +A sudden flurry of alerts and the intensifying glow of monitors heralded that they had bridged a technological chasm. The alien intelligence on the other end was no longer a distant enigma – it was an active participant, responding to their digital overtures with an unknown agenda. + +The team's meticulous efforts had led them to a momentous threshold. Beyond lay unprecedented contact – a nexus of curiosity and potential peril. Within the confines of the base, against the backdrop of a silent desert night, the Paranormal Military Squad operatives became mediators of Earth's bid for cosmic relevance, their every action now a gesture in the grand dance of intergalactic relations. + +## Chapter 10 + +The corridors of the Dulce military base, now silent, echoed with a history of whispered conspiracies and furtive movements. But in the command center, a delicate tapestry of light and sound was being woven as the echoes of cosmic dialogue resonated through the high-tech enclave. Dr. Jordan Hayes, now leading the efforts, called out from their workstation, "I’ve isolated the signal's harmonics. It's more than a call; it's a song, an interstellar siren’s call." + +Alex Mercer, steady and resilient in the face of the incomprehensible, acknowledged with a quiet nod, "A song that we need to learn—quickly." His eyes, heavy with responsibility, scanned the room, watching his team work tirelessly at the intersection of science and speculation. + +Sam Rivera, dulled by fatigue yet driven by unshakeable resolve, manipulated a complex array of audio interfaces. "There's a pattern, a repeating motif. It's structured, intentional," they muttered, their revelation a bridge between the known and the unimaginable. + +Taylor Cruz, a figure of central authority, paced the length of the room, their usual unflappable demeanor betraying a rare flicker of apprehension. "We should be wary of the sirens’ call," Taylor interjected, invoking myths of old as a cautionary metaphor. "We don't want to crash upon unseen shores." + +Undeterred, Jordan cast a determined glance at the team. "We navigate by starlight now, not by the limited light of our previous understanding." Their voice was a beacon, charting a course through unchartered realities. + +Every individual was acutely aware that each moment in that room was a conduit to an epochal shift for civilization. The mysterious signals, once distant and alien, had coalesced into complex and harmonious oscillations—beacons of an extraterrestrial intellect inviting Earth to join in a cosmic consortium. + +Silently, Alex approached the mainframe, his trained fingers aligning with the console’s mechanisms. The room watched in collective breathlessness as he set the frequency in motion, an introductory phrase to an otherworldly melody—a symphony that could bind worlds or spell devastation for all they knew. + +In the control room of Dulce, amongst whispered legends and the quiet hum of machines, humanity's ambassadors now stood, stretching their hands into the void, reaching for the hand that would either pull them into the light of new stars or into the maw of darkness between them. + +\* + +Underground, the Dulce facility's command center was awash with frenetic energy, a stark juxtaposition against the silent, decrepit corridors that enveloped them. The air hummed with anticipation as Dr. Jordan Hayes and Alex Mercer hunched over a console. The sterile light from the monitors cast an otherworldly glow upon their faces, now reflecting a mosaic of alien characters rapidly translating across the screen. + +"The patterns are evolving," Jordan murmured, concentration etched into their every feature. "It’s as if our attempts to decrypt have accelerated its learning. It’s adapting to us." + +Alex, who stood steadfast behind Jordan, felt a tinge of uncharted fear quickly quelled by the fire of discovery raging within him. "Keep it up," he urged. "But whatever this is becoming, we need to ensure it remains within our control." + +Taylor Cruz interjected, their voice slicing through the buzz of activity. "Control may be an illusion when facing an intelligence that literally writes its own rules," they stated stoically, casting a watchful eye over the flurry of data. + +"It's like it's learning to communicate," offered Sam Rivera from a nearby interface, their youthful energy boding a mix of awe and anxiety. "This gives ‘talking to strangers’ a whole new meaning." + +Alex surveyed his team—each face a study in concentration, determination, and not a small measure of trepidation. "This might well be our first contact," he acknowledged, "And we need to be ready for whatever answers back." + +Together, they stood on the edge of the unknown, forging humanity’s response to a message from the heavens. The ensuing silence was palpable—a collective introspection about their role in this grand cosmic play, one that could rewrite human history. + +The encrypted dialogue continued to unfold, its intricate patterns showing an almost uncanny anticipation of their investigative strategies. The air turned heavy with the scent of electricity and ambition as they closed in on a pivotal response. + +As the signal’s intelligence—whether artificial or biological—grew more profound, so too did the realization that their mission had morphed from passive observation to active engagement. There was no turning back now. Each agent embraced their part in the delicate dance of an interstellar exchange that could change everything they thought they knew about life, intelligence, and the dark void beyond Earth's atmosphere. + +\* + +The underground halls of Dulce Base, usually buzzing with covert operations, now thrummed with a different kind of energy, an electric mix of fear and fascination. At the heart of the base, in a room shielded from the world’s eyes, Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera huddled around a bank of monitors. Each screen flickered erratically with the alien script that had become the center of their lives—and perhaps the pivot on which humanity’s future would turn. + +Jordan's eyes never wavered from the displays, their expression was one of rapt concentration, interspersed with flashes of revelation. "We're conversing with the stars," they whispered, almost to themselves. The words hung in the air, a testament to the awe-inspiring strangeness of the situation. + +"The language is morphing; changing its structure with every exchange we have," Sam chimed in, enthusiasm tinged with the solemnity of the occasion. "It's like witnessing the birth of a new form of dialogue—one that spans galaxies." + +Taylor, despite the situation's precariousness, maintained an appearance of ironclad composure. "Keep the communication stream secured and monitored. We don't know what we're dealing with yet," they reminded the team, a bastion of protocol amidst uncertainty. + +Alex watched his team expand the parameters of human achievement; their work here would possibly define an era. "This is untrodden territory," he acknowledged, "and in every word we script, in every response we decode, we're drawing a map that others will follow." + +Jordan turned to Alex, a nod acknowledging the shared responsibility of this moment. They had embarked on a new voyage, an odyssey not of the body, but of the intellect and spirit. No longer explorers of the Earthly realm, they had been promoted by circumstance to ambassadors of humanity in a silent and boundless ocean. + +A sudden pulse of energy from the monitors signaled a breakthrough; the language had not only adapted but it seemed to resonate, to harmonize with their attempts at making contact. The alien script now sprawled across the screens didn't just ask to be understood—it invited interpretation, collaboration, maybe even companionship across the cold distances of space. + +As they stood before the precipice of first contact, Paranormal Military Squad's finest became the architects of a symphony meant to echo through the cosmos. But more than architects, they were the first to play the notes of this cosmic composition, daring to believe that on the other end, someone—or something—might be listening, ready to join the chorus. + +\* + +The underground command center of Dulce Base, once pulsing with clandestine operations, now resonated with the charge of an impending cosmic threshold. Encircled by banks of whirring machinery, each monitor flickered erratically with alien script that had occupied center stage in the lives of Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera. + +Jordan's gaze didn’t flit for even a moment from the screens, where indiscernible alien messages ebbed and flowed like the tide. The ciphers and symbols cascaded down as they tweaked the algorithmic sliders. "This sequence here," Jordan began, voice both hushed and heavy, "it’s not just transmitting; it resonates—it's designed to be felt." + +The room took a collective breath, the remarkable implication hanging in the air like a careful revelation. Sam Rivera was the first to respond, their voice alive with ingenuity: "It's a form of communication stretching well beyond words. We need to respond in kind—the whole array of human expression might be at play here." + +Taylor's eyes remained fixed on the figures playing across the data sheets. "If that's the case," Taylor intoned pragmatically, "we must tread carefully. This is no longer just about being heard—it's about being understood." + +Alex watched his team, each a fulcrum of insight and expertise, and felt the solemnity of the role they were about to assume. "Then we'll ensure our message is clear and full. Our humanity is our strength in this dialogue," he declared, the depths of his experience fueling a commanding reassurance. + +The anticipation was palpable as the agents contemplated the vastness of their endeavor. They were not merely probing at the secrets of the planar cosmos—they were negotiating across the starry expanse, extending to distant intelligences the full spectrum of human curiosity and compassion. + +A symphony of beeping consoles orchestrated their next steps as they prepared to articulate their interplanetary overture. The rhythmic tapping of Jordan's keystrokes set the tempo for an undertaking that traversed beyond algorithms and encryption. + +The base withstood time and whispered secrets of its own, but none so grand as this moment of creation—an invitation to the universe that promised to echo through both the echoes of space and the annals of human history. + +## Chapter 11 + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +\* + +The thrum of the colossal machinery vibrated through the subterranean facility as Alex Mercer stood amidst the whispers of technology, each carrying voices from worlds apart. He watched as Sam Rivera adjusted a complex array of cosmic translators, their expression a mixture of anticipation and awe. + +"Are we ready, Mercer?" Taylor Cruz asked, the soft glow of the command center consoles reflecting upon their stern face. + +Alex turned towards Taylor, his eyes holding a depth that betrayed the enormity of the threshold they were about to cross. "This is it," he said. "Initiate the protocol. It's time we answer the cosmos." + +Jordan Hayes, stationed at the mainframe, typed rhythmically, a blue hue painting their focused features. The eerie silence that had settled over the team was interrupted by a visceral sound—humankind's response to the alien dialogue, now streaming into the abyss. + +The control room, once a fortress of solitude, erupted into an oasis of life. Lights flickered in tandem, echoing the symphony of interstellar communication. They stood together at the edge of discovery, facing the symmetry and discord of a universe unknown. + +"If we're right, we've just become Earth's first emissaries to a celestial congress we're only beginning to comprehend," Jordan's voice was somber, resonating with a mix of trepidation and honor. + +The room filled with the resonance of human and alien minds converging, creating a new narrative within the fathomless expanse of existence. Paranormal Military Squad, once protectors of Earth's clandestine secrets, had now become the tether linking humanity to the cosmic fold. + +\* + +The underground command center of Dulce Base, once pulsing with covert operations, now resonated with the charge of an impending cosmic threshold. Encircled by banks of whirring machinery, each monitor flickered erratically with alien script that had occupied center stage in the lives of Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera. + +Jordan's gaze didn’t flit for even a moment from the screens, where indiscernible alien messages ebbed and flowed like the tide. The ciphers and symbols cascaded down as they tweaked the algorithmic sliders. "This sequence here," Jordan began, voice both hushed and heavy, "it’s not just transmitting; it resonates—it's designed to be felt." + +The room took a collective breath, the remarkable implication hanging in the air like a careful revelation. Sam Rivera was the first to respond, their voice alive with ingenuity: "It's a form of communication stretching well beyond words. We need to respond in kind—the whole array of human expression might be at play here." + +Taylor's eyes remained fixed on the figures playing across the data sheets. "If that's the case," Taylor intoned pragmatically, "we must tread carefully. This is no longer just about being heard—it's about being understood." + +Alex watched his team, each a fulcrum of insight and expertise, and felt the solemnity of the role they were about to assume. "Then we'll ensure our message is clear and full. Our humanity is our strength in this dialogue," he declared, the depths of his experience fueling a commanding reassurance. + +The anticipation was palpable as the agents contemplated the vastness of their endeavor. They were not merely probing at the secrets of the planar cosmos—they were negotiating across the starry expanse, extending to distant intelligences the full spectrum of human curiosity and compassion. + +A symphony of beeping consoles orchestrated their next steps as they prepared to articulate their interplanetary overture. The rhythmic tapping of Jordan's keystrokes set the tempo for an undertaking that traversed beyond algorithms and encryption. + +The base withstood time and whispered secrets of its own, but none so grand as this moment of creation—an invitation to the universe that promised to echo through both the echoes of space and the annals of human history. + +## Chapter 12 + +The underground facility of Dulce Base, once shrouded in silence and operational secrecy, now hummed with an energy that cradled the promise of cosmic revelation. Alex Mercer stood pensively by the central terminal, flanked by Dr. Jordan Hayes, Taylor Cruz, and Sam Rivera, each poised at the edge of a history-defining moment. + +Jordan's fingers ghosted across the console, tracing patterns of otherworldly origin. "The signal’s architecture is becoming more complex, resembling aspects of human cognition—recognition, learning, even... empathy?" they postulated with furrowed concern. + +Alex turned his gaze upon Jordan, his voice quiet but resolute, "Empathy could bridge galaxies. Let's harness this connection and proceed with cautious optimism." + +Taylor, ever the sober sentinel, projected a more pragmatic standpoint. "Empathy or not, we are duty-bound to assess the risk to humanity. Every new discovery warrants a measured response." + +The static hiss of communications equipment filled the air, its purpose now transformed into a dialogue with an intelligence beyond the stars. It was Sam, wide-eyed amid the myriad lights and switches, who broke the silence, "We have provisional confirmation of the signal’s intent—initiation. We’re being brought into a broader spectrum of cognizance." + +The chamber lay still for a heartbeat, the Paranormal Military Squad agents steeped in contemplation of the path unfurling before them—a path paved with possibilities of diplomacy or disruption, each step a venture further into the cosmic unknown. + +Alex stepped closer to the viewing monitors, each depicting alien symbols seemingly reaching out from the void. "Initiate the broadcast," he spoke with quiet command. "Our response will mark humanity’s readiness to partake in the wider conversation of conscious beings." + +Amidst the crackling air of expectation, the team wordlessly returned to their stations. They had transcended their roles as protectors of Earth's clandestine lore to become the harbingers of an interstellar parley that could change the existential course of life on their pale blue dot. + +The deep hum of the terminal emitted a signal—a testament to the uncanny reality that Earth was now actively partaking in an exchange not bound by gravity nor the limits of the solar wind. + +Here, in the depths of Dulce, a message from humanity woven from understanding and uncertainty was cast into the firmament, an epitheg of their desire to join the universal dialogue and discover their place among the constellations. + +\* + +The somber depths of the Dulce Base command center stood in stark counterpoint to the animated flurry of activity around the central comms array. Alex Mercer's silhouette loomed behind Dr. Jordan Hayes, who sat with a posture indicating laser focus on the decryption process. A quiet murmur of digital soundscape filled the space, subtly heightened by the anticipation of contact with an intelligence beyond the Earth. + +Jordan's voice was steady, betraying none of the extraordinary nature of their work, "Looking through the signal's pattern, it's evident we’re dealing with a form of intelligence—calculating, mirroring, possibly even understanding." + +Alex's reflection bounced off the darkened screens, his head nodding in silent affirmation. "We’re walking a delicate line. Our response should be thoughtful, measured. We’re ambassadors, not merely explorers." + +Taylor Cruz approached, arms folded, their words slicing through the din of careful keystrokes and soft whirrs, "If there’s even the slightest chance it understands, we can’t afford missteps. The language of the stars might be more absolute than ours." + +From another terminal, Sam Rivera brought youthful vigor to the conversation, "There’s rhythm in these patterns. If this is their way of reaching out, our reply should encapsulate all that we are—all that humanity stands for." + +Looking around at his team, Alex saw resolve etched on every face. The chamber, usually somber and echoing with the quiet steps of covert agents, now felt alive with the heartbeat of discovery. They were not just professionals operating in the gloom; they were a collective standing at the helm of a momentous journey. + +"Let’s begin," he said, returned by the resolve in his voice. "Every second counts." With that, they pressed forward, setting in motion a reply to a conversation billions of years in the making. + +The dance with an unseen partner commenced, each pulse they sent out a step taken with caution and hope. And as those digital pulses journeyed through the black sea of infinity, Earth, for perhaps the first time, joined a pan-galactic dialogue that whispered secrets of the cosmos—secrets that, until now, had been lost in the silent vastness of space. + +\* + +As the team stood in the centralized nerve center of Dulce's underground fortress, the solemn atmosphere was reverent, overseeing systems that engaged with an intelligence from the void. Alex's stance was contemplative as he gazed at Jordan Hayes, who presided over the console, the tension of the moment reaching a tactile fervor. Each rhythmic tap of Hayes's fingers on the keys was a foray into uncharted symphonies of contact. + +Observing Hayes unravel the dense alien encryption, Alex spoke, a diplomatic tenor underpinning his words, "Keep focused on the syntax, dissect its nuances. We're not just decoding signals; we're translating intentions." + +Without diverting from their task, Jordan acknowledged the insight. "Indeed, if their understanding of us is as deep as we hope, we're paving the way for dialogue far beyond our current realm." + +Taylor Cruz, near the rear of the room, provided a steady oversight. "As horizonless as our prospects may seem," Taylor intoned, "remain diligent. Complacency before alien cognition could spell catastrophe." + +Sam's youthful voice resonated with optimism, "Imagine—forming a rapport with a consciousness separate from our reality; we're drafting the bridge to stars alive with minds!" + +The sentiment hung for a moment before Alex gathered his conviction. "Dialogue is our vessel. We are not just agents of enigma; we are the threads that may weave a new cosmic relationship." His words seemed to reflect off the walls, reaching beyond the room's confines, a quiet yet resilient vow. + +Their task was titanic, stepping stones laid delicately into new territories of existence. The signal, once an esoteric strand in the echo of the universe, beckoned now with a clarity rocketing the complexity of thoughts from a distant order. + +Action by action, the Paranormal Military Squad team bridged the vast interstellar distances, their expertise and empathy casting a beacon of unity into frontiers of intelligence and knowledge. Their work, a partnership struck with an unseen cosmic congregation, each pulse sent and received a line in Earth's novitiate envoi to the cosmic shores. + +\* + +Under the stark, unforgiving lights of Dulce Base's underground command center, tension buzzed harder than the banks of supercomputers that lined the walls. Agent Alex Mercer leaned over the shoulder of Jordan Hayes, whose eyes were locked onto the display screen, where an incomprehensible series of alien symbols streamed past incessantly. + +“Any progress on the decryption?” Alex's voice was steady, a controlled presence necessary in the gravity of their undertaking. + +Jordan tapped a key, pausing the flow of code, and leaned back with a deep sigh. "We've broken through another subset of the cipher. It's revealing... well, indications of a complex society, not unlike our own." His eyes met Alex's with an unspoken question that hung heavily between them—were they truly prepared for what they might find? + +Taylor Cruz strode into the room, a tightly coiled spring of ambition and authority, and peered at the screen. "Understand their society, and we may predict behavior. Remain expedient—we don't know how much time we have before the situation shifts." There was an edge of stark realism to Taylor's words, the underlying message clear: every revelation bore its own set of risks. + +Alex nodded thoughtfully, recognizing the validity of Cruz's caution. Turning to Sam, who was tinkering with a device that buzzed quietly on the table, he asked, “Sam, can your contraption get us any further?” + +Sam looked up with a smirk, a twinkle of mischief in their eye. “It’s not just any contraption, it’s potentially a direct line to their thoughts. Give me a moment more, and I'll have something for you.” + +The air ticked with electronic beeps and the rustling sound of the Paranormal Military Squad team at work. They were so close to peering into the intelligence of an alien race—a reality on the brink of dramatically expanding their understanding of the universe. + +The machinery whirred in response to Sam’s precise touches, and suddenly, the room filled with a low hum—something had changed, a signal had been successfully sent. The team held their breath as they listened. The sound that filled the room was unmistakable: a response, an alien voice filtered through the static of space and time. + +Alex exchanged a look of quiet triumph with Jordan. The breakthrough was monumental; they were no longer casting messages into the void but engaged in a dialogue—an exchange that marked the beginning of Operation: Dulce’s true unfolding. This was it, the first steps into an interstellar odyssey that demanded every ounce of their courage and wit. + +## Chapter 13 + +Dr. Jordan Hayes shuffled a stack of papers, their eyes revealing a tinge of skepticism at Taylor Cruz's authoritarian performance. _Protocols_, Jordan thought, _are just the framework, the true challenges we're about to face lie well beyond the boundaries of any protocol._ They cleared their throat before speaking, tone cautious yet firm, "Let's remember, the unknown variables exceed the known. We should remain adaptive." + +A murmur of agreement echoed from Sam Rivera, who leaned forward, lacing their fingers together as if weaving a digital framework in the air before them, "Exactly, adaptability could be the key to interpreting the signal distortions and system malfunctions. We shouldn't discount the… erratic." + +Their words hung like an electric charge in the room, challenging Taylor's position with an inherent truth. Cruz’s jaw tightened almost imperceptibly, but the agent masked it with a small nod, conceding to the omnipresent threat of the unpredictable. + +Alex glanced at Jordan, who never looked back, their gaze fixed instead on a distant point, as if envisioning the immense dark corridors they were soon to navigate in Dulce. Jordan was not one to embrace fantastical theories, but the air of cautious calculation betrayed a mind bracing for confrontation with the inexplicable, an internal battle between the evidence of their research and the calculating skepticism that kept them alive in their field. + +The meeting adjourned with no further comments, the team members quietly retreading the paths to their personal preparations. Alex, trailing slightly behind, observed the others. _The cautious reserve Jordan wears like armor doesn't fool me_, he thought, _their analytical mind sees the patterns I do. And that's worth more than protocol. That's the connection we need to survive this._ + +As the agents dispersed into the labyrinth of the facility, lost in their thoughts and preparations, the base's halogen lights flickered, a brief and unnoticed harbingers of the darkness to come. + +\* + +The gritty, wind-tossed surface of New Mexico, just above the cavernous domain of Dulce Base, offered no shelter from the burgeoning storm—the scouring sands an earthly reminder of chaos theories in motion. Far beneath, a similar maelstrom brewed within the confines of the command center, as Paranormal Military Squad's handpicked squad stood poised for potential enormities of contact. + +Ruffling through printed transmission logs, Jordan Hayes dialed the focus of their analytical prowess onto the emerging pattern of signals crisscrossing between Earth and the unfathomable. "Our responses so far have echoed their complexity, but the real divergence is yet to come," Jordan remarked stoically, the calm belying the mounting surge of adrenaline for the revelation ahead. + +Alex Mercer's figure, a silhouette sharpened by the purpose, loomed at the periphery of the monitors' sickly glow. "Indeed," he assented, "The echoes are the easy part. It will be the introduction of our own, human variable that truly begins our dialogue." + +Taylor Cruz, windowless command center notwithstanding, appeared as though they could feel the tempest above. Their eyes never left the monitors as they unspooled their hard wisdom. "For all our advances, we find ourselves deciphering the swings and nuances of an interstellar pendulum. Predict its arc, and we may preempt the gravity of its message." + +Amidst a chorus of bleeps and static, Sam Rivera's tech-clad hands moved rhythmically, their spirited approach to unruly streams of data bordering an intimate dance with entropy. "Entropy that leads to discovery," Sam mused, responding to Taylor's metaphor. "Each step into the unknown is a step away from precedent." + +Alex, drawing near Jordan, spoke again, his voice now a thread woven through the very fabric of their operations. "Let's be the cartographers of this new territory. Our initial shades of understanding could color the cosmos for generations to come." + +Their gazes fell upon a screen as the latest transmission painted its digital blooms of alien script across the black. This time, the pattern wavered in an almost imperceptible fashion, a modification that whispered of active, alien thought awaiting their next move. A hush enveloped the Paranormal Military Squad ensemble, the gravity of the pathogen undeniable. They were about to issue a reply, one poised to reshape the very concept of humanity's outreach into the cosmos. + +The New Mexico desert's secrets were infamous, its storms a mere prelude to the revelations that the team—united in purpose—would unleash upon the world. The howling winds outside found their counterpart in the newfound resolve within, as Dulce's stalwart guardians readied themselves to send forth humanity's retort to the echoes from beyond. + +\* + +The cavernous control room, deeply entrenched beneath the desolate New Mexico terrain, held the Paranormal Military Squad team in intense focus; an island of calm amid the storm of cosmic dialectics. Dr. Jordan Hayes worked methodically, every keystroke an intricate step in their tenuous cosmic ballet. Suddenly, they paused, a signal pattern resonating from the screen. "This is new; it's...inviting. It’s as if the signal is not just calling to us but weaving its intelligence through ours." + +Alex Mercer scrutinized the shift in data. "A confluence of minds, then. If we're to meet them halfway, Jordan, our reply must be both innovative and discerning," he proposed, a glimmer of profound curiosity behind his authoritative demeanor. + +Taylor Cruz, whose sharp eyes missed nothing, nodded from beside a secondary panel. "Innovative, yes, but also defensive. This interaction is a razor’s edge, and we cannot afford to bleed before the unknown," Taylor reminded them, the metaphor a stark warning of potential dangers. + +Against the backdrop of their conversation, Sam Rivera’s youthful optimism cut through the tension. "If they’re weaving through our intellect, then we've achieved something beyond first contact—we're at the genesis of interstellar symbiosis," they posited with a mix of reverence and excitement. + +Alex returned Sam’s smile with his own, tempered and faint, as he turned back to the task at hand. The magnitude of their mission extended beyond the fabric of the universe, an exploration into the threads that connected sentient beings across the vast expanse. “Let’s reply with our own woven tapestry of thought—delicate, but deliberate.” + +With renewed determination, the room came alive with an undercurrent of anticipation, its occupants charged with the potential of forging an alliance with the cosmos. Paranormal Military Squad's finest were no longer merely soldiers and scientists; they had become pioneers on the vanguard of humanity’s greatest odyssey. + +The New Mexican sands above, impassive to the change brewing underneath, stood as silent sentinels as Earth's emissaries crafted their response. A response that, composed with care and imbued with humanity's essence, reached into the void, connecting with an otherworldly intelligence that awaited their harmony in the cosmic conversation. + +## Chapter 14 + +The command center of Dulce Base lay shrouded in shadows that seemed to claw at the edges of the dimly lit array of screens and consoles. Alex Mercer, focused and unwavering, watched as Dr. Jordan Hayes parsed the latest string of alien signals—a symphony of otherworldly communications that threatened to either enlighten or confound. + +"We’re encountering a paradigm shift with every transmission," Jordan Hayes murmured, the pulsing glow of the monitor painting their features with an almost spectral hue. "This signal... it’s evolving, becoming denser, more sophisticated. As if it's growing alongside us—tandem evolution." + +The air was electric, charged with the raw potential of uncharted discovery and laden with the gravity of existential risk. Taylor Cruz, who always seemed here to mold such gravity into actionable strategies, stepped forward. "We must contain this evolution within parameters we can manage. We cannot be bystanders to an uncontrolled ascent of intelligence." + +Sam Rivera, the youngest of the cohort, worked feverishly at their station. "It's not just intelligence—these signals have rhythm, a kind of music suggesting not just evolution, but a dance! We're being invited to partake in the cosmos's ballet!" they exclaimed, a touch of youthful exuberance breaking through the solemnity. + +Alex turned, facing his team, the stoic mask of command tempered by the perceptible flicker of awe in his gaze. "Let this dance then be our dialogue. We will match their steps with prudent but daring measures—our humanity as our guide." + +In the ensuing hours, the Paranormal Military Squad team forged a rhythm of their own, their collective expertise a beacon piercing through the fog of the unknown. The signal, increasingly intricate and seemingly conscious, now demanded not just observation but participation, an interstellar pas de deux that hummed with the promise and peril of first contact. + +Before them, the communications interface flickered to life with a received transmission—a resonant hum that seemed to vibrate through the very foundations of the base. They had successfully established a back-and-forth with whatever intelligence lay hidden among the stars. Every subsequent note they struck within the cosmic ether would come to define humanity's place within the galactic community—heralds of Earth's grand entrance into a universe far less silent than once perceived. + +\* + +In the concrete belly of Dulce Base, dimly lit by the jagged dance of fluorescent lights above, Sam Rivera perched on the edge of their seat, their eager fingers fluttering across an ancient keyboard. The stark, cold room—reminiscent of a time when covert operations and unspoken dread ruled supreme—now housed a peculiar blend of old-world machinery and sleek, modern interfaces. + +Alex Mercer, standing steadfast like a bridge between the enigmatic past and the unfathomable present, watched on. In his eyes flashed the foreboding excitement of change. "Sam," he started, his voice steadfast, "the patterns in these signals, what do they tell us about the nature of our... guest?" + +Sam's eyes glimmered with something akin to thrill—or was it trepidation? "It's like we're mirroring each other, evolving together through this.. dialogue. Like it knows us, understands us, and it's… learning." + +Jordan Hayes, preoccupied at a nearby console, chimed in without lifting their gaze. "It's a dialogue that transcends mere words, Alex. We're being woven into a narrative far grander than the sum of our known sciences." + +Taylor Cruz, arms crossed, wore the heavy mantle of their skepticism comfortably. "Keep theorizing," they interjected crisply, "but remember the grounding reality of what we are part of here. This contact is a blade that cuts both ways." + +In this cavern of history, voices both human and inhuman whispered secrets to those brave enough to listen. Each member present understood the gravity that pulled at their feet; no longer were they mere mortals shackled to their terrestrial plane. The digital pings and encrypted calls resonated with an implication of a cosmic agenda that would not be ignored. + +Jordan's fingers paused, hovering in hesitation. What ripple might the next keystroke send through the fabric of known existence? It was a step into the ballet of the infinite, where the Paranormal Military Squad team played their part in the waltz of wonders with an audience of stars. + +\* + +## Chapter 15 + +In the clandestine hush of Dulce Base's subterranean command center, the Paranormal Military Squad team had become a crucible for interstellar communication. Dr. Jordan Hayes' gaze lingered on the screen as they navigated through the convolution of alien code. Each character held the potential to unravel a new dimension of contact, and with Sam Rivera's keen interjection, they were crafting humanity's inaugural cosmological discourse. + +Alex Mercer peered over Jordan's shoulder, calculating the implications of every visual nuance that cascaded across the monitor. "Look for consistency—any repeating motifs could signal a willingness to engage. We're drafting history with each exchange," he remarked, aware of the delicate balance between forging a bond and exposing vulnerabilities. + +Taylor Cruz, stoic and enigmatic, observed the interplay from the threshold, a silhouette against the machinery's luminescence. "Remember, while we seek common ground, the foundation we stand upon remains Terra firma. Caution must temper our curiosity," they stated, their voice an anchor amidst the current of excitement. + +The command center buzzed with energy, rivaled only by the tempest overhead that concealed their operation. Sam, with swift dexterity, navigated the communications relay. "Their signals resonate almost musically. It's as if they're composing a symphony, and we've been handed the baton to conduct the next movement," they offered, imbuing the scenario with a blend of scientific adventurism and poetic license. + +Amidst the whirring servers and the occasional flicker of emergency lighting, the essence of their mission transcended mere reconnaissance. They were humanity's elected envoys at the brink of a celestial alliance—or confrontation—with an audience as vast as the universe itself. + +Alex stepped back, his profile etched by the chamber's artificial day. "Then let's ensure our contribution to this symphony harmonizes with theirs. It's time for humanity's voice to rise and be counted among the cosmic ensemble." + +Under his directive, the Paranormal Military Squad team initiated their calculated response, weaving thoughts and theories into a digital overture aimed at the heart of alien intellect. As the digital stream punctured the endless night, each member of this clandestine group was acutely aware of the irrevocable step they undertook—bringing Earth into the pantheon of galactic entities designed to converse among the stars. + +\* + +Clusters of high-tech equipment bathed the Dulce underground command center in an eerie blue light. Sam Rivera's fingers flew across the keyboard, navigating an elaborate network of alien patterns. The very air seemed to pulse with the ebb and flow of cryptic communications reaching across the stars. "I've got something!" Sam's announcement tore through the focus in the room, drawing every pair of eyes to the torrent of symbols unraveling on the screen. + +With the pacing of a seasoned officer gauging the moment before action, Alex Mercer approached, his calm demeanor belying an acute awareness of the precipice on which they now stood. "Define 'something," Alex prompted, reinforcing the need for clarity amidst the extraordinary. + +"It's repeating—a sequence that’s evolved with each interaction, almost as if it's... singing," Sam theorized, the awe in their voice reflecting the potential magnitude of their discovery. + +Jordan Hayes interjected from across the console, their eyes not leaving the display as they absorbed the new data. "A cosmic vocalization, then," they mused, intrigued. "A singularity in the signal that might represent a point of reference for both parties." + +Taylor Cruz, hands clasped behind their back, regarded the unfolding scene, their own calculations etching lines of concern onto their stern visage. "Or a beacon—a homing tune, calling out to something we might not be ready to greet," Taylor offered, voicing the group's unspoken apprehension. + +Alex's eyes locked on the screen, taking in the scope of what they were attempting to interpret. Drawing a deep breath, Alex gave a slight nod. "If this is their song, then let us respond with ours. We've come this far by mirroring their signals, now let's engage in an interstellar duet, and see where the music leads us." + +With the expectation of the significant achieving a crescendo, the members of Paranormal Military Squad huddled over their equipment—sages at the threshold of a potentially world-altering communion. The strange harmonies that reverberated through the command center suggested that their interlocutors were poised, waiting, perhaps even eager, for Earth's chorus to join the symphony. + +As the team initiated their reply, weaving humanity's own intricate melody into the vast cosmic dialogue, they each felt a profound change within—an evolution of purpose. They were not just messengers or investigators; they had become co-composers in a galactic orchestra, with the universe itself as their witness and concert hall. + +With the exchange of harmonious signals crawling through the vacuum of space, the Paranormal Military Squad operatives found themselves part of a bridging of minds—a realization that out there, among the vast arrays of stars and planets, harmony was the true universal language. + +\* + +The dim glow of monitors cast an otherworldly ambiance upon Dulce Base's command center, where Paranormal Military Squad's chosen stood huddled over their instruments, suspended at history's threshold. Codes—alien in origin and nature—were being deciphered by Dr. Jordan Hayes, whose countenance bore the marks of deep concentration. + +Alex Mercer, the bedrock upon which their team's resolve was founded, leaned in with an eagerness tempered by his chain of command. "Jordan, we've invested our expertise into comprehending their patterns, but now we must also endeavor to understand their intent," he urged, his voice bearing the gravitas of their mission's potential consequences. + +At another console, Sam Rivera's youth did not betray their crucial role in the operation. With eyes alight, they mirrored the rapid computing before them. "There's emotion here—complex, profound even. This isn't just the output of a cold machine; it's...sentience," Sam whispered, nearly drowned by the mechanical chorus around them. + +Jordan, without shifting focus from their work, replied, "It's a sentience that—should we succeed here—ushers us into a new era of existence. The cadence of these signals," they tapped the screen with a flourish, "could well be the heartbeat of this new dawn." + +Taylor Cruz paused beside Mercer, their expression unreadable beneath the sterile light. "And as it beats, we must gauge whether its rhythm bodes well for us, or spells our missteps. Courage must not blind us to the hazards intrinsic to such contact," Taylor cautioned, the sentinel within them ever alert. + +Alex nodded, a gesture that carried the weight of responsibility and a silent command: proceed, but with circumspection. They were not merely decoding a message; they were interpreting a dialogue across the celestial divide. + +The room fell into a rhythm akin to a well-conducted ensemble. Each member's expertise proved a critical note in the unfolding symphony. Their actions were now more than mere research or defense; they were the tentative overtures of humankind reaching out to grasp the vast unknown. + +Textures of sound meshed with the light from countless computations, the palpable anticipation of the agents at the edge of discovery cresting with an awareness that their work would reshape future chronicles. And when the response finally came—a signal piercing the deafening silence of uncertainty—all within Dulce's confines understood: the dawn of an interstellar continuum had just begun to break. + +\* + +In the sterile hum and flickering lights of Dulce Base's command center, the Paranormal Military Squad team stood as humanity's vanguard, verging on the brim of an intergalactic abyss. Dr. Jordan Hayes, analytical edges sharp, deciphered extraterrestrial patterns that bled across screens in enigmatic cascades—a daunting mosaic of potential threats and untapped wisdom. + +Agent Alex Mercer, the embodiment of focus and a steadfast nerve, observed the unfolding digital drama with the gravitas due a historic first contact. "Let the data weave its narrative, Jordan," he instructed, a moderate undertone of exhilaration within his command. "It's encoding more than information—it's outlining civilization." + +Jordan absorbed the directive, their gaze unflinching from the screens, feeling the weight of their next move. "The nuances here are extraordinary," they acknowledged. "It paints a picture of a culture steeped in complexities we're only starting to fathom.” + +Taylor Cruz, stoicism personified yet not immune to the situation's gravity, chimed in. "Understand it, but guard against it," they cautioned, bringing a sober prudence to the room. "This culture, however advanced, remains an unknown quantity—an ocean of wonders and darkness with uncertain tides." + +Sam Rivera, a visual contrast with wide eyes and restless hands, represented the other side of the room — intrigue and optimism against the drawn swords of precaution. “Think of it,” they proposed, voice bouncing with a rebellious upbeat timbre, “as the first act of a play written in constellations. We're setting the stage for a galactic narrative.” + +Each team member, in their way, was both actor and scribe in this moment of tense pageantry. Heavy with the presence of risk, the command center had become not just a room of computers and glass panels but a theater for performing the elaborate choreography of contact. + +Bound by resolve and curiosity, they proceeded, each data entry a trembling step onto the cosmic stage. And like all cautious pioneers edging into fertile but unnavigated lands, they understood: as they mapped the heavens, they were simultaneously mapping the furthest reaches of their own existential horizons. + diff --git a/graphrag/docsite/img/GraphRag-Figure1.jpg b/graphrag/docsite/img/GraphRag-Figure1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dda8c771f5731a8d8d75050d7149dcbe9e8ea776 Binary files /dev/null and b/graphrag/docsite/img/GraphRag-Figure1.jpg differ diff --git a/graphrag/docsite/img/pipeline-running.png b/graphrag/docsite/img/pipeline-running.png new file mode 100644 index 0000000000000000000000000000000000000000..7522c2a9a72924c44415a16c8628fa4c380ca0fd Binary files /dev/null and b/graphrag/docsite/img/pipeline-running.png differ diff --git a/graphrag/docsite/index.md b/graphrag/docsite/index.md new file mode 100644 index 0000000000000000000000000000000000000000..1f230c395e6e1b987f31112223491e34bd42cced --- /dev/null +++ b/graphrag/docsite/index.md @@ -0,0 +1,62 @@ +--- +title: Welcome to GraphRAG +layout: page +--- + +👉 [Microsoft Research Blog Post](https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/)
+👉 [GraphRAG Accelerator](https://github.com/Azure-Samples/graphrag-accelerator)
+👉 [GitHub Repository](https://github.com/microsoft/graphrag)
+👉 [GraphRAG Arxiv](https://arxiv.org/pdf/2404.16130) + +

+Figure 1: LLM-generated knowledge graph built from a private dataset using GPT-4 Turbo. +

+

+Figure 1: An LLM-generated knowledge graph built using GPT-4 Turbo. +

+ +GraphRAG is a structured, hierarchical approach to Retrieval Augmented Generation (RAG), as opposed to naive semantic-search +approaches using plain text snippets. The GraphRAG process involves extracting a knowledge graph out of raw text, building a community hierarchy, generating summaries for these communities, and then leveraging these structures when perform RAG-based tasks. + +To learn more about GraphRAG and how it can be used to enhance your LLMs ability to reason about your private data, please visit the [Microsoft Research Blog Post](https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/). + +## Solution Accelerator 🚀 + +To quickstart the GraphRAG system we recommend trying the [Solution Accelerator](https://github.com/Azure-Samples/graphrag-accelerator) package. This provides a user-friendly end-to-end experience with Azure resources. + +## Get Started with GraphRAG 🚀 + +To start using GraphRAG, check out the [_Get Started_](posts/get_started) guide. +For a deeper dive into the main sub-systems, please visit the docpages for the [Indexer](posts/index/overview) and [Query](posts/query/overview) packages. + +## GraphRAG vs Baseline RAG 🔍 + +Retrieval-Augmented Generation (RAG) is a technique to improve LLM outputs using real-world information. This technique is an important part of most LLM-based tools and the majority of RAG approaches use vector similarity as the search technique, which we call _Baseline RAG_. GraphRAG uses knowledge graphs to provide substantial improvements in question-and-answer performance when reasoning about complex information. RAG techniques have shown promise in helping LLMs to reason about _private datasets_ - data that the LLM is not trained on and has never seen before, such as an enterprise’s proprietary research, business documents, or communications. _Baseline RAG_ was created to help solve this problem, but we observe situations where baseline RAG performs very poorly. For example: + +- Baseline RAG struggles to connect the dots. This happens when answering a question requires traversing disparate pieces of information through their shared attributes in order to provide new synthesized insights. +- Baseline RAG performs poorly when being asked to holistically understand summarized semantic concepts over large data collections or even singular large documents. + +To address this, the tech community is working to develop methods that extend and enhance RAG. Microsoft Research’s new approach, GraphRAG, uses LLMs to create a knowledge graph based on an input corpus. This graph, along with community summaries and graph machine learning outputs, are used to augment prompts at query time. GraphRAG shows substantial improvement in answering the two classes of questions described above, demonstrating intelligence or mastery that outperforms other approaches previously applied to private datasets. + +## The GraphRAG Process 🤖 + +GraphRAG builds upon our prior [research](https://www.microsoft.com/en-us/worklab/patterns-hidden-inside-the-org-chart) and [tooling](https://github.com/graspologic-org/graspologic) using graph machine learning. The basic steps of the GraphRAG process are as follows: + +### Index + +- Slice up an input corpus into a series of TextUnits, which act as analyzable units for the rest of the process, and provide fine-grained references into our outputs. +- Extract all entities, relationships, and key claims from the TextUnits using an LLM. +- Perform a hierarchical clustering of the graph using the [Leiden technique](https://arxiv.org/pdf/1810.08473.pdf). To see this visually, check out Figure 1 above. Each circle is an entity (e.g., a person, place, or organization), with the size representing the degree of the entity, and the color representing its community. +- Generate summaries of each community and its constituents from the bottom-up. This aids in holistic understanding of the dataset. + +### Query + +At query time, these structures are used to provide materials for the LLM context window when answering a question. The primary query modes are: + +- [_Global Search_](posts/query/0-global_search) for reasoning about holistic questions about the corpus by leveraging the community summaries. +- [_Local Search_](posts/query/1-local_search) for reasoning about specific entities by fanning-out to their neighbors and associated concepts. + +### Prompt Tuning + +Using _GraphRAG_ with your data out of the box may not yield the best possible results. +We strongly recommend to fine-tune your prompts following the [Prompt Tuning Guide](posts/prompt_tuning/overview/) in our documentation. diff --git a/graphrag/docsite/nbdocsite_template/conf.json b/graphrag/docsite/nbdocsite_template/conf.json new file mode 100644 index 0000000000000000000000000000000000000000..62feba72d477f55e690f1b3e145f34bea25066fa --- /dev/null +++ b/graphrag/docsite/nbdocsite_template/conf.json @@ -0,0 +1,5 @@ +{ + "mimetypes": { + "text/markdown": true + } + } \ No newline at end of file diff --git a/graphrag/docsite/nbdocsite_template/index.md.j2 b/graphrag/docsite/nbdocsite_template/index.md.j2 new file mode 100644 index 0000000000000000000000000000000000000000..46b7b5fada21b2eddf28d677ecf11239d7b4d23d --- /dev/null +++ b/graphrag/docsite/nbdocsite_template/index.md.j2 @@ -0,0 +1,94 @@ +{% extends 'base/display_priority.j2' %} + + +{%- block header -%} +--- +title: +layout: page +tags: [post, notebook] +--- +{%- endblock header -%} + +{% block in_prompt %} +{% endblock in_prompt %} + +{% block output_prompt %} +{%- endblock output_prompt %} + +{% block input %} +``` +{%- if 'magics_language' in cell.metadata -%} + {{ cell.metadata.magics_language}} +{%- elif 'name' in nb.metadata.get('language_info', {}) -%} + {{ nb.metadata.language_info.name }} +{%- endif %} +{{ cell.source}} +``` +{% endblock input %} + +{% block error %} +{{ super() }} +{% endblock error %} + +{% block traceback_line %} +{{ line | indent | strip_ansi }} +{% endblock traceback_line %} + +{% block execute_result %} + +{% block data_priority scoped %} +{{ super() }} +{% endblock %} +{% endblock execute_result %} + +{% block stream %} +{{ output.text | indent }} +{% endblock stream %} + +{% block data_svg %} + {% if "filenames" in output.metadata %} +![svg]({{ output.metadata.filenames['image/svg+xml'] | path2url }}) + {% else %} +![svg](data:image/svg;base64,{{ output.data['image/svg+xml'] }}) + {% endif %} +{% endblock data_svg %} + +{% block data_png %} + {% if "filenames" in output.metadata %} +![png]({{ output.metadata.filenames['image/png'] | path2url }}) + {% else %} +![png](data:image/png;base64,{{ output.data['image/png'] }}) + {% endif %} +{% endblock data_png %} + +{% block data_jpg %} + {% if "filenames" in output.metadata %} +![jpeg]({{ output.metadata.filenames['image/jpeg'] | path2url }}) + {% else %} +![jpeg](data:image/jpeg;base64,{{ output.data['image/jpeg'] }}) + {% endif %} +{% endblock data_jpg %} + +{% block data_latex %} +{{ output.data['text/latex'] }} +{% endblock data_latex %} + +{% block data_html scoped %} +{{ output.data['text/html'] }} +{% endblock data_html %} + +{% block data_markdown scoped %} +{{ output.data['text/markdown'] }} +{% endblock data_markdown %} + +{% block data_text scoped %} +{{ output.data['text/plain'] | indent }} +{% endblock data_text %} + +{% block markdowncell scoped %} +{{ cell.source }} +{% endblock markdowncell %} + +{% block unknowncell scoped %} +unknown type {{ cell.type }} +{% endblock unknowncell %} \ No newline at end of file diff --git a/graphrag/docsite/package.json b/graphrag/docsite/package.json new file mode 100644 index 0000000000000000000000000000000000000000..4ed4295a349303fb6a5a726e59ef7d35b67e0725 --- /dev/null +++ b/graphrag/docsite/package.json @@ -0,0 +1,18 @@ +{ + "name": "@graphrag/docsite", + "version": "0.0.1", + "private": true, + "scripts": { + "start": "eleventy --serve", + "build": "eleventy && touch _site/.nojekyll", + "build:docs": "yarn build", + "start:docs": "yarn start" + }, + "dependencies": { + "@11ty/eleventy": "^2.0.1", + "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", + "@kevingimbel/eleventy-plugin-mermaid": "^2.2.1", + "eleventy-plugin-code-clipboard": "^0.1.1", + "markdown-it": "^14.1.0" + } +} diff --git a/graphrag/docsite/posts/config/custom.md b/graphrag/docsite/posts/config/custom.md new file mode 100644 index 0000000000000000000000000000000000000000..c6f051cdbc24a0a11648bc46a21d254d2daf8d42 --- /dev/null +++ b/graphrag/docsite/posts/config/custom.md @@ -0,0 +1,168 @@ +--- +title: Custom Configuration Mode +navtitle: Fully Custom Config +layout: page +tags: [post] +date: 2023-01-04 +--- + +The primary configuration sections for Indexing Engine pipelines are described below. Each configuration section can be expressed in Python (for use in Python API mode) as well as YAML, but YAML is show here for brevity. + +Using custom configuration is an advanced use-case. Most users will want to use the [Default Configuration](/posts/config/overview) instead. + +## Indexing Engine Examples + +The [examples](https://github.com/microsoft/graphrag/blob/main/examples/) directory contains several examples of how to use the indexing engine with _custom configuration_. + +Most examples include two different forms of running the pipeline, both are contained in the examples `run.py` + +1. Using mostly the Python API +2. Using mostly the a pipeline configuration file + +To run an example: + +- Run `poetry shell` to activate a virtual environment with the required dependencies. +- Run `PYTHONPATH="$(pwd)" python examples/path_to_example/run.py` from the `root` directory. + +For example to run the single_verb example, you would run the following commands: + +```bash +poetry shell +``` + +```sh +PYTHONPATH="$(pwd)" python examples/single_verb/run.py +``` + +# Configuration Sections + +# > extends + +This configuration allows you to extend a base configuration file or files. + +```yaml +# single base +extends: ../base_config.yml +``` + +```yaml +# multiple bases +extends: + - ../base_config.yml + - ../base_config2.yml +``` + +# > root_dir + +This configuration allows you to set the root directory for the pipeline. All data inputs and outputs are assumed to be relative to this path. + +```yaml +root_dir: /workspace/data_project +``` + +# > storage + +This configuration allows you define the output strategy for the pipeline. + +- `type`: The type of storage to use. Options are `file`, `memory`, and `blob` +- `base_dir` (`type: file` only): The base directory to store the data in. This is relative to the config root. +- `connection_string` (`type: blob` only): The connection string to use for blob storage. +- `container_name` (`type: blob` only): The container to use for blob storage. + +# > cache + +This configuration allows you define the cache strategy for the pipeline. + +- `type`: The type of cache to use. Options are `file` and `memory`, and `blob`. +- `base_dir` (`type: file` only): The base directory to store the cache in. This is relative to the config root. +- `connection_string` (`type: blob` only): The connection string to use for blob storage. +- `container_name` (`type: blob` only): The container to use for blob storage. + +# > reporting + +This configuration allows you define the reporting strategy for the pipeline. Report files are generated artifacts that summarize the performance metrics of the pipeline and emit any error messages. + +- `type`: The type of reporting to use. Options are `file`, `memory`, and `blob` +- `base_dir` (`type: file` only): The base directory to store the reports in. This is relative to the config root. +- `connection_string` (`type: blob` only): The connection string to use for blob storage. +- `container_name` (`type: blob` only): The container to use for blob storage. + +# > workflows + +This configuration section defines the workflow DAG for the pipeline. Here we define an array of workflows and express their inter-dependencies in steps: + +- `name`: The name of the workflow. This is used to reference the workflow in other parts of the config. +- `steps`: The DataShaper steps that this workflow comprises. If a step defines an input in the form of `workflow:`, then it is assumed to have a dependency on the output of that workflow. + +```yaml +workflows: + - name: workflow1 + steps: + - verb: derive + args: + column1: "col1" + column2: "col2" + - name: workflow2 + steps: + - verb: derive + args: + column1: "col1" + column2: "col2" + input: + # dependency established here + source: workflow:workflow1 +``` + +# > input + +- `type`: The type of input to use. Options are `file` or `blob`. +- `file_type`: The file type field discriminates between the different input types. Options are `csv` and `text`. +- `base_dir`: The base directory to read the input files from. This is relative to the config file. +- `file_pattern`: A regex to match the input files. The regex must have named groups for each of the fields in the file_filter. +- `post_process`: A DataShaper workflow definition to apply to the input before executing the primary workflow. +- `source_column` (`type: csv` only): The column containing the source/author of the data +- `text_column` (`type: csv` only): The column containing the text of the data +- `timestamp_column` (`type: csv` only): The column containing the timestamp of the data +- `timestamp_format` (`type: csv` only): The format of the timestamp + +```yaml +input: + type: file + file_type: csv + base_dir: ../data/csv # the directory containing the CSV files, this is relative to the config file + file_pattern: '.*[\/](?P[^\/]+)[\/](?P\d{4})-(?P\d{2})-(?P\d{2})_(?P[^_]+)_\d+\.csv$' # a regex to match the CSV files + # An additional file filter which uses the named groups from the file_pattern to further filter the files + # file_filter: + # # source: (source_filter) + # year: (2023) + # month: (06) + # # day: (22) + source_column: "author" # the column containing the source/author of the data + text_column: "message" # the column containing the text of the data + timestamp_column: "date(yyyyMMddHHmmss)" # optional, the column containing the timestamp of the data + timestamp_format: "%Y%m%d%H%M%S" # optional, the format of the timestamp + post_process: # Optional, set of steps to process the data before going into the workflow + - verb: filter + args: + column: "title", + value: "My document" +``` + +```yaml +input: + type: file + file_type: csv + base_dir: ../data/csv # the directory containing the CSV files, this is relative to the config file + file_pattern: '.*[\/](?P[^\/]+)[\/](?P\d{4})-(?P\d{2})-(?P\d{2})_(?P[^_]+)_\d+\.csv$' # a regex to match the CSV files + # An additional file filter which uses the named groups from the file_pattern to further filter the files + # file_filter: + # # source: (source_filter) + # year: (2023) + # month: (06) + # # day: (22) + post_process: # Optional, set of steps to process the data before going into the workflow + - verb: filter + args: + column: "title", + value: "My document" +``` diff --git a/graphrag/docsite/posts/config/env_vars.md b/graphrag/docsite/posts/config/env_vars.md new file mode 100644 index 0000000000000000000000000000000000000000..0dd133d6c9865a1524f25dd31f2d71d4755ff4a4 --- /dev/null +++ b/graphrag/docsite/posts/config/env_vars.md @@ -0,0 +1,220 @@ +--- +title: Default Configuration Mode (using Env Vars) +navtitle: Using Env Vars +tags: [post] +layout: page +date: 2023-01-03 +--- + +## Text-Embeddings Customization + +By default, the GraphRAG indexer will only emit embeddings required for our query methods. However, the model has embeddings defined for all plaintext fields, and these can be generated by setting the `GRAPHRAG_EMBEDDING_TARGET` environment variable to `all`. + +If the embedding target is `all`, and you want to only embed a subset of these fields, you may specify which embeddings to skip using the `GRAPHRAG_EMBEDDING_SKIP` argument described below. + +### Embedded Fields + +- `text_unit.text` +- `document.raw_content` +- `entity.name` +- `entity.description` +- `relationship.description` +- `community.title` +- `community.summary` +- `community.full_content` + +## Input Data + +Our pipeline can ingest .csv or .txt data from an input folder. These files can be nested within subfolders. To configure how input data is handled, what fields are mapped over, and how timestamps are parsed, look for configuration values starting with `GRAPHRAG_INPUT_` below. In general, CSV-based data provides the most customizeability. Each CSV should at least contain a `text` field (which can be mapped with environment variables), but it's helpful if they also have `title`, `timestamp`, and `source` fields. Additional fields can be included as well, which will land as extra fields on the `Document` table. + +## Base LLM Settings + +These are the primary settings for configuring LLM connectivity. + +| Parameter | Required? | Description | Type | Default Value | +| --------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ----- | ------------- | +| `GRAPHRAG_API_KEY` | **Yes for OpenAI. Optional for AOAI** | The API key. (Note: `OPENAI_API_KEY is also used as a fallback). If not defined when using AOAI, managed identity will be used. | `str` | `None` | +| `GRAPHRAG_API_BASE` | **For AOAI** | The API Base URL | `str` | `None` | +| `GRAPHRAG_API_VERSION` | **For AOAI** | The AOAI API version. | `str` | `None` | +| `GRAPHRAG_API_ORGANIZATION` | | The AOAI organization. | `str` | `None` | +| `GRAPHRAG_API_PROXY` | | The AOAI proxy. | `str` | `None` | + +## Text Generation Settings + +These settings control the text generation model used by the pipeline. Any settings with a fallback will use the base LLM settings, if available. + +| Parameter | Required? | Description | Type | Default Value | +| ------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------ | ------- | --------------------- | +| `GRAPHRAG_LLM_TYPE` | **For AOAI** | The LLM operation type. Either `openai_chat` or `azure_openai_chat` | `str` | `openai_chat` | +| `GRAPHRAG_LLM_DEPLOYMENT_NAME` | **For AOAI** | The AOAI model deployment name. | `str` | `None` | +| `GRAPHRAG_LLM_API_KEY` | Yes (uses fallback) | The API key. If not defined when using AOAI, managed identity will be used. | `str` | `None` | +| `GRAPHRAG_LLM_API_BASE` | For AOAI (uses fallback) | The API Base URL | `str` | `None` | +| `GRAPHRAG_LLM_API_VERSION` | For AOAI (uses fallback) | The AOAI API version. | `str` | `None` | +| `GRAPHRAG_LLM_API_ORGANIZATION` | For AOAI (uses fallback) | The AOAI organization. | `str` | `None` | +| `GRAPHRAG_LLM_API_PROXY` | | The AOAI proxy. | `str` | `None` | +| `GRAPHRAG_LLM_MODEL` | | The LLM model. | `str` | `gpt-4-turbo-preview` | +| `GRAPHRAG_LLM_MAX_TOKENS` | | The maximum number of tokens. | `int` | `4000` | +| `GRAPHRAG_LLM_REQUEST_TIMEOUT` | | The maximum number of seconds to wait for a response from the chat client. | `int` | `180` | +| `GRAPHRAG_LLM_MODEL_SUPPORTS_JSON` | | Indicates whether the given model supports JSON output mode. `True` to enable. | `str` | `None` | +| `GRAPHRAG_LLM_THREAD_COUNT` | | The number of threads to use for LLM parallelization. | `int` | 50 | +| `GRAPHRAG_LLM_THREAD_STAGGER` | | The time to wait (in seconds) between starting each thread. | `float` | 0.3 | +| `GRAPHRAG_LLM_CONCURRENT_REQUESTS` | | The number of concurrent requests to allow for the embedding client. | `int` | 25 | +| `GRAPHRAG_LLM_TOKENS_PER_MINUTE` | | The number of tokens per minute to allow for the LLM client. 0 = Bypass | `int` | 0 | +| `GRAPHRAG_LLM_REQUESTS_PER_MINUTE` | | The number of requests per minute to allow for the LLM client. 0 = Bypass | `int` | 0 | +| `GRAPHRAG_LLM_MAX_RETRIES` | | The maximum number of retries to attempt when a request fails. | `int` | 10 | +| `GRAPHRAG_LLM_MAX_RETRY_WAIT` | | The maximum number of seconds to wait between retries. | `int` | 10 | +| `GRAPHRAG_LLM_SLEEP_ON_RATE_LIMIT_RECOMMENDATION` | | Whether to sleep on rate limit recommendation. (Azure Only) | `bool` | `True` | +| `GRAPHRAG_LLM_TEMPERATURE` | | The temperature to use generation. | `float` | 0 | +| `GRAPHRAG_LLM_TOP_P` | | The top_p to use for sampling. | `float` | 1 | +| `GRAPHRAG_LLM_N` | | The number of responses to generate. | `int` | 1 | + +## Text Embedding Settings + +These settings control the text embedding model used by the pipeline. Any settings with a fallback will use the base LLM settings, if available. + +| Parameter | Required ? | Description | Type | Default | +| ------------------------------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------- | ------- | ------------------------ | +| `GRAPHRAG_EMBEDDING_TYPE` | **For AOAI** | The embedding client to use. Either `openai_embedding` or `azure_openai_embedding` | `str` | `openai_embedding` | +| `GRAPHRAG_EMBEDDING_DEPLOYMENT_NAME` | **For AOAI** | The AOAI deployment name. | `str` | `None` | +| `GRAPHRAG_EMBEDDING_API_KEY` | Yes (uses fallback) | The API key to use for the embedding client. If not defined when using AOAI, managed identity will be used. | `str` | `None` | +| `GRAPHRAG_EMBEDDING_API_BASE` | For AOAI (uses fallback) | The API base URL. | `str` | `None` | +| `GRAPHRAG_EMBEDDING_API_VERSION` | For AOAI (uses fallback) | The AOAI API version to use for the embedding client. | `str` | `None` | +| `GRAPHRAG_EMBEDDING_API_ORGANIZATION` | For AOAI (uses fallback) | The AOAI organization to use for the embedding client. | `str` | `None` | +| `GRAPHRAG_EMBEDDING_API_PROXY` | | The AOAI proxy to use for the embedding client. | `str` | `None` | +| `GRAPHRAG_EMBEDDING_MODEL` | | The model to use for the embedding client. | `str` | `text-embedding-3-small` | +| `GRAPHRAG_EMBEDDING_BATCH_SIZE` | | The number of texts to embed at once. [(Azure limit is 16)](https://learn.microsoft.com/en-us/azure/ai-ce) | `int` | 16 | +| `GRAPHRAG_EMBEDDING_BATCH_MAX_TOKENS` | | The maximum tokens per batch [(Azure limit is 8191)](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference) | `int` | 8191 | +| `GRAPHRAG_EMBEDDING_TARGET` | | The target fields to embed. Either `required` or `all`. | `str` | `required` | +| `GRAPHRAG_EMBEDDING_SKIP` | | A comma-separated list of fields to skip embeddings for . (e.g. 'relationship.description') | `str` | `None` | +| `GRAPHRAG_EMBEDDING_THREAD_COUNT` | | The number of threads to use for parallelization for embeddings. | `int` | | +| `GRAPHRAG_EMBEDDING_THREAD_STAGGER` | | The time to wait (in seconds) between starting each thread for embeddings. | `float` | 50 | +| `GRAPHRAG_EMBEDDING_CONCURRENT_REQUESTS` | | The number of concurrent requests to allow for the embedding client. | `int` | 25 | +| `GRAPHRAG_EMBEDDING_TOKENS_PER_MINUTE` | | The number of tokens per minute to allow for the embedding client. 0 = Bypass | `int` | 0 | +| `GRAPHRAG_EMBEDDING_REQUESTS_PER_MINUTE` | | The number of requests per minute to allow for the embedding client. 0 = Bypass | `int` | 0 | +| `GRAPHRAG_EMBEDDING_MAX_RETRIES` | | The maximum number of retries to attempt when a request fails. | `int` | 10 | +| `GRAPHRAG_EMBEDDING_MAX_RETRY_WAIT` | | The maximum number of seconds to wait between retries. | `int` | 10 | +| `GRAPHRAG_EMBEDDING_TARGET` | | The target fields to embed. Either `required` or `all`. | `str` | `required` | +| `GRAPHRAG_EMBEDDING_SLEEP_ON_RATE_LIMIT_RECOMMENDATION` | | Whether to sleep on rate limit recommendation. (Azure Only) | `bool` | `True` | + +## Input Settings + +These settings control the data input used by the pipeline. Any settings with a fallback will use the base LLM settings, if available. + +### Plaintext Input Data (`GRAPHRAG_INPUT_FILE_TYPE`=text) + +| Parameter | Description | Type | Required or Optional | Default | +| ----------------------------- | --------------------------------------------------------------------------------- | ----- | -------------------- | ---------- | +| `GRAPHRAG_INPUT_FILE_PATTERN` | The file pattern regexp to use when reading input files from the input directory. | `str` | optional | `.*\.txt$` | + +### CSV Input Data (`GRAPHRAG_INPUT_FILE_TYPE`=csv) + +| Parameter | Description | Type | Required or Optional | Default | +| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----- | -------------------- | ---------- | +| `GRAPHRAG_INPUT_TYPE` | The input storage type to use when reading files. (`file` or `blob`) | `str` | optional | `file` | +| `GRAPHRAG_INPUT_FILE_PATTERN` | The file pattern regexp to use when reading input files from the input directory. | `str` | optional | `.*\.txt$` | +| `GRAPHRAG_INPUT_SOURCE_COLUMN` | The 'source' column to use when reading CSV input files. | `str` | optional | `source` | +| `GRAPHRAG_INPUT_TIMESTAMP_COLUMN` | The 'timestamp' column to use when reading CSV input files. | `str` | optional | `None` | +| `GRAPHRAG_INPUT_TIMESTAMP_FORMAT` | The timestamp format to use when parsing timestamps in the timestamp column. | `str` | optional | `None` | +| `GRAPHRAG_INPUT_TEXT_COLUMN` | The 'text' column to use when reading CSV input files. | `str` | optional | `text` | +| `GRAPHRAG_INPUT_DOCUMENT_ATTRIBUTE_COLUMNS` | A list of CSV columns, comma-separated, to incorporate as document fields. | `str` | optional | `id` | +| `GRAPHRAG_INPUT_TITLE_COLUMN` | The 'title' column to use when reading CSV input files. | `str` | optional | `title` | +| `GRAPHRAG_INPUT_STORAGE_ACCOUNT_BLOB_URL` | The Azure Storage blob endpoint to use when in `blob` mode and using managed identity. Will have the format `https://.blob.core.windows.net` | `str` | optional | `None` | +| `GRAPHRAG_INPUT_CONNECTION_STRING` | The connection string to use when reading CSV input files from Azure Blob Storage. | `str` | optional | `None` | +| `GRAPHRAG_INPUT_CONTAINER_NAME` | The container name to use when reading CSV input files from Azure Blob Storage. | `str` | optional | `None` | +| `GRAPHRAG_INPUT_BASE_DIR` | The base directory to read input files from. | `str` | optional | `None` | + +## Data Mapping Settings + +| Parameter | Description | Type | Required or Optional | Default | +| -------------------------- | -------------------------------------------------------- | ----- | -------------------- | ------- | +| `GRAPHRAG_INPUT_FILE_TYPE` | The type of input data, `csv` or `text` | `str` | optional | `text` | +| `GRAPHRAG_INPUT_ENCODING` | The encoding to apply when reading CSV/text input files. | `str` | optional | `utf-8` | + +## Data Chunking + +| Parameter | Description | Type | Required or Optional | Default | +| --------------------------- | ------------------------------------------------------------------------------------------- | ----- | -------------------- | ------- | +| `GRAPHRAG_CHUNK_SIZE` | The chunk size in tokens for text-chunk analysis windows. | `str` | optional | 1200 | +| `GRAPHRAG_CHUNK_OVERLAP` | The chunk overlap in tokens for text-chunk analysis windows. | `str` | optional | 100 | +| `GRAPHRAG_CHUNK_BY_COLUMNS` | A comma-separated list of document attributes to groupby when performing TextUnit chunking. | `str` | optional | `id` | + +## Prompting Overrides + +| Parameter | Description | Type | Required or Optional | Default | +| --------------------------------------------- | ------------------------------------------------------------------------------------------ | -------- | -------------------- | ---------------------------------------------------------------- | +| `GRAPHRAG_ENTITY_EXTRACTION_PROMPT_FILE` | The path (relative to the root) of an entity extraction prompt template text file. | `str` | optional | `None` | +| `GRAPHRAG_ENTITY_EXTRACTION_MAX_GLEANINGS` | The maximum number of redrives (gleanings) to invoke when extracting entities in a loop. | `int` | optional | 1 | +| `GRAPHRAG_ENTITY_EXTRACTION_ENTITY_TYPES` | A comma-separated list of entity types to extract. | `str` | optional | `organization,person,event,geo` | +| `GRAPHRAG_SUMMARIZE_DESCRIPTIONS_PROMPT_FILE` | The path (relative to the root) of an description summarization prompt template text file. | `str` | optional | `None` | +| `GRAPHRAG_SUMMARIZE_DESCRIPTIONS_MAX_LENGTH` | The maximum number of tokens to generate per description summarization. | `int` | optional | 500 | +| `GRAPHRAG_CLAIM_EXTRACTION_ENABLED` | Whether claim extraction is enabled for this pipeline. | `bool` | optional | `False` | +| `GRAPHRAG_CLAIM_EXTRACTION_DESCRIPTION` | The claim_description prompting argument to utilize. | `string` | optional | "Any claims or facts that could be relevant to threat analysis." | +| `GRAPHRAG_CLAIM_EXTRACTION_PROMPT_FILE` | The claim extraction prompt to utilize. | `string` | optional | `None` | +| `GRAPHRAG_CLAIM_EXTRACTION_MAX_GLEANINGS` | The maximum number of redrives (gleanings) to invoke when extracting claims in a loop. | `int` | optional | 1 | +| `GRAPHRAG_COMMUNITY_REPORTS_PROMPT_FILE` | The community reports extraction prompt to utilize. | `string` | optional | `None` | +| `GRAPHRAG_COMMUNITY_REPORTS_MAX_LENGTH` | The maximum number of tokens to generate per community reports. | `int` | optional | 1500 | + +## Storage + +This section controls the storage mechanism used by the pipeline used for emitting output tables. + +| Parameter | Description | Type | Required or Optional | Default | +| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----- | -------------------- | ------- | +| `GRAPHRAG_STORAGE_TYPE` | The type of reporter to use. Options are `file`, `memory`, or `blob` | `str` | optional | `file` | +| `GRAPHRAG_STORAGE_STORAGE_ACCOUNT_BLOB_URL` | The Azure Storage blob endpoint to use when in `blob` mode and using managed identity. Will have the format `https://.blob.core.windows.net` | `str` | optional | None | +| `GRAPHRAG_STORAGE_CONNECTION_STRING` | The Azure Storage connection string to use when in `blob` mode. | `str` | optional | None | +| `GRAPHRAG_STORAGE_CONTAINER_NAME` | The Azure Storage container name to use when in `blob` mode. | `str` | optional | None | +| `GRAPHRAG_STORAGE_BASE_DIR` | The base path to data outputs outputs. | `str` | optional | None | + +## Cache + +This section controls the cache mechanism used by the pipeline. This is used to cache LLM invocation results. + +| Parameter | Description | Type | Required or Optional | Default | +| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----- | -------------------- | ------- | +| `GRAPHRAG_CACHE_TYPE` | The type of cache to use. Options are `file`, `memory`, `none` or `blob` | `str` | optional | `file` | +| `GRAPHRAG_CACHE_STORAGE_ACCOUNT_BLOB_URL` | The Azure Storage blob endpoint to use when in `blob` mode and using managed identity. Will have the format `https://.blob.core.windows.net` | `str` | optional | None | +| `GRAPHRAG_CACHE_CONNECTION_STRING` | The Azure Storage connection string to use when in `blob` mode. | `str` | optional | None | +| `GRAPHRAG_CACHE_CONTAINER_NAME` | The Azure Storage container name to use when in `blob` mode. | `str` | optional | None | +| `GRAPHRAG_CACHE_BASE_DIR` | The base path to the reporting outputs. | `str` | optional | None | + +## Reporting + +This section controls the reporting mechanism used by the pipeline, for common events and error messages. The default is to write reports to a file in the output directory. However, you can also choose to write reports to the console or to an Azure Blob Storage container. + +| Parameter | Description | Type | Required or Optional | Default | +| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----- | -------------------- | ------- | +| `GRAPHRAG_REPORTING_TYPE` | The type of reporter to use. Options are `file`, `console`, or `blob` | `str` | optional | `file` | +| `GRAPHRAG_REPORTING_STORAGE_ACCOUNT_BLOB_URL` | The Azure Storage blob endpoint to use when in `blob` mode and using managed identity. Will have the format `https://.blob.core.windows.net` | `str` | optional | None | +| `GRAPHRAG_REPORTING_CONNECTION_STRING` | The Azure Storage connection string to use when in `blob` mode. | `str` | optional | None | +| `GRAPHRAG_REPORTING_CONTAINER_NAME` | The Azure Storage container name to use when in `blob` mode. | `str` | optional | None | +| `GRAPHRAG_REPORTING_BASE_DIR` | The base path to the reporting outputs. | `str` | optional | None | + +## Node2Vec Parameters + +| Parameter | Description | Type | Required or Optional | Default | +| ------------------------------- | ---------------------------------------- | ------ | -------------------- | ------- | +| `GRAPHRAG_NODE2VEC_ENABLED` | Whether to enable Node2Vec | `bool` | optional | False | +| `GRAPHRAG_NODE2VEC_NUM_WALKS` | The Node2Vec number of walks to perform | `int` | optional | 10 | +| `GRAPHRAG_NODE2VEC_WALK_LENGTH` | The Node2Vec walk length | `int` | optional | 40 | +| `GRAPHRAG_NODE2VEC_WINDOW_SIZE` | The Node2Vec window size | `int` | optional | 2 | +| `GRAPHRAG_NODE2VEC_ITERATIONS` | The number of iterations to run node2vec | `int` | optional | 3 | +| `GRAPHRAG_NODE2VEC_RANDOM_SEED` | The random seed to use for node2vec | `int` | optional | 597832 | + +## Data Snapshotting + +| Parameter | Description | Type | Required or Optional | Default | +| ----------------------------------- | ------------------------------------------- | ------ | -------------------- | ------- | +| `GRAPHRAG_SNAPSHOT_GRAPHML` | Whether to enable GraphML snapshots. | `bool` | optional | False | +| `GRAPHRAG_SNAPSHOT_RAW_ENTITIES` | Whether to enable raw entity snapshots. | `bool` | optional | False | +| `GRAPHRAG_SNAPSHOT_TOP_LEVEL_NODES` | Whether to enable top-level node snapshots. | `bool` | optional | False | + +# Miscellaneous Settings + +| Parameter | Description | Type | Required or Optional | Default | +| --------------------------- | --------------------------------------------------------------------- | ------ | -------------------- | ------------- | +| `GRAPHRAG_ASYNC_MODE` | Which async mode to use. Either `asyncio` or `threaded`. | `str` | optional | `asyncio` | +| `GRAPHRAG_ENCODING_MODEL` | The text encoding model, used in tiktoken, to encode text. | `str` | optional | `cl100k_base` | +| `GRAPHRAG_MAX_CLUSTER_SIZE` | The maximum number of entities to include in a single Leiden cluster. | `int` | optional | 10 | +| `GRAPHRAG_SKIP_WORKFLOWS` | A comma-separated list of workflow names to skip. | `str` | optional | `None` | +| `GRAPHRAG_UMAP_ENABLED` | Whether to enable UMAP layouts | `bool` | optional | False | diff --git a/graphrag/docsite/posts/config/init.md b/graphrag/docsite/posts/config/init.md new file mode 100644 index 0000000000000000000000000000000000000000..afaa571254ac874e5bb40d988db4d88f0d6e7fcd --- /dev/null +++ b/graphrag/docsite/posts/config/init.md @@ -0,0 +1,38 @@ +--- +title: Configuring GraphRAG Indexing +navtitle: Init Command +tags: [post] +layout: page +date: 2023-01-03 +--- + +To start using GraphRAG, you need to configure the system. The `init` command is the easiest way to get started. It will create a `.env` and `settings.yaml` files in the specified directory with the necessary configuration settings. It will also output the default LLM prompts used by GraphRAG. + +## Usage + +```sh +python -m graphrag.index [--init] [--root PATH] +``` + +## Options + +- `--init` - Initialize the directory with the necessary configuration files. +- `--root PATH` - The root directory to initialize. Default is the current directory. + +## Example + +```sh +python -m graphrag.index --init --root ./ragtest +``` + +## Output + +The `init` command will create the following files in the specified directory: + +- `settings.yaml` - The configuration settings file. This file contains the configuration settings for GraphRAG. +- `.env` - The environment variables file. These are referenced in the `settings.yaml` file. +- `prompts/` - The LLM prompts folder. This contains the default prompts used by GraphRAG, you can modify them or run the [Auto Prompt Tuning](/posts/prompt_tuning/auto_prompt_tuning) command to generate new prompts adapted to your data. + +## Next Steps + +After initializing your workspace, you can either run the [Prompt Tuning](/posts/prompt_tuning/auto_prompt_tuning) command to adapt the prompts to your data or even start running the [Indexing Pipeline](/posts/index/overview) to index your data. For more information on configuring GraphRAG, see the [Configuration](/posts/config/overview) documentation. diff --git a/graphrag/docsite/posts/config/json_yaml.md b/graphrag/docsite/posts/config/json_yaml.md new file mode 100644 index 0000000000000000000000000000000000000000..b1350cded0cefdf9fbaf5ff5031c2d71adb92067 --- /dev/null +++ b/graphrag/docsite/posts/config/json_yaml.md @@ -0,0 +1,224 @@ +--- +title: Default Configuration Mode (using JSON/YAML) +navtitle: Using JSON or YAML +tags: [post] +layout: page +date: 2023-01-03 +--- + +The default configuration mode may be configured by using a `config.json` or `config.yml` file in the data project root. If a `.env` file is present along with this config file, then it will be loaded, and the environment variables defined therein will be available for token replacements in your configuration document using `${ENV_VAR}` syntax. + +For example: + +``` +# .env +API_KEY=some_api_key + +# config.json +{ + "llm": { + "api_key": "${API_KEY}" + } +} +``` + +# Config Sections + +## input + +### Fields + +- `type` **file|blob** - The input type to use. Default=`file` +- `file_type` **text|csv** - The type of input data to load. Either `text` or `csv`. Default is `text` +- `file_encoding` **str** - The encoding of the input file. Default is `utf-8` +- `file_pattern` **str** - A regex to match input files. Default is `.*\.csv$` if in csv mode and `.*\.txt$` if in text mode. +- `source_column` **str** - (CSV Mode Only) The source column name. +- `timestamp_column` **str** - (CSV Mode Only) The timestamp column name. +- `timestamp_format` **str** - (CSV Mode Only) The source format. +- `text_column` **str** - (CSV Mode Only) The text column name. +- `title_column` **str** - (CSV Mode Only) The title column name. +- `document_attribute_columns` **list[str]** - (CSV Mode Only) The additional document attributes to include. +- `connection_string` **str** - (blob only) The Azure Storage connection string. +- `container_name` **str** - (blob only) The Azure Storage container name. +- `base_dir` **str** - The base directory to read input from, relative to the root. +- `storage_account_blob_url` **str** - The storage account blob URL to use. + +## llm + +This is the base LLM configuration section. Other steps may override this configuration with their own LLM configuration. + +### Fields + +- `api_key` **str** - The OpenAI API key to use. +- `type` **openai_chat|azure_openai_chat|openai_embedding|azure_openai_embedding** - The type of LLM to use. +- `model` **str** - The model name. +- `max_tokens` **int** - The maximum number of output tokens. +- `request_timeout` **float** - The per-request timeout. +- `api_base` **str** - The API base url to use. +- `api_version` **str** - The API version +- `organization` **str** - The client organization. +- `proxy` **str** - The proxy URL to use. +- `cognitive_services_endpoint` **str** - The url endpoint for cognitive services. +- `deployment_name` **str** - The deployment name to use (Azure). +- `model_supports_json` **bool** - Whether the model supports JSON-mode output. +- `tokens_per_minute` **int** - Set a leaky-bucket throttle on tokens-per-minute. +- `requests_per_minute` **int** - Set a leaky-bucket throttle on requests-per-minute. +- `max_retries` **int** - The maximum number of retries to use. +- `max_retry_wait` **float** - The maximum backoff time. +- `sleep_on_rate_limit_recommendation` **bool** - Whether to adhere to sleep recommendations (Azure). +- `concurrent_requests` **int** The number of open requests to allow at once. +- `temperature` **float** - The temperature to use. +- `top_p` **float** - The top-p value to use. +- `n` **int** - The number of completions to generate. + +## parallelization + +### Fields + +- `stagger` **float** - The threading stagger value. +- `num_threads` **int** - The maximum number of work threads. + +## async_mode + +**asyncio|threaded** The async mode to use. Either `asyncio` or `threaded. + +## embeddings + +### Fields + +- `llm` (see LLM top-level config) +- `parallelization` (see Parallelization top-level config) +- `async_mode` (see Async Mode top-level config) +- `batch_size` **int** - The maximum batch size to use. +- `batch_max_tokens` **int** - The maximum batch #-tokens. +- `target` **required|all** - Determines which set of embeddings to emit. +- `skip` **list[str]** - Which embeddings to skip. +- `strategy` **dict** - Fully override the text-embedding strategy. + +## chunks + +### Fields + +- `size` **int** - The max chunk size in tokens. +- `overlap` **int** - The chunk overlap in tokens. +- `group_by_columns` **list[str]** - group documents by fields before chunking. +- `strategy` **dict** - Fully override the chunking strategy. + +## cache + +### Fields + +- `type` **file|memory|none|blob** - The cache type to use. Default=`file` +- `connection_string` **str** - (blob only) The Azure Storage connection string. +- `container_name` **str** - (blob only) The Azure Storage container name. +- `base_dir` **str** - The base directory to write cache to, relative to the root. +- `storage_account_blob_url` **str** - The storage account blob URL to use. + +## storage + +### Fields + +- `type` **file|memory|blob** - The storage type to use. Default=`file` +- `connection_string` **str** - (blob only) The Azure Storage connection string. +- `container_name` **str** - (blob only) The Azure Storage container name. +- `base_dir` **str** - The base directory to write reports to, relative to the root. +- `storage_account_blob_url` **str** - The storage account blob URL to use. + +## reporting + +### Fields + +- `type` **file|console|blob** - The reporting type to use. Default=`file` +- `connection_string` **str** - (blob only) The Azure Storage connection string. +- `container_name` **str** - (blob only) The Azure Storage container name. +- `base_dir` **str** - The base directory to write reports to, relative to the root. +- `storage_account_blob_url` **str** - The storage account blob URL to use. + +## entity_extraction + +### Fields + +- `llm` (see LLM top-level config) +- `parallelization` (see Parallelization top-level config) +- `async_mode` (see Async Mode top-level config) +- `prompt` **str** - The prompt file to use. +- `entity_types` **list[str]** - The entity types to identify. +- `max_gleanings` **int** - The maximum number of gleaning cycles to use. +- `strategy` **dict** - Fully override the entity extraction strategy. + +## summarize_descriptions + +### Fields + +- `llm` (see LLM top-level config) +- `parallelization` (see Parallelization top-level config) +- `async_mode` (see Async Mode top-level config) +- `prompt` **str** - The prompt file to use. +- `max_length` **int** - The maximum number of output tokens per summarization. +- `strategy` **dict** - Fully override the summarize description strategy. + +## claim_extraction + +### Fields + +- `enabled` **bool** - Whether to enable claim extraction. default=False +- `llm` (see LLM top-level config) +- `parallelization` (see Parallelization top-level config) +- `async_mode` (see Async Mode top-level config) +- `prompt` **str** - The prompt file to use. +- `description` **str** - Describes the types of claims we want to extract. +- `max_gleanings` **int** - The maximum number of gleaning cycles to use. +- `strategy` **dict** - Fully override the claim extraction strategy. + +## community_reports + +### Fields + +- `llm` (see LLM top-level config) +- `parallelization` (see Parallelization top-level config) +- `async_mode` (see Async Mode top-level config) +- `prompt` **str** - The prompt file to use. +- `max_length` **int** - The maximum number of output tokens per report. +- `max_input_length` **int** - The maximum number of input tokens to use when generating reports. +- `strategy` **dict** - Fully override the community reports strategy. + +## cluster_graph + +### Fields + +- `max_cluster_size` **int** - The maximum cluster size to emit. +- `strategy` **dict** - Fully override the cluster_graph strategy. + +## embed_graph + +### Fields + +- `enabled` **bool** - Whether to enable graph embeddings. +- `num_walks` **int** - The node2vec number of walks. +- `walk_length` **int** - The node2vec walk length. +- `window_size` **int** - The node2vec window size. +- `iterations` **int** - The node2vec number of iterations. +- `random_seed` **int** - The node2vec random seed. +- `strategy` **dict** - Fully override the embed graph strategy. + +## umap + +### Fields + +- `enabled` **bool** - Whether to enable UMAP layouts. + +## snapshots + +### Fields + +- `graphml` **bool** - Emit graphml snapshots. +- `raw_entities` **bool** - Emit raw entity snapshots. +- `top_level_nodes` **bool** - Emit top-level-node snapshots. + +## encoding_model + +**str** - The text encoding model to use. Default is `cl100k_base`. + +## skip_workflows + +**list[str]** - Which workflow names to skip. diff --git a/graphrag/docsite/posts/config/overview.md b/graphrag/docsite/posts/config/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..ce13d41ee91a194f2c310be295b6b64c2b753e48 --- /dev/null +++ b/graphrag/docsite/posts/config/overview.md @@ -0,0 +1,21 @@ +--- +title: Configuring GraphRAG Indexing +navtitle: Configuration +tags: [post] +layout: page +date: 2023-01-03 +--- + +The GraphRAG system is highly configurable. This page provides an overview of the configuration options available for the GraphRAG indexing engine. + +## Default Configuration Mode + +The default configuration mode is the simplest way to get started with the GraphRAG system. It is designed to work out-of-the-box with minimal configuration. The primary configuration sections for the Indexing Engine pipelines are described below. The main ways to set up GraphRAG in Default Configuration mode are via: + +- [Init command](/posts/config/init) (recommended) +- [Purely using environment variables](/posts/config/env_vars) +- [Using JSON or YAML for deeper control](/posts/config/json_yaml) + +## Custom Configuration Mode + +Custom configuration mode is an advanced use-case. Most users will want to use the Default Configuration instead. The primary configuration sections for Indexing Engine pipelines are described below. Details about how to use custom configuration are available in the [Custom Configuration Mode](/posts/config/custom) documentation. diff --git a/graphrag/docsite/posts/config/template.md b/graphrag/docsite/posts/config/template.md new file mode 100644 index 0000000000000000000000000000000000000000..d3ff14d52f9c3c84cbdef3b94f6f9f5530e6d20f --- /dev/null +++ b/graphrag/docsite/posts/config/template.md @@ -0,0 +1,174 @@ +--- +title: Configuration Template +navtitle: Configuration Template +layout: page +tags: [post] +date: 2024-04-04 +--- + +The following template can be used and stored as a `.env` in the the directory where you're are pointing +the `--root` parameter on your Indexing Pipeline execution. + +For details about how to run the Indexing Pipeline, refer to the [Index CLI](../../index/2-cli) documentation. + +## .env File Template + +Required variables are uncommented. All the optional configuration can be turned on or off as needed. + +### Minimal Configuration + +```bash +# Base LLM Settings +GRAPHRAG_API_KEY="your_api_key" +GRAPHRAG_API_BASE="http://.openai.azure.com" # For Azure OpenAI Users +GRAPHRAG_API_VERSION="api_version" # For Azure OpenAI Users + +# Text Generation Settings +GRAPHRAG_LLM_TYPE="azure_openai_chat" # or openai_chat +GRAPHRAG_LLM_DEPLOYMENT_NAME="gpt-4-turbo-preview" +GRAPHRAG_LLM_MODEL_SUPPORTS_JSON=True + +# Text Embedding Settings +GRAPHRAG_EMBEDDING_TYPE="azure_openai_embedding" # or openai_embedding +GRAPHRAG_LLM_DEPLOYMENT_NAME="text-embedding-3-small" + +# Data Mapping Settings +GRAPHRAG_INPUT_TYPE="text" + +``` + +### Full Configuration + +```bash + +# Required LLM Config + +# Input Data Configuration +GRAPHRAG_INPUT_TYPE="file" + +# Plaintext Input Data Configuration +# GRAPHRAG_INPUT_FILE_PATTERN=.*\.txt + +# Text Input Data Configuration +GRAPHRAG_INPUT_FILE_TYPE="text" +GRAPHRAG_INPUT_FILE_PATTERN=".*\.txt$" +GRAPHRAG_INPUT_SOURCE_COLUMN=source +# GRAPHRAG_INPUT_TIMESTAMP_COLUMN=None +# GRAPHRAG_INPUT_TIMESTAMP_FORMAT=None +# GRAPHRAG_INPUT_TEXT_COLUMN="text" +# GRAPHRAG_INPUT_ATTRIBUTE_COLUMNS=id +# GRAPHRAG_INPUT_TITLE_COLUMN="title" +# GRAPHRAG_INPUT_TYPE="file" +# GRAPHRAG_INPUT_CONNECTION_STRING=None +# GRAPHRAG_INPUT_CONTAINER_NAME=None +# GRAPHRAG_INPUT_BASE_DIR=None + +# Base LLM Settings +GRAPHRAG_API_KEY="your_api_key" +GRAPHRAG_API_BASE="http://.openai.azure.com" # For Azure OpenAI Users +GRAPHRAG_API_VERSION="api_version" # For Azure OpenAI Users +# GRAPHRAG_API_ORGANIZATION=None +# GRAPHRAG_API_PROXY=None + +# Text Generation Settings +# GRAPHRAG_LLM_TYPE=openai_chat +GRAPHRAG_LLM_API_KEY="your_api_key" # If GRAPHRAG_API_KEY is not set +GRAPHRAG_LLM_API_BASE="http://.openai.azure.com" # For Azure OpenAI Users and if GRAPHRAG_API_BASE is not set +GRAPHRAG_LLM_API_VERSION="api_version" # For Azure OpenAI Users and if GRAPHRAG_API_VERSION is not set +GRAPHRAG_LLM_MODEL_SUPPORTS_JSON=True # Suggested by default +# GRAPHRAG_LLM_API_ORGANIZATION=None +# GRAPHRAG_LLM_API_PROXY=None +# GRAPHRAG_LLM_DEPLOYMENT_NAME=None +# GRAPHRAG_LLM_MODEL=gpt-4-turbo-preview +# GRAPHRAG_LLM_MAX_TOKENS=4000 +# GRAPHRAG_LLM_REQUEST_TIMEOUT=180 +# GRAPHRAG_LLM_THREAD_COUNT=50 +# GRAPHRAG_LLM_THREAD_STAGGER=0.3 +# GRAPHRAG_LLM_CONCURRENT_REQUESTS=25 +# GRAPHRAG_LLM_TPM=0 +# GRAPHRAG_LLM_RPM=0 +# GRAPHRAG_LLM_MAX_RETRIES=10 +# GRAPHRAG_LLM_MAX_RETRY_WAIT=10 +# GRAPHRAG_LLM_SLEEP_ON_RATE_LIMIT_RECOMMENDATION=True + +# Text Embedding Settings +# GRAPHRAG_EMBEDDING_TYPE=openai_embedding +GRAPHRAG_EMBEDDING_API_KEY="your_api_key" # If GRAPHRAG_API_KEY is not set +GRAPHRAG_EMBEDDING_API_BASE="http://.openai.azure.com" # For Azure OpenAI Users and if GRAPHRAG_API_BASE is not set +GRAPHRAG_EMBEDDING_API_VERSION="api_version" # For Azure OpenAI Users and if GRAPHRAG_API_VERSION is not set +# GRAPHRAG_EMBEDDING_API_ORGANIZATION=None +# GRAPHRAG_EMBEDDING_API_PROXY=None +# GRAPHRAG_EMBEDDING_DEPLOYMENT_NAME=None +# GRAPHRAG_EMBEDDING_MODEL=text-embedding-3-small +# GRAPHRAG_EMBEDDING_BATCH_SIZE=16 +# GRAPHRAG_EMBEDDING_BATCH_MAX_TOKENS=8191 +# GRAPHRAG_EMBEDDING_TARGET=required +# GRAPHRAG_EMBEDDING_SKIP=None +# GRAPHRAG_EMBEDDING_THREAD_COUNT=None +# GRAPHRAG_EMBEDDING_THREAD_STAGGER=50 +# GRAPHRAG_EMBEDDING_CONCURRENT_REQUESTS=25 +# GRAPHRAG_EMBEDDING_TPM=0 +# GRAPHRAG_EMBEDDING_RPM=0 +# GRAPHRAG_EMBEDDING_MAX_RETRIES=10 +# GRAPHRAG_EMBEDDING_MAX_RETRY_WAIT=10 +# GRAPHRAG_EMBEDDING_SLEEP_ON_RATE_LIMIT_RECOMMENDATION=True + +# Data Mapping Settings +# GRAPHRAG_INPUT_ENCODING=utf-8 + +# Data Chunking +# GRAPHRAG_CHUNK_SIZE=1200 +# GRAPHRAG_CHUNK_OVERLAP=100 +# GRAPHRAG_CHUNK_BY_COLUMNS=id + +# Prompting Overrides +# GRAPHRAG_ENTITY_EXTRACTION_PROMPT_FILE=None +# GRAPHRAG_ENTITY_EXTRACTION_MAX_GLEANINGS=1 +# GRAPHRAG_ENTITY_EXTRACTION_ENTITY_TYPES=organization,person,event,geo +# GRAPHRAG_SUMMARIZE_DESCRIPTIONS_PROMPT_FILE=None +# GRAPHRAG_SUMMARIZE_DESCRIPTIONS_MAX_LENGTH=500 +# GRAPHRAG_CLAIM_EXTRACTION_DESCRIPTION="Any claims or facts that could be relevant to threat analysis." +# GRAPHRAG_CLAIM_EXTRACTION_PROMPT_FILE=None +# GRAPHRAG_CLAIM_EXTRACTION_MAX_GLEANINGS=1 +# GRAPHRAG_COMMUNITY_REPORT_PROMPT_FILE=None +# GRAPHRAG_COMMUNITY_REPORT_MAX_LENGTH=1500 + +# Storage +# GRAPHRAG_STORAGE_TYPE=file +# GRAPHRAG_STORAGE_CONNECTION_STRING=None +# GRAPHRAG_STORAGE_CONTAINER_NAME=None +# GRAPHRAG_STORAGE_BASE_DIR=None + +# Cache +# GRAPHRAG_CACHE_TYPE=file +# GRAPHRAG_CACHE_CONNECTION_STRING=None +# GRAPHRAG_CACHE_CONTAINER_NAME=None +# GRAPHRAG_CACHE_BASE_DIR=None + +# Reporting +# GRAPHRAG_REPORTING_TYPE=file +# GRAPHRAG_REPORTING_CONNECTION_STRING=None +# GRAPHRAG_REPORTING_CONTAINER_NAME=None +# GRAPHRAG_REPORTING_BASE_DIR=None + +# Node2Vec Parameters +# GRAPHRAG_NODE2VEC_ENABLED=False +# GRAPHRAG_NODE2VEC_NUM_WALKS=10 +# GRAPHRAG_NODE2VEC_WALK_LENGTH=40 +# GRAPHRAG_NODE2VEC_WINDOW_SIZE=2 +# GRAPHRAG_NODE2VEC_ITERATIONS=3 +# GRAPHRAG_NODE2VEC_RANDOM_SEED=597832 + +# Data Snapshotting +# GRAPHRAG_SNAPSHOT_GRAPHML=False +# GRAPHRAG_SNAPSHOT_RAW_ENTITIES=False +# GRAPHRAG_SNAPSHOT_TOP_LEVEL_NODES=False + +# Miscellaneous Settings +# GRAPHRAG_ASYNC_MODE=asyncio +# GRAPHRAG_ENCODING_MODEL=cl100k_base +# GRAPHRAG_MAX_CLUSTER_SIZE=10 +# GRAPHRAG_ENTITY_RESOLUTION_ENABLED=False +# GRAPHRAG_SKIP_WORKFLOWS=None +# GRAPHRAG_UMAP_ENABLED=False +``` diff --git a/graphrag/docsite/posts/developing.md b/graphrag/docsite/posts/developing.md new file mode 100644 index 0000000000000000000000000000000000000000..f4a83dc77a87687c642470c10c1b462c55cdea0b --- /dev/null +++ b/graphrag/docsite/posts/developing.md @@ -0,0 +1,90 @@ +--- +title: Developing GraphRAG +navtitle: Developing +layout: page +tags: [post] +--- + +# Requirements + +| Name | Installation | Purpose | +| ------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------- | +| Python 3.10-3.12 | [Download](https://www.python.org/downloads/) | The library is Python-based. | +| Poetry | [Instructions](https://python-poetry.org/docs/#installation) | Poetry is used for package management and virtualenv management in Python codebases | + +# Getting Started + +## Install Dependencies + +```sh +# Install Python dependencies. +poetry install +``` + +## Execute the Indexing Engine + +```sh +poetry run poe index <...args> +``` + +## Executing Queries + +```sh +poetry run poe query <...args> +``` + +# Azurite + +Some unit and smoke tests use Azurite to emulate Azure resources. This can be started by running: + +```sh +./scripts/start-azurite.sh +``` + +or by simply running `azurite` in the terminal if already installed globally. See the [Azurite documentation](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite) for more information about how to install and use Azurite. + +# Lifecycle Scripts + +Our Python package utilizes Poetry to manage dependencies and [poethepoet](https://pypi.org/project/poethepoet/) to manage build scripts. + +Available scripts are: + +- `poetry run poe index` - Run the Indexing CLI +- `poetry run poe query` - Run the Query CLI +- `poetry build` - This invokes `poetry build`, which will build a wheel file and other distributable artifacts. +- `poetry run poe test` - This will execute all tests. +- `poetry run poe test_unit` - This will execute unit tests. +- `poetry run poe test_integration` - This will execute integration tests. +- `poetry run poe test_smoke` - This will execute smoke tests. +- `poetry run poe check` - This will perform a suite of static checks across the package, including: + - formatting + - documentation formatting + - linting + - security patterns + - type-checking +- `poetry run poe fix` - This will apply any available auto-fixes to the package. Usually this is just formatting fixes. +- `poetry run poe fix_unsafe` - This will apply any available auto-fixes to the package, including those that may be unsafe. +- `poetry run poe format` - Explicitly run the formatter across the package. + +## Troubleshooting + +### "RuntimeError: llvm-config failed executing, please point LLVM_CONFIG to the path for llvm-config" when running poetry install + +Make sure llvm-9 and llvm-9-dev are installed: + +`sudo apt-get install llvm-9 llvm-9-dev` + +and then in your bashrc, add + +`export LLVM_CONFIG=/usr/bin/llvm-config-9` + +### "numba/\_pymodule.h:6:10: fatal error: Python.h: No such file or directory" when running poetry install + +Make sure you have python3.10-dev installed or more generally `python-dev` + +`sudo apt-get install python3.10-dev` + +### LLM call constantly exceeds TPM, RPM or time limits + +`GRAPHRAG_LLM_THREAD_COUNT` and `GRAPHRAG_EMBEDDING_THREAD_COUNT` are both set to 50 by default. You can modify this values +to reduce concurrency. Please refer to the [Configuration Documents](../config/overview) diff --git a/graphrag/docsite/posts/get_started.md b/graphrag/docsite/posts/get_started.md new file mode 100644 index 0000000000000000000000000000000000000000..f2c0e7fbf0f551021413d8ec6709087c9a50ea4b --- /dev/null +++ b/graphrag/docsite/posts/get_started.md @@ -0,0 +1,130 @@ +--- +title: Get Started +navtitle: Get started +layout: page +tags: [post] +--- + +## Requirements + +[Python 3.10-3.12](https://www.python.org/downloads/) + +To get started with the GraphRAG system, you have a few options: + +👉 [Use the GraphRAG Accelerator solution](https://github.com/Azure-Samples/graphrag-accelerator)
+👉 [Install from pypi](https://pypi.org/project/graphrag/).
+👉 [Use it from source](/posts/developing)
+ +## Quickstart + +To get started with the GraphRAG system we recommend trying the [Solution Accelerator](https://github.com/Azure-Samples/graphrag-accelerator) package. This provides a user-friendly end-to-end experience with Azure resources. + +# Top-Level Modules + +[Indexing Pipeline Overview](/posts/index/overview)
+[Query Engine Overview](/posts/query/overview) + +# Overview + +The following is a simple end-to-end example for using the GraphRAG system. +It shows how to use the system to index some text, and then use the indexed data to answer questions about the documents. + +# Install GraphRAG + +```bash +pip install graphrag +``` + +# Running the Indexer + +Now we need to set up a data project and some initial configuration. Let's set that up. We're using the [default configuration mode](/posts/config/overview/), which you can customize as needed using a [config file](/posts/config/json_yaml/), which we recommend, or [environment variables](/posts/config/env_vars/). + +First let's get a sample dataset ready: + +```sh +mkdir -p ./ragtest/input +``` + +Now let's get a copy of A Christmas Carol by Charles Dickens from a trusted source + +```sh +curl https://www.gutenberg.org/cache/epub/24022/pg24022.txt > ./ragtest/input/book.txt +``` + +Next we'll inject some required config variables: + +## Set Up Your Workspace Variables + +First let's make sure to setup the required environment variables. For details on these environment variables, and what environment variables are available, see the [variables documentation](/posts/config/overview/). + +To initialize your workspace, let's first run the `graphrag.index --init` command. +Since we have already configured a directory named \.ragtest` in the previous step, we can run the following command: + +```sh +python -m graphrag.index --init --root ./ragtest +``` + +This will create two files: `.env` and `settings.yaml` in the `./ragtest` directory. + +- `.env` contains the environment variables required to run the GraphRAG pipeline. If you inspect the file, you'll see a single environment variable defined, + `GRAPHRAG_API_KEY=`. This is the API key for the OpenAI API or Azure OpenAI endpoint. You can replace this with your own API key. +- `settings.yaml` contains the settings for the pipeline. You can modify this file to change the settings for the pipeline. +
+ +#### OpenAI and Azure OpenAI + +To run in OpenAI mode, just make sure to update the value of `GRAPHRAG_API_KEY` in the `.env` file with your OpenAI API key. + +#### Azure OpenAI + +In addition, Azure OpenAI users should set the following variables in the settings.yaml file. To find the appropriate sections, just search for the `llm:` configuration, you should see two sections, one for the chat endpoint and one for the embeddings endpoint. Here is an example of how to configure the chat endpoint: + +```yaml +type: azure_openai_chat # Or azure_openai_embedding for embeddings +api_base: https://.openai.azure.com +api_version: 2024-02-15-preview # You can customize this for other versions +deployment_name: +``` + +- For more details about configuring GraphRAG, see the [configuration documentation](/posts/config/overview/). +- To learn more about Initialization, refer to the [Initialization documentation](/posts/config/init/). +- For more details about using the CLI, refer to the [CLI documentation](/posts/query/3-cli/). + +## Running the Indexing pipeline + +Finally we'll run the pipeline! + +```sh +python -m graphrag.index --root ./ragtest +``` + +![pipeline executing from the CLI](/img/pipeline-running.png) + +This process will take some time to run. This depends on the size of your input data, what model you're using, and the text chunk size being used (these can be configured in your `.env` file). +Once the pipeline is complete, you should see a new folder called `./ragtest/output//artifacts` with a series of parquet files. + +# Using the Query Engine + +## Running the Query Engine + +Now let's ask some questions using this dataset. + +Here is an example using Global search to ask a high-level question: + +```sh +python -m graphrag.query \ +--root ./ragtest \ +--method global \ +"What are the top themes in this story?" +``` + +Here is an example using Local search to ask a more specific question about a particular character: + +```sh +python -m graphrag.query \ +--root ./ragtest \ +--method local \ +"Who is Scrooge, and what are his main relationships?" +``` + +Please refer to [Query Engine](/posts/query/overview) docs for detailed information about how to leverage our Local and Global search mechanisms for extracting meaningful insights from data after the Indexer has wrapped up execution. diff --git a/graphrag/docsite/posts/index/0-architecture.md b/graphrag/docsite/posts/index/0-architecture.md new file mode 100644 index 0000000000000000000000000000000000000000..4826bdabb2b4f7a1c84f0cf9b9feee4bddd80944 --- /dev/null +++ b/graphrag/docsite/posts/index/0-architecture.md @@ -0,0 +1,73 @@ +--- +title: Indexing Architecture +navtitle: Architecture +tags: [post, indexing] +layout: page +date: 2023-01-01 +--- + +## Key Concepts + +### Knowledge Model + +In order to support the GraphRAG system, the outputs of the indexing engine (in the Default Configuration Mode) are aligned to a knowledge model we call the _GraphRAG Knowledge Model_. +This model is designed to be an abstraction over the underlying data storage technology, and to provide a common interface for the GraphRAG system to interact with. +In normal use-cases the outputs of the GraphRAG Indexer would be loaded into a database system, and the GraphRAG's Query Engine would interact with the database using the knowledge model data-store types. + +### DataShaper Workflows + +GraphRAG's Indexing Pipeline is built on top of our open-source library, [DataShaper](https://github.com/microsoft/datashaper). +DataShaper is a data processing library that allows users to declaratively express data pipelines, schemas, and related assets using well-defined schemas. +DataShaper has implementations in JavaScript and Python, and is designed to be extensible to other languages. + +One of the core resource types within DataShaper is a [Workflow](https://github.com/microsoft/datashaper/blob/main/javascript/schema/src/workflow/WorkflowSchema.ts). +Workflows are expressed as sequences of steps, which we call [verbs](https://github.com/microsoft/datashaper/blob/main/javascript/schema/src/workflow/verbs.ts). +Each step has a verb name and a configuration object. +In DataShaper, these verbs model relational concepts such as SELECT, DROP, JOIN, etc.. Each verb transforms an input data table, and that table is passed down the pipeline. + +```mermaid +--- +title: Sample Workflow +--- +flowchart LR + input[Input Table] --> select[SELECT] --> join[JOIN] --> binarize[BINARIZE] --> output[Output Table] +``` + +### LLM-based Workflow Steps + +GraphRAG's Indexing Pipeline implements a handful of custom verbs on top of the standard, relational verbs that our DataShaper library provides. These verbs give us the ability to augment text documents with rich, structured data using the power of LLMs such as GPT-4. We utilize these verbs in our standard workflow to extract entities, relationships, claims, community structures, and community reports and summaries. This behavior is customizable and can be extended to support many kinds of AI-based data enrichment and extraction tasks. + +### Workflow Graphs + +Because of the complexity of our data indexing tasks, we needed to be able to express our data pipeline as series of multiple, interdependent workflows. +In the GraphRAG Indexing Pipeline, each workflow may define dependencies on other workflows, effectively forming a directed acyclic graph (DAG) of workflows, which is then used to schedule processing. + +```mermaid +--- +title: Sample Workflow DAG +--- +stateDiagram-v2 + [*] --> Prepare + Prepare --> Chunk + Chunk --> ExtractGraph + Chunk --> EmbedDocuments + ExtractGraph --> GenerateReports + ExtractGraph --> EmbedGraph + EntityResolution --> EmbedGraph + EntityResolution --> GenerateReports + ExtractGraph --> EntityResolution +``` + +### Dataframe Message Format + +The primary unit of communication between workflows, and between workflow steps is an instance of `pandas.DataFrame`. +Although side-effects are possible, our goal is to be _data-centric_ and _table-centric_ in our approach to data processing. +This allows us to easily reason about our data, and to leverage the power of dataframe-based ecosystems. +Our underlying dataframe technology may change over time, but our primary goal is to support the DataShaper workflow schema while retaining single-machine ease of use and developer ergonomics. + +### LLM Caching + +The GraphRAG library was designed with LLM interactions in mind, and a common setback when working with LLM APIs is various errors errors due to network latency, throttling, etc.. +Because of these potential error cases, we've added a cache layer around LLM interactions. +When completion requests are made using the same input set (prompt and tuning parameters), we return a cached result if one exists. +This allows our indexer to be more resilient to network issues, to act idempotently, and to provide a more efficient end-user experience. diff --git a/graphrag/docsite/posts/index/1-default_dataflow.md b/graphrag/docsite/posts/index/1-default_dataflow.md new file mode 100644 index 0000000000000000000000000000000000000000..1b8d135dabe32be625c87b7786a58eef21077963 --- /dev/null +++ b/graphrag/docsite/posts/index/1-default_dataflow.md @@ -0,0 +1,218 @@ +--- +title: Indexing Dataflow +navtitle: Dataflow +layout: page +tags: [post, indexing] +date: 2023-01-02 +--- + +## The GraphRAG Knowledge Model + +The knowledge model is a specification for data outputs that conform to our data-model definition. You can find these definitions in the python/graphrag/graphrag/model folder within the GraphRAG repository. The following entity types are provided. The fields here represent the fields that are text-embedded by default. + +- `Document` - An input document into the system. These either represent individual rows in a CSV or individual .txt file. +- `TextUnit` - A chunk of text to analyze. The size of these chunks, their overlap, and whether they adhere to any data boundaries may be configured below. A common use case is to set `CHUNK_BY_COLUMNS` to `id` so that there is a 1-to-many relationship between documents and TextUnits instead of a many-to-many. +- `Entity` - An entity extracted from a TextUnit. These represent people, places, events, or some other entity-model that you provide. +- `Relationship` - A relationship between two entities. These are generated from the covariates. +- `Covariate` - Extracted claim information, which contains statements about entities which may be time-bound. +- `Community Report` - Once entities are generated, we perform hierarchical community detection on them and generate reports for each community in this hierarchy. +- `Node` - This table contains layout information for rendered graph-views of the Entities and Documents which have been embedded and clustered. + +## The Default Configuration Workflow + +Let's take a look at how the default-configuration workflow transforms text documents into the _GraphRAG Knowledge Model_. This page gives a general overview of the major steps in this process. To fully configure this workflow, check out the [configuration](/posts/config/overview/) documentation. + +```mermaid +--- +title: Dataflow Overview +--- +flowchart TB + subgraph phase1[Phase 1: Compose TextUnits] + documents[Documents] --> chunk[Chunk] + chunk --> embed[Embed] --> textUnits[Text Units] + end + subgraph phase2[Phase 2: Graph Extraction] + textUnits --> graph_extract[Entity & Relationship Extraction] + graph_extract --> graph_summarize[Entity & Relationship Summarization] + graph_summarize --> entity_resolve[Entity Resolution] + entity_resolve --> claim_extraction[Claim Extraction] + claim_extraction --> graph_outputs[Graph Tables] + end + subgraph phase3[Phase 3: Graph Augmentation] + graph_outputs --> community_detect[Community Detection] + community_detect --> graph_embed[Graph Embedding] + graph_embed --> augmented_graph[Augmented Graph Tables] + end + subgraph phase4[Phase 4: Community Summarization] + augmented_graph --> summarized_communities[Community Summarization] + summarized_communities --> embed_communities[Community Embedding] + embed_communities --> community_outputs[Community Tables] + end + subgraph phase5[Phase 5: Document Processing] + documents --> link_to_text_units[Link to TextUnits] + textUnits --> link_to_text_units + link_to_text_units --> embed_documents[Document Embedding] + embed_documents --> document_graph[Document Graph Creation] + document_graph --> document_outputs[Document Tables] + end + subgraph phase6[Phase 6: Network Visualization] + document_outputs --> umap_docs[Umap Documents] + augmented_graph --> umap_entities[Umap Entities] + umap_docs --> combine_nodes[Nodes Table] + umap_entities --> combine_nodes + end +``` + +## Phase 1: Compose TextUnits + +The first phase of the default-configuration workflow is to transform input documents into _TextUnits_. A _TextUnit_ is a chunk of text that is used for our graph extraction techniques. They are also used as source-references by extracted knowledge items in order to empower breadcrumbs and provenance by concepts back to their original source tex. + +The chunk size (counted in tokens), is user-configurable. By default this is set to 300 tokens, although we've had positive experience with 1200-token chunks using a single "glean" step. (A "glean" step is a follow-on extraction). Larger chunks result in lower-fidelity output and less meaningful reference texts; however, using larger chunks can result in much faster processing time. + +The group-by configuration is also user-configurable. By default, we align our chunks to document boundaries, meaning that there is a strict 1-to-many relationship between Documents and TextUnits. In rare cases, this can be turned into a many-to-many relationship. This is useful when the documents are very short and we need several of them to compose a meaningful analysis unit (e.g. Tweets or a chat log) + +Each of these text-units are text-embedded and passed into the next phase of the pipeline. + +```mermaid +--- +title: Documents into Text Chunks +--- +flowchart LR + doc1[Document 1] --> tu1[TextUnit 1] + doc1 --> tu2[TextUnit 2] + doc2[Document 2] --> tu3[TextUnit 3] + doc2 --> tu4[TextUnit 4] + +``` + +## Phase 2: Graph Extraction + +In this phase, we analyze each text unit and extract our graph primitives: _Entities_, _Relationships_, and _Claims_. +Entities and Relationships are extracted at once in our _entity_extract_ verb, and claims are extracted in our _claim_extract_ verb. Results are then combined and passed into following phases of the pipeline. + +```mermaid +--- +title: Graph Extraction +--- +flowchart LR + tu[TextUnit] --> ge[Graph Extraction] --> gs[Graph Summarization] --> er[Entity Resolution] + tu --> ce[Claim Extraction] +``` + +### Entity & Relationship Extraction + +In this first step of graph extraction, we process each text-unit in order to extract entities and relationships out of the raw text using the LLM. The output of this step is a subgraph-per-TextUnit containing a list of **entities** with a _name_, _type_, and _description_, and a list of **relationships** with a _source_, _target_, and _description_. + +These subgraphs are merged together - any entities with the same _name_ and _type_ are merged by creating an array of their descriptions. Similarly, any relationships with the same _source_ and _target_ are merged by creating an array of their descriptions. + +### Entity & Relationship Summarization + +Now that we have a graph of entities and relationships, each with a list of descriptions, we can summarize these lists into a single description per entity and relationship. This is done by asking the LLM for a short summary that captures all of the distinct information from each description. This allows all of our entities and relationships to have a single concise description. + +### Entity Resolution (Not Enabled by Default) + +The final step of graph extraction is to resolve any entities that represent the same real-world entity but but have different names. Since this is done via LLM, and we don't want to lose information, we want to take a conservative, non-destructive approach to this. + +Our current implementation of Entity Resolution, however, is destructive. It will provide the LLM with a series of entities and ask it to determine which ones should be merged. Those entities are then merged together into a single entity and their relationships are updated. + +We are currently exploring other entity resolution techniques. In the near future, entity resolution will be executed by creating an edge between entity variants indicating that the entities have been resolved by the indexing engine. This will allow for end-users to undo indexing-side resolutions, and add their own non-destructive resolutions using a similar process. + +### Claim Extraction & Emission + +Finally, as an independent workflow, we extract claims from the source TextUnits. These claims represent positive factual statements with an evaluated status and time-bounds. These are emitted as a primary artifact called **Covariates**. + +## Phase 3: Graph Augmentation + +Now that we have a usable graph of entities and relationships, we want to understand their community structure and augment the graph with additional information. This is done in two steps: _Community Detection_ and _Graph Embedding_. These give us explicit (communities) and implicit (embeddings) ways of understanding the topological structure of our graph. + +```mermaid +--- +title: Graph Augmentation +--- +flowchart LR + cd[Leiden Hierarchical Community Detection] --> ge[Node2Vec Graph Embedding] --> ag[Graph Table Emission] +``` + +### Community Detection + +In this step, we generate a hierarchy of entity communities using the Hierarchical Leiden Algorithm. This method will apply a recursive community-clustering to our graph until we reach a community-size threshold. This will allow us to understand the community structure of our graph and provide a way to navigate and summarize the graph at different levels of granularity. + +### Graph Embedding + +In this step, we generate a vector representation of our graph using the Node2Vec algorithm. This will allow us to understand the implicit structure of our graph and provide an additional vector-space in which to search for related concepts during our query phase. + +### Graph Tables Emission + +Once our graph augmentation steps are complete, the final **Entities** and **Relationships** tables are emitted after their text fields are text-embedded. + +## Phase 4: Community Summarization + +```mermaid +--- +title: Community Summarization +--- +flowchart LR + sc[Generate Community Reports] --> ss[Summarize Community Reports] --> ce[Community Embedding] --> co[Community Tables Emission] +``` + +At this point, we have a functional graph of entities and relationships, a hierarchy of communities for the entities, as well as node2vec embeddings. + +Now we want to build on the communities data and generate reports for each community. This gives us a high-level understanding of the graph at several points of graph granularity. For example, if community A is the top-level community, we'll get a report about the entire graph. If the community is lower-level, we'll get a report about a local cluster. + +### Generate Community Reports + +In this step, we generate a summary of each community using the LLM. This will allow us to understand the distinct information contained within each community and provide a scoped understanding of the graph, from either a high-level or a low-level perspective. These reports contain an executive overview and reference the key entities, relationships, and claims within the community sub-structure. + +### Summarize Community Reports + +In this step, each _community report_ is then summarized via the LLM for shorthand use. + +### Community Embedding + +In this step, we generate a vector representation of our communities by generating text embeddings of the community report, the community report summary, and the title of the community report. + +### Community Tables Emission + +At this point, some bookkeeping work is performed and we emit the **Communities** and **CommunityReports** tables. + +## Phase 5: Document Processing + +In this phase of the workflow, we create the _Documents_ table for the knowledge model. + +```mermaid +--- +title: Document Processing +--- +flowchart LR + aug[Augment] --> dp[Link to TextUnits] --> de[Avg. Embedding] --> dg[Document Table Emission] +``` + +### Augment with Columns (CSV Only) + +If the workflow is operating on CSV data, you may configure your workflow to add additional fields to Documents output. These fields should exist on the incoming CSV tables. Details about configuring this can be found in the [configuration documentation](/posts/config/overview/). + +### Link to TextUnits + +In this step, we link each document to the text-units that were created in the first phase. This allows us to understand which documents are related to which text-units and vice-versa. + +### Document Embedding + +In this step, we generate a vector representation of our documents using an average embedding of document slices. We re-chunk documents without overlapping chunks, and then generate an embedding for each chunk. We create an average of these chunks weighted by token-count and use this as the document embedding. This will allow us to understand the implicit relationship between documents, and will help us generate a network representation of our documents. + +### Documents Table Emission + +At this point, we can emit the **Documents** table into the knowledge Model. + +## Phase 6: Network Visualization + +In this phase of the workflow, we perform some steps to support network visualization of our high-dimensional vector spaces within our existing graphs. At this point there are two logical graphs at play: the _Entity-Relationship_ graph and the _Document_ graph. + +```mermaid +--- +title: Network Visualization Workflows +--- +flowchart LR + nv[Umap Documents] --> ne[Umap Entities] --> ng[Nodes Table Emission] +``` + +For each of the logical graphs, we perform a UMAP dimensionality reduction to generate a 2D representation of the graph. This will allow us to visualize the graph in a 2D space and understand the relationships between the nodes in the graph. The UMAP embeddings are then emitted as a table of _Nodes_. The rows of this table include a discriminator indicating whether the node is a document or an entity, and the UMAP coordinates. diff --git a/graphrag/docsite/posts/index/2-cli.md b/graphrag/docsite/posts/index/2-cli.md new file mode 100644 index 0000000000000000000000000000000000000000..97911bbcb2e807bf359d19dfcbe3febf489e4ec2 --- /dev/null +++ b/graphrag/docsite/posts/index/2-cli.md @@ -0,0 +1,26 @@ +--- +title: Indexer CLI +navtitle: CLI +layout: page +tags: [post, indexing] +date: 2023-01-03 +--- + +The GraphRAG indexer CLI allows for no-code usage of the GraphRAG Indexer. + +```bash +python -m graphrag.index --verbose --root --config +--resume --reporter --emit json,csv,parquet +--nocache +``` + +## CLI Arguments + +- `--verbose` - Adds extra logging information during the run. +- `--root ` - the data root directory. This should contain an `input` directory with the input data, and an `.env` file with environment variables. These are described below. +- `--init` - This will initialize the data project directory at the specified `root` with bootstrap configuration and prompt-overrides. +- `--resume ` - if specified, the pipeline will attempt to resume a prior run. The parquet files from the prior run will be loaded into the system as inputs, and the workflows that generated those files will be skipped. The input value should be the timestamped output folder, e.g. "20240105-143721". +- `--config ` - This will opt-out of the Default Configuration mode and execute a custom configuration. If this is used, then none of the environment-variables below will apply. +- `--reporter ` - This will specify the progress reporter to use. The default is `rich`. Valid values are `rich`, `print`, and `none`. +- `--emit ` - This specifies the table output formats the pipeline should emit. The default is `parquet`. Valid values are `parquet`, `csv`, and `json`, comma-separated. +- `--nocache` - This will disable the caching mechanism. This is useful for debugging and development, but should not be used in production. diff --git a/graphrag/docsite/posts/index/overview.md b/graphrag/docsite/posts/index/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..51555c9abbf66664c75831d0562583abee156a3e --- /dev/null +++ b/graphrag/docsite/posts/index/overview.md @@ -0,0 +1,82 @@ +--- +title: GraphRAG Indexing 🤖 +navtitle: Indexing Overview +layout: page +tags: [post] +--- + +The GraphRAG indexing package is a data pipeline and transformation suite that is designed to extract meaningful, structured data from unstructured text using LLMs. + +Indexing Pipelines are configurable. They are composed of workflows, standard and custom steps, prompt templates, and input/output adapters. Our standard pipeline is designed to: + +- extract entities, relationships and claims from raw text +- perform community detection in entities +- generate community summaries and reports at multiple levels of granularity +- embed entities into a graph vector space +- embed text chunks into a textual vector space + +The outputs of the pipeline can be stored in a variety of formats, including JSON and Parquet - or they can be handled manually via the Python API. + +## Getting Started + +### Requirements + +See the [requirements](/posts/developing#requirements) section in [Get Started](/posts/get_started) for details on setting up a development environment. + +The Indexing Engine can be used in either a default configuration mode or with a custom pipeline. +To configure GraphRAG, see the [configuration](/posts/config/overview) documentation. +After you have a config file you can run the pipeline using the CLI or the Python API. + +## Usage + +### CLI + +```bash +# Via Poetry +poetry run poe cli --root # default config mode +poetry run poe cli --config your_pipeline.yml # custom config mode + +# Via Node +yarn run:index --root # default config mode +yarn run:index --config your_pipeline.yml # custom config mode + +``` + +### Python API + +```python +from graphrag.index import run_pipeline +from graphrag.index.config import PipelineWorkflowReference + +workflows: list[PipelineWorkflowReference] = [ + PipelineWorkflowReference( + steps=[ + { + # built-in verb + "verb": "derive", # https://github.com/microsoft/datashaper/blob/main/python/datashaper/datashaper/engine/verbs/derive.py + "args": { + "column1": "col1", # from above + "column2": "col2", # from above + "to": "col_multiplied", # new column name + "operator": "*", # multiply the two columns + }, + # Since we're trying to act on the default input, we don't need explicitly to specify an input + } + ] + ), +] + +dataset = pd.DataFrame([{"col1": 2, "col2": 4}, {"col1": 5, "col2": 10}]) +outputs = [] +async for output in await run_pipeline(dataset=dataset, workflows=workflows): + outputs.append(output) +pipeline_result = outputs[-1] +print(pipeline_result) +``` + +## Further Reading + +- To start developing within the _GraphRAG_ project, see [getting started](/posts/developing/) +- To understand the underlying concepts and execution model of the indexing library, see [the architecture documentation](/posts/index/0-architecture/) +- To get running with a series of examples, see [the examples documentation](https://github.com/microsoft/graphrag/blob/main/examples/README.md) +- To read more about configuring the indexing engine, see [the configuration documentation](/posts/config/overview) diff --git a/graphrag/docsite/posts/prompt_tuning/auto_prompt_tuning.md b/graphrag/docsite/posts/prompt_tuning/auto_prompt_tuning.md new file mode 100644 index 0000000000000000000000000000000000000000..88b7418873642e0d0fcfb5e777b9ff59b1d7cc63 --- /dev/null +++ b/graphrag/docsite/posts/prompt_tuning/auto_prompt_tuning.md @@ -0,0 +1,74 @@ +--- +title: Prompt Tuning ⚙️ +navtitle: Auto templating +layout: page +tags: [post, tuning] +date: 2024-06-13 +--- + +GraphRAG provides the ability to create domain adaptive templates for the generation of the knowledge graph. This step is optional, though it is highly encouraged to run it as it will yield better results when executing an Index Run. + +The templates are generated by loading the inputs, splitting them into chunks (text units) and then running a series of LLM invocations and template substitutions to generate the final prompts. We suggest using the default values provided by the script, but in this page you'll find the detail of each in case you want to further explore and tweak the template generation algorithm. + +## Prerequisites + +Before running the automatic template generation make sure you have already initialized your workspace with the `graphrag.index --init` command. This will create the necessary configuration files and the default prompts. Refer to the [Init Documentation](/posts/config/init) for more information about the initialization process. + +## Usage + +You can run the main script from the command line with various options: + +```bash +python -m graphrag.prompt_tune [--root ROOT] [--domain DOMAIN] [--method METHOD] [--limit LIMIT] [--language LANGUAGE] [--max-tokens MAX_TOKENS] [--chunk-size CHUNK_SIZE] [--no-entity-types] [--output OUTPUT] +``` + +## Command-Line Options + +- `--root` (optional): The data project root directory, including the config files (YML, JSON, or .env). Defaults to the current directory. + +- `--domain` (optional): The domain related to your input data, such as 'space science', 'microbiology', or 'environmental news'. If left empty, the domain will be inferred from the input data. + +- `--method` (optional): The method to select documents. Options are all, random, or top. Default is random. + +- `--limit` (optional): The limit of text units to load when using random or top selection. Default is 15. + +- `--language` (optional): The language to use for input processing. If it is different from the inputs' language, the LLM will translate. Default is "" meaning it will be automatically detected from the inputs. + +- `--max-tokens` (optional): Maximum token count for prompt generation. Default is 2000. + +- `--chunk-size` (optional): The size in tokens to use for generating text units from input documents. Default is 200. + +- `--no-entity-types` (optional): Use untyped entity extraction generation. We recommend using this when your data covers a lot of topics or it is highly randomized. + +- `--output` (optional): The folder to save the generated prompts. Default is "prompts". + +## Example Usage + +```bash +python -m graphrag.prompt_tune --root /path/to/project --domain "environmental news" --method random --limit 10 --language English --max-tokens 2048 --chunk-size 256 --no-entity-types --output /path/to/output +``` + +or, with minimal configuration (suggested): + +```bash +python -m graphrag.prompt_tune --root /path/to/project --no-entity-types +``` + +## Document Selection Methods + +The auto template feature ingests the input data and then divides it into text units the size of the chunk size parameter. +After that, it uses one of the following selection methods to pick a sample to work with for template generation: + +- `random`: Select text units randomly. This is the default and recommended option. +- `top`: Select the head n text units. +- `all`: Use all text units for the generation. Use only with small datasets; this option is not usually recommended. + +## Modify Env Vars + +After running auto-templating, you should modify the following environment variables (or config variables) to pick up the new prompts on your index run. Note: Please make sure to update the correct path to the generated prompts, in this example we are using the default "prompts" path. + +- `GRAPHRAG_ENTITY_EXTRACTION_PROMPT_FILE` = "prompts/entity_extraction.txt" + +- `GRAPHRAG_COMMUNITY_REPORT_PROMPT_FILE` = "prompts/community_report.txt" + +- `GRAPHRAG_SUMMARIZE_DESCRIPTIONS_PROMPT_FILE` = "prompts/summarize_descriptions.txt" diff --git a/graphrag/docsite/posts/prompt_tuning/manual_prompt_tuning.md b/graphrag/docsite/posts/prompt_tuning/manual_prompt_tuning.md new file mode 100644 index 0000000000000000000000000000000000000000..935840d253fe103f729a3b862d5e017c0bc2d9a2 --- /dev/null +++ b/graphrag/docsite/posts/prompt_tuning/manual_prompt_tuning.md @@ -0,0 +1,60 @@ +--- +title: Prompt Tuning⚙️ +navtitle: Manual Tuning +layout: page +tags: [post, tuning] +date: 2023-01-03 +--- + +The GraphRAG indexer, by default, will run with a handful of prompts that are designed to work well in the broad context of knowledge discovery. +However, it is quite common to want to tune the prompts to better suit your specific use case. +We provide a means for you to do this by allowing you to specify a custom prompt file, which will each use a series of token-replacements internally. + +Each of these prompts may be overridden by writing a custom prompt file in plaintext. We use token-replacements in the form of `{token_name}`, and the descriptions for the available tokens can be found below. + +## Entity/Relationship Extraction + +[Prompt Source](http://github.com/microsoft/graphrag/blob/main/graphrag/index/graph/extractors/graph/prompts.py) + +### Tokens (values provided by extractor) + +- **{input_text}** - The input text to be processed. +- **{entity_types}** - A list of entity types +- **{tuple_delimiter}** - A delimiter for separating values within a tuple. A single tuple is used to represent an individual entity or relationship. +- **{record_delimiter}** - A delimiter for separating tuple instances. +- **{completion_delimiter}** - An indicator for when generation is complete. + +## Summarize Entity/Relationship Descriptions + +[Prompt Source](http://github.com/microsoft/graphrag/blob/main/graphrag/index/graph/extractors/summarize/prompts.py) + +### Tokens (values provided by extractor) + +- **{entity_name}** - The name of the entity or the source/target pair of the relationship. +- **{description_list}** - A list of descriptions for the entity or relationship. + +## Claim Extraction + +[Prompt Source](http://github.com/microsoft/graphrag/blob/main/graphrag/index/graph/extractors/claims/prompts.py) + +### Tokens (values provided by extractor) + +- **{input_text}** - The input text to be processed. +- **{tuple_delimiter}** - A delimiter for separating values within a tuple. A single tuple is used to represent an individual entity or relationship. +- **{record_delimiter}** - A delimiter for separating tuple instances. +- **{completion_delimiter}** - An indicator for when generation is complete. + +Note: there is additional paramater for the `Claim Description` that is used in claim extraction. +The default value is + +`"Any claims or facts that could be relevant to information discovery."` + +See the [configuration documentation](/posts/config/overview/) for details on how to change this. + +## Generate Community Reports + +[Prompt Source](http://github.com/microsoft/graphrag/blob/main/graphrag/index/graph/extractors/community_reports/prompts.py) + +### Tokens (values provided by extractor) + +- **{input_text}** - The input text to generate the report with. This will contain tables of entities and relationships. diff --git a/graphrag/docsite/posts/prompt_tuning/overview.md b/graphrag/docsite/posts/prompt_tuning/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..f71b167d650ad4cd515837d625bd5bf1335eacd7 --- /dev/null +++ b/graphrag/docsite/posts/prompt_tuning/overview.md @@ -0,0 +1,26 @@ +--- +title: Prompt Tuning ⚙️ +navtitle: Overview +layout: page +tags: [post, tuning] +date: 2024-06-13 +--- + +This page provides an overview of the prompt tuning options available for the GraphRAG indexing engine. + +## Default Prompts + +The default prompts are the simplest way to get started with the GraphRAG system. It is designed to work out-of-the-box with minimal configuration. You can find more detail about these prompts in the following links: + +- [Entity/Relationship Extraction](http://github.com/microsoft/graphrag/blob/main/graphrag/index/graph/extractors/graph/prompts.py) +- [Entity/Relationship Description Summarization](http://github.com/microsoft/graphrag/blob/main/graphrag/index/graph/extractors/summarize/prompts.py) +- [Claim Extraction](http://github.com/microsoft/graphrag/blob/main/graphrag/index/graph/extractors/claims/prompts.py) +- [Community Reports](http://github.com/microsoft/graphrag/blob/main/graphrag/index/graph/extractors/community_reports/prompts.py) + +## Auto Templating + +Auto Templating leverages your input data and LLM interactions to create domain adaptive templates for the generation of the knowledge graph. It is highly encouraged to run it as it will yield better results when executing an Index Run. For more details about how to use it, please refer to the [Auto Templating](/posts/prompt_tuning/auto_prompt_tuning) documentation. + +## Manual Configuration + +Manual configuration is an advanced use-case. Most users will want to use the Auto Templating feature instead. Details about how to use manual configuration are available in the [Manual Prompt Configuration](/posts/prompt_tuning/manual_prompt_tuning) documentation. diff --git a/graphrag/docsite/posts/query/0-global_search.md b/graphrag/docsite/posts/query/0-global_search.md new file mode 100644 index 0000000000000000000000000000000000000000..1a0eda22fe4bc86ff6be9dd9fb3800d4a59ca0f3 --- /dev/null +++ b/graphrag/docsite/posts/query/0-global_search.md @@ -0,0 +1,78 @@ +--- +title: Global Search 🔎 +navtitle: Global Search +tags: [post, orchestration] +layout: page +date: 2024-06-03 +--- + +## Whole Dataset Reasoning + +Baseline RAG struggles with queries that require aggregation of information across the dataset to compose an answer. Queries such as “What are the top 5 themes in the data?” perform terribly because baseline RAG relies on a vector search of semantically similar text content within the dataset. There is nothing in the query to direct it to the correct information. + +However, with GraphRAG we can answer such questions, because the structure of the LLM-generated knowledge graph tells us about the structure (and thus themes) of the dataset as a whole. This allows the private dataset to be organized into meaningful semantic clusters that are pre-summarized. Using our [global search](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/global_search/) method, the LLM uses these clusters to summarize these themes when responding to a user query. + +## Methodology + +```mermaid +--- +title: Global Search Dataflow +--- +%%{ init: { 'flowchart': { 'curve': 'step' } } }%% +flowchart LR + + uq[User Query] --- .1 + ch1[Conversation History] --- .1 + + subgraph RIR + direction TB + ri1[Rated Intermediate
Response 1]~~~ri2[Rated Intermediate
Response 2] -."{1..N}".-rin[Rated Intermediate
Response N] + end + + .1--Shuffled Community
Report Batch 1-->RIR + .1--Shuffled Community
Report Batch 2-->RIR---.2 + .1--Shuffled Community
Report Batch N-->RIR + + .2--Ranking +
Filtering-->agr[Aggregated Intermediate
Responses]-->res[Response] + + + + classDef green fill:#26B653,stroke:#333,stroke-width:2px,color:#fff; + classDef turquoise fill:#19CCD3,stroke:#333,stroke-width:2px,color:#fff; + classDef rose fill:#DD8694,stroke:#333,stroke-width:2px,color:#fff; + classDef orange fill:#F19914,stroke:#333,stroke-width:2px,color:#fff; + classDef purple fill:#B356CD,stroke:#333,stroke-width:2px,color:#fff; + classDef invisible fill:#fff,stroke:#fff,stroke-width:0px,color:#fff, width:0px; + class uq,ch1 turquoise; + class ri1,ri2,rin rose; + class agr orange; + class res purple; + class .1,.2 invisible; + +``` + +Given a user query and, optionally, the conversation history, the global search method uses a collection of LLM-generated community reports from a specified level of the graph's community hierarchy as context data to generate response in a map-reduce manner. At the `map` step, community reports are segmented into text chunks of pre-defined size. Each text chunk is then used to produce an intermediate response containing a list of point, each of which is accompanied by a numerical rating indicating the importance of the point. At the `reduce` step, a filtered set of the most important points from the intermediate responses are aggregated and used as the context to generate the final response. + +The quality of the global search’s response can be heavily influenced by the level of the community hierarchy chosen for sourcing community reports. Lower hierarchy levels, with their detailed reports, tend to yield more thorough responses, but may also increase the time and LLM resources needed to generate the final response due to the volume of reports. + + +## Configuration + +Below are the key parameters of the [GlobalSearch class](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/global_search/search.py): +* `llm`: OpenAI model object to be used for response generation +* `context_builder`: [context builder](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/global_search/community_context.py) object to be used for preparing context data from community reports +* `map_system_prompt`: prompt template used in the `map` stage. Default template can be found at [map_system_prompt](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/global_search/map_system_prompt.py) +* `reduce_system_prompt`: prompt template used in the `reduce` stage, default template can be found at [reduce_system_prompt](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/global_search/reduce_system_prompt.py) +* `response_type`: free-form text describing the desired response type and format (e.g., `Multiple Paragraphs`, `Multi-Page Report`) +* `allow_general_knowledge`: setting this to True will include additional instructions to the `reduce_system_prompt` to prompt the LLM to incorporate relevant real-world knowledge outside of the dataset. Note that this may increase hallucinations, but can be useful for certain scenarios. Default is False +*`general_knowledge_inclusion_prompt`: instruction to add to the `reduce_system_prompt` if `allow_general_knowledge` is enabled. Default instruction can be found at [general_knowledge_instruction](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/global_search/reduce_system_prompt.py) +* `max_data_tokens`: token budget for the context data +* `map_llm_params`: a dictionary of additional parameters (e.g., temperature, max_tokens) to be passed to the LLM call at the `map` stage +* `reduce_llm_params`: a dictionary of additional parameters (e.g., temperature, max_tokens) to passed to the LLM call at the `reduce` stage +* `context_builder_params`: a dictionary of additional parameters to be passed to the [`context_builder`](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/global_search/community_context.py) object when building context window for the `map` stage. +* `concurrent_coroutines`: controls the degree of parallelism in the `map` stage. +* `callbacks`: optional callback functions, can be used to provide custom event handlers for LLM's completion streaming events + +## How to Use + +An example of a global search scenario can be found in the following [notebook](../notebooks/global_search_nb). \ No newline at end of file diff --git a/graphrag/docsite/posts/query/1-local_search.md b/graphrag/docsite/posts/query/1-local_search.md new file mode 100644 index 0000000000000000000000000000000000000000..7d2a465d40b6b6c2ebc6bb78abf2d0c0c478cca7 --- /dev/null +++ b/graphrag/docsite/posts/query/1-local_search.md @@ -0,0 +1,67 @@ +--- +title: Local Search 🔎 +navtitle: Local Search +tags: [post, orchestration] +layout: page +date: 2024-03-28 +--- + +## Entity-based Reasoning + +The [local search](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/local_search/) method combines structured data from the knowledge graph with unstructured data from the input documents to augment the LLM context with relevant entity information at query time. It is well-suited for answering questions that require an understanding of specific entities mentioned in the input documents (e.g., “What are the healing properties of chamomile?”). + +## Methodology + +```mermaid +--- +title: Local Search Dataflow +--- +%%{ init: { 'flowchart': { 'curve': 'step' } } }%% +flowchart LR + + uq[User Query] ---.1 + ch1[Conversation
History]---.1 + + .1--Entity
Description
Embedding--> ee[Extracted Entities] + + ee[Extracted Entities] ---.2--Entity-Text
Unit Mapping--> ctu[Candidate
Text Units]--Ranking +
Filtering -->ptu[Prioritized
Text Units]---.3 + .2--Entity-Report
Mapping--> ccr[Candidate
Community Reports]--Ranking +
Filtering -->pcr[Prioritized
Community Reports]---.3 + .2--Entity-Entity
Relationships--> ce[Candidate
Entities]--Ranking +
Filtering -->pe[Prioritized
Entities]---.3 + .2--Entity-Entity
Relationships--> cr[Candidate
Relationships]--Ranking +
Filtering -->pr[Prioritized
Relationships]---.3 + .2--Entity-Covariate
Mappings--> cc[Candidate
Covariates]--Ranking +
Filtering -->pc[Prioritized
Covariates]---.3 + ch1 -->ch2[Conversation History]---.3 + .3-->res[Response] + + classDef green fill:#26B653,stroke:#333,stroke-width:2px,color:#fff; + classDef turquoise fill:#19CCD3,stroke:#333,stroke-width:2px,color:#fff; + classDef rose fill:#DD8694,stroke:#333,stroke-width:2px,color:#fff; + classDef orange fill:#F19914,stroke:#333,stroke-width:2px,color:#fff; + classDef purple fill:#B356CD,stroke:#333,stroke-width:2px,color:#fff; + classDef invisible fill:#fff,stroke:#fff,stroke-width:0px,color:#fff, width:0px; + class uq,ch1 turquoise + class ee green + class ctu,ccr,ce,cr,cc rose + class ptu,pcr,pe,pr,pc,ch2 orange + class res purple + class .1,.2,.3 invisible + + +``` + +Given a user query and, optionally, the conversation history, the local search method identifies a set of entities from the knowledge graph that are semantically-related to the user input. These entities serve as access points into the knowledge graph, enabling the extraction of further relevant details such as connected entities, relationships, entity covariates, and community reports. Additionally, it also extracts relevant text chunks from the raw input documents that are associated with the identified entities. These candidate data sources are then prioritized and filtered to fit within a single context window of pre-defined size, which is used to generate a response to the user query. + +## Configuration + +Below are the key parameters of the [LocalSearch class](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/local_search/search.py): +* `llm`: OpenAI model object to be used for response generation +* `context_builder`: [context builder](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/local_search/mixed_context.py) object to be used for preparing context data from collections of knowledge model objects +* `system_prompt`: prompt template used to generate the search response. Default template can be found at [system_prompt](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/local_search/system_prompt.py) +* `response_type`: free-form text describing the desired response type and format (e.g., `Multiple Paragraphs`, `Multi-Page Report`) +* `llm_params`: a dictionary of additional parameters (e.g., temperature, max_tokens) to be passed to the LLM call +* `context_builder_params`: a dictionary of additional parameters to be passed to the [`context_builder`](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/local_search/mixed_context.py) object when building context for the search prompt +* `callbacks`: optional callback functions, can be used to provide custom event handlers for LLM's completion streaming events + +## How to Use + +An example of a local search scenario can be found in the following [notebook](../notebooks/local_search_nb). + diff --git a/graphrag/docsite/posts/query/2-question_generation.md b/graphrag/docsite/posts/query/2-question_generation.md new file mode 100644 index 0000000000000000000000000000000000000000..73a89f1f294956ad33a89db2375e2e7e4764e4fb --- /dev/null +++ b/graphrag/docsite/posts/query/2-question_generation.md @@ -0,0 +1,28 @@ +--- +title: Question Generation ❔ +navtitle: Question Generation +tags: [post, orchestration] +layout: page +date: 2024-03-28 +--- + +## Entity-based Question Generation + +The [question generation](https://github.com/microsoft/graphrag/blob/main//graphrag/query/question_gen/) method combines structured data from the knowledge graph with unstructured data from the input documents to generate candidate questions related to specific entities. + +## Methodology +Given a list of prior user questions, the question generation method uses the same context-building approach employed in [local search](1-local_search.md) to extract and prioritize relevant structured and unstructured data, including entities, relationships, covariates, community reports and raw text chunks. These data records are then fitted into a single LLM prompt to generate candidate follow-up questions that represent the most important or urgent information content or themes in the data. + +## Configuration + +Below are the key parameters of the [Question Generation class](https://github.com/microsoft/graphrag/blob/main//graphrag/query/question_gen/local_gen.py): +* `llm`: OpenAI model object to be used for response generation +* `context_builder`: [context builder](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/local_search/mixed_context.py) object to be used for preparing context data from collections of knowledge model objects, using the same context builder class as in local search +* `system_prompt`: prompt template used to generate candidate questions. Default template can be found at [system_prompt](https://github.com/microsoft/graphrag/blob/main//graphrag/query/question_gen/system_prompt.py) +* `llm_params`: a dictionary of additional parameters (e.g., temperature, max_tokens) to be passed to the LLM call +* `context_builder_params`: a dictionary of additional parameters to be passed to the [`context_builder`](https://github.com/microsoft/graphrag/blob/main//graphrag/query/structured_search/local_search/mixed_context.py) object when building context for the question generation prompt +* `callbacks`: optional callback functions, can be used to provide custom event handlers for LLM's completion streaming events + +## How to Use + +An example of the question generation function can be found in the following [notebook](../notebooks/local_search_nb). diff --git a/graphrag/docsite/posts/query/3-cli.md b/graphrag/docsite/posts/query/3-cli.md new file mode 100644 index 0000000000000000000000000000000000000000..c1a88f9eb4651578decace8935f1ab2747336fcd --- /dev/null +++ b/graphrag/docsite/posts/query/3-cli.md @@ -0,0 +1,48 @@ +--- +title: Query CLI +navtitle: CLI +layout: page +tags: [post, orchestration] +date: 2024-27-03 +--- + +The GraphRAG query CLI allows for no-code usage of the GraphRAG Query engine. + +```bash +python -m graphrag.query --data --community_level --response_type --method <"local"|"global"> +``` + +## CLI Arguments + +- `--data ` - Folder containing the `.parquet` output files from running the Indexer. +- `--community_level ` - Community level in the Leiden community hierarchy from which we will load the community reports higher value means we use reports on smaller communities. Default: 2 +- `--response_type ` - Free form text describing the response type and format, can be anything, e.g. `Multiple Paragraphs`, `Single Paragraph`, `Single Sentence`, `List of 3-7 Points`, `Single Page`, `Multi-Page Report`. Default: `Multiple Paragraphs`. +- `--method <"local"|"global">` - Method to use to answer the query, one of local or global. For more information check [Overview](overview.md) + +## Env Variables + +Required environment variables to execute: +- `GRAPHRAG_API_KEY` - API Key for executing the model, will fallback to `OPENAI_API_KEY` if one is not provided. +- `GRAPHRAG_LLM_MODEL` - Model to use for Chat Completions. +- `GRAPHRAG_EMBEDDING_MODEL` - Model to use for Embeddings. + +You can further customize the execution by providing these environment variables: + +- `GRAPHRAG_LLM_API_BASE` - The API Base URL. Default: `None` +- `GRAPHRAG_LLM_TYPE` - The LLM operation type. Either `openai_chat` or `azure_openai_chat`. Default: `openai_chat` +- `GRAPHRAG_LLM_MAX_RETRIES` - The maximum number of retries to attempt when a request fails. Default: `20` +- `GRAPHRAG_EMBEDDING_API_BASE` - The API Base URL. Default: `None` +- `GRAPHRAG_EMBEDDING_TYPE` - The embedding client to use. Either `openai_embedding` or `azure_openai_embedding`. Default: `openai_embedding` +- `GRAPHRAG_EMBEDDING_MAX_RETRIES` - The maximum number of retries to attempt when a request fails. Default: `20` +- `GRAPHRAG_LOCAL_SEARCH_TEXT_UNIT_PROP` - Proportion of context window dedicated to related text units. Default: `0.5` +- `GRAPHRAG_LOCAL_SEARCH_COMMUNITY_PROP` - Proportion of context window dedicated to community reports. Default: `0.1` +- `GRAPHRAG_LOCAL_SEARCH_CONVERSATION_HISTORY_MAX_TURNS` - Maximum number of turns to include in the conversation history. Default: `5` +- `GRAPHRAG_LOCAL_SEARCH_TOP_K_ENTITIES` - Number of related entities to retrieve from the entity description embedding store. Default: `10` +- `GRAPHRAG_LOCAL_SEARCH_TOP_K_RELATIONSHIPS` - Control the number of out-of-network relationships to pull into the context window. Default: `10` +- `GRAPHRAG_LOCAL_SEARCH_MAX_TOKENS` - Change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 5000). Default: `12000` +- `GRAPHRAG_LOCAL_SEARCH_LLM_MAX_TOKENS` - Change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 1000=1500). Default: `2000` +- `GRAPHRAG_GLOBAL_SEARCH_MAX_TOKENS` - Change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 5000). Default: `12000` +- `GRAPHRAG_GLOBAL_SEARCH_DATA_MAX_TOKENS` - Change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 5000). Default: `12000` +- `GRAPHRAG_GLOBAL_SEARCH_MAP_MAX_TOKENS` - Default: `500` +- `GRAPHRAG_GLOBAL_SEARCH_REDUCE_MAX_TOKENS` - Change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 1000-1500). Default: `2000` +- `GRAPHRAG_GLOBAL_SEARCH_CONCURRENCY` - Default: `32` \ No newline at end of file diff --git a/graphrag/docsite/posts/query/notebooks/overview.md b/graphrag/docsite/posts/query/notebooks/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..cf1a82593d09bb7e29f6ec486107f8ec02204c63 --- /dev/null +++ b/graphrag/docsite/posts/query/notebooks/overview.md @@ -0,0 +1,13 @@ +--- +title: Query Engine Notebooks +navtitle: Query Engine Notebooks +layout: page +tags: [post, notebook] +--- + +For examples about running Query please refer to the following notebooks: + +- [Global Search Notebook](/posts/query/notebooks/global_search_nb) +- [Local Search Notebook](/posts/query/notebooks/local_search_nb) + +The test dataset for these notebooks can be found [here](/data/operation_dulce/dataset.zip). \ No newline at end of file diff --git a/graphrag/docsite/posts/query/overview.md b/graphrag/docsite/posts/query/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..2b725759eb228711fc29a7cd7d59e37fe460a573 --- /dev/null +++ b/graphrag/docsite/posts/query/overview.md @@ -0,0 +1,31 @@ +--- +title: Query Engine 🔎 +navtitle: Overview +tags: [post] +layout: page +--- + +The Query Engine is the retrieval module of the Graph RAG Library. It is one of the two main components of the Graph RAG library, the other being the Indexing Pipeline (see [Indexing Pipeline](/posts/index/overview)). +It is responsible for the following tasks: + +- [Local Search](#local-search) +- [Global Search](#global-search) +- [Question Generation](#question-generation) + +## Local Search + +Local search method generates answers by combining relevant data from the AI-extracted knowledge-graph with text chunks of the raw documents. This method is suitable for questions that require an understanding of specific entities mentioned in the documents (e.g. What are the healing properties of chamomile?). + +For more details about how Local Search works please refer to the [Local Search](/posts/query/1-local_search) documentation. + +## Global Search + +Global search method generates answers by searching over all AI-generated community reports in a map-reduce fashion. This is a resource-intensive method, but often gives good responses for questions that require an understanding of the dataset as a whole (e.g. What are the most significant values of the herbs mentioned in this notebook?). + +More about this can be checked at the [Global Search](/posts/query/0-global_search) documentation. + +## Question Generation + +This functionality takes a list of user queries and generates the next candidate questions. This is useful for generating follow-up questions in a conversation or for generating a list of questions for the investigator to dive deeper into the dataset. + +Information about how question generation works can be found at the [Question Generation](/posts/query/2-question_generation) documentation page. diff --git a/graphrag/docsite/yarn.lock b/graphrag/docsite/yarn.lock new file mode 100644 index 0000000000000000000000000000000000000000..ad5b51fa2cd7c9a66396c4b2b52fa3926835230f --- /dev/null +++ b/graphrag/docsite/yarn.lock @@ -0,0 +1,2793 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10 + +"@11ty/dependency-tree@npm:^2.0.1": + version: 2.0.1 + resolution: "@11ty/dependency-tree@npm:2.0.1" + checksum: f10df6f7fe71fd39ee6820146b450440bd0a03d7abb065e3486de6aa3e9cb341a480b912f650b360bf4a4383f87197f169a550c418e36efd359eaef17e97ea74 + languageName: node + linkType: hard + +"@11ty/eleventy-dev-server@npm:^1.0.4": + version: 1.0.4 + resolution: "@11ty/eleventy-dev-server@npm:1.0.4" + dependencies: + "@11ty/eleventy-utils": "npm:^1.0.1" + chokidar: "npm:^3.5.3" + debug: "npm:^4.3.4" + dev-ip: "npm:^1.0.1" + finalhandler: "npm:^1.2.0" + mime: "npm:^3.0.0" + minimist: "npm:^1.2.8" + morphdom: "npm:^2.7.0" + please-upgrade-node: "npm:^3.2.0" + ssri: "npm:^8.0.1" + ws: "npm:^8.13.0" + bin: + eleventy-dev-server: cmd.js + checksum: ff8dffcbd0eb2dfc3213cede12d09ddeaae39b2db68ac67685b55e9f0f2e3824e5065279ee0fd52b3190bf552219027fdac051d450364f0fefd6f6cc2ad9a194 + languageName: node + linkType: hard + +"@11ty/eleventy-plugin-syntaxhighlight@npm:^5.0.0": + version: 5.0.0 + resolution: "@11ty/eleventy-plugin-syntaxhighlight@npm:5.0.0" + dependencies: + prismjs: "npm:^1.29.0" + checksum: b6d2663a8fc2874e7893ce345e4a231bcdfbff58df79cc8974a39e34bef71bb0dfa8289a8123b7ed5324a4c842ad5f5021111189c0b43ba1a64a21001480b0c9 + languageName: node + linkType: hard + +"@11ty/eleventy-utils@npm:^1.0.1": + version: 1.0.2 + resolution: "@11ty/eleventy-utils@npm:1.0.2" + dependencies: + normalize-path: "npm:^3.0.0" + checksum: a7602dcf92197259d7dad5a5fd01cc425e8fe47e003f27404020eeeb4cabb641b036eb7d04b323dc9cd25382f92d4ab314de785e7c262e4627074d5797e27513 + languageName: node + linkType: hard + +"@11ty/eleventy@npm:^2.0.1": + version: 2.0.1 + resolution: "@11ty/eleventy@npm:2.0.1" + dependencies: + "@11ty/dependency-tree": "npm:^2.0.1" + "@11ty/eleventy-dev-server": "npm:^1.0.4" + "@11ty/eleventy-utils": "npm:^1.0.1" + "@11ty/lodash-custom": "npm:^4.17.21" + "@iarna/toml": "npm:^2.2.5" + "@sindresorhus/slugify": "npm:^1.1.2" + bcp-47-normalize: "npm:^1.1.1" + chokidar: "npm:^3.5.3" + cross-spawn: "npm:^7.0.3" + debug: "npm:^4.3.4" + dependency-graph: "npm:^0.11.0" + ejs: "npm:^3.1.9" + fast-glob: "npm:^3.2.12" + graceful-fs: "npm:^4.2.11" + gray-matter: "npm:^4.0.3" + hamljs: "npm:^0.6.2" + handlebars: "npm:^4.7.7" + is-glob: "npm:^4.0.3" + iso-639-1: "npm:^2.1.15" + kleur: "npm:^4.1.5" + liquidjs: "npm:^10.7.0" + luxon: "npm:^3.3.0" + markdown-it: "npm:^13.0.1" + micromatch: "npm:^4.0.5" + minimist: "npm:^1.2.8" + moo: "npm:^0.5.2" + multimatch: "npm:^5.0.0" + mustache: "npm:^4.2.0" + normalize-path: "npm:^3.0.0" + nunjucks: "npm:^3.2.3" + path-to-regexp: "npm:^6.2.1" + please-upgrade-node: "npm:^3.2.0" + posthtml: "npm:^0.16.6" + posthtml-urls: "npm:^1.0.0" + pug: "npm:^3.0.2" + recursive-copy: "npm:^2.0.14" + semver: "npm:^7.3.8" + slugify: "npm:^1.6.6" + bin: + eleventy: cmd.js + checksum: 560655c9f955c2597191c7dcc761b846b7b44bd5494a2fdfb58971841ff81a37ac3404cdbce49ea74b72f32f509982bf366e31e455f3112ca2671516fe79a709 + languageName: node + linkType: hard + +"@11ty/lodash-custom@npm:^4.17.21": + version: 4.17.21 + resolution: "@11ty/lodash-custom@npm:4.17.21" + checksum: 1b4658f2054757075ede5fd364613516513295c2f0d7112afb78133eb79c922310844196630046aa0d3687298f4d6040cdd043883511c368cbc7d61f4619fe4c + languageName: node + linkType: hard + +"@babel/helper-string-parser@npm:^7.23.4": + version: 7.24.1 + resolution: "@babel/helper-string-parser@npm:7.24.1" + checksum: 04c0ede77b908b43e6124753b48bc485528112a9335f0a21a226bff1ace75bb6e64fab24c85cb4b1610ef3494dacd1cb807caeb6b79a7b36c43d48c289b35949 + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-validator-identifier@npm:7.22.20" + checksum: df882d2675101df2d507b95b195ca2f86a3ef28cb711c84f37e79ca23178e13b9f0d8b522774211f51e40168bf5142be4c1c9776a150cddb61a0d5bf3e95750b + languageName: node + linkType: hard + +"@babel/parser@npm:^7.6.0, @babel/parser@npm:^7.9.6": + version: 7.24.4 + resolution: "@babel/parser@npm:7.24.4" + bin: + parser: ./bin/babel-parser.js + checksum: 3742cc5068036287e6395269dce5a2735e6349cdc8d4b53297c75f98c580d7e1c8cb43235623999d151f2ef975d677dbc2c2357573a1855caa71c271bf3046c9 + languageName: node + linkType: hard + +"@babel/types@npm:^7.6.1, @babel/types@npm:^7.8.3, @babel/types@npm:^7.9.6": + version: 7.24.0 + resolution: "@babel/types@npm:7.24.0" + dependencies: + "@babel/helper-string-parser": "npm:^7.23.4" + "@babel/helper-validator-identifier": "npm:^7.22.20" + to-fast-properties: "npm:^2.0.0" + checksum: a0b4875ce2e132f9daff0d5b27c7f4c4fcc97f2b084bdc5834e92c9d32592778489029e65d99d00c406da612d87b72d7a236c0afccaa1435c028d0c94c9b6da4 + languageName: node + linkType: hard + +"@graphrag/docsite@workspace:.": + version: 0.0.0-use.local + resolution: "@graphrag/docsite@workspace:." + dependencies: + "@11ty/eleventy": "npm:^2.0.1" + "@11ty/eleventy-plugin-syntaxhighlight": "npm:^5.0.0" + "@kevingimbel/eleventy-plugin-mermaid": "npm:^2.2.1" + eleventy-plugin-code-clipboard: "npm:^0.1.1" + markdown-it: "npm:^14.1.0" + languageName: unknown + linkType: soft + +"@iarna/toml@npm:^2.2.5": + version: 2.2.5 + resolution: "@iarna/toml@npm:2.2.5" + checksum: b61426dc1a3297bbcb24cb8e9c638663866b4bb6f28f2c377b167e4b1f8956d8d208c484b73bb59f4232249903545cc073364c43576d2d5ad66afbd730ad24a9 + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: e9ed5fd27c3aec1095e3a16e0c0cf148d1fee55a38665c35f7b3f86a9b5d00d042ddaabc98e8a1cb7463b9378c15f22a94eb35e99469c201453eb8375191f243 + languageName: node + linkType: hard + +"@kevingimbel/eleventy-plugin-mermaid@npm:^2.2.1": + version: 2.2.1 + resolution: "@kevingimbel/eleventy-plugin-mermaid@npm:2.2.1" + dependencies: + htmlencode: "npm:^0.0.4" + checksum: 4870aca1f4d918e3174ba6b0fa1a3c71b8880ccd1b67d28490a67d90deeb6bad829bc97dc2e588be569c44a2d374cc0215f0019b9407b03c513d3e41038b6ba3 + languageName: node + linkType: hard + +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": "npm:2.0.5" + run-parallel: "npm:^1.1.9" + checksum: 6ab2a9b8a1d67b067922c36f259e3b3dfd6b97b219c540877a4944549a4d49ea5ceba5663905ab5289682f1f3c15ff441d02f0447f620a42e1cb5e1937174d4b + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": "npm:2.1.5" + fastq: "npm:^1.6.0" + checksum: 40033e33e96e97d77fba5a238e4bba4487b8284678906a9f616b5579ddaf868a18874c0054a75402c9fbaaa033a25ceae093af58c9c30278e35c23c9479e79b0 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^2.0.0": + version: 2.2.2 + resolution: "@npmcli/agent@npm:2.2.2" + dependencies: + agent-base: "npm:^7.1.0" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.1" + lru-cache: "npm:^10.0.1" + socks-proxy-agent: "npm:^8.0.3" + checksum: 96fc0036b101bae5032dc2a4cd832efb815ce9b33f9ee2f29909ee49d96a0026b3565f73c507a69eb8603f5cb32e0ae45a70cab1e2655990a4e06ae99f7f572a + languageName: node + linkType: hard + +"@npmcli/fs@npm:^3.1.0": + version: 3.1.0 + resolution: "@npmcli/fs@npm:3.1.0" + dependencies: + semver: "npm:^7.3.5" + checksum: f3a7ab3a31de65e42aeb6ed03ed035ef123d2de7af4deb9d4a003d27acc8618b57d9fb9d259fe6c28ca538032a028f37337264388ba27d26d37fff7dde22476e + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 115e8ceeec6bc69dff2048b35c0ab4f8bbee12d8bb6c1f4af758604586d802b6e669dcb02dda61d078de42c2b4ddce41b3d9e726d7daa6b4b850f4adbf7333ff + languageName: node + linkType: hard + +"@sindresorhus/slugify@npm:^1.1.2": + version: 1.1.2 + resolution: "@sindresorhus/slugify@npm:1.1.2" + dependencies: + "@sindresorhus/transliterate": "npm:^0.1.1" + escape-string-regexp: "npm:^4.0.0" + checksum: 5177152d3edb223650e71dcbf234b18ddd1782af1c0cf0787034f059399c0ddf22514cd3fdea0db86d7e3c9a96edae3a605e67ce1616962f7ac46f51a7f4a267 + languageName: node + linkType: hard + +"@sindresorhus/transliterate@npm:^0.1.1": + version: 0.1.2 + resolution: "@sindresorhus/transliterate@npm:0.1.2" + dependencies: + escape-string-regexp: "npm:^2.0.0" + lodash.deburr: "npm:^4.1.0" + checksum: bbe48cf3ecf53c25ef3d7f6a75521b95cd37ab5d786dd4fc9cddfb00502d8455720d7c585958caf34ab6f5fb7f8f4a9c055bfbe0d4a395523448f02a73c850a3 + languageName: node + linkType: hard + +"@types/minimatch@npm:^3.0.3": + version: 3.0.5 + resolution: "@types/minimatch@npm:3.0.5" + checksum: c41d136f67231c3131cf1d4ca0b06687f4a322918a3a5adddc87ce90ed9dbd175a3610adee36b106ae68c0b92c637c35e02b58c8a56c424f71d30993ea220b92 + languageName: node + linkType: hard + +"a-sync-waterfall@npm:^1.0.0": + version: 1.0.1 + resolution: "a-sync-waterfall@npm:1.0.1" + checksum: 6069080aff936c88fc32f798cc172a8b541e35b993dc5d2e43b74b6f37c522744eec107e1d475d2c624825c6cb7d2ec9ec020dbe4520578afcae74f11902daa2 + languageName: node + linkType: hard + +"abbrev@npm:^2.0.0": + version: 2.0.0 + resolution: "abbrev@npm:2.0.0" + checksum: ca0a54e35bea4ece0ecb68a47b312e1a9a6f772408d5bcb9051230aaa94b0460671c5b5c9cb3240eb5b7bc94c52476550eb221f65a0bbd0145bdc9f3113a6707 + languageName: node + linkType: hard + +"acorn@npm:^7.1.1": + version: 7.4.1 + resolution: "acorn@npm:7.4.1" + bin: + acorn: bin/acorn + checksum: 8be2a40714756d713dfb62544128adce3b7102c6eb94bc312af196c2cc4af76e5b93079bd66b05e9ca31b35a9b0ce12171d16bc55f366cafdb794fdab9d753ec + languageName: node + linkType: hard + +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": + version: 7.1.1 + resolution: "agent-base@npm:7.1.1" + dependencies: + debug: "npm:^4.3.4" + checksum: c478fec8f79953f118704d007a38f2a185458853f5c45579b9669372bd0e12602e88dc2ad0233077831504f7cd6fcc8251c383375bba5eaaf563b102938bda26 + languageName: node + linkType: hard + +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" + dependencies: + clean-stack: "npm:^2.0.0" + indent-string: "npm:^4.0.0" + checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.0.1 + resolution: "ansi-regex@npm:6.0.1" + checksum: 1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169 + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: b4494dfbfc7e4591b4711a396bd27e540f8153914123dccb4cdbbcb514015ada63a3809f362b9d8d4f6b17a706f1d7bea3c6f974b15fa5ae76b5b502070889ff + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: 70fdf883b704d17a5dfc9cde206e698c16bcd74e7f196ab821511651aee4f9f76c9514bdfa6ca3a27b5e49138b89cb222a28caf3afe4567570139577f991df32 + languageName: node + linkType: hard + +"any-promise@npm:^0.1.0": + version: 0.1.0 + resolution: "any-promise@npm:0.1.0" + checksum: d618bab8f9fec26593f004c7733e685463106bd36e166349891f3bac84fc30d1b4211730b5e2e6cb16e7d7faa5e61651adec362a1f54a6cd2c110d7ad8d5fb85 + languageName: node + linkType: hard + +"anymatch@npm:~3.1.2": + version: 3.1.3 + resolution: "anymatch@npm:3.1.3" + dependencies: + normalize-path: "npm:^3.0.0" + picomatch: "npm:^2.0.4" + checksum: 3e044fd6d1d26545f235a9fe4d7a534e2029d8e59fa7fd9f2a6eb21230f6b5380ea1eaf55136e60cbf8e613544b3b766e7a6fa2102e2a3a117505466e3025dc2 + languageName: node + linkType: hard + +"argparse@npm:^1.0.7": + version: 1.0.10 + resolution: "argparse@npm:1.0.10" + dependencies: + sprintf-js: "npm:~1.0.2" + checksum: c6a621343a553ff3779390bb5ee9c2263d6643ebcd7843227bdde6cc7adbed796eb5540ca98db19e3fd7b4714e1faa51551f8849b268bb62df27ddb15cbcd91e + languageName: node + linkType: hard + +"argparse@npm:^2.0.1": + version: 2.0.1 + resolution: "argparse@npm:2.0.1" + checksum: 18640244e641a417ec75a9bd38b0b2b6b95af5199aa241b131d4b2fb206f334d7ecc600bd194861610a5579084978bfcbb02baa399dbe442d56d0ae5e60dbaef + languageName: node + linkType: hard + +"array-differ@npm:^1.0.0": + version: 1.0.0 + resolution: "array-differ@npm:1.0.0" + checksum: ac6060952c7cb0a534c06ea3c6c960432d605d905e9901afe386e841aadc6e102ed81e0e6abe5eb4b50dd43907fc6426f6012b5ca784ec7741a5b398690c0998 + languageName: node + linkType: hard + +"array-differ@npm:^3.0.0": + version: 3.0.0 + resolution: "array-differ@npm:3.0.0" + checksum: 117edd9df5c1530bd116c6e8eea891d4bd02850fd89b1b36e532b6540e47ca620a373b81feca1c62d1395d9ae601516ba538abe5e8172d41091da2c546b05fb7 + languageName: node + linkType: hard + +"array-union@npm:^1.0.1": + version: 1.0.2 + resolution: "array-union@npm:1.0.2" + dependencies: + array-uniq: "npm:^1.0.1" + checksum: 82cec6421b6e6766556c484835a6d476a873f1b71cace5ab2b4f1b15b1e3162dc4da0d16f7a2b04d4aec18146c6638fe8f661340b31ba8e469fd811a1b45dc8d + languageName: node + linkType: hard + +"array-union@npm:^2.1.0": + version: 2.1.0 + resolution: "array-union@npm:2.1.0" + checksum: 5bee12395cba82da674931df6d0fea23c4aa4660cb3b338ced9f828782a65caa232573e6bf3968f23e0c5eb301764a382cef2f128b170a9dc59de0e36c39f98d + languageName: node + linkType: hard + +"array-uniq@npm:^1.0.1": + version: 1.0.3 + resolution: "array-uniq@npm:1.0.3" + checksum: 1625f06b093d8bf279b81adfec6e72951c0857d65b5e3f65f053fffe9f9dd61c2fc52cff57e38a4700817e7e3f01a4faa433d505ea9e33cdae4514c334e0bf9e + languageName: node + linkType: hard + +"arrify@npm:^1.0.0": + version: 1.0.1 + resolution: "arrify@npm:1.0.1" + checksum: 745075dd4a4624ff0225c331dacb99be501a515d39bcb7c84d24660314a6ec28e68131b137e6f7e16318170842ce97538cd298fc4cd6b2cc798e0b957f2747e7 + languageName: node + linkType: hard + +"arrify@npm:^2.0.1": + version: 2.0.1 + resolution: "arrify@npm:2.0.1" + checksum: 067c4c1afd182806a82e4c1cb8acee16ab8b5284fbca1ce29408e6e91281c36bb5b612f6ddfbd40a0f7a7e0c75bf2696eb94c027f6e328d6e9c52465c98e4209 + languageName: node + linkType: hard + +"asap@npm:^2.0.3, asap@npm:~2.0.3": + version: 2.0.6 + resolution: "asap@npm:2.0.6" + checksum: b244c0458c571945e4b3be0b14eb001bea5596f9868cc50cc711dc03d58a7e953517d3f0dad81ccde3ff37d1f074701fa76a6f07d41aaa992d7204a37b915dda + languageName: node + linkType: hard + +"assert-never@npm:^1.2.1": + version: 1.2.1 + resolution: "assert-never@npm:1.2.1" + checksum: ea4f1756d90f55254c4dc7a20d6c5d5bc169160562aefe3d8756b598c10e695daf568f21b6d6b12245d7f3782d3ff83ef6a01ab75d487adfc6909470a813bf8c + languageName: node + linkType: hard + +"async@npm:^3.2.3": + version: 3.2.5 + resolution: "async@npm:3.2.5" + checksum: 323c3615c3f0ab1ac25a6f953296bc0ac3213d5e0f1c0debdb12964e55963af288d570293c11e44f7967af58c06d2a88d0ea588c86ec0fbf62fa98037f604a0f + languageName: node + linkType: hard + +"babel-walk@npm:3.0.0-canary-5": + version: 3.0.0-canary-5 + resolution: "babel-walk@npm:3.0.0-canary-5" + dependencies: + "@babel/types": "npm:^7.9.6" + checksum: f4cea17303b33266fa97be471df9917d386bb5cd2756ae4c4725b3f105b9d630789818be202de06afa546e94810add61d614aa5eeb16e2a3027636cbafac2c1a + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 + languageName: node + linkType: hard + +"bcp-47-match@npm:^1.0.0": + version: 1.0.3 + resolution: "bcp-47-match@npm:1.0.3" + checksum: 27dd9792d611cffde96722a6c251d924d0f2a085219e59270600b02c544814f759ccc5ffdbf3f01bb154e750d80327e3df6c6f304f10bb38b3c974bb247bafaa + languageName: node + linkType: hard + +"bcp-47-normalize@npm:^1.1.1": + version: 1.1.1 + resolution: "bcp-47-normalize@npm:1.1.1" + dependencies: + bcp-47: "npm:^1.0.0" + bcp-47-match: "npm:^1.0.0" + checksum: 2c5b9219299765eb6298b436bc5f05b1ed33c1898130e548b139efd5dea9bd9d1d953949786883d7c1e61372f096c50cf2f008a7b31fd155933c567723885e1b + languageName: node + linkType: hard + +"bcp-47@npm:^1.0.0": + version: 1.0.8 + resolution: "bcp-47@npm:1.0.8" + dependencies: + is-alphabetical: "npm:^1.0.0" + is-alphanumerical: "npm:^1.0.0" + is-decimal: "npm:^1.0.0" + checksum: 0291be2a5989df2710c8b0af1e5b2e44069b317428445a66973e6b67b8d349ac7ac00e75838d1262b768be5811e52f4a2934f8d8874cbd433e2c9934b1896871 + languageName: node + linkType: hard + +"binary-extensions@npm:^2.0.0": + version: 2.3.0 + resolution: "binary-extensions@npm:2.3.0" + checksum: bcad01494e8a9283abf18c1b967af65ee79b0c6a9e6fcfafebfe91dbe6e0fc7272bafb73389e198b310516ae04f7ad17d79aacf6cb4c0d5d5202a7e2e52c7d98 + languageName: node + linkType: hard + +"brace-expansion@npm:^1.1.7": + version: 1.1.11 + resolution: "brace-expansion@npm:1.1.11" + dependencies: + balanced-match: "npm:^1.0.0" + concat-map: "npm:0.0.1" + checksum: faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + languageName: node + linkType: hard + +"braces@npm:^3.0.2, braces@npm:~3.0.2": + version: 3.0.3 + resolution: "braces@npm:3.0.3" + dependencies: + fill-range: "npm:^7.1.1" + checksum: fad11a0d4697a27162840b02b1fad249c1683cbc510cd5bf1a471f2f8085c046d41094308c577a50a03a579dd99d5a6b3724c4b5e8b14df2c4443844cfcda2c6 + languageName: node + linkType: hard + +"cacache@npm:^18.0.0": + version: 18.0.2 + resolution: "cacache@npm:18.0.2" + dependencies: + "@npmcli/fs": "npm:^3.1.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^10.2.2" + lru-cache: "npm:^10.0.1" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^2.0.1" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^4.0.0" + ssri: "npm:^10.0.0" + tar: "npm:^6.1.11" + unique-filename: "npm:^3.0.0" + checksum: 5ca58464f785d4d64ac2019fcad95451c8c89bea25949f63acd8987fcc3493eaef1beccc0fa39e673506d879d3fc1ab420760f8a14f8ddf46ea2d121805a5e96 + languageName: node + linkType: hard + +"call-bind@npm:^1.0.2": + version: 1.0.7 + resolution: "call-bind@npm:1.0.7" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + set-function-length: "npm:^1.2.1" + checksum: cd6fe658e007af80985da5185bff7b55e12ef4c2b6f41829a26ed1eef254b1f1c12e3dfd5b2b068c6ba8b86aba62390842d81752e67dcbaec4f6f76e7113b6b7 + languageName: node + linkType: hard + +"chalk@npm:^4.0.2": + version: 4.1.2 + resolution: "chalk@npm:4.1.2" + dependencies: + ansi-styles: "npm:^4.1.0" + supports-color: "npm:^7.1.0" + checksum: cb3f3e594913d63b1814d7ca7c9bafbf895f75fbf93b92991980610dfd7b48500af4e3a5d4e3a8f337990a96b168d7eb84ee55efdce965e2ee8efc20f8c8f139 + languageName: node + linkType: hard + +"character-parser@npm:^2.2.0": + version: 2.2.0 + resolution: "character-parser@npm:2.2.0" + dependencies: + is-regex: "npm:^1.0.3" + checksum: 5980ddc776a133ba7a264aaec77ab9dd883aa9ff45bb335bfa93ae26b8e7360e60b2c97119f85cc4d2203829c9977df7c6ba6612354b1dfc9ef41d84fde03002 + languageName: node + linkType: hard + +"chokidar@npm:^3.5.3": + version: 3.6.0 + resolution: "chokidar@npm:3.6.0" + dependencies: + anymatch: "npm:~3.1.2" + braces: "npm:~3.0.2" + fsevents: "npm:~2.3.2" + glob-parent: "npm:~5.1.2" + is-binary-path: "npm:~2.1.0" + is-glob: "npm:~4.0.1" + normalize-path: "npm:~3.0.0" + readdirp: "npm:~3.6.0" + dependenciesMeta: + fsevents: + optional: true + checksum: c327fb07704443f8d15f7b4a7ce93b2f0bc0e6cea07ec28a7570aa22cd51fcf0379df589403976ea956c369f25aa82d84561947e227cd925902e1751371658df + languageName: node + linkType: hard + +"chownr@npm:^2.0.0": + version: 2.0.0 + resolution: "chownr@npm:2.0.0" + checksum: c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f + languageName: node + linkType: hard + +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: fa00c91b4332b294de06b443923246bccebe9fab1b253f7fe1772d37b06a2269b4039a85e309abe1fe11b267b11c08d1d0473fda3badd6167f57313af2887a64 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 + languageName: node + linkType: hard + +"commander@npm:^10.0.0": + version: 10.0.1 + resolution: "commander@npm:10.0.1" + checksum: 8799faa84a30da985802e661cc9856adfaee324d4b138413013ef7f087e8d7924b144c30a1f1405475f0909f467665cd9e1ce13270a2f41b141dab0b7a58f3fb + languageName: node + linkType: hard + +"commander@npm:^5.1.0": + version: 5.1.0 + resolution: "commander@npm:5.1.0" + checksum: 3e2ef5c003c5179250161e42ce6d48e0e69a54af970c65b7f985c70095240c260fd647453efd4c2c5a31b30ce468f373dc70f769c2f54a2c014abc4792aaca28 + languageName: node + linkType: hard + +"concat-map@npm:0.0.1": + version: 0.0.1 + resolution: "concat-map@npm:0.0.1" + checksum: 9680699c8e2b3af0ae22592cb764acaf973f292a7b71b8a06720233011853a58e256c89216a10cbe889727532fd77f8bcd49a760cedfde271b8e006c20e079f2 + languageName: node + linkType: hard + +"constantinople@npm:^4.0.1": + version: 4.0.1 + resolution: "constantinople@npm:4.0.1" + dependencies: + "@babel/parser": "npm:^7.6.0" + "@babel/types": "npm:^7.6.1" + checksum: 15fc9bec82711f275e35581fe97a7e7b8d30441745955023570f258bbf876f4bf3de84faa6e7a663a3048565d9cc58bde65d300f74d090faec6afe07913d584f + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3": + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: e1a13869d2f57d974de0d9ef7acbf69dc6937db20b918525a01dacb5032129bd552d290d886d981e99f1b624cb03657084cc87bd40f115c07ecf376821c729ce + languageName: node + linkType: hard + +"debug@npm:2.6.9": + version: 2.6.9 + resolution: "debug@npm:2.6.9" + dependencies: + ms: "npm:2.0.0" + checksum: e07005f2b40e04f1bd14a3dd20520e9c4f25f60224cb006ce9d6781732c917964e9ec029fc7f1a151083cd929025ad5133814d4dc624a9aaf020effe4914ed14 + languageName: node + linkType: hard + +"debug@npm:4, debug@npm:^4.3.4": + version: 4.3.4 + resolution: "debug@npm:4.3.4" + dependencies: + ms: "npm:2.1.2" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 0073c3bcbd9cb7d71dd5f6b55be8701af42df3e56e911186dfa46fac3a5b9eb7ce7f377dd1d3be6db8977221f8eb333d945216f645cf56f6b688cd484837d255 + languageName: node + linkType: hard + +"define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.0.1" + checksum: abdcb2505d80a53524ba871273e5da75e77e52af9e15b3aa65d8aad82b8a3a424dad7aee2cc0b71470ac7acf501e08defac362e8b6a73cdb4309f028061df4ae + languageName: node + linkType: hard + +"dependency-graph@npm:^0.11.0": + version: 0.11.0 + resolution: "dependency-graph@npm:0.11.0" + checksum: 6b5eb540303753037a613e781da4b81534d139cbabc92f342630ed622e3ef4c332fc40cf87823e1ec71a7aeb4b195f8d88d7e625931ce6007bf2bf09a8bfb01e + languageName: node + linkType: hard + +"dev-ip@npm:^1.0.1": + version: 1.0.1 + resolution: "dev-ip@npm:1.0.1" + bin: + dev-ip: lib/dev-ip.js + checksum: 274a6470c2143e4cdcb2b27e0bea137dbc2b42667eb59c890e703185054cb2bcaf2d8533e7ad2f532fe551a90542abc6b37053e8d73918a4fcfb7ffd76589620 + languageName: node + linkType: hard + +"doctypes@npm:^1.1.0": + version: 1.1.0 + resolution: "doctypes@npm:1.1.0" + checksum: 6e6c2d1a80f2072dc4831994c914c44455e341c5ab18c16797368a0afd59d7c22f3335805ba2c1dd2931e9539d1ba8b613b7650dc63f6ab56b77b8d888055de8 + languageName: node + linkType: hard + +"dom-serializer@npm:^1.0.1": + version: 1.4.1 + resolution: "dom-serializer@npm:1.4.1" + dependencies: + domelementtype: "npm:^2.0.1" + domhandler: "npm:^4.2.0" + entities: "npm:^2.0.0" + checksum: 53b217bcfed4a0f90dd47f34f239b1c81fff53ffa39d164d722325817fdb554903b145c2d12c8421ce0df7d31c1b180caf7eacd3c86391dd925f803df8027dcc + languageName: node + linkType: hard + +"domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0": + version: 2.3.0 + resolution: "domelementtype@npm:2.3.0" + checksum: ee837a318ff702622f383409d1f5b25dd1024b692ef64d3096ff702e26339f8e345820f29a68bcdcea8cfee3531776b3382651232fbeae95612d6f0a75efb4f6 + languageName: node + linkType: hard + +"domhandler@npm:^4.2.0, domhandler@npm:^4.2.2": + version: 4.3.1 + resolution: "domhandler@npm:4.3.1" + dependencies: + domelementtype: "npm:^2.2.0" + checksum: e0d2af7403997a3ca040a9ace4a233b75ebe321e0ef628b417e46d619d65d47781b2f2038b6c2ef6e56e73e66aec99caf6a12c7e687ecff18ef74af6dfbde5de + languageName: node + linkType: hard + +"domutils@npm:^2.8.0": + version: 2.8.0 + resolution: "domutils@npm:2.8.0" + dependencies: + dom-serializer: "npm:^1.0.1" + domelementtype: "npm:^2.2.0" + domhandler: "npm:^4.2.0" + checksum: 1f316a03f00b09a8893d4a25d297d5cbffd02c564509dede28ef72d5ce38d93f6d61f1de88d439f31b14a1d9b42f587ed711b9e8b1b4d3bf6001399832bfc4e0 + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 9b1d3e1baefeaf7d70799db8774149cef33b97183a6addceeba0cf6b85ba23ee2686f302f14482006df32df75d32b17c509c143a3689627929e4a8efaf483952 + languageName: node + linkType: hard + +"ee-first@npm:1.1.1": + version: 1.1.1 + resolution: "ee-first@npm:1.1.1" + checksum: 1b4cac778d64ce3b582a7e26b218afe07e207a0f9bfe13cc7395a6d307849cfe361e65033c3251e00c27dd060cab43014c2d6b2647676135e18b77d2d05b3f4f + languageName: node + linkType: hard + +"ejs@npm:^3.1.9": + version: 3.1.10 + resolution: "ejs@npm:3.1.10" + dependencies: + jake: "npm:^10.8.5" + bin: + ejs: bin/cli.js + checksum: a9cb7d7cd13b7b1cd0be5c4788e44dd10d92f7285d2f65b942f33e127230c054f99a42db4d99f766d8dbc6c57e94799593ee66a14efd7c8dd70c4812bf6aa384 + languageName: node + linkType: hard + +"eleventy-plugin-code-clipboard@npm:^0.1.1": + version: 0.1.1 + resolution: "eleventy-plugin-code-clipboard@npm:0.1.1" + dependencies: + uglify-js: "npm:^3.14.5" + checksum: c3bd659bd9d950cad786fd4ff14fcdd7dc9046269de3f3694d4cc1a87c51ea3bb6b263acd7b78a5954d0fef103463808cdb17269c86455f0e2a4a5790905db45 + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: c72d67a6821be15ec11997877c437491c313d924306b8da5d87d2a2bcc2cec9903cb5b04ee1a088460501d8e5b44f10df82fdc93c444101a7610b80c8b6938e1 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 915acf859cea7131dac1b2b5c9c8e35c4849e325a1d114c30adb8cd615970f6dca0e27f64f3a4949d7d6ed86ecd79a1c5c63f02e697513cddd7b5835c90948b8 + languageName: node + linkType: hard + +"encodeurl@npm:~1.0.2": + version: 1.0.2 + resolution: "encodeurl@npm:1.0.2" + checksum: e50e3d508cdd9c4565ba72d2012e65038e5d71bdc9198cb125beb6237b5b1ade6c0d343998da9e170fb2eae52c1bed37d4d6d98a46ea423a0cddbed5ac3f780c + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f + languageName: node + linkType: hard + +"entities@npm:^2.0.0": + version: 2.2.0 + resolution: "entities@npm:2.2.0" + checksum: 2c765221ee324dbe25e1b8ca5d1bf2a4d39e750548f2e85cbf7ca1d167d709689ddf1796623e66666ae747364c11ed512c03b48c5bbe70968d30f2a4009509b7 + languageName: node + linkType: hard + +"entities@npm:^3.0.1, entities@npm:~3.0.1": + version: 3.0.1 + resolution: "entities@npm:3.0.1" + checksum: 3706e0292ea3f3679720b3d3b1ed6290b164aaeb11116691a922a3acea144503871e0de2170b47671c3b735549b8b7f4741d0d3c2987e8f985ccaa0dd3762eba + languageName: node + linkType: hard + +"entities@npm:^4.4.0": + version: 4.5.0 + resolution: "entities@npm:4.5.0" + checksum: ede2a35c9bce1aeccd055a1b445d41c75a14a2bb1cd22e242f20cf04d236cdcd7f9c859eb83f76885327bfae0c25bf03303665ee1ce3d47c5927b98b0e3e3d48 + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 1d20d825cdcce8d811bfbe86340f4755c02655a7feb2f13f8c880566d9d72a3f6c92c192a6867632e490d6da67b678271f46e01044996a6443e870331100dfdd + languageName: node + linkType: hard + +"errno@npm:^0.1.2": + version: 0.1.8 + resolution: "errno@npm:0.1.8" + dependencies: + prr: "npm:~1.0.1" + bin: + errno: cli.js + checksum: 93076ed11bedb8f0389cbefcbdd3445f66443159439dccbaac89a053428ad92147676736235d275612dc0296d3f9a7e6b7177ed78a566b6cd15dacd4fa0d5888 + languageName: node + linkType: hard + +"es-define-property@npm:^1.0.0": + version: 1.0.0 + resolution: "es-define-property@npm:1.0.0" + dependencies: + get-intrinsic: "npm:^1.2.4" + checksum: f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6 + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: 96e65d640156f91b707517e8cdc454dd7d47c32833aa3e85d79f24f9eb7ea85f39b63e36216ef0114996581969b59fe609a94e30316b08f5f4df1d44134cf8d5 + languageName: node + linkType: hard + +"escape-html@npm:~1.0.3": + version: 1.0.3 + resolution: "escape-html@npm:1.0.3" + checksum: 6213ca9ae00d0ab8bccb6d8d4e0a98e76237b2410302cf7df70aaa6591d509a2a37ce8998008cbecae8fc8ffaadf3fb0229535e6a145f3ce0b211d060decbb24 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^2.0.0": + version: 2.0.0 + resolution: "escape-string-regexp@npm:2.0.0" + checksum: 9f8a2d5743677c16e85c810e3024d54f0c8dea6424fad3c79ef6666e81dd0846f7437f5e729dfcdac8981bc9e5294c39b4580814d114076b8d36318f46ae4395 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^4.0.0": + version: 4.0.0 + resolution: "escape-string-regexp@npm:4.0.0" + checksum: 98b48897d93060f2322108bf29db0feba7dd774be96cd069458d1453347b25ce8682ecc39859d4bca2203cc0ab19c237bcc71755eff49a0f8d90beadeeba5cc5 + languageName: node + linkType: hard + +"esprima@npm:^4.0.0": + version: 4.0.1 + resolution: "esprima@npm:4.0.1" + bin: + esparse: ./bin/esparse.js + esvalidate: ./bin/esvalidate.js + checksum: f1d3c622ad992421362294f7acf866aa9409fbad4eb2e8fa230bd33944ce371d32279667b242d8b8907ec2b6ad7353a717f3c0e60e748873a34a7905174bc0eb + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 2d9bbb6473de7051f96790d5f9a678f32e60ed0aa70741dc7fdc96fec8d631124ec3374ac144387604f05afff9500f31a1d45bd9eee4cdc2e4f9ad2d9b9d5dbd + languageName: node + linkType: hard + +"extend-shallow@npm:^2.0.1": + version: 2.0.1 + resolution: "extend-shallow@npm:2.0.1" + dependencies: + is-extendable: "npm:^0.1.0" + checksum: 8fb58d9d7a511f4baf78d383e637bd7d2e80843bd9cd0853649108ea835208fb614da502a553acc30208e1325240bb7cc4a68473021612496bb89725483656d8 + languageName: node + linkType: hard + +"fast-glob@npm:^3.2.12": + version: 3.3.2 + resolution: "fast-glob@npm:3.3.2" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.4" + checksum: 222512e9315a0efca1276af9adb2127f02105d7288fa746145bf45e2716383fb79eb983c89601a72a399a56b7c18d38ce70457c5466218c5f13fad957cee16df + languageName: node + linkType: hard + +"fastq@npm:^1.6.0": + version: 1.17.1 + resolution: "fastq@npm:1.17.1" + dependencies: + reusify: "npm:^1.0.4" + checksum: a443180068b527dd7b3a63dc7f2a47ceca2f3e97b9c00a1efe5538757e6cc4056a3526df94308075d7727561baf09ebaa5b67da8dcbddb913a021c5ae69d1f69 + languageName: node + linkType: hard + +"filelist@npm:^1.0.4": + version: 1.0.4 + resolution: "filelist@npm:1.0.4" + dependencies: + minimatch: "npm:^5.0.1" + checksum: 4b436fa944b1508b95cffdfc8176ae6947b92825483639ef1b9a89b27d82f3f8aa22b21eed471993f92709b431670d4e015b39c087d435a61e1bb04564cf51de + languageName: node + linkType: hard + +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: a7095cb39e5bc32fada2aa7c7249d3f6b01bd1ce461a61b0adabacccabd9198500c6fb1f68a7c851a657e273fce2233ba869638897f3d7ed2e87a2d89b4436ea + languageName: node + linkType: hard + +"finalhandler@npm:^1.2.0": + version: 1.2.0 + resolution: "finalhandler@npm:1.2.0" + dependencies: + debug: "npm:2.6.9" + encodeurl: "npm:~1.0.2" + escape-html: "npm:~1.0.3" + on-finished: "npm:2.4.1" + parseurl: "npm:~1.3.3" + statuses: "npm:2.0.1" + unpipe: "npm:~1.0.0" + checksum: 635718cb203c6d18e6b48dfbb6c54ccb08ea470e4f474ddcef38c47edcf3227feec316f886dd701235997d8af35240cae49856721ce18f539ad038665ebbf163 + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.1.1 + resolution: "foreground-child@npm:3.1.1" + dependencies: + cross-spawn: "npm:^7.0.0" + signal-exit: "npm:^4.0.1" + checksum: 087edd44857d258c4f73ad84cb8df980826569656f2550c341b27adf5335354393eec24ea2fabd43a253233fb27cee177ebe46bd0b7ea129c77e87cb1e9936fb + languageName: node + linkType: hard + +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: "npm:^3.0.0" + checksum: 03191781e94bc9a54bd376d3146f90fe8e082627c502185dbf7b9b3032f66b0b142c1115f3b2cc5936575fc1b44845ce903dd4c21bec2a8d69f3bd56f9cee9ec + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: af143246cf6884fe26fa281621d45cfe111d34b30535a475bfa38dafe343dadb466c047a924ffc7d6b7b18265df4110224ce3803806dbb07173bf2087b648d7f + languageName: node + linkType: hard + +"fs.realpath@npm:^1.0.0": + version: 1.0.0 + resolution: "fs.realpath@npm:1.0.0" + checksum: e703107c28e362d8d7b910bbcbfd371e640a3bb45ae157a362b5952c0030c0b6d4981140ec319b347bce7adc025dd7813da1ff908a945ac214d64f5402a51b96 + languageName: node + linkType: hard + +"fsevents@npm:~2.3.2": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: "npm:latest" + checksum: 4c1ade961ded57cdbfbb5cac5106ec17bc8bccd62e16343c569a0ceeca83b9dfef87550b4dc5cbb89642da412b20c5071f304c8c464b80415446e8e155a038c0 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 185e20d20f10c8d661d59aac0f3b63b31132d492e1b11fcc2a93cb2c47257ebaee7407c38513efd2b35cafdf972d9beb2ea4593c1e0f3bf8f2744836928d7454 + languageName: node + linkType: hard + +"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.4": + version: 1.2.4 + resolution: "get-intrinsic@npm:1.2.4" + dependencies: + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + has-proto: "npm:^1.0.1" + has-symbols: "npm:^1.0.3" + hasown: "npm:^2.0.0" + checksum: 85bbf4b234c3940edf8a41f4ecbd4e25ce78e5e6ad4e24ca2f77037d983b9ef943fd72f00f3ee97a49ec622a506b67db49c36246150377efcda1c9eb03e5f06d + languageName: node + linkType: hard + +"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: "npm:^4.0.1" + checksum: 32cd106ce8c0d83731966d31517adb766d02c3812de49c30cfe0675c7c0ae6630c11214c54a5ae67aca882cf738d27fd7768f21aa19118b9245950554be07247 + languageName: node + linkType: hard + +"glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.3.12 + resolution: "glob@npm:10.3.12" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^2.3.6" + minimatch: "npm:^9.0.1" + minipass: "npm:^7.0.4" + path-scurry: "npm:^1.10.2" + bin: + glob: dist/esm/bin.mjs + checksum: 9e8186abc22dc824b5dd86cefd8e6b5621a72d1be7f68bacc0fd681e8c162ec5546660a6ec0553d6a74757a585e655956c7f8f1a6d24570e8d865c307323d178 + languageName: node + linkType: hard + +"glob@npm:^7.1.3": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^3.1.1" + once: "npm:^1.3.0" + path-is-absolute: "npm:^1.0.0" + checksum: 59452a9202c81d4508a43b8af7082ca5c76452b9fcc4a9ab17655822e6ce9b21d4f8fbadabe4fe3faef448294cec249af305e2cd824b7e9aaf689240e5e96a7b + languageName: node + linkType: hard + +"gopd@npm:^1.0.1": + version: 1.0.1 + resolution: "gopd@npm:1.0.1" + dependencies: + get-intrinsic: "npm:^1.1.3" + checksum: 5fbc7ad57b368ae4cd2f41214bd947b045c1a4be2f194a7be1778d71f8af9dbf4004221f3b6f23e30820eb0d052b4f819fe6ebe8221e2a3c6f0ee4ef173421ca + languageName: node + linkType: hard + +"graceful-fs@npm:^4.1.4, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 + languageName: node + linkType: hard + +"gray-matter@npm:^4.0.3": + version: 4.0.3 + resolution: "gray-matter@npm:4.0.3" + dependencies: + js-yaml: "npm:^3.13.1" + kind-of: "npm:^6.0.2" + section-matter: "npm:^1.0.0" + strip-bom-string: "npm:^1.0.0" + checksum: 9a8f146a7a918d2524d5d60e0b4d45729f5bca54aa41247f971d9e4bc984943fda58159435763d463ec2abc8a0e238e807bd9b05e3a48f4a613a325c9dd5ad0c + languageName: node + linkType: hard + +"hamljs@npm:^0.6.2": + version: 0.6.2 + resolution: "hamljs@npm:0.6.2" + checksum: 7810b962a5e7356bf3131b17645220f0a672d1bcd201336f5e2a83d615bd753fb5312b338e6b8a2f9b81c07bcac95ca3ca8481ca4384fbe768f6bef657fe10c2 + languageName: node + linkType: hard + +"handlebars@npm:^4.7.7": + version: 4.7.8 + resolution: "handlebars@npm:4.7.8" + dependencies: + minimist: "npm:^1.2.5" + neo-async: "npm:^2.6.2" + source-map: "npm:^0.6.1" + uglify-js: "npm:^3.1.4" + wordwrap: "npm:^1.0.0" + dependenciesMeta: + uglify-js: + optional: true + bin: + handlebars: bin/handlebars + checksum: bd528f4dd150adf67f3f857118ef0fa43ff79a153b1d943fa0a770f2599e38b25a7a0dbac1a3611a4ec86970fd2325a81310fb788b5c892308c9f8743bd02e11 + languageName: node + linkType: hard + +"has-flag@npm:^4.0.0": + version: 4.0.0 + resolution: "has-flag@npm:4.0.0" + checksum: 261a1357037ead75e338156b1f9452c016a37dcd3283a972a30d9e4a87441ba372c8b81f818cd0fbcd9c0354b4ae7e18b9e1afa1971164aef6d18c2b6095a8ad + languageName: node + linkType: hard + +"has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: "npm:^1.0.0" + checksum: 2d8c9ab8cebb572e3362f7d06139a4592105983d4317e68f7adba320fe6ddfc8874581e0971e899e633fd5f72e262830edce36d5a0bc863dad17ad20572484b2 + languageName: node + linkType: hard + +"has-proto@npm:^1.0.1": + version: 1.0.3 + resolution: "has-proto@npm:1.0.3" + checksum: 0b67c2c94e3bea37db3e412e3c41f79d59259875e636ba471e94c009cdfb1fa82bf045deeffafc7dbb9c148e36cae6b467055aaa5d9fad4316e11b41e3ba551a + languageName: node + linkType: hard + +"has-symbols@npm:^1.0.3": + version: 1.0.3 + resolution: "has-symbols@npm:1.0.3" + checksum: 464f97a8202a7690dadd026e6d73b1ceeddd60fe6acfd06151106f050303eaa75855aaa94969df8015c11ff7c505f196114d22f7386b4a471038da5874cf5e9b + languageName: node + linkType: hard + +"has-tostringtag@npm:^1.0.0": + version: 1.0.2 + resolution: "has-tostringtag@npm:1.0.2" + dependencies: + has-symbols: "npm:^1.0.3" + checksum: c74c5f5ceee3c8a5b8bc37719840dc3749f5b0306d818974141dda2471a1a2ca6c8e46b9d6ac222c5345df7a901c9b6f350b1e6d62763fec877e26609a401bfe + languageName: node + linkType: hard + +"hasown@npm:^2.0.0": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" + dependencies: + function-bind: "npm:^1.1.2" + checksum: 7898a9c1788b2862cf0f9c345a6bec77ba4a0c0983c7f19d610c382343d4f98fa260686b225dfb1f88393a66679d2ec58ee310c1d6868c081eda7918f32cc70a + languageName: node + linkType: hard + +"htmlencode@npm:^0.0.4": + version: 0.0.4 + resolution: "htmlencode@npm:0.0.4" + checksum: a36da12431c32acd8c55b2d2266c7cf6697616730011d28cb84765bf9aae62002224c74411622cf209be6da81024c72734de727f96e337130619f5cc60b23932 + languageName: node + linkType: hard + +"htmlparser2@npm:^7.1.1": + version: 7.2.0 + resolution: "htmlparser2@npm:7.2.0" + dependencies: + domelementtype: "npm:^2.0.1" + domhandler: "npm:^4.2.2" + domutils: "npm:^2.8.0" + entities: "npm:^3.0.1" + checksum: fd097e19c01fb4ac8f44e432ae2908a606a382ccfec90efc91354a5b153540feade679ab8dca5fdebbe4f27c5a700743e2a0794f5a7a1beae9cc59d47e0f24b5 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.1.1": + version: 4.1.1 + resolution: "http-cache-semantics@npm:4.1.1" + checksum: 362d5ed66b12ceb9c0a328fb31200b590ab1b02f4a254a697dc796850cc4385603e75f53ec59f768b2dad3bfa1464bd229f7de278d2899a0e3beffc634b6683f + languageName: node + linkType: hard + +"http-equiv-refresh@npm:^1.0.0": + version: 1.0.0 + resolution: "http-equiv-refresh@npm:1.0.0" + checksum: 4404bbb9eb163382cd4ecfff359bf1eb709e3dc266af725b27ae96d08eb079e86508cfd59cf04eca3fadc2351e0077b0edd7ced01d1f219c20da28997d350ab6 + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: d062acfa0cb82beeb558f1043c6ba770ea892b5fb7b28654dbc70ea2aeea55226dd34c02a294f6c1ca179a5aa483c4ea641846821b182edbd9cc5d89b54c6848 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.4 + resolution: "https-proxy-agent@npm:7.0.4" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:4" + checksum: 405fe582bba461bfe5c7e2f8d752b384036854488b828ae6df6a587c654299cbb2c50df38c4b6ab303502c3c5e029a793fbaac965d1e86ee0be03faceb554d63 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 2d30b157a91fe1c1d7c6f653cbf263f039be6c5bfa959245a16d4ee191fc0f2af86c08545b6e6beeb041c56b574d2d5b9f95343d378ab49c0f37394d541e7fc8 + languageName: node + linkType: hard + +"indent-string@npm:^4.0.0": + version: 4.0.0 + resolution: "indent-string@npm:4.0.0" + checksum: cd3f5cbc9ca2d624c6a1f53f12e6b341659aba0e2d3254ae2b4464aaea8b4294cdb09616abbc59458f980531f2429784ed6a420d48d245bcad0811980c9efae9 + languageName: node + linkType: hard + +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: "npm:^1.3.0" + wrappy: "npm:1" + checksum: d2ebd65441a38c8336c223d1b80b921b9fa737e37ea466fd7e253cb000c64ae1f17fa59e68130ef5bda92cfd8d36b83d37dab0eb0a4558bcfec8e8cdfd2dcb67 + languageName: node + linkType: hard + +"inherits@npm:2": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 + languageName: node + linkType: hard + +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: "npm:1.1.0" + sprintf-js: "npm:^1.1.3" + checksum: 1ed81e06721af012306329b31f532b5e24e00cb537be18ddc905a84f19fe8f83a09a1699862bf3a1ec4b9dea93c55a3fa5faf8b5ea380431469df540f38b092c + languageName: node + linkType: hard + +"is-alphabetical@npm:^1.0.0": + version: 1.0.4 + resolution: "is-alphabetical@npm:1.0.4" + checksum: 6508cce44fd348f06705d377b260974f4ce68c74000e7da4045f0d919e568226dc3ce9685c5a2af272195384df6930f748ce9213fc9f399b5d31b362c66312cb + languageName: node + linkType: hard + +"is-alphanumerical@npm:^1.0.0": + version: 1.0.4 + resolution: "is-alphanumerical@npm:1.0.4" + dependencies: + is-alphabetical: "npm:^1.0.0" + is-decimal: "npm:^1.0.0" + checksum: e2e491acc16fcf5b363f7c726f666a9538dba0a043665740feb45bba1652457a73441e7c5179c6768a638ed396db3437e9905f403644ec7c468fb41f4813d03f + languageName: node + linkType: hard + +"is-binary-path@npm:~2.1.0": + version: 2.1.0 + resolution: "is-binary-path@npm:2.1.0" + dependencies: + binary-extensions: "npm:^2.0.0" + checksum: 078e51b4f956c2c5fd2b26bb2672c3ccf7e1faff38e0ebdba45612265f4e3d9fc3127a1fa8370bbf09eab61339203c3d3b7af5662cbf8be4030f8fac37745b0e + languageName: node + linkType: hard + +"is-core-module@npm:^2.13.0": + version: 2.13.1 + resolution: "is-core-module@npm:2.13.1" + dependencies: + hasown: "npm:^2.0.0" + checksum: d53bd0cc24b0a0351fb4b206ee3908f71b9bbf1c47e9c9e14e5f06d292af1663704d2abd7e67700d6487b2b7864e0d0f6f10a1edf1892864bdffcb197d1845a2 + languageName: node + linkType: hard + +"is-decimal@npm:^1.0.0": + version: 1.0.4 + resolution: "is-decimal@npm:1.0.4" + checksum: ed483a387517856dc395c68403a10201fddcc1b63dc56513fbe2fe86ab38766120090ecdbfed89223d84ca8b1cd28b0641b93cb6597b6e8f4c097a7c24e3fb96 + languageName: node + linkType: hard + +"is-expression@npm:^4.0.0": + version: 4.0.0 + resolution: "is-expression@npm:4.0.0" + dependencies: + acorn: "npm:^7.1.1" + object-assign: "npm:^4.1.1" + checksum: 0f01d0ff53fbbec36abae8fbb7ef056c6d024f7128646856a3e6c500b205788d3e0f337025e72df979d7d7cf4674a00370633d7f8974c668b2d3fdb7e8a83bdb + languageName: node + linkType: hard + +"is-extendable@npm:^0.1.0": + version: 0.1.1 + resolution: "is-extendable@npm:0.1.1" + checksum: 3875571d20a7563772ecc7a5f36cb03167e9be31ad259041b4a8f73f33f885441f778cee1f1fe0085eb4bc71679b9d8c923690003a36a6a5fdf8023e6e3f0672 + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + languageName: node + linkType: hard + +"is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: "npm:^2.1.1" + checksum: 3ed74f2b0cdf4f401f38edb0442ddfde3092d79d7d35c9919c86641efdbcbb32e45aa3c0f70ce5eecc946896cd5a0f26e4188b9f2b881876f7cb6c505b82da11 + languageName: node + linkType: hard + +"is-json@npm:^2.0.1": + version: 2.0.1 + resolution: "is-json@npm:2.0.1" + checksum: 29a768ad31d2ade15188578967120aa730cd2145e53a88ab88e022f0b4597368228f28a9de08c3cfbb0c80de1fae26fab21910e5b71c3b5661f2a41c05f9ae8d + languageName: node + linkType: hard + +"is-lambda@npm:^1.0.1": + version: 1.0.1 + resolution: "is-lambda@npm:1.0.1" + checksum: 93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35 + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 6a6c3383f68afa1e05b286af866017c78f1226d43ac8cb064e115ff9ed85eb33f5c4f7216c96a71e4dfea289ef52c5da3aef5bbfade8ffe47a0465d70c0c8e86 + languageName: node + linkType: hard + +"is-promise@npm:^2.0.0": + version: 2.2.2 + resolution: "is-promise@npm:2.2.2" + checksum: 18bf7d1c59953e0ad82a1ed963fb3dc0d135c8f299a14f89a17af312fc918373136e56028e8831700e1933519630cc2fd4179a777030330fde20d34e96f40c78 + languageName: node + linkType: hard + +"is-regex@npm:^1.0.3": + version: 1.1.4 + resolution: "is-regex@npm:1.1.4" + dependencies: + call-bind: "npm:^1.0.2" + has-tostringtag: "npm:^1.0.0" + checksum: 36d9174d16d520b489a5e9001d7d8d8624103b387be300c50f860d9414556d0485d74a612fdafc6ebbd5c89213d947dcc6b6bff6b2312093f71ea03cbb19e564 + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 7c9f715c03aff08f35e98b1fadae1b9267b38f0615d501824f9743f3aab99ef10e303ce7db3f186763a0b70a19de5791ebfc854ff884d5a8c4d92211f642ec92 + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 7fe1931ee4e88eb5aa524cd3ceb8c882537bc3a81b02e438b240e47012eef49c86904d0f0e593ea7c3a9996d18d0f1f3be8d3eaa92333977b0c3a9d353d5563e + languageName: node + linkType: hard + +"iso-639-1@npm:^2.1.15": + version: 2.1.15 + resolution: "iso-639-1@npm:2.1.15" + checksum: 32f6cfdfa5e85eef54cb2df77829e6678e9479e9b6a7fdb7e75ba0005957d4da35ff315b69c354e216ba46044e4437b1823362d27dff14bcefbb408b2a66e2f8 + languageName: node + linkType: hard + +"jackspeak@npm:^2.3.6": + version: 2.3.6 + resolution: "jackspeak@npm:2.3.6" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 6e6490d676af8c94a7b5b29b8fd5629f21346911ebe2e32931c2a54210134408171c24cee1a109df2ec19894ad04a429402a8438cbf5cc2794585d35428ace76 + languageName: node + linkType: hard + +"jake@npm:^10.8.5": + version: 10.8.7 + resolution: "jake@npm:10.8.7" + dependencies: + async: "npm:^3.2.3" + chalk: "npm:^4.0.2" + filelist: "npm:^1.0.4" + minimatch: "npm:^3.1.2" + bin: + jake: bin/cli.js + checksum: ad1cfe398836df4e6962954e5095597c21c5af1ea5a4182f6adf0869df8aca467a2eeca7869bf44f47120f4dd4ea52589d16050d295c87a5906c0d744775acc3 + languageName: node + linkType: hard + +"js-stringify@npm:^1.0.2": + version: 1.0.2 + resolution: "js-stringify@npm:1.0.2" + checksum: f9701d9e535d3ac0f62bbf2624b76c5d0af5b889187232817ae284a41ba21fd7a8b464c2dce3815d8cf52c8bea3480be6b368cfc2c67da799cad458058e8bbf5 + languageName: node + linkType: hard + +"js-yaml@npm:^3.13.1": + version: 3.14.1 + resolution: "js-yaml@npm:3.14.1" + dependencies: + argparse: "npm:^1.0.7" + esprima: "npm:^4.0.0" + bin: + js-yaml: bin/js-yaml.js + checksum: 9e22d80b4d0105b9899135365f746d47466ed53ef4223c529b3c0f7a39907743fdbd3c4379f94f1106f02755b5e90b2faaf84801a891135544e1ea475d1a1379 + languageName: node + linkType: hard + +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: bebe7ae829bbd586ce8cbe83501dd8cb8c282c8902a8aeeed0a073a89dc37e8103b1244f3c6acd60278bcbfe12d93a3f83c9ac396868a3b3bbc3c5e5e3b648ef + languageName: node + linkType: hard + +"jstransformer@npm:1.0.0": + version: 1.0.0 + resolution: "jstransformer@npm:1.0.0" + dependencies: + is-promise: "npm:^2.0.0" + promise: "npm:^7.0.1" + checksum: 7bca6e2e2fb4b6e65e567965e0370488699eb05cbbf27e6cb2ee2a89912d9c238aceb5c63216d834c50a000ed991b2bbd703b5432351aa2a15ee979b5180e652 + languageName: node + linkType: hard + +"junk@npm:^1.0.1": + version: 1.0.3 + resolution: "junk@npm:1.0.3" + checksum: 0646ce69b7292c970e7071c028a2537c29297802209301de48aef96557a8c23cfc9058f19f672b95260c1776fb0b5e4b055ac48a282163b069f391cd644b4324 + languageName: node + linkType: hard + +"kind-of@npm:^6.0.0, kind-of@npm:^6.0.2": + version: 6.0.3 + resolution: "kind-of@npm:6.0.3" + checksum: 5873d303fb36aad875b7538798867da2ae5c9e328d67194b0162a3659a627d22f742fc9c4ae95cd1704132a24b00cae5041fc00c0f6ef937dc17080dc4dbb962 + languageName: node + linkType: hard + +"kleur@npm:^4.1.5": + version: 4.1.5 + resolution: "kleur@npm:4.1.5" + checksum: 44d84cc4eedd4311099402ef6d4acd9b2d16e08e499d6ef3bb92389bd4692d7ef09e35248c26e27f98acac532122acb12a1bfee645994ae3af4f0a37996da7df + languageName: node + linkType: hard + +"linkify-it@npm:^4.0.1": + version: 4.0.1 + resolution: "linkify-it@npm:4.0.1" + dependencies: + uc.micro: "npm:^1.0.1" + checksum: d0a786d2e3f02f46b6f4a9b466af9eb936fb68e86b7cd305933d5457b12fdc53a4d0e0b697b02dc2e7d84a51d2425d719598bb7b47af7e01911e492e07a97957 + languageName: node + linkType: hard + +"linkify-it@npm:^5.0.0": + version: 5.0.0 + resolution: "linkify-it@npm:5.0.0" + dependencies: + uc.micro: "npm:^2.0.0" + checksum: ef3b7609dda6ec0c0be8a7b879cea195f0d36387b0011660cd6711bba0ad82137f59b458b7e703ec74f11d88e7c1328e2ad9b855a8500c0ded67461a8c4519e6 + languageName: node + linkType: hard + +"liquidjs@npm:^10.7.0": + version: 10.10.2 + resolution: "liquidjs@npm:10.10.2" + dependencies: + commander: "npm:^10.0.0" + bin: + liquid: bin/liquid.js + liquidjs: bin/liquid.js + checksum: 5257257a03526db1f15a41a60508be481450a719cbfa4ee078ad34db0c8c27377d211e07a030aa9c1154b2d26838b7c10fb2687a65e543e3f7256932e7609c40 + languageName: node + linkType: hard + +"list-to-array@npm:^1.1.0": + version: 1.1.0 + resolution: "list-to-array@npm:1.1.0" + checksum: c5b0e100799170005b034d83ea3628b0e9af566bc6a280f263564fe02f1590d75fddd4c2f28a11bddc89ab27217b372a9ba0e7b6caeb0a7c7dc77bda6413e6ff + languageName: node + linkType: hard + +"lodash.deburr@npm:^4.1.0": + version: 4.1.0 + resolution: "lodash.deburr@npm:4.1.0" + checksum: 165ce8f8a051360f98ce977f12bd645fe3faf3cc2452aa36f5a8849e3e69463e2252ff952ed6b7cc33c8f608fcbe56e7d13baf524818da95cb53849d366b62be + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.2.0 + resolution: "lru-cache@npm:10.2.0" + checksum: 502ec42c3309c0eae1ce41afca471f831c278566d45a5273a0c51102dee31e0e250a62fa9029c3370988df33a14188a38e682c16143b794de78668de3643e302 + languageName: node + linkType: hard + +"lru-cache@npm:^6.0.0": + version: 6.0.0 + resolution: "lru-cache@npm:6.0.0" + dependencies: + yallist: "npm:^4.0.0" + checksum: fc1fe2ee205f7c8855fa0f34c1ab0bcf14b6229e35579ec1fd1079f31d6fc8ef8eb6fd17f2f4d99788d7e339f50e047555551ebd5e434dda503696e7c6591825 + languageName: node + linkType: hard + +"luxon@npm:^3.3.0": + version: 3.4.4 + resolution: "luxon@npm:3.4.4" + checksum: c14164bc338987349075a08e63ea3ff902866735f7f5553a355b27be22667919765ff96fde4d3413d0e9a0edc4ff9e2e74ebcb8f86eae0ce8b14b27330d87d6e + languageName: node + linkType: hard + +"make-fetch-happen@npm:^13.0.0": + version: 13.0.0 + resolution: "make-fetch-happen@npm:13.0.0" + dependencies: + "@npmcli/agent": "npm:^2.0.0" + cacache: "npm:^18.0.0" + http-cache-semantics: "npm:^4.1.1" + is-lambda: "npm:^1.0.1" + minipass: "npm:^7.0.2" + minipass-fetch: "npm:^3.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^0.6.3" + promise-retry: "npm:^2.0.1" + ssri: "npm:^10.0.0" + checksum: ded5a91a02b76381b06a4ec4d5c1d23ebbde15d402b3c3e4533b371dac7e2f7ca071ae71ae6dae72aa261182557b7b1b3fd3a705b39252dc17f74fa509d3e76f + languageName: node + linkType: hard + +"markdown-it@npm:^13.0.1": + version: 13.0.2 + resolution: "markdown-it@npm:13.0.2" + dependencies: + argparse: "npm:^2.0.1" + entities: "npm:~3.0.1" + linkify-it: "npm:^4.0.1" + mdurl: "npm:^1.0.1" + uc.micro: "npm:^1.0.5" + bin: + markdown-it: bin/markdown-it.js + checksum: 4f48271bbd44d16502efd4148d7c05ca1fb4b50719a07d34c91e8d16f8d065c558fed0fafe07cd13ca5958096bfe295b37cd4f042add7ec49f73c70154e75f58 + languageName: node + linkType: hard + +"markdown-it@npm:^14.1.0": + version: 14.1.0 + resolution: "markdown-it@npm:14.1.0" + dependencies: + argparse: "npm:^2.0.1" + entities: "npm:^4.4.0" + linkify-it: "npm:^5.0.0" + mdurl: "npm:^2.0.0" + punycode.js: "npm:^2.3.1" + uc.micro: "npm:^2.1.0" + bin: + markdown-it: bin/markdown-it.mjs + checksum: f34f921be178ed0607ba9e3e27c733642be445e9bb6b1dba88da7aafe8ba1bc5d2f1c3aa8f3fc33b49a902da4e4c08c2feadfafb290b8c7dda766208bb6483a9 + languageName: node + linkType: hard + +"maximatch@npm:^0.1.0": + version: 0.1.0 + resolution: "maximatch@npm:0.1.0" + dependencies: + array-differ: "npm:^1.0.0" + array-union: "npm:^1.0.1" + arrify: "npm:^1.0.0" + minimatch: "npm:^3.0.0" + checksum: 6effa7fc9bd4d7ddbc6714b5c36642ffff96dbd603e6a8dd939802aa0cbd67be38b19c316e9d3d8253225d7adb63ebdbb0fdd21683f8f3cec9ec63cbd8387af0 + languageName: node + linkType: hard + +"mdurl@npm:^1.0.1": + version: 1.0.1 + resolution: "mdurl@npm:1.0.1" + checksum: ada367d01c9e81d07328101f187d5bd8641b71f33eab075df4caed935a24fa679e625f07108801d8250a5e4a99e5cd4be7679957a11424a3aa3e740d2bb2d5cb + languageName: node + linkType: hard + +"mdurl@npm:^2.0.0": + version: 2.0.0 + resolution: "mdurl@npm:2.0.0" + checksum: 1720349d4a53e401aa993241368e35c0ad13d816ad0b28388928c58ca9faa0cf755fa45f18ccbf64f4ce54a845a50ddce5c84e4016897b513096a68dac4b0158 + languageName: node + linkType: hard + +"merge2@npm:^1.3.0": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 + languageName: node + linkType: hard + +"micromatch@npm:^4.0.4, micromatch@npm:^4.0.5": + version: 4.0.5 + resolution: "micromatch@npm:4.0.5" + dependencies: + braces: "npm:^3.0.2" + picomatch: "npm:^2.3.1" + checksum: a749888789fc15cac0e03273844dbd749f9f8e8d64e70c564bcf06a033129554c789bb9e30d7566d7ff6596611a08e58ac12cf2a05f6e3c9c47c50c4c7e12fa2 + languageName: node + linkType: hard + +"mime@npm:^3.0.0": + version: 3.0.0 + resolution: "mime@npm:3.0.0" + bin: + mime: cli.js + checksum: b2d31580deb58be89adaa1877cbbf152b7604b980fd7ef8f08b9e96bfedf7d605d9c23a8ba62aa12c8580b910cd7c1d27b7331d0f40f7a14e17d5a0bbec3b49f + languageName: node + linkType: hard + +"minimatch@npm:^3.0.0, minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: e0b25b04cd4ec6732830344e5739b13f8690f8a012d73445a4a19fbc623f5dd481ef7a5827fde25954cd6026fede7574cc54dc4643c99d6c6b653d6203f94634 + languageName: node + linkType: hard + +"minimatch@npm:^5.0.1": + version: 5.1.6 + resolution: "minimatch@npm:5.1.6" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 126b36485b821daf96d33b5c821dac600cc1ab36c87e7a532594f9b1652b1fa89a1eebcaad4dff17c764dce1a7ac1531327f190fed5f97d8f6e5f889c116c429 + languageName: node + linkType: hard + +"minimatch@npm:^9.0.1": + version: 9.0.4 + resolution: "minimatch@npm:9.0.4" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 4cdc18d112b164084513e890d6323370db14c22249d536ad1854539577a895e690a27513dc346392f61a4a50afbbd8abc88f3f25558bfbbbb862cd56508b20f5 + languageName: node + linkType: hard + +"minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": + version: 1.2.8 + resolution: "minimist@npm:1.2.8" + checksum: 908491b6cc15a6c440ba5b22780a0ba89b9810e1aea684e253e43c4e3b8d56ec1dcdd7ea96dde119c29df59c936cde16062159eae4225c691e19c70b432b6e6f + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: "npm:^7.0.3" + checksum: b251bceea62090f67a6cced7a446a36f4cd61ee2d5cea9aee7fff79ba8030e416327a1c5aa2908dc22629d06214b46d88fdab8c51ac76bacbf5703851b5ad342 + languageName: node + linkType: hard + +"minipass-fetch@npm:^3.0.0": + version: 3.0.4 + resolution: "minipass-fetch@npm:3.0.4" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^2.1.2" + dependenciesMeta: + encoding: + optional: true + checksum: 3edf72b900e30598567eafe96c30374432a8709e61bb06b87198fa3192d466777e2ec21c52985a0999044fa6567bd6f04651585983a1cbb27e2c1770a07ed2a2 + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 40982d8d836a52b0f37049a0a7e5d0f089637298e6d9b45df9c115d4f0520682a78258905e5c8b180fb41b593b0a82cc1361d2c74b45f7ada66334f84d1ecfdd + languageName: node + linkType: hard + +"minipass@npm:^3.0.0, minipass@npm:^3.1.1": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: a5c6ef069f70d9a524d3428af39f2b117ff8cd84172e19b754e7264a33df460873e6eb3d6e55758531580970de50ae950c496256bb4ad3691a2974cddff189f0 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 61682162d29f45d3152b78b08bab7fb32ca10899bc5991ffe98afc18c9e9543bd1e3be94f8b8373ba6262497db63607079dc242ea62e43e7b2270837b7347c93 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4": + version: 7.0.4 + resolution: "minipass@npm:7.0.4" + checksum: e864bd02ceb5e0707696d58f7ce3a0b89233f0d686ef0d447a66db705c0846a8dc6f34865cd85256c1472ff623665f616b90b8ff58058b2ad996c5de747d2d18 + languageName: node + linkType: hard + +"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" + dependencies: + minipass: "npm:^3.0.0" + yallist: "npm:^4.0.0" + checksum: ae0f45436fb51344dcb87938446a32fbebb540d0e191d63b35e1c773d47512e17307bf54aa88326cc6d176594d00e4423563a091f7266c2f9a6872cdc1e234d1 + languageName: node + linkType: hard + +"mkdirp@npm:^0.5.1": + version: 0.5.6 + resolution: "mkdirp@npm:0.5.6" + dependencies: + minimist: "npm:^1.2.6" + bin: + mkdirp: bin/cmd.js + checksum: 0c91b721bb12c3f9af4b77ebf73604baf350e64d80df91754dc509491ae93bf238581e59c7188360cec7cb62fc4100959245a42cfe01834efedc5e9d068376c2 + languageName: node + linkType: hard + +"mkdirp@npm:^1.0.3": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: d71b8dcd4b5af2fe13ecf3bd24070263489404fe216488c5ba7e38ece1f54daf219e72a833a3a2dc404331e870e9f44963a33399589490956bff003a3404d3b2 + languageName: node + linkType: hard + +"moo@npm:^0.5.2": + version: 0.5.2 + resolution: "moo@npm:0.5.2" + checksum: fee356cb13b52e259c925fe297d71b3f47b98b06444b696dd4870d20cad4711eb58d24131afeba9bf7a51d77c77a3cbe8479066497d12a88abb51865c1be7de7 + languageName: node + linkType: hard + +"morphdom@npm:^2.7.0": + version: 2.7.2 + resolution: "morphdom@npm:2.7.2" + checksum: aa8860bf4a31c9272bfb5ca3ade7db63009a4971d587a369f2e55d669b6ce3e6a674ed0bb16f542cd1f7102b46f2fcafecd9052f8768d7ac11abdd4204bc1e3b + languageName: node + linkType: hard + +"ms@npm:2.0.0": + version: 2.0.0 + resolution: "ms@npm:2.0.0" + checksum: 0e6a22b8b746d2e0b65a430519934fefd41b6db0682e3477c10f60c76e947c4c0ad06f63ffdf1d78d335f83edee8c0aa928aa66a36c7cd95b69b26f468d527f4 + languageName: node + linkType: hard + +"ms@npm:2.1.2": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f + languageName: node + linkType: hard + +"multimatch@npm:^5.0.0": + version: 5.0.0 + resolution: "multimatch@npm:5.0.0" + dependencies: + "@types/minimatch": "npm:^3.0.3" + array-differ: "npm:^3.0.0" + array-union: "npm:^2.1.0" + arrify: "npm:^2.0.1" + minimatch: "npm:^3.0.4" + checksum: 82c8030a53af965cab48da22f1b0f894ef99e16ee680dabdfbd38d2dfacc3c8208c475203d747afd9e26db44118ed0221d5a0d65268c864f06d6efc7ac6df812 + languageName: node + linkType: hard + +"mustache@npm:^4.2.0": + version: 4.2.0 + resolution: "mustache@npm:4.2.0" + bin: + mustache: bin/mustache + checksum: 6e668bd5803255ab0779c3983b9412b5c4f4f90e822230e0e8f414f5449ed7a137eed29430e835aa689886f663385cfe05f808eb34b16e1f3a95525889b05cd3 + languageName: node + linkType: hard + +"negotiator@npm:^0.6.3": + version: 0.6.3 + resolution: "negotiator@npm:0.6.3" + checksum: 2723fb822a17ad55c93a588a4bc44d53b22855bf4be5499916ca0cab1e7165409d0b288ba2577d7b029f10ce18cf2ed8e703e5af31c984e1e2304277ef979837 + languageName: node + linkType: hard + +"neo-async@npm:^2.6.2": + version: 2.6.2 + resolution: "neo-async@npm:2.6.2" + checksum: 1a7948fea86f2b33ec766bc899c88796a51ba76a4afc9026764aedc6e7cde692a09067031e4a1bf6db4f978ccd99e7f5b6c03fe47ad9865c3d4f99050d67e002 + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 10.1.0 + resolution: "node-gyp@npm:10.1.0" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + glob: "npm:^10.3.10" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^13.0.0" + nopt: "npm:^7.0.0" + proc-log: "npm:^3.0.0" + semver: "npm:^7.3.5" + tar: "npm:^6.1.2" + which: "npm:^4.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 89e105e495e66cd4568af3cf79cdeb67d670eb069e33163c7781d3366470a30367c9bd8dea59e46db16370020139e5bf78b1fbc03284cb571754dfaa59744db5 + languageName: node + linkType: hard + +"nopt@npm:^7.0.0": + version: 7.2.0 + resolution: "nopt@npm:7.2.0" + dependencies: + abbrev: "npm:^2.0.0" + bin: + nopt: bin/nopt.js + checksum: 1e7489f17cbda452c8acaf596a8defb4ae477d2a9953b76eb96f4ec3f62c6b421cd5174eaa742f88279871fde9586d8a1d38fb3f53fa0c405585453be31dff4c + languageName: node + linkType: hard + +"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0": + version: 3.0.0 + resolution: "normalize-path@npm:3.0.0" + checksum: 88eeb4da891e10b1318c4b2476b6e2ecbeb5ff97d946815ffea7794c31a89017c70d7f34b3c2ebf23ef4e9fc9fb99f7dffe36da22011b5b5c6ffa34f4873ec20 + languageName: node + linkType: hard + +"nunjucks@npm:^3.2.3": + version: 3.2.4 + resolution: "nunjucks@npm:3.2.4" + dependencies: + a-sync-waterfall: "npm:^1.0.0" + asap: "npm:^2.0.3" + commander: "npm:^5.1.0" + peerDependencies: + chokidar: ^3.3.0 + peerDependenciesMeta: + chokidar: + optional: true + bin: + nunjucks-precompile: bin/precompile + checksum: 8decb8bb762501aa1a44366acff50ab9d4ff9e57034455e62056b4ac117da40140e1f34f2270c38884f1a5b84b7d97c4afcb2e8c789ddd09f4dcfe71ce7b56bf + languageName: node + linkType: hard + +"object-assign@npm:^4.1.1": + version: 4.1.1 + resolution: "object-assign@npm:4.1.1" + checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f + languageName: node + linkType: hard + +"on-finished@npm:2.4.1": + version: 2.4.1 + resolution: "on-finished@npm:2.4.1" + dependencies: + ee-first: "npm:1.1.1" + checksum: 8e81472c5028125c8c39044ac4ab8ba51a7cdc19a9fbd4710f5d524a74c6d8c9ded4dd0eed83f28d3d33ac1d7a6a439ba948ccb765ac6ce87f30450a26bfe2ea + languageName: node + linkType: hard + +"once@npm:^1.3.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 + languageName: node + linkType: hard + +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: "npm:^3.0.0" + checksum: 7ba4a2b1e24c05e1fc14bbaea0fc6d85cf005ae7e9c9425d4575550f37e2e584b1af97bcde78eacd7559208f20995988d52881334db16cf77bc1bcf68e48ed7c + languageName: node + linkType: hard + +"parse-srcset@npm:^1.0.2": + version: 1.0.2 + resolution: "parse-srcset@npm:1.0.2" + checksum: d40c131cfc3ab7bb6333b788d30a30d063d76a83b49fa752229823f96475e36cf29fea09e035ce3b2a634b686e93e2a7429cb8dad0041d8a3a3df622093b9ea1 + languageName: node + linkType: hard + +"parseurl@npm:~1.3.3": + version: 1.3.3 + resolution: "parseurl@npm:1.3.3" + checksum: 407cee8e0a3a4c5cd472559bca8b6a45b82c124e9a4703302326e9ab60fc1081442ada4e02628efef1eb16197ddc7f8822f5a91fd7d7c86b51f530aedb17dfa2 + languageName: node + linkType: hard + +"path-is-absolute@npm:^1.0.0": + version: 1.0.1 + resolution: "path-is-absolute@npm:1.0.1" + checksum: 060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8 + languageName: node + linkType: hard + +"path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 + languageName: node + linkType: hard + +"path-parse@npm:^1.0.7": + version: 1.0.7 + resolution: "path-parse@npm:1.0.7" + checksum: 49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a + languageName: node + linkType: hard + +"path-scurry@npm:^1.10.2": + version: 1.10.2 + resolution: "path-scurry@npm:1.10.2" + dependencies: + lru-cache: "npm:^10.2.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: a2bbbe8dc284c49dd9be78ca25f3a8b89300e0acc24a77e6c74824d353ef50efbf163e64a69f4330b301afca42d0e2229be0560d6d616ac4e99d48b4062016b1 + languageName: node + linkType: hard + +"path-to-regexp@npm:^6.2.1": + version: 6.2.1 + resolution: "path-to-regexp@npm:6.2.1" + checksum: 1e266be712d1a08086ee77beab12a1804842ec635dfed44f9ee1ba960a0e01cec8063fb8c92561115cdc0ce73158cdc7766e353ffa039340b4a85b370084c4d4 + languageName: node + linkType: hard + +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc + languageName: node + linkType: hard + +"pify@npm:^2.3.0": + version: 2.3.0 + resolution: "pify@npm:2.3.0" + checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba + languageName: node + linkType: hard + +"please-upgrade-node@npm:^3.2.0": + version: 3.2.0 + resolution: "please-upgrade-node@npm:3.2.0" + dependencies: + semver-compare: "npm:^1.0.0" + checksum: d87c41581a2a022fbe25965a97006238cd9b8cbbf49b39f78d262548149a9d30bd2bdf35fec3d810e0001e630cd46ef13c7e19c389dea8de7e64db271a2381bb + languageName: node + linkType: hard + +"posthtml-parser@npm:^0.11.0": + version: 0.11.0 + resolution: "posthtml-parser@npm:0.11.0" + dependencies: + htmlparser2: "npm:^7.1.1" + checksum: 7a26e975b5e69ae0dcb900f2212aa2df2e1215a5aee13d5876217b7f2a6abf7c6535f10643e439d9afb404d8c6869cd51a9f8164fe7dca5d6435a60757a96217 + languageName: node + linkType: hard + +"posthtml-render@npm:^3.0.0": + version: 3.0.0 + resolution: "posthtml-render@npm:3.0.0" + dependencies: + is-json: "npm:^2.0.1" + checksum: ca73e98b9d62c89eaa892b675643d4135431bcb5b1c5c00cb21802f875fd5c5caee208aa0ecdc1d803239ec3088a8138be416470eeb0b02f1f424cf90f20a8eb + languageName: node + linkType: hard + +"posthtml-urls@npm:^1.0.0": + version: 1.0.0 + resolution: "posthtml-urls@npm:1.0.0" + dependencies: + http-equiv-refresh: "npm:^1.0.0" + list-to-array: "npm:^1.1.0" + parse-srcset: "npm:^1.0.2" + promise-each: "npm:^2.2.0" + checksum: cd105988e583489153edc99e4780fb2b162afd776bf2cdb9da04642be02e490538be5fda14429a8dc302904530b0abba65a2a401682832de4d4ce565f081155f + languageName: node + linkType: hard + +"posthtml@npm:^0.16.6": + version: 0.16.6 + resolution: "posthtml@npm:0.16.6" + dependencies: + posthtml-parser: "npm:^0.11.0" + posthtml-render: "npm:^3.0.0" + checksum: e1ce9cda9b9fea0e1ddaccf13c945ca7e1bae2c6f54d34b2d0c9ed5b4b55d456684732257fc85113291807e99fcea585ad959acedca2de94d0744a84e15b31fb + languageName: node + linkType: hard + +"prismjs@npm:^1.29.0": + version: 1.29.0 + resolution: "prismjs@npm:1.29.0" + checksum: 2080db382c2dde0cfc7693769e89b501ef1bfc8ff4f8d25c07fd4c37ca31bc443f6133d5b7c145a73309dc396e829ddb7cc18560026d862a887ae08864ef6b07 + languageName: node + linkType: hard + +"proc-log@npm:^3.0.0": + version: 3.0.0 + resolution: "proc-log@npm:3.0.0" + checksum: 02b64e1b3919e63df06f836b98d3af002b5cd92655cab18b5746e37374bfb73e03b84fe305454614b34c25b485cc687a9eebdccf0242cda8fda2475dd2c97e02 + languageName: node + linkType: hard + +"promise-each@npm:^2.2.0": + version: 2.2.0 + resolution: "promise-each@npm:2.2.0" + dependencies: + any-promise: "npm:^0.1.0" + checksum: 56f4f0aceeeb52e0b7e0a1ddfca22128e9662041ea430f7a7a465beb7dc54dac5277235a2e0f3d03f0ee8b882d3a006bacad022b2b49d7aeee6b931f56c06523 + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: 96e1a82453c6c96eef53a37a1d6134c9f2482f94068f98a59145d0986ca4e497bf110a410adf73857e588165eab3899f0ebcf7b3890c1b3ce802abc0d65967d4 + languageName: node + linkType: hard + +"promise@npm:^7.0.1": + version: 7.3.1 + resolution: "promise@npm:7.3.1" + dependencies: + asap: "npm:~2.0.3" + checksum: 37dbe58ca7b0716cc881f0618128f1fd6ff9c46cdc529a269fd70004e567126a449a94e9428e2d19b53d06182d11b45d0c399828f103e06b2bb87643319bd2e7 + languageName: node + linkType: hard + +"prr@npm:~1.0.1": + version: 1.0.1 + resolution: "prr@npm:1.0.1" + checksum: 3bca2db0479fd38f8c4c9439139b0c42dcaadcc2fbb7bb8e0e6afaa1383457f1d19aea9e5f961d5b080f1cfc05bfa1fe9e45c97a1d3fd6d421950a73d3108381 + languageName: node + linkType: hard + +"pug-attrs@npm:^3.0.0": + version: 3.0.0 + resolution: "pug-attrs@npm:3.0.0" + dependencies: + constantinople: "npm:^4.0.1" + js-stringify: "npm:^1.0.2" + pug-runtime: "npm:^3.0.0" + checksum: 2ca2d34de3065239f01f0fc3c0e104c17f7a7105684d088bb71df623005a45f40a2301e65f49ec4581bb31794c74e691862643d4e34062d1509e92fa56a15aa5 + languageName: node + linkType: hard + +"pug-code-gen@npm:^3.0.3": + version: 3.0.3 + resolution: "pug-code-gen@npm:3.0.3" + dependencies: + constantinople: "npm:^4.0.1" + doctypes: "npm:^1.1.0" + js-stringify: "npm:^1.0.2" + pug-attrs: "npm:^3.0.0" + pug-error: "npm:^2.1.0" + pug-runtime: "npm:^3.0.1" + void-elements: "npm:^3.1.0" + with: "npm:^7.0.0" + checksum: 1918b2a75794b730ee29fc2278658ff2ccb74445742c175c55b18e414cf038e5ac5802e71db070b08f92c5304a66e141dc2261e401be4d5884f1c0bcfb3194ee + languageName: node + linkType: hard + +"pug-error@npm:^2.0.0": + version: 2.0.0 + resolution: "pug-error@npm:2.0.0" + checksum: c5372d018c897c1d6a141dd803c50957feecfda1f3d84a6adc6149801315d6c7f8c28b05f3e186d98d774fc9718699d1e1caa675630dd3c4453f8c5ec4e4a986 + languageName: node + linkType: hard + +"pug-error@npm:^2.1.0": + version: 2.1.0 + resolution: "pug-error@npm:2.1.0" + checksum: 9aefacfa156f0eb439ddab86c7136f998a532481a80665c9fb6b998afeea5bc8c4f83eb6ad8a4c7804c44927737df913b768b713995e6892112bbc05762e5415 + languageName: node + linkType: hard + +"pug-filters@npm:^4.0.0": + version: 4.0.0 + resolution: "pug-filters@npm:4.0.0" + dependencies: + constantinople: "npm:^4.0.1" + jstransformer: "npm:1.0.0" + pug-error: "npm:^2.0.0" + pug-walk: "npm:^2.0.0" + resolve: "npm:^1.15.1" + checksum: ca8b7ffede57d13679ec8c3ee2791feabb7ab3972e02f16fffe328ab9de42961758c3115b0536b2e6cf14a4dc2b2381a172adba84423be4137298fd59ff92853 + languageName: node + linkType: hard + +"pug-lexer@npm:^5.0.1": + version: 5.0.1 + resolution: "pug-lexer@npm:5.0.1" + dependencies: + character-parser: "npm:^2.2.0" + is-expression: "npm:^4.0.0" + pug-error: "npm:^2.0.0" + checksum: 18d74a2dfbee892a71ca973e72be60acc36a30b5b7325e2cd723691779e505bfecd2206453b09c2b7f868af9ec0204ed4ea7a26c2a835172a22618b350b6aeb1 + languageName: node + linkType: hard + +"pug-linker@npm:^4.0.0": + version: 4.0.0 + resolution: "pug-linker@npm:4.0.0" + dependencies: + pug-error: "npm:^2.0.0" + pug-walk: "npm:^2.0.0" + checksum: 423f62e8600fb66c785ef4e11d9a7833a959677d67443980fd66248da56cebed0a8867f7aa78dc5631803cd1ce71a00b0abf78229b2a2d2ec8779a8b3afb5079 + languageName: node + linkType: hard + +"pug-load@npm:^3.0.0": + version: 3.0.0 + resolution: "pug-load@npm:3.0.0" + dependencies: + object-assign: "npm:^4.1.1" + pug-walk: "npm:^2.0.0" + checksum: 1800ec51994c92338401bcf79bbfa0d5ef9aa312bc415c2618263d6c04d1d7c5be5ac4a333c47a0eaa823f6231b4ade1a1c40f5784b99eb576d25853597bff2f + languageName: node + linkType: hard + +"pug-parser@npm:^6.0.0": + version: 6.0.0 + resolution: "pug-parser@npm:6.0.0" + dependencies: + pug-error: "npm:^2.0.0" + token-stream: "npm:1.0.0" + checksum: 4c23e154ea2c8c4355ee0291fefa7210f24beecff7c4af2d1e8b7e86ce2923d3213f31bbd9e33bd6703c25ea625dc6494a2ca68a21dcb105b5ac9204248cf4a8 + languageName: node + linkType: hard + +"pug-runtime@npm:^3.0.0, pug-runtime@npm:^3.0.1": + version: 3.0.1 + resolution: "pug-runtime@npm:3.0.1" + checksum: d34ee1b95121576bd389dccd2f6d7dc6fb0bf24963d2b7d1471795d35d8fba90ee8e16c2e022084bdc2f2cfbd56aaa2f452ea872135baf54dbb54a0d5aedd856 + languageName: node + linkType: hard + +"pug-strip-comments@npm:^2.0.0": + version: 2.0.0 + resolution: "pug-strip-comments@npm:2.0.0" + dependencies: + pug-error: "npm:^2.0.0" + checksum: 2cfcbf506c14bb3e64204a1d93f12ca61658d2540475b0f0911c35531ad28421e8d1e73a646d841d58cfa2c20f8593c52e492dfe5b6bec968e20b614e4dea1e4 + languageName: node + linkType: hard + +"pug-walk@npm:^2.0.0": + version: 2.0.0 + resolution: "pug-walk@npm:2.0.0" + checksum: bee64e133b711e1ed58022c0869b59e62f9f3ebb7084293857f074120b3cb588e7b8f74c4566426bf2b26dc1ec176ca6b64a2d1e53782f3fbbe039c5d4816638 + languageName: node + linkType: hard + +"pug@npm:^3.0.2": + version: 3.0.3 + resolution: "pug@npm:3.0.3" + dependencies: + pug-code-gen: "npm:^3.0.3" + pug-filters: "npm:^4.0.0" + pug-lexer: "npm:^5.0.1" + pug-linker: "npm:^4.0.0" + pug-load: "npm:^3.0.0" + pug-parser: "npm:^6.0.0" + pug-runtime: "npm:^3.0.1" + pug-strip-comments: "npm:^2.0.0" + checksum: a88364757512e3b9af024c008f23b910de049659655b5d9e6ca42f996d7849ce1aab059f61e2d44ccce0dde5ff291995682338c285e9f76f3e5bfa02de9c481b + languageName: node + linkType: hard + +"punycode.js@npm:^2.3.1": + version: 2.3.1 + resolution: "punycode.js@npm:2.3.1" + checksum: f0e946d1edf063f9e3d30a32ca86d8ff90ed13ca40dad9c75d37510a04473340cfc98db23a905cc1e517b1e9deb0f6021dce6f422ace235c60d3c9ac47c5a16a + languageName: node + linkType: hard + +"queue-microtask@npm:^1.2.2": + version: 1.2.3 + resolution: "queue-microtask@npm:1.2.3" + checksum: 72900df0616e473e824202113c3df6abae59150dfb73ed13273503127235320e9c8ca4aaaaccfd58cf417c6ca92a6e68ee9a5c3182886ae949a768639b388a7b + languageName: node + linkType: hard + +"readdirp@npm:~3.6.0": + version: 3.6.0 + resolution: "readdirp@npm:3.6.0" + dependencies: + picomatch: "npm:^2.2.1" + checksum: 196b30ef6ccf9b6e18c4e1724b7334f72a093d011a99f3b5920470f0b3406a51770867b3e1ae9711f227ef7a7065982f6ee2ce316746b2cb42c88efe44297fe7 + languageName: node + linkType: hard + +"recursive-copy@npm:^2.0.14": + version: 2.0.14 + resolution: "recursive-copy@npm:2.0.14" + dependencies: + errno: "npm:^0.1.2" + graceful-fs: "npm:^4.1.4" + junk: "npm:^1.0.1" + maximatch: "npm:^0.1.0" + mkdirp: "npm:^0.5.1" + pify: "npm:^2.3.0" + promise: "npm:^7.0.1" + rimraf: "npm:^2.7.1" + slash: "npm:^1.0.0" + checksum: 9ea6676a063bf1dec0911b97d9b2c346159e00312d0a61ce19150debaf39453df058802a3824c7cd585856fb8ce919501bde87fbe85414ecec16e833dcde2318 + languageName: node + linkType: hard + +"resolve@npm:^1.15.1": + version: 1.22.8 + resolution: "resolve@npm:1.22.8" + dependencies: + is-core-module: "npm:^2.13.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: c473506ee01eb45cbcfefb68652ae5759e092e6b0fb64547feadf9736a6394f258fbc6f88e00c5ca36d5477fbb65388b272432a3600fa223062e54333c156753 + languageName: node + linkType: hard + +"resolve@patch:resolve@npm%3A^1.15.1#optional!builtin": + version: 1.22.8 + resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d" + dependencies: + is-core-module: "npm:^2.13.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: f345cd37f56a2c0275e3fe062517c650bb673815d885e7507566df589375d165bbbf4bdb6aa95600a9bc55f4744b81f452b5a63f95b9f10a72787dba3c90890a + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 1f914879f97e7ee931ad05fe3afa629bd55270fc6cf1c1e589b6a99fab96d15daad0fa1a52a00c729ec0078045fe3e399bd4fd0c93bcc906957bdc17f89cb8e6 + languageName: node + linkType: hard + +"reusify@npm:^1.0.4": + version: 1.0.4 + resolution: "reusify@npm:1.0.4" + checksum: 14222c9e1d3f9ae01480c50d96057228a8524706db79cdeb5a2ce5bb7070dd9f409a6f84a02cbef8cdc80d39aef86f2dd03d155188a1300c599b05437dcd2ffb + languageName: node + linkType: hard + +"rimraf@npm:^2.7.1": + version: 2.7.1 + resolution: "rimraf@npm:2.7.1" + dependencies: + glob: "npm:^7.1.3" + bin: + rimraf: ./bin.js + checksum: 4586c296c736483e297da7cffd19475e4a3e41d07b1ae124aad5d687c79e4ffa716bdac8732ed1db942caf65271cee9dd39f8b639611de161a2753e2112ffe1d + languageName: node + linkType: hard + +"run-parallel@npm:^1.1.9": + version: 1.2.0 + resolution: "run-parallel@npm:1.2.0" + dependencies: + queue-microtask: "npm:^1.2.2" + checksum: cb4f97ad25a75ebc11a8ef4e33bb962f8af8516bb2001082ceabd8902e15b98f4b84b4f8a9b222e5d57fc3bd1379c483886ed4619367a7680dad65316993021d + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 7eaf7a0cf37cc27b42fb3ef6a9b1df6e93a1c6d98c6c6702b02fe262d5fcbd89db63320793b99b21cb5348097d0a53de81bd5f4e8b86e20cc9412e3f1cfb4e83 + languageName: node + linkType: hard + +"section-matter@npm:^1.0.0": + version: 1.0.0 + resolution: "section-matter@npm:1.0.0" + dependencies: + extend-shallow: "npm:^2.0.1" + kind-of: "npm:^6.0.0" + checksum: cedfda3a9238f66942d92531fe043dd134702a462cdc9e254cd6aa418c66ca0d229900e4da78ffd1a07051e7b239251c4dc4748e9d1c76bf41a37bff7a478556 + languageName: node + linkType: hard + +"semver-compare@npm:^1.0.0": + version: 1.0.0 + resolution: "semver-compare@npm:1.0.0" + checksum: 75f9c7a7786d1756f64b1429017746721e07bd7691bdad6368f7643885d3a98a27586777e9699456564f4844b407e9f186cc1d588a3f9c0be71310e517e942c3 + languageName: node + linkType: hard + +"semver@npm:^7.3.5, semver@npm:^7.3.8": + version: 7.6.0 + resolution: "semver@npm:7.6.0" + dependencies: + lru-cache: "npm:^6.0.0" + bin: + semver: bin/semver.js + checksum: 1b41018df2d8aca5a1db4729985e8e20428c650daea60fcd16e926e9383217d00f574fab92d79612771884a98d2ee2a1973f49d630829a8d54d6570defe62535 + languageName: node + linkType: hard + +"set-function-length@npm:^1.2.1": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: "npm:^1.1.4" + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.2" + checksum: 505d62b8e088468917ca4e3f8f39d0e29f9a563b97dbebf92f4bd2c3172ccfb3c5b8e4566d5fcd00784a00433900e7cb8fbc404e2dbd8c3818ba05bb9d4a8a6d + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: c9fa63bbbd7431066174a48ba2dd9986dfd930c3a8b59de9c29d7b6854ec1c12a80d15310869ea5166d413b99f041bfa3dd80a7947bcd44ea8e6eb3ffeabfa1f + languageName: node + linkType: hard + +"slash@npm:^1.0.0": + version: 1.0.0 + resolution: "slash@npm:1.0.0" + checksum: 4b6e21b1fba6184a7e2efb1dd173f692d8a845584c1bbf9dc818ff86f5a52fc91b413008223d17cc684604ee8bb9263a420b1182027ad9762e35388434918860 + languageName: node + linkType: hard + +"slugify@npm:^1.6.6": + version: 1.6.6 + resolution: "slugify@npm:1.6.6" + checksum: d0737cdedc834c50f74227bc1a1cf4f449f3575893f031b0e8c59f501c73526c866a23e47261b262c7acdaaaaf30d6f9e8aaae22772b3f56e858ac84c35efa7b + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: 927484aa0b1640fd9473cee3e0a0bcad6fce93fd7bbc18bac9ad0c33686f5d2e2c422fba24b5899c184524af01e11dd2bd051c2bf2b07e47aff8ca72cbfc60d2 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.3 + resolution: "socks-proxy-agent@npm:8.0.3" + dependencies: + agent-base: "npm:^7.1.1" + debug: "npm:^4.3.4" + socks: "npm:^2.7.1" + checksum: c2112c66d6322e497d68e913c3780f3683237fd394bfd480b9283486a86e36095d0020db96145d88f8ccd9cc73261b98165b461f9c1bf5dc17abfe75c18029ce + languageName: node + linkType: hard + +"socks@npm:^2.7.1": + version: 2.8.1 + resolution: "socks@npm:2.8.1" + dependencies: + ip-address: "npm:^9.0.5" + smart-buffer: "npm:^4.2.0" + checksum: a3cc38e0716ab53a2db3fa00c703ca682ad54dbbc9ed4c7461624a999be6fa7cdc79fc904c411618e698d5eff55a55aa6d9329169a7db11636d0200814a2b5aa + languageName: node + linkType: hard + +"source-map@npm:^0.6.1": + version: 0.6.1 + resolution: "source-map@npm:0.6.1" + checksum: 59ef7462f1c29d502b3057e822cdbdae0b0e565302c4dd1a95e11e793d8d9d62006cdc10e0fd99163ca33ff2071360cf50ee13f90440806e7ed57d81cba2f7ff + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: e7587128c423f7e43cc625fe2f87e6affdf5ca51c1cc468e910d8aaca46bb44a7fbcfa552f787b1d3987f7043aeb4527d1b99559e6621e01b42b3f45e5a24cbb + languageName: node + linkType: hard + +"sprintf-js@npm:~1.0.2": + version: 1.0.3 + resolution: "sprintf-js@npm:1.0.3" + checksum: c34828732ab8509c2741e5fd1af6b767c3daf2c642f267788f933a65b1614943c282e74c4284f4fa749c264b18ee016a0d37a3e5b73aee446da46277d3a85daa + languageName: node + linkType: hard + +"ssri@npm:^10.0.0": + version: 10.0.5 + resolution: "ssri@npm:10.0.5" + dependencies: + minipass: "npm:^7.0.3" + checksum: 453f9a1c241c13f5dfceca2ab7b4687bcff354c3ccbc932f35452687b9ef0ccf8983fd13b8a3baa5844c1a4882d6e3ddff48b0e7fd21d743809ef33b80616d79 + languageName: node + linkType: hard + +"ssri@npm:^8.0.1": + version: 8.0.1 + resolution: "ssri@npm:8.0.1" + dependencies: + minipass: "npm:^3.1.1" + checksum: fde247b7107674d9a424a20f9c1a6e3ad88a139c2636b9d9ffa7df59e85e11a894cdae48fadd0ad6be41eb0d5b847fe094736513d333615c7eebc3d111abe0d2 + languageName: node + linkType: hard + +"statuses@npm:2.0.1": + version: 2.0.1 + resolution: "statuses@npm:2.0.1" + checksum: 18c7623fdb8f646fb213ca4051be4df7efb3484d4ab662937ca6fbef7ced9b9e12842709872eb3020cc3504b93bde88935c9f6417489627a7786f24f8031cbcb + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193 + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: ae3b5436d34fadeb6096367626ce987057713c566e1e7768818797e00ac5d62023d0f198c4e681eae9e20701721980b26a64a8f5b91238869592a9c6800719a2 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: 475f53e9c44375d6e72807284024ac5d668ee1d06010740dec0b9744f2ddf47de8d7151f80e5f6190fc8f384e802fdf9504b76a7e9020c9faee7103623338be2 + languageName: node + linkType: hard + +"strip-bom-string@npm:^1.0.0": + version: 1.0.0 + resolution: "strip-bom-string@npm:1.0.0" + checksum: 5635a3656d8512a2c194d6c8d5dee7ef0dde6802f7be9413b91e201981ad4132506656d9cf14137f019fd50f0269390d91c7f6a2601b1bee039a4859cfce4934 + languageName: node + linkType: hard + +"supports-color@npm:^7.1.0": + version: 7.2.0 + resolution: "supports-color@npm:7.2.0" + dependencies: + has-flag: "npm:^4.0.0" + checksum: c8bb7afd564e3b26b50ca6ee47572c217526a1389fe018d00345856d4a9b08ffbd61fadaf283a87368d94c3dcdb8f5ffe2650a5a65863e21ad2730ca0f05210a + languageName: node + linkType: hard + +"supports-preserve-symlinks-flag@npm:^1.0.0": + version: 1.0.0 + resolution: "supports-preserve-symlinks-flag@npm:1.0.0" + checksum: a9dc19ae2220c952bd2231d08ddeecb1b0328b61e72071ff4000c8384e145cc07c1c0bdb3b5a1cb06e186a7b2790f1dee793418b332f6ddf320de25d9125be7e + languageName: node + linkType: hard + +"tar@npm:^6.1.11, tar@npm:^6.1.2": + version: 6.2.1 + resolution: "tar@npm:6.2.1" + dependencies: + chownr: "npm:^2.0.0" + fs-minipass: "npm:^2.0.0" + minipass: "npm:^5.0.0" + minizlib: "npm:^2.1.1" + mkdirp: "npm:^1.0.3" + yallist: "npm:^4.0.0" + checksum: bfbfbb2861888077fc1130b84029cdc2721efb93d1d1fb80f22a7ac3a98ec6f8972f29e564103bbebf5e97be67ebc356d37fa48dbc4960600a1eb7230fbd1ea0 + languageName: node + linkType: hard + +"to-fast-properties@npm:^2.0.0": + version: 2.0.0 + resolution: "to-fast-properties@npm:2.0.0" + checksum: be2de62fe58ead94e3e592680052683b1ec986c72d589e7b21e5697f8744cdbf48c266fa72f6c15932894c10187b5f54573a3bcf7da0bfd964d5caf23d436168 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 10dda13571e1f5ad37546827e9b6d4252d2e0bc176c24a101252153ef435d83696e2557fe128c4678e4e78f5f01e83711c703eef9814eb12dab028580d45980a + languageName: node + linkType: hard + +"token-stream@npm:1.0.0": + version: 1.0.0 + resolution: "token-stream@npm:1.0.0" + checksum: e8adb56f31b813b6157130e7fc2fe14eb60e7cbf7b746e70e8293c7e55664d8e7ad5d93d7ae3aa4cad7fcb2b0aaf59dad6f2fd4ee0269204e55af5b05bc369e2 + languageName: node + linkType: hard + +"uc.micro@npm:^1.0.1, uc.micro@npm:^1.0.5": + version: 1.0.6 + resolution: "uc.micro@npm:1.0.6" + checksum: 6898bb556319a38e9cf175e3628689347bd26fec15fc6b29fa38e0045af63075ff3fea4cf1fdba9db46c9f0cbf07f2348cd8844889dd31ebd288c29fe0d27e7a + languageName: node + linkType: hard + +"uc.micro@npm:^2.0.0, uc.micro@npm:^2.1.0": + version: 2.1.0 + resolution: "uc.micro@npm:2.1.0" + checksum: 37197358242eb9afe367502d4638ac8c5838b78792ab218eafe48287b0ed28aaca268ec0392cc5729f6c90266744de32c06ae938549aee041fc93b0f9672d6b2 + languageName: node + linkType: hard + +"uglify-js@npm:^3.1.4, uglify-js@npm:^3.14.5": + version: 3.17.4 + resolution: "uglify-js@npm:3.17.4" + bin: + uglifyjs: bin/uglifyjs + checksum: 4c0b800e0ff192079d2c3ce8414fd3b656a570028c7c79af5c29c53d5c532b68bbcae4ad47307f89c2ee124d11826fff7a136b59d5c5bb18422bcdf5568afe1e + languageName: node + linkType: hard + +"unique-filename@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-filename@npm:3.0.0" + dependencies: + unique-slug: "npm:^4.0.0" + checksum: 8e2f59b356cb2e54aab14ff98a51ac6c45781d15ceaab6d4f1c2228b780193dc70fae4463ce9e1df4479cb9d3304d7c2043a3fb905bdeca71cc7e8ce27e063df + languageName: node + linkType: hard + +"unique-slug@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-slug@npm:4.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 40912a8963fc02fb8b600cf50197df4a275c602c60de4cac4f75879d3c48558cfac48de08a25cc10df8112161f7180b3bbb4d662aadb711568602f9eddee54f0 + languageName: node + linkType: hard + +"unpipe@npm:~1.0.0": + version: 1.0.0 + resolution: "unpipe@npm:1.0.0" + checksum: 4fa18d8d8d977c55cb09715385c203197105e10a6d220087ec819f50cb68870f02942244f1017565484237f1f8c5d3cd413631b1ae104d3096f24fdfde1b4aa2 + languageName: node + linkType: hard + +"void-elements@npm:^3.1.0": + version: 3.1.0 + resolution: "void-elements@npm:3.1.0" + checksum: 0390f818107fa8fce55bb0a5c3f661056001c1d5a2a48c28d582d4d847347c2ab5b7f8272314cac58acf62345126b6b09bea623a185935f6b1c3bbce0dfd7f7f + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 4782f8a1d6b8fc12c65e968fea49f59752bf6302dc43036c3bf87da718a80710f61a062516e9764c70008b487929a73546125570acea95c5b5dcc8ac3052c70f + languageName: node + linkType: hard + +"which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 + languageName: node + linkType: hard + +"with@npm:^7.0.0": + version: 7.0.2 + resolution: "with@npm:7.0.2" + dependencies: + "@babel/parser": "npm:^7.9.6" + "@babel/types": "npm:^7.9.6" + assert-never: "npm:^1.2.1" + babel-walk: "npm:3.0.0-canary-5" + checksum: 06ad978f9ac11268186060af7e19ff33bcfe1631ecbce4c676cb43168e3d6e62a5c6e697bd6dda8570c93b117a9b12980061ff66c3428a4e5cdcf0637e8ed81f + languageName: node + linkType: hard + +"wordwrap@npm:^1.0.0": + version: 1.0.0 + resolution: "wordwrap@npm:1.0.0" + checksum: 497d40beb2bdb08e6d38754faa17ce20b0bf1306327f80cb777927edb23f461ee1f6bc659b3c3c93f26b08e1cf4b46acc5bae8fda1f0be3b5ab9a1a0211034cd + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: cebdaeca3a6880da410f75209e68cd05428580de5ad24535f22696d7d9cab134d1f8498599f344c3cf0fb37c1715807a183778d8c648d6cc0cb5ff2bb4236540 + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 7b1e4b35e9bb2312d2ee9ee7dc95b8cb5f8b4b5a89f7dde5543fe66c1e3715663094defa50d75454ac900bd210f702d575f15f3f17fa9ec0291806d2578d1ddf + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 + languageName: node + linkType: hard + +"ws@npm:^8.13.0": + version: 8.17.1 + resolution: "ws@npm:8.17.1" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 4264ae92c0b3e59c7e309001e93079b26937aab181835fb7af79f906b22cd33b6196d96556dafb4e985742dd401e99139572242e9847661fdbc96556b9e6902d + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 4cb02b42b8a93b5cf50caf5d8e9beb409400a8a4d85e83bb0685c1457e9ac0b7a00819e9f5991ac25ffabb56a78e2f017c1acc010b3a1babfe6de690ba531abd + languageName: node + linkType: hard diff --git a/graphrag/examples/README.md b/graphrag/examples/README.md new file mode 100644 index 0000000000000000000000000000000000000000..5d80b4fd4c4b13d94d57189acc588d35e5a24015 --- /dev/null +++ b/graphrag/examples/README.md @@ -0,0 +1,19 @@ +# Indexing Engine Examples +This directory contains several examples of how to use the indexing engine. + +Most examples include two different forms of running the pipeline, both are contained in the examples `run.py` +1. Using mostly the Python API +2. Using mostly the a pipeline configuration file + +# Running an Example +First run `poetry shell` to activate a virtual environment with the required dependencies. + +Then run `PYTHONPATH="$(pwd)" python examples/path_to_example/run.py` from the `python/graphrag` directory. + +For example to run the single_verb example, you would run the following commands: + +```bash +cd python/graphrag +poetry shell +PYTHONPATH="$(pwd)" python examples/single_verb/run.py +``` \ No newline at end of file diff --git a/graphrag/examples/__init__.py b/graphrag/examples/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/examples/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/examples/custom_input/__init__.py b/graphrag/examples/custom_input/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/examples/custom_input/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/examples/custom_input/pipeline.yml b/graphrag/examples/custom_input/pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..80340c82911a91ce99955f275f0478d0064e01a4 --- /dev/null +++ b/graphrag/examples/custom_input/pipeline.yml @@ -0,0 +1,24 @@ + +# Setup reporting however you'd like +reporting: + type: console + +# Setup storage however you'd like +storage: + type: memory + +# Setup cache however you'd like +cache: + type: memory + +# Just a simple workflow +workflows: + + # This is an anonymous workflow, it doesn't have a name + - steps: + + # Unpack the nodes from the graph + - verb: fill + args: + to: filled_column + value: "Filled Value" \ No newline at end of file diff --git a/graphrag/examples/custom_input/run.py b/graphrag/examples/custom_input/run.py new file mode 100644 index 0000000000000000000000000000000000000000..ba39033e120daa1fc15855e5473ae390636cbc85 --- /dev/null +++ b/graphrag/examples/custom_input/run.py @@ -0,0 +1,46 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import os + +import pandas as pd + +from graphrag.index import run_pipeline_with_config + +pipeline_file = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "./pipeline.yml" +) + + +async def run(): + # Load your dataset + dataset = _load_dataset_some_unique_way() + + # Load your config without the input section + config = pipeline_file + + # Grab the last result from the pipeline, should be our entity extraction + outputs = [] + async for output in run_pipeline_with_config( + config_or_path=config, dataset=dataset + ): + outputs.append(output) + pipeline_result = outputs[-1] + + if pipeline_result.result is not None: + # Should look something like + # col1 col2 filled_column + # 0 2 4 Filled Value + # 1 5 10 Filled Value + print(pipeline_result.result) + else: + print("No results!") + + +def _load_dataset_some_unique_way() -> pd.DataFrame: + # Totally loaded from some other place + return pd.DataFrame([{"col1": 2, "col2": 4}, {"col1": 5, "col2": 10}]) + + +if __name__ == "__main__": + asyncio.run(run()) diff --git a/graphrag/examples/custom_set_of_available_verbs/__init__.py b/graphrag/examples/custom_set_of_available_verbs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/examples/custom_set_of_available_verbs/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/examples/custom_set_of_available_verbs/custom_verb_definitions.py b/graphrag/examples/custom_set_of_available_verbs/custom_verb_definitions.py new file mode 100644 index 0000000000000000000000000000000000000000..ef058ed3d63e3feb42fd05dc90657a8b7af0878d --- /dev/null +++ b/graphrag/examples/custom_set_of_available_verbs/custom_verb_definitions.py @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +from datashaper import TableContainer, VerbInput + + +def str_append( + input: VerbInput, source_column: str, target_column: str, string_to_append: str +): + """A custom verb that appends a string to a column""" + # by convention, we typically use "column" as the input column name and "to" as the output column name, but you can use whatever you want + # just as long as the "args" in the workflow reference match the function signature + input_data = input.get_input() + output_df = input_data.copy() + output_df[target_column] = output_df[source_column].apply( + lambda x: f"{x}{string_to_append}" + ) + return TableContainer(table=output_df) + + +custom_verbs = { + "str_append": str_append, +} diff --git a/graphrag/examples/custom_set_of_available_verbs/pipeline.yml b/graphrag/examples/custom_set_of_available_verbs/pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..85bcdb24b73808cf99cfc6194b7d524c8676f113 --- /dev/null +++ b/graphrag/examples/custom_set_of_available_verbs/pipeline.yml @@ -0,0 +1,7 @@ +workflows: + - steps: + - verb: "str_append" # should be the key that you pass to the custom_verbs dict below + args: + source_column: "col1" + target_column: "col_1_custom" + string_to_append: " - custom verb" \ No newline at end of file diff --git a/graphrag/examples/custom_set_of_available_verbs/run.py b/graphrag/examples/custom_set_of_available_verbs/run.py new file mode 100644 index 0000000000000000000000000000000000000000..7e3f461731cc1df3c1635378a7ec6747c2dd850d --- /dev/null +++ b/graphrag/examples/custom_set_of_available_verbs/run.py @@ -0,0 +1,84 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import os + +import pandas as pd + +from examples.custom_set_of_available_verbs.custom_verb_definitions import custom_verbs +from graphrag.index import run_pipeline, run_pipeline_with_config +from graphrag.index.config import PipelineWorkflowReference + +# Our fake dataset +dataset = pd.DataFrame([{"col1": 2, "col2": 4}, {"col1": 5, "col2": 10}]) + + +async def run_with_config(): + """Run a pipeline with a config file""" + # load pipeline.yml in this directory + config_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "./pipeline.yml" + ) + + outputs = [] + async for output in run_pipeline_with_config( + config_or_path=config_path, dataset=dataset + ): + outputs.append(output) + pipeline_result = outputs[-1] + + if pipeline_result.result is not None: + # Should look something like this, which should be identical to the python example: + # col1 col2 col_1_custom + # 0 2 4 2 - custom verb + # 1 5 10 5 - custom verb + print(pipeline_result.result) + else: + print("No results!") + + +async def run_python(): + workflows: list[PipelineWorkflowReference] = [ + PipelineWorkflowReference( + name="my_workflow", + steps=[ + { + "verb": "str_append", # should be the key that you pass to the custom_verbs dict below + "args": { + "source_column": "col1", # from above + "target_column": "col_1_custom", # new column name, + "string_to_append": " - custom verb", # The string to append to the column + }, + # Since we're trying to act on the default input, we don't need explicitly to specify an input + } + ], + ), + ] + + # Run the pipeline + outputs = [] + async for output in run_pipeline( + dataset=dataset, + workflows=workflows, + additional_verbs=custom_verbs, + ): + outputs.append(output) + + # Find the result from the workflow we care about + pipeline_result = next( + (output for output in outputs if output.workflow == "my_workflow"), None + ) + + if pipeline_result is not None and pipeline_result.result is not None: + # Should look something like this: + # col1 col2 col_1_custom + # 0 2 4 2 - custom verb + # 1 5 10 5 - custom verb + print(pipeline_result.result) + else: + print("No results!") + + +if __name__ == "__main__": + asyncio.run(run_python()) + asyncio.run(run_with_config()) diff --git a/graphrag/examples/custom_set_of_available_workflows/__init__.py b/graphrag/examples/custom_set_of_available_workflows/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/examples/custom_set_of_available_workflows/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/examples/custom_set_of_available_workflows/custom_workflow_definitions.py b/graphrag/examples/custom_set_of_available_workflows/custom_workflow_definitions.py new file mode 100644 index 0000000000000000000000000000000000000000..7d91750fa0382c9a0a296fbf09109e2b73bb9c17 --- /dev/null +++ b/graphrag/examples/custom_set_of_available_workflows/custom_workflow_definitions.py @@ -0,0 +1,36 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +from graphrag.index.workflows import WorkflowDefinitions + +# Sets up the list of custom workflows that can be used in a pipeline +# The idea being that you can have a pool of workflows that can be used in any number of +# your pipelines +custom_workflows: WorkflowDefinitions = { + "my_workflow": lambda config: [ + { + "verb": "derive", + "args": { + "column1": "col1", # looks for col1 in the dataset + "column2": "col2", # looks for col2 in the dataset + "to": config.get( + # Allow the user to specify the output column name, + # otherwise default to "output_column" + "derive_output_column", + "output_column", + ), # new column name, + "operator": "*", + }, + } + ], + "my_unused_workflow": lambda _config: [ + { + "verb": "derive", + "args": { + "column1": "col1", # looks for col1 in the dataset + "column2": "col2", # looks for col2 in the dataset + "to": "unused_output_column", + "operator": "*", + }, + } + ], +} diff --git a/graphrag/examples/custom_set_of_available_workflows/pipeline.yml b/graphrag/examples/custom_set_of_available_workflows/pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..0ce004d154ec6e5ecdcf0db7ba7c987afe6c1a24 --- /dev/null +++ b/graphrag/examples/custom_set_of_available_workflows/pipeline.yml @@ -0,0 +1,4 @@ +workflows: + - name: my_workflow + config: + derive_output_column: "col_1_multiplied" diff --git a/graphrag/examples/custom_set_of_available_workflows/run.py b/graphrag/examples/custom_set_of_available_workflows/run.py new file mode 100644 index 0000000000000000000000000000000000000000..c91f24f795acaf7e6de46de6fe5274528c870bce --- /dev/null +++ b/graphrag/examples/custom_set_of_available_workflows/run.py @@ -0,0 +1,85 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import os + +import pandas as pd + +from examples.custom_set_of_available_workflows.custom_workflow_definitions import ( + custom_workflows, +) +from graphrag.index import run_pipeline, run_pipeline_with_config +from graphrag.index.config import PipelineWorkflowReference + +sample_data_dir = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "../_sample_data/" +) + +# our fake dataset +dataset = pd.DataFrame([{"col1": 2, "col2": 4}, {"col1": 5, "col2": 10}]) + + +async def run_with_config(): + """Run a pipeline with a config file""" + # load pipeline.yml in this directory + config_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "./pipeline.yml" + ) + + # Grab the last result from the pipeline, should be our entity extraction + tables = [] + async for table in run_pipeline_with_config( + config_or_path=config_path, + dataset=dataset, + additional_workflows=custom_workflows, + ): + tables.append(table) + pipeline_result = tables[-1] + + if pipeline_result.result is not None: + # Should look something like this: + # col1 col2 col_1_multiplied + # 0 2 4 8 + # 1 5 10 50 + print(pipeline_result.result) + else: + print("No results!") + + +async def run_python(): + """Run a pipeline using the python API""" + # Define the actual workflows to be run, this is identical to the python api + # but we're defining the workflows to be run via python instead of via a config file + workflows: list[PipelineWorkflowReference] = [ + # run my_workflow against the dataset, notice we're only using the "my_workflow" workflow + # and not the "my_unused_workflow" workflow + PipelineWorkflowReference( + name="my_workflow", # should match the name of the workflow in the custom_workflows dict above + config={ # pass in a config + # set the derive_output_column to be "col_1_multiplied", this will be passed to the workflow definition above + "derive_output_column": "col_1_multiplied" + }, + ), + ] + + # Grab the last result from the pipeline, should be our entity extraction + tables = [] + async for table in run_pipeline( + workflows, dataset=dataset, additional_workflows=custom_workflows + ): + tables.append(table) + pipeline_result = tables[-1] + + if pipeline_result.result is not None: + # Should look something like this: + # col1 col2 col_1_multiplied + # 0 2 4 8 + # 1 5 10 50 + print(pipeline_result.result) + else: + print("No results!") + + +if __name__ == "__main__": + asyncio.run(run_python()) + asyncio.run(run_with_config()) diff --git a/graphrag/examples/entity_extraction/__init__.py b/graphrag/examples/entity_extraction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/examples/entity_extraction/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/examples/entity_extraction/with_graph_intelligence/__init__.py b/graphrag/examples/entity_extraction/with_graph_intelligence/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/examples/entity_extraction/with_graph_intelligence/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/examples/entity_extraction/with_graph_intelligence/pipeline.yml b/graphrag/examples/entity_extraction/with_graph_intelligence/pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..ffa5bee843540ac5b58ce0b931cc76d936934d50 --- /dev/null +++ b/graphrag/examples/entity_extraction/with_graph_intelligence/pipeline.yml @@ -0,0 +1,16 @@ +workflows: + - name: "entity_extraction" + config: + entity_extract: + strategy: + type: "graph_intelligence" + llm: + type: "openai_chat" + + # create a .env file in the same directory as this pipeline.yml file + # end add the following lines to it: + # EXAMPLE_OPENAI_API_KEY="YOUR_API_KEY" + api_key: !ENV ${EXAMPLE_OPENAI_API_KEY:None} # None is the default + model: !ENV ${EXAMPLE_OPENAI_MODEL:gpt-3.5-turbo} # gpt-3.5-turbo is the default + max_tokens: !ENV ${EXAMPLE_OPENAI_MAX_TOKENS:2500} # 2500 is the default + temperature: !ENV ${EXAMPLE_OPENAI_TEMPERATURE:0} # 0 is the default diff --git a/graphrag/examples/entity_extraction/with_graph_intelligence/run.py b/graphrag/examples/entity_extraction/with_graph_intelligence/run.py new file mode 100644 index 0000000000000000000000000000000000000000..0ec54dda29672d35b6d6c1bb38ceec5a5dc13626 --- /dev/null +++ b/graphrag/examples/entity_extraction/with_graph_intelligence/run.py @@ -0,0 +1,111 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import os + +from graphrag.index import run_pipeline, run_pipeline_with_config +from graphrag.index.config import PipelineCSVInputConfig, PipelineWorkflowReference +from graphrag.index.input import load_input + +sample_data_dir = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "../../_sample_data/" +) + +shared_dataset = asyncio.run( + load_input( + PipelineCSVInputConfig( + file_pattern=".*\\.csv$", + base_dir=sample_data_dir, + source_column="author", + text_column="message", + timestamp_column="date(yyyyMMddHHmmss)", + timestamp_format="%Y%m%d%H%M%S", + title_column="message", + ), + ) +) + + +async def run_with_config(): + """Run a pipeline with a config file""" + # We're cheap, and this is an example, lets just do 10 + dataset = shared_dataset.head(10) + + # load pipeline.yml in this directory + config_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "./pipeline.yml" + ) + + # Grab the last result from the pipeline, should be our entity extraction + tables = [] + async for table in run_pipeline_with_config( + config_or_path=config_path, dataset=dataset + ): + tables.append(table) + pipeline_result = tables[-1] + + # Print the entities. This will be a row for each text unit, each with a list of entities, + # This should look pretty close to the python version, but since we're using an LLM + # it will be a little different depending on how it feels about the text + if pipeline_result.result is not None: + print(pipeline_result.result["entities"].to_list()) + else: + print("No results!") + + +async def run_python(): + if ( + "EXAMPLE_OPENAI_API_KEY" not in os.environ + and "OPENAI_API_KEY" not in os.environ + ): + msg = "Please set EXAMPLE_OPENAI_API_KEY or OPENAI_API_KEY environment variable to run this example" + raise Exception(msg) + + # We're cheap, and this is an example, lets just do 10 + dataset = shared_dataset.head(10) + + workflows: list[PipelineWorkflowReference] = [ + PipelineWorkflowReference( + name="entity_extraction", + config={ + "entity_extract": { + "strategy": { + "type": "graph_intelligence", + "llm": { + "type": "openai_chat", + "api_key": os.environ.get( + "EXAMPLE_OPENAI_API_KEY", + os.environ.get("OPENAI_API_KEY", None), + ), + "model": os.environ.get( + "EXAMPLE_OPENAI_MODEL", "gpt-3.5-turbo" + ), + "max_tokens": os.environ.get( + "EXAMPLE_OPENAI_MAX_TOKENS", 2500 + ), + "temperature": os.environ.get( + "EXAMPLE_OPENAI_TEMPERATURE", 0 + ), + }, + } + } + }, + ) + ] + + # Grab the last result from the pipeline, should be our entity extraction + tables = [] + async for table in run_pipeline(dataset=dataset, workflows=workflows): + tables.append(table) + pipeline_result = tables[-1] + + # Print the entities. This will be a row for each text unit, each with a list of entities + if pipeline_result.result is not None: + print(pipeline_result.result["entities"].to_list()) + else: + print("No results!") + + +if __name__ == "__main__": + asyncio.run(run_python()) + asyncio.run(run_with_config()) diff --git a/graphrag/examples/entity_extraction/with_nltk/__init__.py b/graphrag/examples/entity_extraction/with_nltk/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/examples/entity_extraction/with_nltk/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/examples/entity_extraction/with_nltk/pipeline.yml b/graphrag/examples/entity_extraction/with_nltk/pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..10984f348224024ca9e871949379f09731ffda1b --- /dev/null +++ b/graphrag/examples/entity_extraction/with_nltk/pipeline.yml @@ -0,0 +1,6 @@ +workflows: + - name: "entity_extraction" + config: + entity_extract: + strategy: + type: "nltk" \ No newline at end of file diff --git a/graphrag/examples/entity_extraction/with_nltk/run.py b/graphrag/examples/entity_extraction/with_nltk/run.py new file mode 100644 index 0000000000000000000000000000000000000000..68575ad67b0f73ea6ba4f38298dc99623a2e6341 --- /dev/null +++ b/graphrag/examples/entity_extraction/with_nltk/run.py @@ -0,0 +1,78 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import os + +from graphrag.index import run_pipeline, run_pipeline_with_config +from graphrag.index.config import PipelineCSVInputConfig, PipelineWorkflowReference +from graphrag.index.input import load_input + +sample_data_dir = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "../../_sample_data/" +) +shared_dataset = asyncio.run( + load_input( + PipelineCSVInputConfig( + file_pattern=".*\\.csv$", + base_dir=sample_data_dir, + source_column="author", + text_column="message", + timestamp_column="date(yyyyMMddHHmmss)", + timestamp_format="%Y%m%d%H%M%S", + title_column="message", + ), + ) +) + + +async def run_with_config(): + """Run a pipeline with a config file""" + # We're cheap, and this is an example, lets just do 10 + dataset = shared_dataset.head(10) + + # load pipeline.yml in this directory + config_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "./pipeline.yml" + ) + + # Grab the last result from the pipeline, should be our entity extraction + tables = [] + async for table in run_pipeline_with_config( + config_or_path=config_path, dataset=dataset + ): + tables.append(table) + pipeline_result = tables[-1] + + # Print the entities. This will be a row for each text unit, each with a list of entities + if pipeline_result.result is not None: + print(pipeline_result.result["entities"].to_list()) + else: + print("No results!") + + +async def run_python(): + dataset = shared_dataset.head(10) + + workflows: list[PipelineWorkflowReference] = [ + PipelineWorkflowReference( + name="entity_extraction", + config={"entity_extract": {"strategy": {"type": "nltk"}}}, + ) + ] + + # Grab the last result from the pipeline, should be our entity extraction + tables = [] + async for table in run_pipeline(dataset=dataset, workflows=workflows): + tables.append(table) + pipeline_result = tables[-1] + + # Print the entities. This will be a row for each text unit, each with a list of entities + if pipeline_result.result is not None: + print(pipeline_result.result["entities"].to_list()) + else: + print("No results!") + + +if __name__ == "__main__": + asyncio.run(run_python()) + asyncio.run(run_with_config()) diff --git a/graphrag/examples/interdependent_workflows/__init__.py b/graphrag/examples/interdependent_workflows/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/examples/interdependent_workflows/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/examples/interdependent_workflows/pipeline.yml b/graphrag/examples/interdependent_workflows/pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..30bf81f9d2e93e3f0d77bf7736d57681e0f1ce2b --- /dev/null +++ b/graphrag/examples/interdependent_workflows/pipeline.yml @@ -0,0 +1,23 @@ +workflows: + - name: aggregate_workflow + steps: + - verb: "aggregate" # https://github.com/microsoft/datashaper/blob/main/python/datashaper/datashaper/engine/verbs/aggregate.py + args: + groupby: "type" + column: "col_multiplied" + to: "aggregated_output" + operation: "sum" + input: + source: "workflow:derive_workflow" # reference the derive_workflow, cause this one requires that one to run first + # Notice, these are out of order, the indexing engine will figure out the right order to run them in + + - name: derive_workflow + steps: + - verb: "derive" # https://github.com/microsoft/datashaper/blob/main/python/datashaper/datashaper/engine/verbs/derive.py + args: + column1: "col1" # from above + column2: "col2" # from above + to: "col_multiplied" # new column name + operator: "*" # multiply the two columns, + # Since we're trying to act on the dataset, we don't need explicitly to specify an input + # "input": { "source": "source" } # use the dataset as the input to this verb. This is the default, so you can omit it. \ No newline at end of file diff --git a/graphrag/examples/interdependent_workflows/run.py b/graphrag/examples/interdependent_workflows/run.py new file mode 100644 index 0000000000000000000000000000000000000000..9b486fa0e73f65d996af6fa4e78e83b51917535f --- /dev/null +++ b/graphrag/examples/interdependent_workflows/run.py @@ -0,0 +1,102 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import os + +import pandas as pd + +from graphrag.index import run_pipeline, run_pipeline_with_config +from graphrag.index.config import PipelineWorkflowReference + +# Our fake dataset +dataset = pd.DataFrame([ + {"type": "A", "col1": 2, "col2": 4}, + {"type": "A", "col1": 5, "col2": 10}, + {"type": "A", "col1": 15, "col2": 26}, + {"type": "B", "col1": 6, "col2": 15}, +]) + + +async def run_with_config(): + """Run a pipeline with a config file""" + # load pipeline.yml in this directory + config_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "./pipeline.yml" + ) + + tables = [] + async for table in run_pipeline_with_config( + config_or_path=config_path, dataset=dataset + ): + tables.append(table) + pipeline_result = tables[-1] + + if pipeline_result.result is not None: + # Should look something like this, which should be identical to the python example: + # type aggregated_output + # 0 A 448 + # 1 B 90 + print(pipeline_result.result) + else: + print("No results!") + + +async def run_python(): + workflows: list[PipelineWorkflowReference] = [ + PipelineWorkflowReference( + name="aggregate_workflow", + steps=[ + { + "verb": "aggregate", # https://github.com/microsoft/datashaper/blob/main/python/datashaper/datashaper/engine/verbs/aggregate.py + "args": { + "groupby": "type", + "column": "col_multiplied", + "to": "aggregated_output", + "operation": "sum", + }, + "input": { + "source": "workflow:derive_workflow", # reference the derive_workflow, cause this one requires that one to run first + # Notice, these are out of order, the indexing engine will figure out the right order to run them in + }, + } + ], + ), + PipelineWorkflowReference( + name="derive_workflow", + steps=[ + { + # built-in verb + "verb": "derive", # https://github.com/microsoft/datashaper/blob/main/python/datashaper/datashaper/engine/verbs/derive.py + "args": { + "column1": "col1", # from above + "column2": "col2", # from above + "to": "col_multiplied", # new column name + "operator": "*", # multiply the two columns, + }, + # Since we're trying to act on the default input, we don't need explicitly to specify an input + } + ], + ), + ] + + # Grab the last result from the pipeline, should be our aggregate_workflow since it should be the last one to run + tables = [] + async for table in run_pipeline(dataset=dataset, workflows=workflows): + tables.append(table) + pipeline_result = tables[-1] + + if pipeline_result.result is not None: + # Should look something like this: + # type aggregated_output + # 0 A 448 + # 1 B 90 + + # This is because we first in "derive_workflow" we multiply col1 and col2 together, then in "aggregate_workflow" we sum them up by type + print(pipeline_result.result) + else: + print("No results!") + + +if __name__ == "__main__": + asyncio.run(run_python()) + asyncio.run(run_with_config()) diff --git a/graphrag/examples/multiple_workflows/__init__.py b/graphrag/examples/multiple_workflows/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/examples/multiple_workflows/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/examples/multiple_workflows/pipeline.yml b/graphrag/examples/multiple_workflows/pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..1cbbaba74838c794fef928ce0da0a1a0165f3cf3 --- /dev/null +++ b/graphrag/examples/multiple_workflows/pipeline.yml @@ -0,0 +1,4 @@ +workflows: + - !include workflows/workflow_1.yml + - !include workflows/workflow_2.yml + - !include workflows/workflow_3.yml \ No newline at end of file diff --git a/graphrag/examples/multiple_workflows/run.py b/graphrag/examples/multiple_workflows/run.py new file mode 100644 index 0000000000000000000000000000000000000000..a583632789d26873f9f5063030dda952b630b59e --- /dev/null +++ b/graphrag/examples/multiple_workflows/run.py @@ -0,0 +1,43 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import os + +from graphrag.index import run_pipeline_with_config +from graphrag.index.config import PipelineCSVInputConfig +from graphrag.index.input import load_input + +sample_data_dir = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "./../_sample_data/" +) + + +async def run_with_config(): + dataset = await load_input( + PipelineCSVInputConfig( + file_pattern=".*\\.csv$", + base_dir=sample_data_dir, + source_column="author", + text_column="message", + timestamp_column="date(yyyyMMddHHmmss)", + timestamp_format="%Y%m%d%H%M%S", + title_column="message", + ), + ) + + # We're cheap, and this is an example, lets just do 10 + dataset = dataset.head(2) + + # run the pipeline with the config, and override the dataset with the one we just created + # and grab the last result from the pipeline, should be the last workflow that was run (our nodes) + pipeline_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "./pipeline.yml" + ) + + async for result in run_pipeline_with_config(pipeline_path, dataset=dataset): + print(f"Workflow {result.workflow} result\n: ") + print(result.result) + + +if __name__ == "__main__": + asyncio.run(run_with_config()) diff --git a/graphrag/examples/multiple_workflows/workflows/shared/shared_fill_value.txt b/graphrag/examples/multiple_workflows/workflows/shared/shared_fill_value.txt new file mode 100644 index 0000000000000000000000000000000000000000..5f790cbca958bee57e9ae7ba8b27fbf2ff06cc29 --- /dev/null +++ b/graphrag/examples/multiple_workflows/workflows/shared/shared_fill_value.txt @@ -0,0 +1 @@ +value_from_shared_file \ No newline at end of file diff --git a/graphrag/examples/multiple_workflows/workflows/workflow_1.yml b/graphrag/examples/multiple_workflows/workflows/workflow_1.yml new file mode 100644 index 0000000000000000000000000000000000000000..9ed87e1c439de77aabf493818be2ee187b1f70c1 --- /dev/null +++ b/graphrag/examples/multiple_workflows/workflows/workflow_1.yml @@ -0,0 +1,6 @@ +name: workflow_1 +steps: + - verb: fill + args: + to: "col_workflow_1" + value: 1 diff --git a/graphrag/examples/multiple_workflows/workflows/workflow_2.yml b/graphrag/examples/multiple_workflows/workflows/workflow_2.yml new file mode 100644 index 0000000000000000000000000000000000000000..c08147f2cb5447a123088ac721f9886686f7d4bb --- /dev/null +++ b/graphrag/examples/multiple_workflows/workflows/workflow_2.yml @@ -0,0 +1,17 @@ +name: workflow_2 +steps: + - verb: fill + args: + to: "col_workflow_2" + value: 2 + input: + + # workflow_2 is dependent on workflow_1 + # so in workflow_2 output, you'll also see the output from workflow_1 + source: "workflow:workflow_1" + + # Example of pulling in values from a shared file + - verb: fill + args: + to: "col_from_shared_file" + value: !include ./shared/shared_fill_value.txt diff --git a/graphrag/examples/multiple_workflows/workflows/workflow_3.yml b/graphrag/examples/multiple_workflows/workflows/workflow_3.yml new file mode 100644 index 0000000000000000000000000000000000000000..1a65f2d6b3af303cf97c13bbb61d32eec9de13e3 --- /dev/null +++ b/graphrag/examples/multiple_workflows/workflows/workflow_3.yml @@ -0,0 +1,6 @@ +name: workflow_3 +steps: + - verb: fill + args: + to: "col_workflow_3" + value: 3 diff --git a/graphrag/examples/single_verb/__init__.py b/graphrag/examples/single_verb/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/examples/single_verb/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/examples/single_verb/input/data.csv b/graphrag/examples/single_verb/input/data.csv new file mode 100644 index 0000000000000000000000000000000000000000..d1aaf77bfe97c03bdc87bc2360b54f815daa19b6 --- /dev/null +++ b/graphrag/examples/single_verb/input/data.csv @@ -0,0 +1,3 @@ +col1,col2 +2,4 +5,10 \ No newline at end of file diff --git a/graphrag/examples/single_verb/pipeline.yml b/graphrag/examples/single_verb/pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..9e8046124d2a4104883d73fc03d32a505a30cbdd --- /dev/null +++ b/graphrag/examples/single_verb/pipeline.yml @@ -0,0 +1,12 @@ +input: + file_type: csv + base_dir: ./input + file_pattern: .*\.csv$ +workflows: + - steps: + - verb: derive # https://github.com/microsoft/datashaper/blob/main/python/datashaper/datashaper/verbs/derive.py + args: + column1: "col1" + column2: "col2" + to: "col_multiplied" + operator: "*" diff --git a/graphrag/examples/single_verb/run.py b/graphrag/examples/single_verb/run.py new file mode 100644 index 0000000000000000000000000000000000000000..4c9f522521cdb291a58afdc3c6872405aac2c4bc --- /dev/null +++ b/graphrag/examples/single_verb/run.py @@ -0,0 +1,77 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import os + +import pandas as pd + +from graphrag.index import run_pipeline, run_pipeline_with_config +from graphrag.index.config import PipelineWorkflowReference + +# our fake dataset +dataset = pd.DataFrame([{"col1": 2, "col2": 4}, {"col1": 5, "col2": 10}]) + + +async def run_with_config(): + """Run a pipeline with a config file""" + # load pipeline.yml in this directory + config_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "./pipeline.yml" + ) + + tables = [] + async for table in run_pipeline_with_config( + config_or_path=config_path, dataset=dataset + ): + tables.append(table) + pipeline_result = tables[-1] + + if pipeline_result.result is not None: + # Should look something like this, which should be identical to the python example: + # col1 col2 col_multiplied + # 0 2 4 8 + # 1 5 10 50 + print(pipeline_result.result) + else: + print("No results!") + + +async def run_python(): + """Run a pipeline using the python API""" + workflows: list[PipelineWorkflowReference] = [ + PipelineWorkflowReference( + steps=[ + { + # built-in verb + "verb": "derive", # https://github.com/microsoft/datashaper/blob/main/python/datashaper/datashaper/engine/verbs/derive.py + "args": { + "column1": "col1", # from above + "column2": "col2", # from above + "to": "col_multiplied", # new column name + "operator": "*", # multiply the two columns + }, + # Since we're trying to act on the default input, we don't need explicitly to specify an input + } + ] + ), + ] + + # Grab the last result from the pipeline, should be our entity extraction + tables = [] + async for table in run_pipeline(dataset=dataset, workflows=workflows): + tables.append(table) + pipeline_result = tables[-1] + + if pipeline_result.result is not None: + # Should look something like this: + # col1 col2 col_multiplied + # 0 2 4 8 + # 1 5 10 50 + print(pipeline_result.result) + else: + print("No results!") + + +if __name__ == "__main__": + asyncio.run(run_with_config()) + asyncio.run(run_python()) diff --git a/graphrag/examples/use_built_in_workflows/__init__.py b/graphrag/examples/use_built_in_workflows/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/examples/use_built_in_workflows/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/examples/use_built_in_workflows/pipeline.yml b/graphrag/examples/use_built_in_workflows/pipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..cb1896857f0bfd6dd472ee0d1d666d6e7f64d8f9 --- /dev/null +++ b/graphrag/examples/use_built_in_workflows/pipeline.yml @@ -0,0 +1,23 @@ +workflows: + - name: "entity_extraction" + config: + entity_extract: + strategy: + type: "nltk" + + - name: "entity_graph" + config: + cluster_graph: + strategy: + type: "leiden" + embed_graph: + strategy: + type: "node2vec" + num_walks: 10 + walk_length: 40 + window_size: 2 + iterations: 3 + random_seed: 597832 + layout_graph: + strategy: + type: "umap" \ No newline at end of file diff --git a/graphrag/examples/use_built_in_workflows/run.py b/graphrag/examples/use_built_in_workflows/run.py new file mode 100644 index 0000000000000000000000000000000000000000..def3a0a67e54d7b21d1de5b0cf6b3c727dc4ef9c --- /dev/null +++ b/graphrag/examples/use_built_in_workflows/run.py @@ -0,0 +1,117 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import os + +from graphrag.index import run_pipeline, run_pipeline_with_config +from graphrag.index.config import PipelineCSVInputConfig, PipelineWorkflowReference +from graphrag.index.input import load_input + +sample_data_dir = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "../_sample_data/" +) + +# Load our dataset once +shared_dataset = asyncio.run( + load_input( + PipelineCSVInputConfig( + file_pattern=".*\\.csv$", + base_dir=sample_data_dir, + source_column="author", + text_column="message", + timestamp_column="date(yyyyMMddHHmmss)", + timestamp_format="%Y%m%d%H%M%S", + title_column="message", + ), + ) +) + + +async def run_with_config(): + """Run a pipeline with a config file""" + # We're cheap, and this is an example, lets just do 10 + dataset = shared_dataset.head(10) + + # load pipeline.yml in this directory + config_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "./pipeline.yml" + ) + + # Grab the last result from the pipeline, should be our entity extraction + tables = [] + async for table in run_pipeline_with_config( + config_or_path=config_path, dataset=dataset + ): + tables.append(table) + pipeline_result = tables[-1] + + if pipeline_result.result is not None: + # The output of this should match the run_python() example + first_result = pipeline_result.result.head(1) + print(f"level: {first_result['level'][0]}") + print(f"embeddings: {first_result['embeddings'][0]}") + print(f"entity_graph_positions: {first_result['node_positions'][0]}") + else: + print("No results!") + + +async def run_python(): + # We're cheap, and this is an example, lets just do 10 + dataset = shared_dataset.head(10) + + workflows: list[PipelineWorkflowReference] = [ + # This workflow reference here is only necessary + # because we want to customize the entity_extraction workflow is configured + # otherwise, it can be omitted, but you're stuck with the default configuration for entity_extraction + PipelineWorkflowReference( + name="entity_extraction", + config={ + "entity_extract": { + "strategy": { + "type": "nltk", + } + } + }, + ), + PipelineWorkflowReference( + name="entity_graph", + config={ + "cluster_graph": {"strategy": {"type": "leiden"}}, + "embed_graph": { + "strategy": { + "type": "node2vec", + "num_walks": 10, + "walk_length": 40, + "window_size": 2, + "iterations": 3, + "random_seed": 597832, + } + }, + "layout_graph": { + "strategy": { + "type": "umap", + }, + }, + }, + ), + ] + + # Grab the last result from the pipeline, should be our entity extraction + tables = [] + async for table in run_pipeline(dataset=dataset, workflows=workflows): + tables.append(table) + pipeline_result = tables[-1] + + # The output will contain entity graphs per hierarchical level, with embeddings per entity + if pipeline_result.result is not None: + first_result = pipeline_result.result.head(1) + print(f"level: {first_result['level'][0]}") + print(f"embeddings: {first_result['embeddings'][0]}") + print(f"entity_graph_positions: {first_result['node_positions'][0]}") + else: + print("No results!") + + +if __name__ == "__main__": + asyncio.run(run_python()) + asyncio.run(run_with_config()) diff --git a/graphrag/examples/various_levels_of_configs/__init__.py b/graphrag/examples/various_levels_of_configs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/examples/various_levels_of_configs/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/examples/various_levels_of_configs/pipelines/workflows_and_inputs.yml b/graphrag/examples/various_levels_of_configs/pipelines/workflows_and_inputs.yml new file mode 100644 index 0000000000000000000000000000000000000000..0a653831f20b3d13373338f16f3dd8007fac173b --- /dev/null +++ b/graphrag/examples/various_levels_of_configs/pipelines/workflows_and_inputs.yml @@ -0,0 +1,64 @@ +input: + file_type: csv + base_dir: ../../_sample_data + file_pattern: .*\.csv$ + source_column: "author" + text_column: "message" + timestamp_column: "date(yyyyMMddHHmmss)" + timestamp_format: "%Y%m%d%H%M%S" + title_column: "message" + + # Limit to 10, we're not rich + post_process: + - verb: sample + args: + size: 10 + input: + source: source + +workflows: + + # This workflow reference here is only necessary + # because we want to customize the how the entity_extraction workflow is configured + # otherwise, it can be omitted, but you're stuck with the default configuration for entity_extraction + - name: entity_extraction + config: + entity_extract: + strategy: + type: graph_intelligence + llm: + type: openai_chat + api_key: !ENV ${EXAMPLE_OPENAI_API_KEY} + model: !ENV ${EXAMPLE_OPENAI_MODEL:gpt-3.5-turbo} + max_tokens: !ENV ${EXAMPLE_OPENAI_MAX_TOKENS:2500} + temperature: !ENV ${EXAMPLE_OPENAI_TEMPERATURE:0} + + - name: entity_graph + config: + cluster_graph: + strategy: + type: leiden + embed_graph: + strategy: + type: node2vec + num_walks: 10 + walk_length: 40 + window_size: 2 + iterations: 3 + random_seed: 597832 + layout_graph: + strategy: + type: umap + + # This is an anonymous workflow, it doesn't have a name + - steps: + + # Unpack the nodes from the graph + - verb: graph.unpack + args: + column: positioned_graph + type: nodes + input: + + # This is saying use the output of the entity_graph workflow as the input to this step + source: workflow:entity_graph \ No newline at end of file diff --git a/graphrag/examples/various_levels_of_configs/pipelines/workflows_only.yml b/graphrag/examples/various_levels_of_configs/pipelines/workflows_only.yml new file mode 100644 index 0000000000000000000000000000000000000000..2c3c43de6e25f6d0a7f513e979ac6c636cfc1a33 --- /dev/null +++ b/graphrag/examples/various_levels_of_configs/pipelines/workflows_only.yml @@ -0,0 +1,46 @@ +workflows: + + # This workflow reference here is only necessary + # because we want to customize the how the entity_extraction workflow is configured + # otherwise, it can be omitted, but you're stuck with the default configuration for entity_extraction + - name: entity_extraction + config: + entity_extract: + strategy: + type: graph_intelligence + llm: + type: openai_chat + api_key: !ENV ${EXAMPLE_OPENAI_API_KEY} + model: !ENV ${EXAMPLE_OPENAI_MODEL:gpt-3.5-turbo} + max_tokens: !ENV ${EXAMPLE_OPENAI_MAX_TOKENS:2500} + temperature: !ENV ${EXAMPLE_OPENAI_TEMPERATURE:0} + + - name: entity_graph + config: + cluster_graph: + strategy: + type: leiden + embed_graph: + strategy: + type: node2vec + num_walks: 10 + walk_length: 40 + window_size: 2 + iterations: 3 + random_seed: 597832 + layout_graph: + strategy: + type: umap + + # This is an anonymous workflow, it doesn't have a name + - steps: + + # Unpack the nodes from the graph + - verb: graph.unpack + args: + column: positioned_graph + type: nodes + input: + + # This is saying use the output of the entity_graph workflow as the input to this step + source: workflow:entity_graph \ No newline at end of file diff --git a/graphrag/examples/various_levels_of_configs/workflows_and_inputs.py b/graphrag/examples/various_levels_of_configs/workflows_and_inputs.py new file mode 100644 index 0000000000000000000000000000000000000000..87c7c2f8d47e7fe465e3413c61f5803afda27cb6 --- /dev/null +++ b/graphrag/examples/various_levels_of_configs/workflows_and_inputs.py @@ -0,0 +1,40 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import os + +from graphrag.index import run_pipeline_with_config + + +async def main(): + if ( + "EXAMPLE_OPENAI_API_KEY" not in os.environ + and "OPENAI_API_KEY" not in os.environ + ): + msg = "Please set EXAMPLE_OPENAI_API_KEY or OPENAI_API_KEY environment variable to run this example" + raise Exception(msg) + + # run the pipeline with the config, and override the dataset with the one we just created + # and grab the last result from the pipeline, should be our entity extraction + pipeline_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "./pipelines/workflows_and_inputs.yml", + ) + + # run the pipeline with the config, and override the dataset with the one we just created + # and grab the last result from the pipeline, should be the last workflow that was run (our nodes) + tables = [] + async for table in run_pipeline_with_config(pipeline_path): + tables.append(table) + pipeline_result = tables[-1] + + # The output will contain a list of positioned nodes + if pipeline_result.result is not None: + top_nodes = pipeline_result.result.head(10) + print("pipeline result", top_nodes) + else: + print("No results!") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/graphrag/examples/various_levels_of_configs/workflows_and_inputs_with_custom_handlers.py b/graphrag/examples/various_levels_of_configs/workflows_and_inputs_with_custom_handlers.py new file mode 100644 index 0000000000000000000000000000000000000000..880c72ad9191d067af4021933c40936200ac2c83 --- /dev/null +++ b/graphrag/examples/various_levels_of_configs/workflows_and_inputs_with_custom_handlers.py @@ -0,0 +1,131 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import os +from typing import Any + +from datashaper import NoopWorkflowCallbacks, Progress + +from graphrag.index import run_pipeline_with_config +from graphrag.index.cache import InMemoryCache, PipelineCache +from graphrag.index.storage import MemoryPipelineStorage + + +async def main(): + if ( + "EXAMPLE_OPENAI_API_KEY" not in os.environ + and "OPENAI_API_KEY" not in os.environ + ): + msg = "Please set EXAMPLE_OPENAI_API_KEY or OPENAI_API_KEY environment variable to run this example" + raise Exception(msg) + + # run the pipeline with the config, and override the dataset with the one we just created + # and grab the last result from the pipeline, should be our entity extraction + pipeline_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "./pipelines/workflows_and_inputs.yml", + ) + + # Create our custom storage + custom_storage = ExampleStorage() + + # Create our custom reporter + custom_reporter = ExampleReporter() + + # Create our custom cache + custom_cache = ExampleCache() + + # run the pipeline with the config, and override the dataset with the one we just created + # and grab the last result from the pipeline, should be the last workflow that was run (our nodes) + pipeline_result = [] + async for result in run_pipeline_with_config( + pipeline_path, + storage=custom_storage, + callbacks=custom_reporter, + cache=custom_cache, + ): + pipeline_result.append(result) + pipeline_result = pipeline_result[-1] + + # The output will contain a list of positioned nodes + if pipeline_result.result is not None: + top_nodes = pipeline_result.result.head(10) + print("pipeline result", top_nodes) + else: + print("No results!") + + +class ExampleStorage(MemoryPipelineStorage): + """Example of a custom storage handler""" + + async def get( + self, key: str, as_bytes: bool | None = None, encoding: str | None = None + ) -> Any: + print(f"ExampleStorage.get {key}") + return await super().get(key, as_bytes) + + async def set( + self, key: str, value: str | bytes | None, encoding: str | None = None + ) -> None: + print(f"ExampleStorage.set {key}") + return await super().set(key, value) + + async def has(self, key: str) -> bool: + print(f"ExampleStorage.has {key}") + return await super().has(key) + + async def delete(self, key: str) -> None: + print(f"ExampleStorage.delete {key}") + return await super().delete(key) + + async def clear(self) -> None: + print("ExampleStorage.clear") + return await super().clear() + + +class ExampleCache(InMemoryCache): + """Example of a custom cache handler""" + + async def get(self, key: str) -> Any: + print(f"ExampleCache.get {key}") + return await super().get(key) + + async def set(self, key: str, value: Any, debug_data: dict | None = None) -> None: + print(f"ExampleCache.set {key}") + return await super().set(key, value, debug_data) + + async def has(self, key: str) -> bool: + print(f"ExampleCache.has {key}") + return await super().has(key) + + async def delete(self, key: str) -> None: + print(f"ExampleCache.delete {key}") + return await super().delete(key) + + async def clear(self) -> None: + print("ExampleCache.clear") + return await super().clear() + + def child(self, name: str) -> PipelineCache: + print(f"ExampleCache.child {name}") + return ExampleCache(name) + + +class ExampleReporter(NoopWorkflowCallbacks): + """Example of a custom reporter. This will print out all of the status updates from the pipeline.""" + + def progress(self, progress: Progress): + print("ExampleReporter.progress: ", progress) + + def error(self, message: str, details: dict[str, Any] | None = None): + print("ExampleReporter.error: ", message) + + def warning(self, message: str, details: dict[str, Any] | None = None): + print("ExampleReporter.warning: ", message) + + def log(self, message: str, details: dict[str, Any] | None = None): + print("ExampleReporter.log: ", message) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/graphrag/examples/various_levels_of_configs/workflows_only.py b/graphrag/examples/various_levels_of_configs/workflows_only.py new file mode 100644 index 0000000000000000000000000000000000000000..192297eb8f369b965dc00bd3d11555dec67b1cf6 --- /dev/null +++ b/graphrag/examples/various_levels_of_configs/workflows_only.py @@ -0,0 +1,59 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import os + +from graphrag.index import run_pipeline_with_config +from graphrag.index.config import PipelineCSVInputConfig +from graphrag.index.input import load_input + +sample_data_dir = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "../_sample_data/" +) + + +async def main(): + if ( + "EXAMPLE_OPENAI_API_KEY" not in os.environ + and "OPENAI_API_KEY" not in os.environ + ): + msg = "Please set EXAMPLE_OPENAI_API_KEY or OPENAI_API_KEY environment variable to run this example" + raise Exception(msg) + + dataset = await load_input( + PipelineCSVInputConfig( + file_pattern=".*\\.csv$", + base_dir=sample_data_dir, + source_column="author", + text_column="message", + timestamp_column="date(yyyyMMddHHmmss)", + timestamp_format="%Y%m%d%H%M%S", + title_column="message", + ), + ) + + # We're cheap, and this is an example, lets just do 10 + dataset = dataset.head(10) + + # run the pipeline with the config, and override the dataset with the one we just created + # and grab the last result from the pipeline, should be the last workflow that was run (our nodes) + pipeline_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "./pipelines/workflows_only.yml" + ) + tables = [] + async for table in run_pipeline_with_config(pipeline_path, dataset=dataset): + tables.append(table) + pipeline_result = tables[-1] + + # The output will contain a list of positioned nodes + if pipeline_result.result is not None: + top_nodes = pipeline_result.result.head(10) + print( + "pipeline result\ncols: ", pipeline_result.result.columns, "\n", top_nodes + ) + else: + print("No results!") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/graphrag/examples_notebooks/community/yfiles-jupyter-graphs/graph-visualization.ipynb b/graphrag/examples_notebooks/community/yfiles-jupyter-graphs/graph-visualization.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..bb2e93d8f0ad5835ef2c00fc27b80d863c6c19ed --- /dev/null +++ b/graphrag/examples_notebooks/community/yfiles-jupyter-graphs/graph-visualization.ipynb @@ -0,0 +1,529 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Visualizing the knowledge graph with `yfiles-jupyter-graphs`\n", + "\n", + "This notebook is a partial copy of [local_search.ipynb](../../local_search.ipynb) that shows how to use `yfiles-jupyter-graphs` to add interactive graph visualizations of the parquet files and how to visualize the result context of `graphrag` queries (see at the end of this notebook)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Copyright (c) 2024 Microsoft Corporation.\n", + "# Licensed under the MIT License." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "import pandas as pd\n", + "import tiktoken\n", + "\n", + "from graphrag.query.context_builder.entity_extraction import EntityVectorStoreKey\n", + "from graphrag.query.indexer_adapters import (\n", + " read_indexer_covariates,\n", + " read_indexer_entities,\n", + " read_indexer_relationships,\n", + " read_indexer_reports,\n", + " read_indexer_text_units,\n", + ")\n", + "from graphrag.query.input.loaders.dfs import (\n", + " store_entity_semantic_embeddings,\n", + ")\n", + "from graphrag.query.llm.oai.chat_openai import ChatOpenAI\n", + "from graphrag.query.llm.oai.embedding import OpenAIEmbedding\n", + "from graphrag.query.llm.oai.typing import OpenaiApiType\n", + "from graphrag.query.structured_search.local_search.mixed_context import (\n", + " LocalSearchMixedContext,\n", + ")\n", + "from graphrag.query.structured_search.local_search.search import LocalSearch\n", + "from graphrag.vector_stores.lancedb import LanceDBVectorStore" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Local Search Example\n", + "\n", + "Local search method generates answers by combining relevant data from the AI-extracted knowledge-graph with text chunks of the raw documents. This method is suitable for questions that require an understanding of specific entities mentioned in the documents (e.g. What are the healing properties of chamomile?)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load text units and graph data tables as context for local search\n", + "\n", + "- In this test we first load indexing outputs from parquet files to dataframes, then convert these dataframes into collections of data objects aligning with the knowledge model." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load tables to dataframes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "INPUT_DIR = \"../../inputs/operation dulce\"\n", + "LANCEDB_URI = f\"{INPUT_DIR}/lancedb\"\n", + "\n", + "COMMUNITY_REPORT_TABLE = \"create_final_community_reports\"\n", + "ENTITY_TABLE = \"create_final_nodes\"\n", + "ENTITY_EMBEDDING_TABLE = \"create_final_entities\"\n", + "RELATIONSHIP_TABLE = \"create_final_relationships\"\n", + "COVARIATE_TABLE = \"create_final_covariates\"\n", + "TEXT_UNIT_TABLE = \"create_final_text_units\"\n", + "COMMUNITY_LEVEL = 2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Read entities" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# read nodes table to get community and degree data\n", + "entity_df = pd.read_parquet(f\"{INPUT_DIR}/{ENTITY_TABLE}.parquet\")\n", + "entity_embedding_df = pd.read_parquet(f\"{INPUT_DIR}/{ENTITY_EMBEDDING_TABLE}.parquet\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Read relationships" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "relationship_df = pd.read_parquet(f\"{INPUT_DIR}/{RELATIONSHIP_TABLE}.parquet\")\n", + "relationships = read_indexer_relationships(relationship_df)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Visualizing nodes and relationships with `yfiles-jupyter-graphs`\n", + "\n", + "`yfiles-jupyter-graphs` is a graph visualization extension that provides interactive and customizable visualizations for structured node and relationship data.\n", + "\n", + "In this case, we use it to provide an interactive visualization for the knowledge graph of the [local_search.ipynb](../../local_search.ipynb) sample by passing node and relationship lists converted from the given parquet files. The requirements for the input data is an `id` attribute for the nodes and `start`/`end` properties for the relationships that correspond to the node ids. Additional attributes can be added in the `properties` of each node/relationship dict:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%pip install yfiles_jupyter_graphs --quiet\n", + "from yfiles_jupyter_graphs import GraphWidget\n", + "\n", + "\n", + "# converts the entities dataframe to a list of dicts for yfiles-jupyter-graphs\n", + "def convert_entities_to_dicts(df):\n", + " \"\"\"Convert the entities dataframe to a list of dicts for yfiles-jupyter-graphs.\"\"\"\n", + " nodes_dict = {}\n", + " for _, row in df.iterrows():\n", + " # Create a dictionary for each row and collect unique nodes\n", + " node_id = row[\"title\"]\n", + " if node_id not in nodes_dict:\n", + " nodes_dict[node_id] = {\n", + " \"id\": node_id,\n", + " \"properties\": row.to_dict(),\n", + " }\n", + " return list(nodes_dict.values())\n", + "\n", + "\n", + "# converts the relationships dataframe to a list of dicts for yfiles-jupyter-graphs\n", + "def convert_relationships_to_dicts(df):\n", + " \"\"\"Convert the relationships dataframe to a list of dicts for yfiles-jupyter-graphs.\"\"\"\n", + " relationships = []\n", + " for _, row in df.iterrows():\n", + " # Create a dictionary for each row\n", + " relationships.append({\n", + " \"start\": row[\"source\"],\n", + " \"end\": row[\"target\"],\n", + " \"properties\": row.to_dict(),\n", + " })\n", + " return relationships\n", + "\n", + "\n", + "w = GraphWidget()\n", + "w.directed = True\n", + "w.nodes = convert_entities_to_dicts(entity_df)\n", + "w.edges = convert_relationships_to_dicts(relationship_df)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configure data-driven visualization\n", + "\n", + "The additional properties can be used to configure the visualization for different use cases." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# show title on the node\n", + "w.node_label_mapping = \"title\"\n", + "\n", + "\n", + "# map community to a color\n", + "def community_to_color(community):\n", + " \"\"\"Map a community to a color.\"\"\"\n", + " colors = [\n", + " \"crimson\",\n", + " \"darkorange\",\n", + " \"indigo\",\n", + " \"cornflowerblue\",\n", + " \"cyan\",\n", + " \"teal\",\n", + " \"green\",\n", + " ]\n", + " return (\n", + " colors[int(community) % len(colors)] if community is not None else \"lightgray\"\n", + " )\n", + "\n", + "\n", + "def edge_to_source_community(edge):\n", + " \"\"\"Get the community of the source node of an edge.\"\"\"\n", + " source_node = next(\n", + " (entry for entry in w.nodes if entry[\"properties\"][\"title\"] == edge[\"start\"]),\n", + " None,\n", + " )\n", + " source_node_community = source_node[\"properties\"][\"community\"]\n", + " return source_node_community if source_node_community is not None else None\n", + "\n", + "\n", + "w.node_color_mapping = lambda node: community_to_color(node[\"properties\"][\"community\"])\n", + "w.edge_color_mapping = lambda edge: community_to_color(edge_to_source_community(edge))\n", + "# map size data to a reasonable factor\n", + "w.node_scale_factor_mapping = lambda node: 0.5 + node[\"properties\"][\"size\"] * 1.5 / 20\n", + "# use weight for edge thickness\n", + "w.edge_thickness_factor_mapping = \"weight\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Automatic layouts\n", + "\n", + "The widget provides different automatic layouts that serve different purposes: `Circular`, `Hierarchic`, `Organic (interactiv or static)`, `Orthogonal`, `Radial`, `Tree`, `Geo-spatial`.\n", + "\n", + "For the knowledge graph, this sample uses the `Circular` layout, though `Hierarchic` or `Organic` are also suitable choices." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Use the circular layout for this visualization. For larger graphs, the default organic layout is often preferrable.\n", + "w.circular_layout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Display the graph" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "display(w)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Visualizing the result context of `graphrag` queries\n", + "\n", + "The result context of `graphrag` queries allow to inspect the context graph of the request. This data can similarly be visualized as graph with `yfiles-jupyter-graphs`.\n", + "\n", + "## Making the request\n", + "\n", + "The following cell recreates the sample queries from [local_search.ipynb](../../local_search.ipynb)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# setup (see also ../../local_search.ipynb)\n", + "entities = read_indexer_entities(entity_df, entity_embedding_df, COMMUNITY_LEVEL)\n", + "\n", + "description_embedding_store = LanceDBVectorStore(\n", + " collection_name=\"entity_description_embeddings\",\n", + ")\n", + "description_embedding_store.connect(db_uri=LANCEDB_URI)\n", + "entity_description_embeddings = store_entity_semantic_embeddings(\n", + " entities=entities, vectorstore=description_embedding_store\n", + ")\n", + "covariate_df = pd.read_parquet(f\"{INPUT_DIR}/{COVARIATE_TABLE}.parquet\")\n", + "claims = read_indexer_covariates(covariate_df)\n", + "covariates = {\"claims\": claims}\n", + "report_df = pd.read_parquet(f\"{INPUT_DIR}/{COMMUNITY_REPORT_TABLE}.parquet\")\n", + "reports = read_indexer_reports(report_df, entity_df, COMMUNITY_LEVEL)\n", + "text_unit_df = pd.read_parquet(f\"{INPUT_DIR}/{TEXT_UNIT_TABLE}.parquet\")\n", + "text_units = read_indexer_text_units(text_unit_df)\n", + "\n", + "api_key = os.environ[\"GRAPHRAG_API_KEY\"]\n", + "llm_model = os.environ[\"GRAPHRAG_LLM_MODEL\"]\n", + "embedding_model = os.environ[\"GRAPHRAG_EMBEDDING_MODEL\"]\n", + "\n", + "llm = ChatOpenAI(\n", + " api_key=api_key,\n", + " model=llm_model,\n", + " api_type=OpenaiApiType.OpenAI, # OpenaiApiType.OpenAI or OpenaiApiType.AzureOpenAI\n", + " max_retries=20,\n", + ")\n", + "\n", + "token_encoder = tiktoken.get_encoding(\"cl100k_base\")\n", + "\n", + "text_embedder = OpenAIEmbedding(\n", + " api_key=api_key,\n", + " api_base=None,\n", + " api_type=OpenaiApiType.OpenAI,\n", + " model=embedding_model,\n", + " deployment_name=embedding_model,\n", + " max_retries=20,\n", + ")\n", + "\n", + "context_builder = LocalSearchMixedContext(\n", + " community_reports=reports,\n", + " text_units=text_units,\n", + " entities=entities,\n", + " relationships=relationships,\n", + " covariates=covariates,\n", + " entity_text_embeddings=description_embedding_store,\n", + " embedding_vectorstore_key=EntityVectorStoreKey.ID, # if the vectorstore uses entity title as ids, set this to EntityVectorStoreKey.TITLE\n", + " text_embedder=text_embedder,\n", + " token_encoder=token_encoder,\n", + ")\n", + "\n", + "local_context_params = {\n", + " \"text_unit_prop\": 0.5,\n", + " \"community_prop\": 0.1,\n", + " \"conversation_history_max_turns\": 5,\n", + " \"conversation_history_user_turns_only\": True,\n", + " \"top_k_mapped_entities\": 10,\n", + " \"top_k_relationships\": 10,\n", + " \"include_entity_rank\": True,\n", + " \"include_relationship_weight\": True,\n", + " \"include_community_rank\": False,\n", + " \"return_candidate_context\": False,\n", + " \"embedding_vectorstore_key\": EntityVectorStoreKey.ID, # set this to EntityVectorStoreKey.TITLE if the vectorstore uses entity title as ids\n", + " \"max_tokens\": 12_000, # change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 5000)\n", + "}\n", + "\n", + "llm_params = {\n", + " \"max_tokens\": 2_000, # change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 1000=1500)\n", + " \"temperature\": 0.0,\n", + "}\n", + "\n", + "search_engine = LocalSearch(\n", + " llm=llm,\n", + " context_builder=context_builder,\n", + " token_encoder=token_encoder,\n", + " llm_params=llm_params,\n", + " context_builder_params=local_context_params,\n", + " response_type=\"multiple paragraphs\", # free form text describing the response type and format, can be anything, e.g. prioritized list, single paragraph, multiple paragraphs, multiple-page report\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run local search on sample queries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "result = await search_engine.asearch(\"Tell me about Agent Mercer\")\n", + "print(result.response)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "question = \"Tell me about Dr. Jordan Hayes\"\n", + "result = await search_engine.asearch(question)\n", + "print(result.response)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Inspecting the context data used to generate the response" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "result.context_data[\"entities\"].head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "result.context_data[\"relationships\"].head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Visualizing the result context as graph" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"\n", + "Helper function to visualize the result context with `yfiles-jupyter-graphs`.\n", + "\n", + "The dataframes are converted into supported nodes and relationships lists and then passed to yfiles-jupyter-graphs.\n", + "Additionally, some values are mapped to visualization properties.\n", + "\"\"\"\n", + "\n", + "\n", + "def show_graph(result):\n", + " \"\"\"Visualize the result context with yfiles-jupyter-graphs.\"\"\"\n", + " from yfiles_jupyter_graphs import GraphWidget\n", + "\n", + " if (\n", + " \"entities\" not in result.context_data\n", + " or \"relationships\" not in result.context_data\n", + " ):\n", + " msg = \"The passed results do not contain 'entities' or 'relationships'\"\n", + " raise ValueError(msg)\n", + "\n", + " # converts the entities dataframe to a list of dicts for yfiles-jupyter-graphs\n", + " def convert_entities_to_dicts(df):\n", + " \"\"\"Convert the entities dataframe to a list of dicts for yfiles-jupyter-graphs.\"\"\"\n", + " nodes_dict = {}\n", + " for _, row in df.iterrows():\n", + " # Create a dictionary for each row and collect unique nodes\n", + " node_id = row[\"entity\"]\n", + " if node_id not in nodes_dict:\n", + " nodes_dict[node_id] = {\n", + " \"id\": node_id,\n", + " \"properties\": row.to_dict(),\n", + " }\n", + " return list(nodes_dict.values())\n", + "\n", + " # converts the relationships dataframe to a list of dicts for yfiles-jupyter-graphs\n", + " def convert_relationships_to_dicts(df):\n", + " \"\"\"Convert the relationships dataframe to a list of dicts for yfiles-jupyter-graphs.\"\"\"\n", + " relationships = []\n", + " for _, row in df.iterrows():\n", + " # Create a dictionary for each row\n", + " relationships.append({\n", + " \"start\": row[\"source\"],\n", + " \"end\": row[\"target\"],\n", + " \"properties\": row.to_dict(),\n", + " })\n", + " return relationships\n", + "\n", + " w = GraphWidget()\n", + " # use the converted data to visualize the graph\n", + " w.nodes = convert_entities_to_dicts(result.context_data[\"entities\"])\n", + " w.edges = convert_relationships_to_dicts(result.context_data[\"relationships\"])\n", + " w.directed = True\n", + " # show title on the node\n", + " w.node_label_mapping = \"entity\"\n", + " # use weight for edge thickness\n", + " w.edge_thickness_factor_mapping = \"weight\"\n", + " display(w)\n", + "\n", + "\n", + "show_graph(result)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.0" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/graphrag/examples_notebooks/global_search.ipynb b/graphrag/examples_notebooks/global_search.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..fdde2c706cf787c16a49b43a424c5ad32dd01c2b --- /dev/null +++ b/graphrag/examples_notebooks/global_search.ipynb @@ -0,0 +1,264 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\nCopyright (c) Microsoft Corporation.\\n'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Copyright (c) 2024 Microsoft Corporation.\n", + "# Licensed under the MIT License." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "import pandas as pd\n", + "import tiktoken\n", + "\n", + "from graphrag.query.indexer_adapters import read_indexer_entities, read_indexer_reports\n", + "from graphrag.query.llm.oai.chat_openai import ChatOpenAI\n", + "from graphrag.query.llm.oai.typing import OpenaiApiType\n", + "from graphrag.query.structured_search.global_search.community_context import (\n", + " GlobalCommunityContext,\n", + ")\n", + "from graphrag.query.structured_search.global_search.search import GlobalSearch" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Global Search example\n", + "\n", + "Global search method generates answers by searching over all AI-generated community reports in a map-reduce fashion. This is a resource-intensive method, but often gives good responses for questions that require an understanding of the dataset as a whole (e.g. What are the most significant values of the herbs mentioned in this notebook?)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### LLM setup" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "api_key = os.environ[\"GRAPHRAG_API_KEY\"]\n", + "llm_model = os.environ[\"GRAPHRAG_LLM_MODEL\"]\n", + "\n", + "llm = ChatOpenAI(\n", + " api_key=api_key,\n", + " model=llm_model,\n", + " api_type=OpenaiApiType.OpenAI, # OpenaiApiType.OpenAI or OpenaiApiType.AzureOpenAI\n", + " max_retries=20,\n", + ")\n", + "\n", + "token_encoder = tiktoken.get_encoding(\"cl100k_base\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load community reports as context for global search\n", + "\n", + "- Load all community reports in the `create_final_community_reports` table from the ire-indexing engine, to be used as context data for global search.\n", + "- Load entities from the `create_final_nodes` and `create_final_entities` tables from the ire-indexing engine, to be used for calculating community weights for context ranking. Note that this is optional (if no entities are provided, we will not calculate community weights and only use the `rank` attribute in the community reports table for context ranking)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# parquet files generated from indexing pipeline\n", + "INPUT_DIR = \"./inputs/operation dulce\"\n", + "COMMUNITY_REPORT_TABLE = \"create_final_community_reports\"\n", + "ENTITY_TABLE = \"create_final_nodes\"\n", + "ENTITY_EMBEDDING_TABLE = \"create_final_entities\"\n", + "\n", + "# community level in the Leiden community hierarchy from which we will load the community reports\n", + "# higher value means we use reports from more fine-grained communities (at the cost of higher computation cost)\n", + "COMMUNITY_LEVEL = 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "entity_df = pd.read_parquet(f\"{INPUT_DIR}/{ENTITY_TABLE}.parquet\")\n", + "report_df = pd.read_parquet(f\"{INPUT_DIR}/{COMMUNITY_REPORT_TABLE}.parquet\")\n", + "entity_embedding_df = pd.read_parquet(f\"{INPUT_DIR}/{ENTITY_EMBEDDING_TABLE}.parquet\")\n", + "\n", + "reports = read_indexer_reports(report_df, entity_df, COMMUNITY_LEVEL)\n", + "entities = read_indexer_entities(entity_df, entity_embedding_df, COMMUNITY_LEVEL)\n", + "print(f\"Report records: {len(report_df)}\")\n", + "report_df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Build global context based on community reports" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "context_builder = GlobalCommunityContext(\n", + " community_reports=reports,\n", + " entities=entities, # default to None if you don't want to use community weights for ranking\n", + " token_encoder=token_encoder,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Perform global search" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "context_builder_params = {\n", + " \"use_community_summary\": False, # False means using full community reports. True means using community short summaries.\n", + " \"shuffle_data\": True,\n", + " \"include_community_rank\": True,\n", + " \"min_community_rank\": 0,\n", + " \"community_rank_name\": \"rank\",\n", + " \"include_community_weight\": True,\n", + " \"community_weight_name\": \"occurrence weight\",\n", + " \"normalize_community_weight\": True,\n", + " \"max_tokens\": 12_000, # change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 5000)\n", + " \"context_name\": \"Reports\",\n", + "}\n", + "\n", + "map_llm_params = {\n", + " \"max_tokens\": 1000,\n", + " \"temperature\": 0.0,\n", + " \"response_format\": {\"type\": \"json_object\"},\n", + "}\n", + "\n", + "reduce_llm_params = {\n", + " \"max_tokens\": 2000, # change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 1000-1500)\n", + " \"temperature\": 0.0,\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "search_engine = GlobalSearch(\n", + " llm=llm,\n", + " context_builder=context_builder,\n", + " token_encoder=token_encoder,\n", + " max_data_tokens=12_000, # change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 5000)\n", + " map_llm_params=map_llm_params,\n", + " reduce_llm_params=reduce_llm_params,\n", + " allow_general_knowledge=False, # set this to True will add instruction to encourage the LLM to incorporate general knowledge in the response, which may increase hallucinations, but could be useful in some use cases.\n", + " json_mode=True, # set this to False if your LLM model does not support JSON mode.\n", + " context_builder_params=context_builder_params,\n", + " concurrent_coroutines=32,\n", + " response_type=\"multiple paragraphs\", # free form text describing the response type and format, can be anything, e.g. prioritized list, single paragraph, multiple paragraphs, multiple-page report\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "result = await search_engine.asearch(\n", + " \"What is the major conflict in this story and who are the protagonist and antagonist?\"\n", + ")\n", + "\n", + "print(result.response)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# inspect the data used to build the context for the LLM responses\n", + "result.context_data[\"reports\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "LLM calls: 13. LLM tokens: 184660\n" + ] + } + ], + "source": [ + "# inspect number of LLM calls and tokens\n", + "print(f\"LLM calls: {result.llm_calls}. LLM tokens: {result.prompt_tokens}\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/graphrag/examples_notebooks/inputs/operation dulce/ABOUT.md b/graphrag/examples_notebooks/inputs/operation dulce/ABOUT.md new file mode 100644 index 0000000000000000000000000000000000000000..cac4ea1182178e0929c7387c58ac707c8dc1964a --- /dev/null +++ b/graphrag/examples_notebooks/inputs/operation dulce/ABOUT.md @@ -0,0 +1,3 @@ +# About + +This document (Operation Dulce) is an AI-generated science fiction novella, included here for the purposes of providing a starting point for notebook experimentation. diff --git a/graphrag/examples_notebooks/inputs/operation dulce/Operation Dulce v2 1 1.md b/graphrag/examples_notebooks/inputs/operation dulce/Operation Dulce v2 1 1.md new file mode 100644 index 0000000000000000000000000000000000000000..95c9e3cd3af76b570f0550d69b2025d7cd6fafbb --- /dev/null +++ b/graphrag/examples_notebooks/inputs/operation dulce/Operation Dulce v2 1 1.md @@ -0,0 +1,970 @@ +# Operation: Dulce + +## Chapter 1 + +The thrumming of monitors cast a stark contrast to the rigid silence enveloping the group. Agent Alex Mercer, unfailingly determined on paper, seemed dwarfed by the enormity of the sterile briefing room where Paranormal Military Squad's elite convened. With dulled eyes, he scanned the projectors outlining their impending odyssey into Operation: Dulce. + +“I assume, Agent Mercer, you’re not having second thoughts?” It was Taylor Cruz’s voice, laced with an edge that demanded attention. + +Alex flickered a strained smile, still thumbing his folder's corner. "Of course not, Agent Cruz. Just trying to soak in all the details." The compliance in his tone was unsettling, even to himself. + +Jordan Hayes, perched on the opposite side of the table, narrowed their eyes but offered a supportive nod. "Details are imperative. We’ll need your clear-headedness down there, Mercer." + +A comfortable silence, the kind that threaded between veterans of shared secrets, lingered briefly before Sam Rivera, never one to submit to quiet, added, "I’ve combed through the last transmission logs. If anyone can make sense of the anomalies, it’s going to be the two of you." + +Taylor snorted dismissively. “Focus, people. We have protocols for a reason. Speculation is counter-productive.” The words 'counter-productive' seemed to hang in the air, a tacit reprimand directed at Alex. + +Feeling the weight of his compliance conflicting with his natural inclination to leave no stone unturned, Alex straightened in his seat. "I agree, Agent Cruz. Protocol is paramount," he said, meeting Taylor's steely gaze. It was an affirmation, but beneath it lay layers of unspoken complexities that would undoubtedly unwind with time. + +Alex's submission, though seemingly complete, didn't escape Jordan, who tilted their head ever so slightly, their eyes revealing a spark of understanding. They knew well enough the struggle of aligning personal convictions with overarching missions. As everyone began to collect their binders and prepare for departure, a quiet resolve took form within Alex, galvanized by the groundwork laid by their interactions. He may have spoken in compliance, but his determination had merely taken a subtler form — one that wouldn't surrender so easily to the forthcoming shadows. + +\* + +Dr. Jordan Hayes shuffled a stack of papers, their eyes revealing a tinge of skepticism at Taylor Cruz's authoritarian performance. _Protocols_, Jordan thought, _are just the framework, the true challenges we're about to face lie well beyond the boundaries of any protocol._ They cleared their throat before speaking, tone cautious yet firm, "Let's remember, the unknown variables exceed the known. We should remain adaptive." + +A murmur of agreement echoed from Sam Rivera, who leaned forward, lacing their fingers together as if weaving a digital framework in the air before them, "Exactly, adaptability could be the key to interpreting the signal distortions and system malfunctions. We shouldn't discount the… erratic." + +Their words hung like an electric charge in the room, challenging Taylor's position with an inherent truth. Cruz’s jaw tightened almost imperceptibly, but the agent masked it with a small nod, conceding to the omnipresent threat of the unpredictable. + +Alex glanced at Jordan, who never looked back, their gaze fixed instead on a distant point, as if envisioning the immense dark corridors they were soon to navigate in Dulce. Jordan was not one to embrace fantastical theories, but the air of cautious calculation betrayed a mind bracing for confrontation with the inexplicable, an internal battle between the evidence of their research and the calculating skepticism that kept them alive in their field. + +The meeting adjourned with no further comments, the team members quietly retreading the paths to their personal preparations. Alex, trailing slightly behind, observed the others. _The cautious reserve Jordan wears like armor doesn't fool me_, he thought, _their analytical mind sees the patterns I do. And that's worth more than protocol. That's the connection we need to survive this._ + +As the agents dispersed into the labyrinth of the facility, lost in their thoughts and preparations, the base's halogen lights flickered, a brief and unnoticed harbingers of the darkness to come. + +\* + +A deserted corridor inside the facility stretched before Taylor Cruz, each footstep rhythmic and precise. Cruz, ambitious and meticulous, eyed the troops passing by with a sardonic tilt of the lips. Obedience—it was as much a tool as any weapon in the arsenal, and Cruz wielded it masterfully. To them, it was another step toward unfettered power within the dark bowels of the military complex. + +Inside a secluded equipment bay, Cruz began checking over gear with mechanical efficiency. They traced fingers over the sleek surface of an encrypted radio transmitter. "If protocols are maintained," said Cruz aloud, rehearsing the speech for their subordinates, "not only will we re-establish a line of communication with Dulce, but we shall also illuminate the darkest secrets it conceals." + +Agent Hayes appeared in the doorway, arms crossed and a knowing glint in their eyes. "You do understand," Jordan began, the words measured and probing, "that once we're in the depths, rank gives way to survival instincts. It's not about commands—it's empowerment through trust." + +The sentiment snagged on Cruz's armor of confidence, probing at the insecurities festering beneath. Taylor offered a brief nod, perhaps too curt, but enough to acknowledge Jordan's point without yielding ground. "Trust," Cruz mused, "or the illusion thereof, is just as potent." + +Silence claimed the space between them, steeped in the reality of the unknown dangers lurking in the shadows of the mission. Cruz diligently returned to the equipment, the act a clear dismissal. + +Not much later, Cruz stood alone, the hollow echo of the bay a stark reminder of the isolation that power often wrought. With each checked box, their resolve steeled further, a silent vow to usher their team through the abyss—whatever it might hold—and emerge enshrined in the respect they so deeply craved. + +## Chapter 2 + +Sam Rivera sat alone in a cramped office, the hum of a dozen servers murmuring a digital lullaby in the background. Surrounded by the glow of multiple screens, their eyes danced across lines of code and intercepted comm signals from Dulce — a kaleidoscope of data that their curious and isolated mind hungered to decrypt. + +To an outsider, it might have looked like obsession, this fervent quest for answers. But to Sam, it was a dance — a give and take with the mysteries of the universe. Their fingers paused over the keyboard as they leaned back in the chair, whispering to thin air, "What secrets are you hiding from us?" + +The stillness of the room broke with the unexpected arrival of Alex Mercer, whose encroaching shadow loomed over Sam's workspace. The cybersecurity expert craned their neck upwards, met by the ever-so-slight furrow in Alex's brow. "Got a minute, Rivera?" + +"Always," Sam said, a smile surfacing as they swiveled to face their mentor more directly. _He has that look — like something's not sitting right with him,_ they noted inwardly. + +Alex hesitated, weighing his words carefully. "Our tech is top-tier, but the silence from Dulce... It's not just technology that will see us through, it's intuition and... trust." His gaze pierced through the digital haze, trying to instill something more profound than advice. + +Sam regarded Alex for a moment, the sincerity in his voice resonating with their own unspoken desire to prove their worth. "Intuition," they mirrored thoughtfully. "I guess sometimes the numbers don't have all the answers." + +Their shared silence held a newfound understanding, a recognition that between the ones and zeros, it was their combined human insights that might prevail against the impossible. As Alex turned to leave, Sam's eyes drifted back to the screens, now seeing them not as barriers to isolate behind, but as windows into the vast and enigmatic challenge that awaited their team. + +Outside the office, the persistent buzz of activity in the facility belied the unease that gripped its inhabitants. A restlessness that nibbled on the edges of reality, as though forewarning of the threshold they were soon to cross — from the known into the realm of cosmic secrets and silent threats. + +\* + +Shadows played against the walls of the cramped underground meeting room, where Alex Mercer stood gazing at the concealed elevator that would deliver them into the bowels of Dulce base. The air was thick, every breath laced with the weight of impending confrontation, the kind one feels when stepping into a legend. Though armed with an array of advanced weaponry and gear, there was an unshakeable sense that they were delving into a conflict where the physical might be of little consequence. + +"I know what you're thinking," Jordan Hayes remarked, approaching Mercer. Their voice was low, a blend of confidence and hidden apprehension. "This feels like more than a rescue or reconnaissance mission, doesn't it?" + +Alex turned, his features a mask of uneasy resolve. "It's like we're being pulled into someone else’s game. Not just observers or participants, but... pawns." + +Jordan gave a short nod, their analytical mind colliding with the uncertain dynamics of this operation. "I've felt that way since the briefing. Like there's a layer we’re not seeing. And yet, we have no choice but to play along." Their eyes locked with Alex's, silently exchanging a vow to remain vigilant. + +"You two need to cut the philosophical chatter. We have positions to secure," Taylor Cruz interjected sharply, stepping into their exchange. The authority in Taylor's voice brooked no argument; it was their way of pulling everyone back to the now. + +Alex's response was measured, more assertive than moments ago. "Acknowledged, Agent Cruz," he replied, his voice steadier, mirroring the transformation brewing within. He gripped his rifle with a newfound firmness. "Let's proceed." + +As they congregated at the elevator, a tension palpable, Sam Rivera piped in with a tone of balanced levity, "Hope everyone’s brought their good luck charms. Something tells me we’re going to need all the help we can get." + +Their laughter served as a brief respite from the gravity of their mission, a shared moment that reinforced their common humanity amidst the unknowable. Then, as one, they stepped into the elevator. The doors closed with a silent hiss, and they descended into the darkness together, aware that when they returned, if they returned, none of them would be the same. + +\* + +The sense of foreboding hung heavier than the darkness that the artificial lights of the elevator shaft failed to fully penetrate. The team was descending into the earth, carrying with them not only the weight of their equipment but also the silent pressure of the invisible war they were about to fight—a war that seemed to edge away from physicality and into the unnervingly psychological. + +As they descended, Dr. Jordan Hayes couldn't help but muse over the layers of data that could wait below, now almost longing for the comfort of empirical evidence. _To think that this reluctance to accept other possibilities may have been my biggest blind spot,_ Jordan contemplated, feeling the hard shell of skepticism begin to crack. + +Alex caught Jordan's reflective gaze and leaned in, his voice barely a murmur over the hum of the elevator. "Once we're down there, keep that analytical edge sharp. You see through the mazes of the unexplained better than anyone." + +The compliment was unexpected and weighed differently than praise from others. This was an acknowledgment from someone who stood on the front lines of the unknown with eyes wide open. "Thank you, Alex," Jordan said, the words carrying a trace of newfound assertiveness. "You can count on me." + +The exchange was cut short by a shudder that ran through the elevator, subtle, but enough to make them instinctively hold their breaths. It wasn't the mechanical stutter of old gears but a vibration that seemed to emanate from the very walls of the shaft—a whisper of something that defied natural explanation. + +Cruz was the first to react, all business despite the shadow that crossed their expression. "Systems check. Now," they barked out, masking the moment of disquiet with swift command. + +Every agent checked their gear, sending confirmation signals through their comms, creating a chorus of electronic beeps that promised readiness. But there was an unspoken question among them: was their technology, their weaponry, their protocols sufficient for what awaited them or merely a fragile comfort? + +Against the gravity of the silence that was once again closing in, Sam's voice crackled through, only half-jest. "I'd laugh if we run into Martians playing poker down there—just to lighten the mood, you know?" + +Despite—or perhaps because of—the oddity of the moment, this elicited a round of chuckles, an audible release of tension that ran counterpoint to the undercurrent of anxiety coursing through the team. + +As the elevator came to a halting, eerie calm at the sub-level, the group stepped off, finding themselves at the threshold of Dulce's mysterious halls. They stood in a tight pack, sharing a cautious glance before fanning out into the unknown, each one acutely aware that the truth was inevitably intertwined with danger. + +Into the depths of Dulce, the team advanced, their silence now a shared testament to the camaraderie born of facing the abyss together—and the steel resolve to uncover whatever horrors lay hidden in its shadows. + +\* + +The weight of the thick metal door closing behind them reverberated through the concrete hallway, marking the final threshold between the familiar world above and the strangeness that lay beneath. Dulce base, a name that had been whispered in the wind-blown deserts above and in the shadowed corners of conspiracy forums, now a tangible cold reality that they could touch — and that touched them back with a chill. + +Like lambs led to an altar of alien deities, so did Agents Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera proceed, their movements measured, their senses heightened. The air was still, almost respectful of the gravity of their presence. Their torch beams sliced through the darkness, uncovering steel doors with warnings that spoke of top secrets and mortal dangers. + +Taylor Cruz, stepping firmly into the role of de facto leader, set a brisk pace. "Eyes sharp, people. Comms check, every thirty seconds," Taylor ordered, their voice echoing slightly before being swallowed by the surrounding silence. + +Sam, fiddling with a handheld device aimed at detecting electronic anomalies, offered a murmured "Copy that," their usual buoyancy dimmed by the oppressive atmosphere. + +It was Jordan Hayes who paused at an innocuous looking panel, nondescript amongst the gauntlet of secured doorways. "Mercer, Rivera, come see this," Jordan’s voice was marked with a rare hint of urgency. + +Alex joined Jordan's side, examining the panel which, at a mere glance, seemed just another part of the base's infrastructure. Yet, to the trained eye, it appeared out of place—a facade. + +Jordan explained their reasoning as Sam approached, instinctively understanding the significance of what lay beneath, "This panel is a recent addition — covering something they didn't want found." + +Before Alex could respond, the soft whir of an approaching drone cut through their muffled exchange. Taylor had looped back upon hearing the commotion. "Explanations later. We can't afford to attract..." Cruz’s voice trailed off as the small airborne device came into view, its sensors locked onto the group. + +Sam was the first to react, their tech-savvy mind already steps ahead. "I've got this," they declared, fingers flying over the controls of their own gadgetry to ward off the impending threat. + +The drone lingered, its scan seeming more curious than hostile. But within moments, courtesy of Sam's interference, the little sentinel drifted away, retreating into the shadows as if accepting a silent truce. The crew exhaled, a moment of collective relief palpable in the air. + +Cruz squared their shoulders, clearly ruffled but not conceding any ground. "Move out," they directed, a hint more forceful than before. "And Rivera, keep that trick handy." + +The team pressed onward, the quiet now filled with the soft beeps of regular comms checks, their pace undeterred by the confrontation. Yet, every agent held a renewed sense of wariness, their trust in one another deepening with the knowledge that the base—its technology, its secrets—was alive in a way they hadn't fully anticipated. + +As they converged upon a central hub, the imposing doors to the mainframe room stood ajar — an invitation or a trap, neither option comforting. Without a word, they fortified their resolve and stepped through the threshold, where the dim glow of operational LED lights and the distant hum of machinery hinted at Dulce’s still-beating heart. + +Solemnly, yet unmistakably together, they moved deeper into the heart of the enigma, ready to unmask the lifeforce of Dulce base or confront whatever existential threat lay in wait. It was in that unwavering march towards the unknown that their destinies were forever cemented to the legacy of Operation: Dulce. + +## Chapter 3 + +The thrumming of monitors cast a stark contrast to the rigid silence enveloping the group. Agent Alex Mercer, unfailingly determined on paper, seemed dwarfed by the enormity of the sterile briefing room where Paranormal Military Squad's elite convened. With dulled eyes, he scanned the projectors outlining their impending odyssey into Operation: Dulce. + +\* + +The cooling vents hummed in a monotonous drone, but it was the crackle of the comms system coming to life that cut through the lab’s tension. Dr. Jordan Hayes hovered over a table arrayed with alien technology, their fingers delicately probing the enigmatic circuitry retrieved from the crash site. Agent Alex Mercer watched, admiration blooming in silent solidarity for Jordan's deft touch and unspoken drive. + +Jordan, always composed, only allowed the faintest furrow of concentration to mar their brow. "What we understand about physics..." they muttered, trailing off as they realigned a translucent component. The device emitted a low pulse, causing Jordan to still. "Could be fundamentally changed by this." + +A calculated risk—that's what this was. And for a person of science, a gamble was worth the potential paradigm shift. + +"I’ve been thinking," Alex started, his eyes still fixed on the immediately tangible mystery before them. "About what’s at stake here. Not the mission parameters, but what this means for us—humanity." + +Jordan glanced up, meeting his eyes just long enough to convey the shared enormity of their situation; the career-defining glory and existential dread entwined. "The quest for understanding always comes at a price. We're standing on the precipice of knowledge that could either elevate us or condemn us." + +The charged air between them spiked as Taylor Cruz’s brusque tones sliced through their reverie. "Hayes, Mercer, this isn't philosophy hour. Focus on the task. We need actionable intel, not daydreams." + +With a sound of restrained acknowledgment, Jordan returned their gaze to the device, while Alex clenched his jaw, the buzz of frustration dull against the backdrop of Taylor's authoritarian certainty. It was this competitive undercurrent that kept him alert, the sense that his and Jordan's shared commitment to discovery was an unspoken rebellion against Cruz's narrowing vision of control and order. + +Then Taylor did something unexpected. They paused beside Jordan and, for a moment, observed the device with something akin to reverence. “If this tech can be understood..." Taylor said, their voice quieter, "It could change the game for us. For all of us.” + +The underlying dismissal earlier seemed to falter, replaced by a glimpse of reluctant respect for the gravity of what lay in their hands. Jordan looked up, and for a fleeting heartbeat, their eyes locked with Taylor's, a wordless clash of wills softening into an uneasy truce. + +It was a small transformation, barely perceptible, but one that Alex noted with an inward nod. They had all been brought here by different paths and for different reasons. Yet, beneath the veneer of duty, the enticement of the vast unknown pulled them inexorably together, coalescing their distinct desires into a shared pulse of anticipation. + +Marshaled back to the moment by the blink of lights and whir of machinery, they refocused their efforts, each movement sharpened by the knowledge that beyond understanding the unearthly artifacts, they might be piecing together the future of their species. + +\* + +Amidst the sterility of the briefing room, the liminal space between the facts laid out and the hidden truths, sat Sam Rivera, his demeanor an artful balance of focus and a casual disguise of his razor-sharp talent with technology. Across from him, Alex Mercer lingered in thought, the mental cogs turning as each file on Dulce stirred more than curiosity—it beckoned to a past both honored and burdensome. + +"You've been quiet, Sam," Alex noted, catching the younger man's contemplative gaze. "Your take on these signal inconsistencies?" + +There was a respect in Alex's tone, though a respectful distance remained—a gulf of experience and a hint of protective mentorship that stood between them. Sam nodded, recognizing the space afforded to him, and he couldn't help but feel the weight of expectation pressing upon his shoulders. It wasn't just the mission that was immense, it was the trust being placed in him. + +"The patterns are... off," Sam admitted, hesitant but driven. "If I'm right, what we're looking at isn't random—it's a structured anomaly. We need to be ready for anything." + +Alex's eyes brightened with a subtle approval that crossed the distance like a silent nod. "Good. Keen eyes will keep us ahead—or at least not blindsided," he said, affirming the belief that inscribed Sam's role as more than the tech personnel—he was to be a guiding intellect in the heart of uncertainty. + +Their exchange was cut short by Taylor Cruz's abrupt arrival, his gait brimming with a robust confidence that veiled the sharp undercurrents of his striving nature. "Time to gear up. Dulce waits for no one," Taylor announced, his voice carrying an iron resolve that knew the costs of hesitation—though whether the cost was calculated in human or career terms was an ambiguity he wore like a badge of honor. + +As Sam and Alex nodded in unison, the icy chasm of hierarchy and cryptic protocols seemed momentarily to bridge over with an understanding—this mission was convergence, a nexus point that would challenge each of their motives and strength. + +They filed out of the briefing room, their footsteps synchronized, a rhythm that spoke volumes of the unknown cadence they would soon march to within the base's veins. For Alex Mercer, the link with Sam Rivera, though distant, was now poised with a mutuality ready to be tested; for Taylor Cruz, the initiative pulsed like a heartbeat, anticipation thinly veiled behind a mask of duty. + +In the midst of the descent, they were each alone yet irrevocably joined, stepping closer towards the volatile embrace of Operation: Dulce. + +## Chapter 4 + +The corridors of the Dulce military base were as silent as a tomb and twice as chilling. Alex Mercer walked with a surety that belied his bubbling undercurrents of doubt. The briefing had been definitive, sturdy pillars of facts and protocols, yet as he ventured deeper, the ominous atmosphere gnawed at him—a stark reminder of how much remained unknown. + +Jordan Hayes trailed a few steps behind, their detached exterior breaking for a moment as they caught up to Alex. "What's on your mind?" Jordan asked, their astuteness cutting through the unspoken tension. + +Alex glanced back at them. This place was a puzzle, a treacherous labyrinth where the walls whispered secrets, and among them, he sensed a call to question, to challenge the narrative they'd been sold. "The silence here... It's almost as if the base is waiting for something—or someone." + +"Just stay sharp, Mercer," Jordan cautioned, yet their eyes lingered on the quietude around them, conceiving the same shadow of doubt that unsettled Alex. + +Before they could delve into further discussion, the distinctive click of a safety catch echoed in the hollow space. Both agents turned to find Taylor Cruz standing resolute, primed for combat. Taylor's gaze was scrutinizing and cold, a stark contrast to the growing unease that smoldered silently amongst the rest. + +"Chatter is a liability," Taylor snapped, with a commanding flair that bordered on tyrannical. "We move forward, eyes open, mouths shut." + +Alex felt the tight grip of compliance strangle his gut, a lesson learned under the hard tutelage of rank and order. But here, in the bowels of Dulce, those instincts began to wane, the imperative to adhere now conflicting with the pressing urgency to confront the shadows they were enmeshed in. + +Then, unexpectedly, the lights flickered, a power fluctuation—or a sign? Alex's hand instinctively went to his sidearm, his mindset shifting from soldier to skeptic. The base, with its unyielding coldness, had just given them their first nudge into the realm of the speculative, an invitation to peel back the veneer of reality. + +"We should consider all possibilities," Alex murmured, more to himself than the others, his voice a barely audible breath against the sterile air of the complex. + +Taylor's posture stiffened at the challenge, yet their response was uncharacteristically reserved, notable in its lack of rebuke. "Agreed. For now, keep moving. But stay vigilant." + +A surprise—an echo of agreement from the last person Alex expected it from. And there it was, the glimpse of a wrinkle in the unyielding fabric of command, a hint that perhaps they were all starting to sense the strangeness that permeated this place. + +Progressing with determined steps, the trio moved deeper, silently acknowledging the evolution of their predicament. It was a small yet transformative concession to the unknown forces at play, an acknowledgment from each agent that, despite their disparate goals and ideals, the true nature of the Dulce base was an enigma that would forge new paths through their convictions. + +As they reached the central communications hub, the truth that awaited them lurked in the shadows, its eyes unseen but felt by all. The walls didn't just whisper now; they spoke in tones only the brave—or the foolish—would dare to listen to. + +\* + +The subterranean silence of Dulce was an oppressive entity of its own, wrapping the team in a cloak of uneasiness as they pressed on through the dimly lit corridor. Jordan Hayes found themselves contemplating the ramifications of each step taken into this suspended world, where the sterile air seemed to mock the gravity of their predicament. The closer they got to the communication hub, the more Jordan's mind wandered toward the realm of the inexplicable. + +Beside Jordan, Alex Mercer moved forward with deliberation, his gaze scanning the heavy utility doors they passed—one of which was partially ajar, beckoning them with its darkness. "After you, Dr. Hayes," Alex said, gesturing toward the mysterious opening. A hint of shared understanding passed between them; knowledge was the guiding star of this mission as much as confrontation or recovery. + +Jordan peered inside, the beam from their flashlight slicing through the obscurity. The room beyond was a chaotic cascade of papers, overturned furniture, and the particular kind of disorder born from hasty evacuation—or something far more sinister. + +"It's like they vanished in the middle of something urgent," Alex murmured, his voice tight with a mix of concern and anticipation. He began to sift through the scattered reports, each page a potential clue to the enigmatic silence that shrouded Dulce. + +Behind them, Taylor watched with a disciplined patience, their authority the foundation upon which the operation was built. Their voice cut into the stillness, a reminder of their presence, "Time is not our ally here." + +Drawing back from momentary distraction, Jordan acknowledged the wisdom in Taylor's words, yet could feel the shift in their stance—from skeptical, reserved analyst, to a proactive agent within the narrative. "You're right; these documents may hold critical insights. Let's collect what we can and analyze them properly." + +From the darkened hollows of the room, shadows seemed to cast subtle judgment as Alex and Jordan worked together with heightened urgency. Taylor, for once, didn't intervene but instead surveyed the entrance, their mind anticipating the unknown variables that lay ahead. + +Unexpectedly, a soft hiss emanated from a neglected terminal on the desk. Jordan's head snapped up, their heart rate accelerating at the potential ramifications. Without a word, they moved to the machine, hands driven by the newfound conviction that knowledge was more than power—it was survival. + +As Jordan began to extract what data they could from the terminal, the first comprehensible communication from the depths of Dulce in far too long crackled through: an automated distress marker, looping endlessly without further context. It was a revelation, one that reverberated through the group, confirming their fears and igniting an even greater need to press on. + +Watching Jordan's dogged determination, Alex witnessed the minor transformation in his colleague unfold—a shift from doubt to action, a sliver of belief in the possibilities beyond their rational understanding. This forge of resolve amidst the alien echoes of Dulce not only bonded them closer as a team but compelled them forward with a sharpened edge of responsibility to the truth, wherever it would lead. + +As they collected their findings and regrouped, the base around them imperceptibly changed, the air charged with the vibration of secrets poised on the brink of revelation. And in that charged silence, the group moved on, each now carrying pieces of a puzzle that would soon converge into a picture of galactic significance. + +\* + +In the chill of the cramped server room, the hum of machinery was the backbone to a symphony of data streams coursing through the air. Dr. Jordan Hayes, nerves alight with the mission's mounting unknowns, patched into the last known coordinates of the unsent distress broadcast they had uncovered. They were so close to the core now – to the truth behind the blackout – it was almost tangible. + +Beside them stood Agent Alex Mercer, ever the soldier, yet with eyes that betrayed an intellect craving to understand the murk beneath the surface. "Any progress, Dr. Hayes?" Alex queried, his voice betraying a subtle urgency. + +"Getting there," Jordan replied, fingers dancing across the keyboard. "Whoever sent this was cut off mid-transmission. It's as if Dulce itself swallowed the message whole." + +Taylor Cruz closed in, their frame casting a long shadow over the duo, evoking an almost palpable wall between them and the forward momentum of their mission. "Time is against us," Taylor intoned, more statement than threat. "What we uncover here determines our next course of action." + +Alex acknowledged Taylor with a brisk nod, his stance firm. Yet inwardly, the tightening grip he felt from Taylor's words couldn't throttle the swell of his own investigative instinct. His soldier's obedience had begun to war with the advocate's zeal for unveiling the dark heart of Dulce's secrets. + +And then, the unexpected occurred. The screens flashed in unison, spilling a discordant stream of symbols and images that defied immediate analysis. Jordan's breath caught – this was the response they had been fishing for, an alien communication protocol resonating just at the edge of human comprehension. + +Each member of the team felt it: a shift in the room’s very atmosphere, like a veil being drawn from their perception. Alex and Jordan stood still, absorbed in the bewilderment of contact, while Taylor, despite their authority, hesitated – a minor betrayal that unease was creeping into even their disciplined heart. + +"Thoughts, Rivera?" Taylor rallied, seeking the counsel of Sam Rivera, whose eyes were wide with exhilaration. + +Sam stepped forward, breaking the spell of stillness. "It's like nothing I've ever seen before, but I think I can bridge our systems to communicate," they declared, a wisp of optimism braiding their voice. They set about adapting their gear to transmute the foreign signals into something the team could dissect, their actions a testament to the mentorship and belief instilled in them by Mercer and the team. + +Taylor observed them, a cold calculation behind their facade, as they weighed the worth of this anomaly. It was a crossroad that potentially led to either monumental breakthrough or unprecedented catastrophe. "Once you've established a line, document everything. We can't afford to miss any detail," Taylor ordered, the words sharper than intended. + +The connection was made, and with trembling anticipation, the team listened as the first garbled outputs began to emerge, their very essence promising insights that could alter the course of history. It was an enigmatic dance with the unknown, the pulse of Dulce no longer just a place, but a herald to an alien register the team had yet to decipher. + +Together, they stood at the precipice of understanding, where the faint glow of their monitors cast more than just light – it cast the shadow of burgeoning transformation. It was in this moment, in the grasp of an extraterrestrial tongue, that the team, bound by a hunger for knowledge and the raw edge of survival, found their mission reframed from a search for answers to the articulation of a question humankind had yet to fully ask. + +Silent in their commune with the inexplicable frequency, they realized they were not merely investigators; they had become liaisons on behalf of Earth, interpreters of a cosmic message that could redefine their very existence. The implications loomed large, but now, they would not face them alone – they would face them as a united front, wrought together by the very mysteries that once drove them apart. + +## Chapter 5 + +Dr. Jordan Hayes clutched the edge of the briefing room table, their fingers white-knuckled against the laminate surface, as an array of constellations rotated on the projector—charts and graphs bleeding across the stars. In the dim room, nebulas and dark matter seemed within arm's reach, tangible yet unfathomable. + +Sam Rivera leaned back against the wall, arms crossed, gaze darting between the swirling cosmos and the faces of their companions. A taut line of concentration etched their young features, a mingling of fervent curiosity with the nascent understanding of the high stakes for which they played. + +Jordan's voice broke the profound silence. "The patterns in the signal disruptions sync with none other than zenithal star alignments. It's as if... as if these 'meet and greets' were scheduled, predestined by celestial mechanics." + +The statement hung heavy, daring the occupants of the room to unravel its implications. Alex Mercer, his prior military resolve momentarily suspended, absorbed the hypothesis with a visible hunger. "It's like we're adhering to an appointment we never knew we had," he murmured, his heart a drumbeat in his chest. + +Taylor Cruz snorted—a sound that clattered against the high concepts like a tumbledown shack in a futurist cityscape. Folding their arms, they glanced between the agents, their apprehension clad in the contempt of practicality. "What we need are facts, not mystic conjecture." + +Alex pivoted on his heel, facing Taylor squarely, and his voice found its edge of steel. "This isn't mysticism, Cruz. It's a hypothesis based on observed phenomena as unpredictable as the place we're standing in." + +Taylor's gaze never wavered, yet the slight twitch at the corner of their mouth belied their taut composure. "If there's a semblance of truth to it, then it's critical intel. But remember, we're not astrologers—we're soldiers and scientists." + +Jordan met Taylor’s gaze with a curt nod, accepting the caution even as the crucible of their intellect smoldered with the fervor of cosmic discovery. Their eyes flicked to Sam, whose steady presence and ready tech affirmed a burgeoning dynamic—the makings of a sentinel, standing guard over the threshold of human understanding and cosmic reality. + +With the projector casting pallid light over their features, each agent became a silhouette of purpose, shadows pillared against the backdrop of an endless universe. The story they were embroiled in would soon demand they plunge into darkness to retrieve the light of knowledge—a light that could very well redraw the shape of their world. + +They left the briefing room with a shared silence, each pondering the vast weave of celestial intent and terrestrial response, sensing that the galactic appointment to which they'd unwittingly RSVP’d was more insistent—and more threatening—than any operation they’d faced before. + +\* + +As the Paranormal Military Squad team convened in the heart of the Dulce military complex, an air of bristling expectation clung to the walls of the underground sanctum. Alex Mercer’s brow furrowed while watching his companions—Jordan Hayes, diligently setting up their makeshift lab station, and Sam Rivera meticulously checking the communication relays they had restored. Taylor Cruz observed with hawk-like focus, yet to betray the strain that their command posed on them. + +The gravity of the mission had shifted, deepened; each member of the team felt its pull, tethered to the understanding that they were now part of a larger narrative—a cosmic play with Earth as a stage and the human race unwitting actors. + +Jordan paused, a tension creeping across their shoulders as they aligned the satellite data with the alien message that had been decoded. "The instructions in this message," Jordan started, the timbre of their voice betraying their usual composure. "They're coordinates and... a warning." + +Sam leaned in, their eyes widening behind the glow of their laptop screen. "A warning? Like, ‘stay away from’, or ‘beware of’...?" Their words trailed off, uncertainty a new companion in their lexicon. + +Alex exhaled slowly, his mind racing to connect the dots. "It doesn't matter which," he said, decisive yet contemplative. "What matters is we understand intent. Are we being warned out of concern, or are we stumbling upon a threat?" + +Cruz’s iron-clad facade momentarily cracked, a fleeting glimpse of vulnerability flashing through their eyes. "We need to know if this entails additional risk to the operation," they said, directing their gaze specifically at Alex. "Mercer, I rely on you to keep the team grounded. No one goes off-course." + +Their reminder seemed both a command and a plea—rooted in an understanding that each member of the team now faced the duality of their roles, protectors of earthly secrets and heralds of potentially devastating revelations. + +Sam's fingers stilled mid-type, their task forgotten as they absorbed the weight of the unfolding reality. "We're the first line of defense... or detection," they mused half to themselves, a growing sense of agency within the larger play they were cast into. + +Jordan returned to the data, more resolute in their actions. The warning, whether cautionary or dire, was a beacon they no longer could ignore; its light casting aside shadows of doubt and igniting a collective purpose within the team. + +Alex watched Jordan and Sam, feeling a brotherhood in their shared quest. As Cruz paced, poised on the cusp of decisions that would mark their career and perhaps the fate of many, Alex knew the narrative had changed. They were no longer mere operatives; they had become guardians of a threshold, keepers of a message from a realm beyond stars and stripes. This elevation in their mission could not be shackled by regulations and established protocols—it demanded a new perspective, a new resolve. + +Tension threaded through the dialogue of beeps and static as communications with Washington buzzed in the background. The team stood, a portentous air enveloping them. It was clear that the decisions they made in the ensuing hours could redefine humanity's place in the cosmos or condemn them to ignorance and potential peril. + +Their connection to the stars solidified, the group moved to address the crystallizing warning, shifting from passive recipients to active participants. Mercer’s latter instincts gained precedence— the team’s mandate had evolved, no longer solely to observe and report but to interact and prepare. A metamorphosis had begun, and Operation: Dulce hummed with the newfound frequency of their daring, a tone set not by the earthly hierarchies but by the pulsing symphony of the universe itself. + +\* + +The desert night loomed eerily still as echoes of hidden activity reverberated deep beneath the bleak sands of New Mexico. Diverting his gaze from the array of sensors before him, Jordan Hayes allowed a rare breath, deep and anxious. Turning to Alex Mercer's focused silhouette, the nocturnal landscape illuminated softly by makeshift floodlights, Jordan felt the syncopated tempo of apprehension and exhilaration jockey for primacy within. + +"The closer we get to unlocking these messages, the more I feel like we're peeling back layers of reality itself," Jordan confided, eyes not leaving the monitors that presented a constellation of data points. + +"Yes," Alex replied, his voice steady as he considered the implications of their discovery. "And we have to be ready for whatever we find beneath those layers. Whether it's a breakthrough or a Pandora's Box." + +Silence settled between them, broken only by the occasional buzz of communications equipment attempting to bridge terrestrial and extraterrestrial intelligences. Tense moments drifted by, laden with the expectant weight of near breakthrough, when a soft chime signaled an incoming transmission -- a rare sound that set every agent on high alert. + +Absent was the voice of Washington or Paranormal Military Squad command. Instead, a rhythmic series of pulses and tones filled the air, deliberately patterned, unmistakably non-human. + +Sam Rivera adjusted the sensitivity of the decoding equipment, their hands shaking with anticipation as much as focus. "I have it!" they announced, the signal transforming under their expertise into a sequence of visual symbols on the screen before them. + +Their shared excitement was palpable, a kinetic force resonating between the team members as they crowded around the display. + +"What does it say?" Taylor Cruz demanded, the urgency in his tone scraping against the newfound wonderment. + +Interpreting the alien syntax required not only decoding but intuition and empathy. The words that emerged upon the screen were at once coherent and enigmatic: "*Voyage. Convergence. Peril.*" + +The stark simplicity of the message struck them collectively, a chill breeze wafting through their resolve. + +Alex stepped forward, piecing together the cryptic communication with a growing sense of obligation. "It’s a call to action," he deduced, "or possibly a summons." + +Jordan's gaze met Alex’s, both understanding that this was no longer an investigation or mere extraction of hidden truths. This was humanity's unwitting enlistment into a galactic dialogue that defied boundaries of nation, creed, or protocol. + +Sam's eyes were aglow, not with fear, but with the profound acceptance of inevitability that comes with groundbreaking revelation. Moreover, within Taylor's stern exterior churned the seed of reluctant admiration for the unclassified, the uncharted realms they were approaching. + +Together, they accepted the pivot in their mission, readjusting their objectives from exploration to engagement, and from isolation to a communal outreach beyond the stars. As dawn's first light threatened the horizon, it became clear that they were no longer merely operatives of a clandestine governmental faction—they were delegates on behalf of Earth, embarking on a voyage orchestrated by destinies unrelated to the mere geopolitics of their world. + +Turning to each other, their silhouettes sketched against the coming dawn, the agents recognized the transformation within and amongst them. They were bound by more than duty—they were intricately woven into the fabric of an unfolding cosmic opera, one in which they had been granted an undeniable role. And as they set course for the coordinates that beckoned them like a distant siren's call, it was with a solemn dedication to not only uncover the mysteries ahead but to navigate the convergence, and the peril, as unified emissaries of a world on the cusp of a broader understanding. + +\* + +Beneath the hum of the fluorescent lights and the vigilance of silent monitors, Alex Mercer stood with his team in the threshold of the base's command center, their faces etched with the fatigue of hours spent unraveling galactic mysteries. Jordan Hayes broke the stillness with a delicate fusion of disbelief and resolve. "The signal..." they began, their tone deliberate, "it’s evolving. It’s not just sending a message—it’s responding to us." + +Taylor Cruz leaned over the console, their eyes narrowing with intrigue and a flicker of unease, studying the alternating patterns on the screen. "Responding? Like it’s alive?" Taylor asked, a question that bordered on the edge of wonder and alarm. + +Sam Rivera’s gaze was locked onto their interface, a digital orchestra at their fingertips. "It could be some form of advanced AI. Or something else entirely," they contributed, a note of exhilaration betraying the gravity of the situation. + +Alex paced before the terminal, absorbing the enormity of their predicament. Their mission—once rooted in the solid ground of military discipline and covert operations—had transcended into an encounter of unprecedented import. "We need to be cautious," he advised, his voice a low rumble of cautious strategy. "If this signal is intelligent, how we interact with it could dictate the outcome of this entire operation." + +Jordan met Alex's gaze with a nod, the weight of the responsibility shared and accepted. "We have protocols for first contact, but nothing for... this," Jordan admitted. The room was gripped with tension, each breath seemingly louder than the last. + +Then, with a sudden burst that filled the command center, the signal coalesced into a clear and distinct pattern which replicated and expanded, its complexity revealing the hand—or mind—of an intelligent architect. + +Taylor's instinct for command surged forth. "Prepare to record and analyze. Whatever it is, we need to understand it—" But their words were cut short as the signal surged, enveloping the room in a brief, blinding cascade of light. + +In that pulse of brilliance, a shared revelation coursed through the team. The signal had become a bridge, an extension of unknown consciousness reaching towards them, testing, communicating, searching. + +Alex stepped back from the light, feeling a profound change unravelling within him. The path forward would not be one of confrontation or conquest, but of connection and comprehension. + +Jordan turned to Alex and Taylor, seeing in their faces a reflection of the same metamorphosis taking place within themselves—a movement from observers to participants, from agents to ambassadors. + +With a collective breath, the team faced the kaleidoscope of lights. The alien signal, once a harbinger of enigma, was now a catalyst for transformation—a symphony of light and sound that echoed the beginnings of a new relationship between humanity and the alien unknown. + +And so, with deliberate steps, Alex Mercer led his team into the luminous fray. Science, protocol, and survival instinct harmonized within them, each member poised on the cusp of a new chapter in human history. + +They were no longer merely the instruments of Paranormal Military Squad's will—they were the vanguard of humankind’s first definitive leap into the cosmic community. + +With the last echoes of the signal resonating in the control room, they each embraced the sequencing of the transmission, the dance of extraterrestrial light that now wrote itself into their story. The chapter of Operation: Dulce drew to a close, but the narrative of their destiny had only just begun. + +## Chapter 6 + +\* + +The cool darkness of the command center at Dulce base was a stark contrast to the brewing storm outside, where the unforgiving New Mexico desert winds whispered of the hidden truths that lay buried deep beneath its surface. Dr. Jordan Hayes sat, their eyes fixed on the readout, the frenetic dance of symbols and numbers reflecting off their determined face. They were on the cusp of an epiphany, teetering between the widely accepted laws of physics and the promise of a new cosmic paradigm. + +Alex Mercer watched from across the room, noting the subtle shifts in Jordan’s posture that belied a developing readiness to embrace the unbelievable. “Find something?” Alex’s question, asked with a blend of curiosity and solidarity, bridged the gap between a command and a genuine query among equals. + +Jordan's response was slow, measured against the magnitude of their analysis. “This isn’t random static. It’s a pattern - a repeated sequence phasing in and out but distinctly artificial.” Jordan turned away from the screen, locking eyes with Alex. “This could change everything.” + +Sam Rivera leaned in, their eyes alight with the fires of revelation and a quenchless thirst for understanding. “A pattern means intention. Could it be a message?” + +A figure emerged from the doorway, casting a long shadow into the room - Taylor Cruz. “Intentions can be friendly, or hostile. We shouldn’t forget that,” said Taylor, bringing a dose of their usual pragmatism into the heart of discovery. + +Alex acknowledged Taylor’s caution with a nod, understanding the need to keep their feet grounded even as their spirits soared toward the unknown. “Then let’s be the first to find out which it is." + +The team gathered around the monitors, the soft tapping of Jordan's keystrokes now punctuated by the occasional crackle of Sam's radio equipment. The sound was almost ritualistic, a prelude to humanity’s potential first, knowing foray into a larger universe. + +Jordan’s fingers paused, suspended in mid-air. The signal had evolved, becoming a beacon that somehow felt less alien and more familiar. It was as if the complexities of their message were unfolding into something more accessible, more terrestrial. + +A hushed excitement swept through the room. The transformation suggested an awareness on the part of the unknown senders; a finesse that spoke volumes about their capabilities and perhaps their intentions. + +With the growing realization that they were engaging with an intelligence far exceeding their previous understanding, the team prepared to reach back across the cosmic divide. Prepared or not, they were no longer bystanders in this galactic narrative. They were active correspondents in an exchange that transcended galaxies and welcomed them into an expansive, possibly fraught, interstellar conversation. + +\* + +Inside the cavernous central hub of Dulce military base, Dr. Jordan Hayes stood in near-darkness, surrounded by a nest of cables and monitors that buzzed with silent, cryptic life. Jordan's eyes narrowed to focus on the sequences that danced across the screen—patterns that could unravel the cosmic enigma surrounding them. + +Alex Mercer approached with his characteristic stride, a signal of reliability in the chaos. "Status report, Dr. Hayes?" he inquired, his voice low, almost blending into the soundscape of beeping consoles and swirling fans. + +"We're on the brink of unravelling the signal's origin," Jordan replied, the weight of implications heavy in their tone. "There's intelligence behind it, a thought process alien to our own." + +As if summoned by their analysis, Taylor Cruz approached with authority radiating from every pore. "Understand this, we need to know if it's friend or foe. Don't get wrapped up in the existential—our lives may depend on the answers you provide." + +Sam Rivera, their hands adroitly adjusting a device to fine-tune the signal, chimed in with optimism undercut by anxious anticipation. "We're deciphering the comm encryption. Soon, we'll have a channel open—not just listening in, but speaking back." + +Alex nodded his understanding, his strategic mind processing the tactical implications while grappling with the more profound humanistic impact. "When we do, we'll tread carefully, communicate with purpose," he reassured the team. + +The operation had evolved rapidly, from a stealthy incursion into a clandestine labyrinth to an exchange with an extraterrestrial intellect. Their earlier trepidation transformed into determined focus, as they prepared to extend humanity’s hand into the vast unknown. + +An alert on one of the monitor stations snapped the team into alarm. The signal had not simply been waiting—it had been calculating. Now, it reached its crescendo, demanding their attention with a provocative urgency. + +Jordan's fingers raced over the keyboard, their eyes simultaneously interpreting data and sharing directives. "It’s a linguistic lock, a test of comprehension. We crack this, we establish dialogue." + +Taylor's presence was a beacon of steely resolve. "Then let’s solve it. This is what we trained for—the unknown." + +Alex and Sam exchanged a look that telegraphed their shared determination—this was not only the mission they had trained for; it was the mission they had been destined for. + +Together, the Paranormal Military Squad team leaned into the challenge, their minds honing in on the complex patterns with a singular goal: to unlock the conversation with an intelligence that had already begun to shift the foundations of what they knew, or thought they knew, about the universe. + +In a symphony of clicks and murmurs, they worked, knowing they were about to make a giant leap not just for themselves or Paranormal Military Squad, but for all of humanity. As the final pieces fell into place, Dulce's militaristic silence was shattered by the sound of intergalactic contact—by the sound of history being made. + +## Chapter 7 + +In the enclosed space of Dulce’s command center, the air was thick with anticipation, each team member poised to tread the razor's edge between scientific breakthrough and galactic peril. Dr. Jordan Hayes focused intently on the screen, their fingers tapping a staccato rhythm against the keyboard as lines of alien code cascaded down the monitor. + +Alex Mercer's steely gaze surveyed the room, stopping on each member of his team. "Thoughts?" he asked, echoing the unspoken tension. His question, while directed at the group, lingered on Jordan—acknowledging their expertise and inviting collaboration rather than dictating orders. + +Jordan’s brow furrowed, an indicator of the mental gymnastics being performed. "It's unprecedented," they finally said, their voice a testament to the gravity of the moment. "Behavioral algorithms... if we're right, this code could reveal extraterrestrial thought patterns." + +Before anyone could react, Taylor Cruz interjected with the assertiveness of someone accustomed to commandeering the discourse. "Then let’s ensure we’re deciphering it correctly," Taylor stated, their tone suggesting they were still battling to maintain control over an increasingly alien situation. + +Sam Rivera hovered near the mainframe, youthful energy barely contained under the surface. "What if it’s more than just a message? What if they’re trying to extend consciousness across the stars?" + +The room fell into a contemplative silence, broken only by the hum of electronic equipment and the distant thud of secured doors locking in rhythm. The weight of responsibility rested on each agent's shoulders—a heaviness palpable in the air they shared. + +Alex stepped forward, reaching a subtle decision, one dictated by foresight and the humanity nestled at the core of their mission. "We approach with the aim to understand, not to confront," he said, softening his military bearing into a more diplomatic stance. + +Jordan nodded, appreciating the leadership that Alex displayed in the face of the unknown, and turned back to the cryptic data. Here, before them all, was a tangible piece of evidence—proof of an extraterrestrial sentience that had outreached the bounds of their expectations. + +Taylor took a breath, simultaneously exuding a sense of preparedness and venturing into the unknown alongside their peers. "Then let’s do what Paranormal Military Squad does best—investigate and adapt," Taylor added, finding comfort in the familiar even as they stood on the cusp of an unprecedented alchemy of science and mystery. + +The team leaned into their respective roles, driven by the urgency of the assignment and the pull of an insatiable curiosity. Sam offered a grin that belied the tension, a youthfulness that reminded them all of the profound excitement nested within the terror of the unknown. + +Quietly but resolutely, they turned back to their instruments, each of them a sentinel on the threshold of a new reality. The once implicit lines of command were now woven into a shared tapestry of hierarchy and camaraderie. As they danced with the unknown, they were beacons of sentient endeavor, casting the light of human consciousness into the vast darkness that called to them. + +\* + +\* + +Dulce Base's cavernous darkness was pierced by the sharp luminescence of monitors, casting an electric glow onto the faces of those who dared to unearth its secrets. Dr. Jordan Hayes stood motionless, eyes glazed in concentration, their mind a nexus where terrestrial science battled with celestial unknowns. + +Alex Mercer watched from a slight distance, the weight of command tangible upon his shoulders, though lightened by the shared burden now held amongst them. "We could be on the frontier of a new kind of diplomacy," he mused aloud, giving voice to the moment's gravity. + +At those words, Jordan's trance broke. "If that's the case, then these communications," Jordan motioned to the stream of data, "are our olive branch across the cosmos." + +Taylor Cruz, who paced with restless energy, halted and faced the team—his stoicism marred by the erratic dance of lights reflected in his eyes. "An olive branch, or an invitation to a battlefield?" he posed, ever the strategist, his words laced with a hint of cynicism. + +Sam Rivera, nestled amongst an array of equipment, licked their lips—a mixture of nerves and anticipation palpable. "We're mapping out something incredible here. Whether it's peace or war, we're the cartographers." + +Silence enveloped them like the expanse of space itself, each member contemplating the chasms they might bridge—or the abysses into which they might unwittingly descend. + +Alex's demeanor assumed a quiet resolve—the profound knowledge that this mission was as much about navigating uncharted philosophical territories as it was about ensuring survival. "Whichever it proves to be, we'll face it. Prepared, unified." + +A nod passed between Jordan and Alex, a silent exchange of mutual respect and shared mission. Sam, buoyed by the weighty encounters of the mind and machinery, entered keystrokes with a fervor that seemed to bring them ever closer to the alien mind. + +They stood there, the Paranormal Military Squad team, not just as guardians of homeworld secrets or as soldiers of clandestine wars, but as humankind's chosen few at the fulcrum of history—a history that was now unfolding to the rhythm of otherworldly codes. + +Each revelation, each parsed symbol, inched them toward the line between the earthly and otherworldly. And as they stood on this precipice of cosmic negotiations, it was clear the ensuing dialogue would not just shape the future of Paranormal Military Squad—it could very well redefine the parameters of human existence. + +\* + +The hum of advanced computational systems tingling with cryptic transmissions framed the ambiance of Dulce's mainframe chamber. Jordan Hayes, fingers hovering over a console dense with blinking lights, furrowed their brow as sequences of alien data streamed across the screen. + +Alex materialized behind them, his presence a stable beacon amidst the technological whirlwind. "Look for patterns, anomalies. Anything that might resemble a handshake protocol in their communications," he directed, his voice a low thrum, reverberating with cautious optimism. + +Jordan cast a glance over their shoulder, acknowledging Alex's contribution with the shared understanding of colleagues who had transcended mere professional acquaintance. "I’m isolating sequences that seem to recur with more intention than static. If these are their ‘handshakes,’ then we might just be making first contact," they remarked, their focus returning to the screen with renewed vigor. + +From the other end of the room, where shadows married the artificial light, Sam's voice crackled through the static of nearby speakers, "Don't forget the anomalies we detected earlier. Each one could be a word, a sentence, or even a concept untranslatable to our current understandings." + +Resolute, Taylor Cruz stood at Jordan's other side, a stoic figure wrestling with the implications of their mission. "Keep pursuing this line," Taylor instructed, an undercurrent of intensity carried forth in their otherwise composed demeanor. "And remember, this isn't just about making contact; it's about securing knowledge for humanity." + +Alex offered a nod that spoke volumes, conveying his understanding of the stakes at play. Here, in this chamber of possibility, the team's actions would determine if humanity stood at the brink of a new age of understanding or the onset of an unprecedented threat. + +Every second thrummed with significance as Jordan and Sam worked in tandem, each keystroke a foray into the unknown. Taylor observed with a commander's scrutiny, the gravity of their role sustaining them against the waves of ambiguity breaking against their resolve. + +Pivotal moments come rarely in the course of human events but here, amidst the electronic symphony of a stalwart command center, lay the incepting notes of a cosmic overture. The harmony between human and alien, between Paranormal Military Squad and the vast reaches of space, began its first tentative measures, with each member of the team a vital instrument in a celestial ensemble yet to be fully heard. + +\* + +The crisp air within the mainframe room of Dulce base seemed to hum with unspoken possibilities. Jordan Hayes was the centerpiece of focus, their hands dancing methodically over the console as streams of otherworldly code cascaded down monitors, each flicker a potential key to the cosmic doors they were inching open. + +Alex Mercer watched, posture relaxed but eyes sharp. "Remember, this could be our first introduction, maybe even our first impression," he said, mindful of the gravity carried by each action they made henceforth. + +A hint of a smile touched Jordan's face, a small acknowledgment of the monumental task at hand. "Understood. I'm balancing the signal's syntax with our algorithms. If we're interpreting this correctly, it could be... well, an invitation." + +Into the electric tension of the chamber walked Taylor Cruz, their silhouette a sharp contrast against the cool lighting, radiating a presence that spoke of command and chilly tenacity. "An invitation, or a challenge?” Taylor questioned, the weight of their suspicion casting a different tint on the cascading data. + +Sam Rivera, in a corner arrayed with sophisticated equipment, piped up, their voice a buoyant note amidst the tentative atmosphere. "Either way, it's a connection. One that we're uniquely positioned to navigate," they remarked with an air of optimism threading through the uncertainty. + +Alex channeled the strengths of his team into the core of their approach, his leadership adapting to the contours of an unprecedented scenario. "Cautious and curious," he reflected aloud, shaping a strategy that balanced their thirst for comprehension with the prudence required in addressing the unknown. + +Jordan, hands momentarily at rest, looked up. The signal was more than a sequence of bits and commands—it was a riddle wrapped in the depths of space-time, and they were on the cusp of parsing its meaning. + +Taylor, hardly a step away, nodded in silent agreement. The implications of their findings might very well direct the course of human destiny from this point onward. + +Finding a tempo among themselves, the Dulce team was a confluence of ambition and acumen, each member intuitive to the beats of discovery. The chamber around them held untold stories, secrets coaxed from the stars, that now, led by Paranormal Military Squad's finest, began to unravel. + +The future in those moments was unwritten, a narrative scribed not in the dust of desert confines, but in the potential for interstellar diplomacy and understanding. As they prepared to script humanity's next chapter, the room seemed to pulse with the heartbeat of a story far greater than the sum of its parts. + +## Chapter 8 + +The grit of an earthbound dust storm contrasted sharply with the pristine sterility of the underground command center. Alex Mercer, eyes set with fervent determination, stood over Jordan Hayes, whose fingers danced across the keyboard with rapid purpose. Monitoring the progression of alien code unraveling before them, Mercer spoke with a tempered urgency, "Keep it steady, Jordan. We might be initiating the first true interspecies communication bridge here. It's all about finesse now." + +Taylor Cruz, the embodiment of military precision, surveyed the room with a calculated gaze from their vigil beside an array of glimmering screens. "Remember, these could be delicate negotiations -- or coded threats. Stay sharp," Cruz added, their voice cool as polished steel. + +Jordan, with a silent nod, recognized the gravity of both stances. Gravitating between scientific acuity and diplomatic caution, they replied, "The sequence is aligning—syncing with our comms. It's looking more and more like direct engagement." + +Amid the banks of electronic machinery, the thrumming pulse of an impending interspecies signal exchange, Sam Rivera interjected with a youthful zeal that cut through the weighty atmosphere, "It's not just an exchange. It's a... symphony. It's as if they're teaching us their language through modulation." + +A moment of profound silence swept over the team. The isolation of their location, deep within the top-secret labyrinth of Dulce, became suffused with an almost palpable sense of historical significance. + +"Then our response needs to be equally symphonic," Alex uttered, contemplating the awe-inspiring transmutation of their task from a simple recovery mission to a full-blown cosmic concerto. + +With a renewed sense of wonder tempered by caution, the Paranormal Military Squad team found themselves harmonizing a delicate balance between envoys and interpreters. The long shadow cast by their duty was now illuminated by the brilliant glow of otherworldly dialogue. + +In this carefully orchestrated march towards the unknown, each individual's expertise became critical notes in a larger melody. The narrative of human achievement, so often defined by solitary pursuits, now emerged as a collaborative opus, each member of the team a maestro in their right. + +The protocols of encounters, the mathematics of languages, and the poetics of connection all fused into a singular moment of convergence. The echo of their efforts reverberated back to them, not through the cavernous base's concrete walls, but from light-years away, in the form of a reply, intangible yet infinitely profound. + +\* + +Amidst the hum of the supercomputers and the faint static from the scrambled transmissions, Alex Mercer cast a thoughtful glance across the dimly lit room toward where Dr. Jordan Hayes was methodically adjusting the archaic dials of the decryption machine. "Any progress?" he asked, his tone conveying both impatience and the deep-seated respect born from countless shared challenges. + +Jordan did not look up, their gaze remained locked on the flickering lights that represented a dialogue suspended between worlds. Their fingers ceased their dance, hovering meditatively over the controls. "We might be on the cusp of a breakthrough," Jordan suggested. "The signal... it's evolved. It's reflexive now, responsive in a way that suggests sentience." + +Taylor Cruz's familiar sharp strides approached the two, breaking the rhythm of soft beeps. "Responsive is good, if it means understanding," Taylor said, head tilted as they peered at the encryption data scrolling by. "But remember, comprehension can bring revelation or conflict." + +Sam Rivera’s youthful voice permeated the tension, brimming with an excitement edged by the enormity of what they faced. "If it's truly sentient, we're not just cracking a code; we're learning how to converse with an entirely new form of consciousness," they chimed in, the weight of history not lost on the zealous astrotechnician. + +Alex nodded, his thoughts alighting on potential strategies for navigating the conversation they were cultivating with the unfathomable. "We need to keep that conversation going, echo its patterns, and speak its language," he resolved, knowing the delicate nature of their work merited every ounce of their collective acumen. + +The chamber now was a crucible, forging within it the future narrative of human contact with the unknown. Every signal pulse they sent out was an invitation for understanding, and every echo back a step closer to bridging the cosmic divide. And so, together, they stood - agents in Paranormal Military Squad's clandestine ranks, united by purpose, sculpting humanity’s first sonnets into the void. + +\* + +#### Knowledge graph updates + +- (Jordan Hayes, Interprets, Communications as cosmic diplomacy, Moderate) + +- (Taylor Cruz, Questions, Potential aggressiveness of alien intent, Minor) + +- (Sam Rivera, Expresses, Optimism about forming a connection, Minor) + +- (Alex Mercer, Adopts, Balanced strategy for contact, Moderate) + +- (Paranormal Military Squad team, Navigates, Beats of cosmic discovery, Moderate) + +- (Paranormal Military Squad team, Prepares, To script humanity's interstellar narrative, Major) + +## Chapter 9 + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +Dr. Jordan Hayes, whose hands had been steadfastly working the decryption algorithms, paused and looked up at Alex. "We're through the next layer of encryption," Jordan announced, a mixture of pride and gravitas in their tone. "It's communicating. It's... aware." + +A shadow momentarily clouded Alex's determined features—awareness implied so much more than mere intelligence. "Aware and reactive or aware and proactive?" he queried, his experience anticipating the pivotal importance of intention. + +"Unknown at this stage," Taylor Cruz interjected, looking up from a datasheet. "But I urge caution. We tread the line between breakthrough and disaster with each keystroke." + +Sam Rivera, ever the source of technological acumen, added their voice to the conversation. "The signal's adapting every time we interact with it. Like a conversation where both parties are learning each other's language in real time." + +Alex leaned in, rested a hand on Jordan's shoulder—a sign of companionship and an affirmation of trust. "Keep the communication channels open. But let no message, no pulse go unchecked. This could be our Rosetta Stone or our Tower of Babel." + +Silence fell over them, a momentary lull as each member of the team contemplated the historic weight of their task. Yet, it was impregnated with a tangible sense of excitement—a collective energy that thrummed through the air just as palpably as the electric current through the banks of machines surrounding them. + +They continued their work, squaring shoulders against the magnitude of their undertaking. The agents were standing not just at the precipice of a new chapter for Paranormal Military Squad but for all of humanity. For now, they communicated with powerful unknowns, but with each exchange, they were etching the first words of a dialogue that might forever alter humanity's place in the cosmos. + +\* + +\* + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +Dr. Jordan Hayes, whose hands had been steadfastly working the decryption algorithms, paused and looked up at Alex. "We're through the next layer of encryption," Jordan announced, a mixture of pride and gravitas in their tone. "It's communicating. It's... aware." + +A shadow momentarily clouded Alex's determined features—awareness implied so much more than mere intelligence. "Aware and reactive or aware and proactive?" he queried, his experience anticipating the pivotal importance of intention. + +"Unknown at this stage," Taylor Cruz interjected, looking up from a datasheet. "But I urge caution. We tread the line between breakthrough and disaster with each keystroke." + +Sam Rivera, ever the source of technological acumen, added their voice to the conversation. "The signal's adapting every time we interact with it. Like a conversation where both parties are learning each other's language in real time." + +Alex leaned in, rested a hand on Jordan's shoulder—a sign of companionship and an affirmation of trust. "Keep the communication channels open. But let no message, no pulse go unchecked. This could be our Rosetta Stone or our Tower of Babel." + +Silence fell over them, a momentary lull as each member of the team contemplated the historic weight of their task. Yet, it was impregnated with a tangible sense of excitement—a collective energy that thrummed through the air just as palpably as the electric current through the banks of machines surrounding them. + +They continued their work, squaring shoulders against the magnitude of their undertaking. The agents were standing not just at the precipice of a new chapter for Paranormal Military Squad but for all of humanity. For now, they communicated with powerful unknowns, but with each exchange, they were etching the first words of a dialogue that might forever alter humanity's place in the cosmos. + +\* + +Alex Mercer's eyes were fixed on the monitors, the reflected light casting an ethereal glow across his stoic face. The room buzzed with tension, a cacophony of low hums and electronic beeps that underscored the historic nature of their actions. He moved to where Dr. Jordan Hayes was immersed in their work, scrutinizing the alien code streaming rapidly down the terminal. + +"Find anything that might look like an entry point or a... digital handshake?" Alex asked, his voice steady, betraying none of the tension gripping his chest. + +Jordan looked up briefly, their expression weary yet intense, "Potentially. It's as if the code is anticipating our input, modifying itself in real-time. I've never seen anything like it." + +From across the room, Taylor Cruz's sharp voice cut through the hum. "Then it's learning or, possibly worse, baiting us. Proceed with extreme caution," they commanded, their firm stance reinforcing the gravity of the situation. + +Sam Rivera, surrounded by a cascade of screens and interfaces, added, "It's almost organic in its complexity. Any minute now, and I might have a way in." + +A slight nod was Alex's immediate response, his mind racing through the potential scenarios. "Everyone, stay alert. This could be the beginning of something profound." His seasoned eyes never left the unfolding drama on the monitors. + +The room fell silent, the air heavy with unspoken questions. Were they mere moments away from unlocking an otherworldly dialogue? Or was it a Pandora's box that, once opened, could not be closed? + +Alex moved closer to the main console, his fingers hovering over the command keys. With the precision of a maestro orchestrating a symphony, he communicated silently with Jordan – respectful of their expertise, aware that the next move could alter the course of human history. + +Jordan met his gaze, nodding sharply, and refocused on the task. The signal seemed to pulse with sentient curiosity, drawing them further into its intricate web. + +A sudden flurry of alerts and the intensifying glow of monitors heralded that they had bridged a technological chasm. The alien intelligence on the other end was no longer a distant enigma – it was an active participant, responding to their digital overtures with an unknown agenda. + +The team's meticulous efforts had led them to a momentous threshold. Beyond lay unprecedented contact – a nexus of curiosity and potential peril. Within the confines of the base, against the backdrop of a silent desert night, the Paranormal Military Squad operatives became mediators of Earth's bid for cosmic relevance, their every action now a gesture in the grand dance of intergalactic relations. + +## Chapter 10 + +The corridors of the Dulce military base, now silent, echoed with a history of whispered conspiracies and furtive movements. But in the command center, a delicate tapestry of light and sound was being woven as the echoes of cosmic dialogue resonated through the high-tech enclave. Dr. Jordan Hayes, now leading the efforts, called out from their workstation, "I’ve isolated the signal's harmonics. It's more than a call; it's a song, an interstellar siren’s call." + +Alex Mercer, steady and resilient in the face of the incomprehensible, acknowledged with a quiet nod, "A song that we need to learn—quickly." His eyes, heavy with responsibility, scanned the room, watching his team work tirelessly at the intersection of science and speculation. + +Sam Rivera, dulled by fatigue yet driven by unshakeable resolve, manipulated a complex array of audio interfaces. "There's a pattern, a repeating motif. It's structured, intentional," they muttered, their revelation a bridge between the known and the unimaginable. + +Taylor Cruz, a figure of central authority, paced the length of the room, their usual unflappable demeanor betraying a rare flicker of apprehension. "We should be wary of the sirens’ call," Taylor interjected, invoking myths of old as a cautionary metaphor. "We don't want to crash upon unseen shores." + +Undeterred, Jordan cast a determined glance at the team. "We navigate by starlight now, not by the limited light of our previous understanding." Their voice was a beacon, charting a course through unchartered realities. + +Every individual was acutely aware that each moment in that room was a conduit to an epochal shift for civilization. The mysterious signals, once distant and alien, had coalesced into complex and harmonious oscillations—beacons of an extraterrestrial intellect inviting Earth to join in a cosmic consortium. + +Silently, Alex approached the mainframe, his trained fingers aligning with the console’s mechanisms. The room watched in collective breathlessness as he set the frequency in motion, an introductory phrase to an otherworldly melody—a symphony that could bind worlds or spell devastation for all they knew. + +In the control room of Dulce, amongst whispered legends and the quiet hum of machines, humanity's ambassadors now stood, stretching their hands into the void, reaching for the hand that would either pull them into the light of new stars or into the maw of darkness between them. + +\* + +Underground, the Dulce facility's command center was awash with frenetic energy, a stark juxtaposition against the silent, decrepit corridors that enveloped them. The air hummed with anticipation as Dr. Jordan Hayes and Alex Mercer hunched over a console. The sterile light from the monitors cast an otherworldly glow upon their faces, now reflecting a mosaic of alien characters rapidly translating across the screen. + +"The patterns are evolving," Jordan murmured, concentration etched into their every feature. "It’s as if our attempts to decrypt have accelerated its learning. It’s adapting to us." + +Alex, who stood steadfast behind Jordan, felt a tinge of uncharted fear quickly quelled by the fire of discovery raging within him. "Keep it up," he urged. "But whatever this is becoming, we need to ensure it remains within our control." + +Taylor Cruz interjected, their voice slicing through the buzz of activity. "Control may be an illusion when facing an intelligence that literally writes its own rules," they stated stoically, casting a watchful eye over the flurry of data. + +"It's like it's learning to communicate," offered Sam Rivera from a nearby interface, their youthful energy boding a mix of awe and anxiety. "This gives ‘talking to strangers’ a whole new meaning." + +Alex surveyed his team—each face a study in concentration, determination, and not a small measure of trepidation. "This might well be our first contact," he acknowledged, "And we need to be ready for whatever answers back." + +Together, they stood on the edge of the unknown, forging humanity’s response to a message from the heavens. The ensuing silence was palpable—a collective introspection about their role in this grand cosmic play, one that could rewrite human history. + +The encrypted dialogue continued to unfold, its intricate patterns showing an almost uncanny anticipation of their investigative strategies. The air turned heavy with the scent of electricity and ambition as they closed in on a pivotal response. + +As the signal’s intelligence—whether artificial or biological—grew more profound, so too did the realization that their mission had morphed from passive observation to active engagement. There was no turning back now. Each agent embraced their part in the delicate dance of an interstellar exchange that could change everything they thought they knew about life, intelligence, and the dark void beyond Earth's atmosphere. + +\* + +The underground halls of Dulce Base, usually buzzing with covert operations, now thrummed with a different kind of energy, an electric mix of fear and fascination. At the heart of the base, in a room shielded from the world’s eyes, Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera huddled around a bank of monitors. Each screen flickered erratically with the alien script that had become the center of their lives—and perhaps the pivot on which humanity’s future would turn. + +Jordan's eyes never wavered from the displays, their expression was one of rapt concentration, interspersed with flashes of revelation. "We're conversing with the stars," they whispered, almost to themselves. The words hung in the air, a testament to the awe-inspiring strangeness of the situation. + +"The language is morphing; changing its structure with every exchange we have," Sam chimed in, enthusiasm tinged with the solemnity of the occasion. "It's like witnessing the birth of a new form of dialogue—one that spans galaxies." + +Taylor, despite the situation's precariousness, maintained an appearance of ironclad composure. "Keep the communication stream secured and monitored. We don't know what we're dealing with yet," they reminded the team, a bastion of protocol amidst uncertainty. + +Alex watched his team expand the parameters of human achievement; their work here would possibly define an era. "This is untrodden territory," he acknowledged, "and in every word we script, in every response we decode, we're drawing a map that others will follow." + +Jordan turned to Alex, a nod acknowledging the shared responsibility of this moment. They had embarked on a new voyage, an odyssey not of the body, but of the intellect and spirit. No longer explorers of the Earthly realm, they had been promoted by circumstance to ambassadors of humanity in a silent and boundless ocean. + +A sudden pulse of energy from the monitors signaled a breakthrough; the language had not only adapted but it seemed to resonate, to harmonize with their attempts at making contact. The alien script now sprawled across the screens didn't just ask to be understood—it invited interpretation, collaboration, maybe even companionship across the cold distances of space. + +As they stood before the precipice of first contact, Paranormal Military Squad's finest became the architects of a symphony meant to echo through the cosmos. But more than architects, they were the first to play the notes of this cosmic composition, daring to believe that on the other end, someone—or something—might be listening, ready to join the chorus. + +\* + +The underground command center of Dulce Base, once pulsing with clandestine operations, now resonated with the charge of an impending cosmic threshold. Encircled by banks of whirring machinery, each monitor flickered erratically with alien script that had occupied center stage in the lives of Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera. + +Jordan's gaze didn’t flit for even a moment from the screens, where indiscernible alien messages ebbed and flowed like the tide. The ciphers and symbols cascaded down as they tweaked the algorithmic sliders. "This sequence here," Jordan began, voice both hushed and heavy, "it’s not just transmitting; it resonates—it's designed to be felt." + +The room took a collective breath, the remarkable implication hanging in the air like a careful revelation. Sam Rivera was the first to respond, their voice alive with ingenuity: "It's a form of communication stretching well beyond words. We need to respond in kind—the whole array of human expression might be at play here." + +Taylor's eyes remained fixed on the figures playing across the data sheets. "If that's the case," Taylor intoned pragmatically, "we must tread carefully. This is no longer just about being heard—it's about being understood." + +Alex watched his team, each a fulcrum of insight and expertise, and felt the solemnity of the role they were about to assume. "Then we'll ensure our message is clear and full. Our humanity is our strength in this dialogue," he declared, the depths of his experience fueling a commanding reassurance. + +The anticipation was palpable as the agents contemplated the vastness of their endeavor. They were not merely probing at the secrets of the planar cosmos—they were negotiating across the starry expanse, extending to distant intelligences the full spectrum of human curiosity and compassion. + +A symphony of beeping consoles orchestrated their next steps as they prepared to articulate their interplanetary overture. The rhythmic tapping of Jordan's keystrokes set the tempo for an undertaking that traversed beyond algorithms and encryption. + +The base withstood time and whispered secrets of its own, but none so grand as this moment of creation—an invitation to the universe that promised to echo through both the echoes of space and the annals of human history. + +## Chapter 11 + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +\* + +The thrum of the colossal machinery vibrated through the subterranean facility as Alex Mercer stood amidst the whispers of technology, each carrying voices from worlds apart. He watched as Sam Rivera adjusted a complex array of cosmic translators, their expression a mixture of anticipation and awe. + +"Are we ready, Mercer?" Taylor Cruz asked, the soft glow of the command center consoles reflecting upon their stern face. + +Alex turned towards Taylor, his eyes holding a depth that betrayed the enormity of the threshold they were about to cross. "This is it," he said. "Initiate the protocol. It's time we answer the cosmos." + +Jordan Hayes, stationed at the mainframe, typed rhythmically, a blue hue painting their focused features. The eerie silence that had settled over the team was interrupted by a visceral sound—humankind's response to the alien dialogue, now streaming into the abyss. + +The control room, once a fortress of solitude, erupted into an oasis of life. Lights flickered in tandem, echoing the symphony of interstellar communication. They stood together at the edge of discovery, facing the symmetry and discord of a universe unknown. + +"If we're right, we've just become Earth's first emissaries to a celestial congress we're only beginning to comprehend," Jordan's voice was somber, resonating with a mix of trepidation and honor. + +The room filled with the resonance of human and alien minds converging, creating a new narrative within the fathomless expanse of existence. Paranormal Military Squad, once protectors of Earth's clandestine secrets, had now become the tether linking humanity to the cosmic fold. + +\* + +The underground command center of Dulce Base, once pulsing with covert operations, now resonated with the charge of an impending cosmic threshold. Encircled by banks of whirring machinery, each monitor flickered erratically with alien script that had occupied center stage in the lives of Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera. + +Jordan's gaze didn’t flit for even a moment from the screens, where indiscernible alien messages ebbed and flowed like the tide. The ciphers and symbols cascaded down as they tweaked the algorithmic sliders. "This sequence here," Jordan began, voice both hushed and heavy, "it’s not just transmitting; it resonates—it's designed to be felt." + +The room took a collective breath, the remarkable implication hanging in the air like a careful revelation. Sam Rivera was the first to respond, their voice alive with ingenuity: "It's a form of communication stretching well beyond words. We need to respond in kind—the whole array of human expression might be at play here." + +Taylor's eyes remained fixed on the figures playing across the data sheets. "If that's the case," Taylor intoned pragmatically, "we must tread carefully. This is no longer just about being heard—it's about being understood." + +Alex watched his team, each a fulcrum of insight and expertise, and felt the solemnity of the role they were about to assume. "Then we'll ensure our message is clear and full. Our humanity is our strength in this dialogue," he declared, the depths of his experience fueling a commanding reassurance. + +The anticipation was palpable as the agents contemplated the vastness of their endeavor. They were not merely probing at the secrets of the planar cosmos—they were negotiating across the starry expanse, extending to distant intelligences the full spectrum of human curiosity and compassion. + +A symphony of beeping consoles orchestrated their next steps as they prepared to articulate their interplanetary overture. The rhythmic tapping of Jordan's keystrokes set the tempo for an undertaking that traversed beyond algorithms and encryption. + +The base withstood time and whispered secrets of its own, but none so grand as this moment of creation—an invitation to the universe that promised to echo through both the echoes of space and the annals of human history. + +## Chapter 12 + +The underground facility of Dulce Base, once shrouded in silence and operational secrecy, now hummed with an energy that cradled the promise of cosmic revelation. Alex Mercer stood pensively by the central terminal, flanked by Dr. Jordan Hayes, Taylor Cruz, and Sam Rivera, each poised at the edge of a history-defining moment. + +Jordan's fingers ghosted across the console, tracing patterns of otherworldly origin. "The signal’s architecture is becoming more complex, resembling aspects of human cognition—recognition, learning, even... empathy?" they postulated with furrowed concern. + +Alex turned his gaze upon Jordan, his voice quiet but resolute, "Empathy could bridge galaxies. Let's harness this connection and proceed with cautious optimism." + +Taylor, ever the sober sentinel, projected a more pragmatic standpoint. "Empathy or not, we are duty-bound to assess the risk to humanity. Every new discovery warrants a measured response." + +The static hiss of communications equipment filled the air, its purpose now transformed into a dialogue with an intelligence beyond the stars. It was Sam, wide-eyed amid the myriad lights and switches, who broke the silence, "We have provisional confirmation of the signal’s intent—initiation. We’re being brought into a broader spectrum of cognizance." + +The chamber lay still for a heartbeat, the Paranormal Military Squad agents steeped in contemplation of the path unfurling before them—a path paved with possibilities of diplomacy or disruption, each step a venture further into the cosmic unknown. + +Alex stepped closer to the viewing monitors, each depicting alien symbols seemingly reaching out from the void. "Initiate the broadcast," he spoke with quiet command. "Our response will mark humanity’s readiness to partake in the wider conversation of conscious beings." + +Amidst the crackling air of expectation, the team wordlessly returned to their stations. They had transcended their roles as protectors of Earth's clandestine lore to become the harbingers of an interstellar parley that could change the existential course of life on their pale blue dot. + +The deep hum of the terminal emitted a signal—a testament to the uncanny reality that Earth was now actively partaking in an exchange not bound by gravity nor the limits of the solar wind. + +Here, in the depths of Dulce, a message from humanity woven from understanding and uncertainty was cast into the firmament, an epitheg of their desire to join the universal dialogue and discover their place among the constellations. + +\* + +The somber depths of the Dulce Base command center stood in stark counterpoint to the animated flurry of activity around the central comms array. Alex Mercer's silhouette loomed behind Dr. Jordan Hayes, who sat with a posture indicating laser focus on the decryption process. A quiet murmur of digital soundscape filled the space, subtly heightened by the anticipation of contact with an intelligence beyond the Earth. + +Jordan's voice was steady, betraying none of the extraordinary nature of their work, "Looking through the signal's pattern, it's evident we’re dealing with a form of intelligence—calculating, mirroring, possibly even understanding." + +Alex's reflection bounced off the darkened screens, his head nodding in silent affirmation. "We’re walking a delicate line. Our response should be thoughtful, measured. We’re ambassadors, not merely explorers." + +Taylor Cruz approached, arms folded, their words slicing through the din of careful keystrokes and soft whirrs, "If there’s even the slightest chance it understands, we can’t afford missteps. The language of the stars might be more absolute than ours." + +From another terminal, Sam Rivera brought youthful vigor to the conversation, "There’s rhythm in these patterns. If this is their way of reaching out, our reply should encapsulate all that we are—all that humanity stands for." + +Looking around at his team, Alex saw resolve etched on every face. The chamber, usually somber and echoing with the quiet steps of covert agents, now felt alive with the heartbeat of discovery. They were not just professionals operating in the gloom; they were a collective standing at the helm of a momentous journey. + +"Let’s begin," he said, returned by the resolve in his voice. "Every second counts." With that, they pressed forward, setting in motion a reply to a conversation billions of years in the making. + +The dance with an unseen partner commenced, each pulse they sent out a step taken with caution and hope. And as those digital pulses journeyed through the black sea of infinity, Earth, for perhaps the first time, joined a pan-galactic dialogue that whispered secrets of the cosmos—secrets that, until now, had been lost in the silent vastness of space. + +\* + +As the team stood in the centralized nerve center of Dulce's underground fortress, the solemn atmosphere was reverent, overseeing systems that engaged with an intelligence from the void. Alex's stance was contemplative as he gazed at Jordan Hayes, who presided over the console, the tension of the moment reaching a tactile fervor. Each rhythmic tap of Hayes's fingers on the keys was a foray into uncharted symphonies of contact. + +Observing Hayes unravel the dense alien encryption, Alex spoke, a diplomatic tenor underpinning his words, "Keep focused on the syntax, dissect its nuances. We're not just decoding signals; we're translating intentions." + +Without diverting from their task, Jordan acknowledged the insight. "Indeed, if their understanding of us is as deep as we hope, we're paving the way for dialogue far beyond our current realm." + +Taylor Cruz, near the rear of the room, provided a steady oversight. "As horizonless as our prospects may seem," Taylor intoned, "remain diligent. Complacency before alien cognition could spell catastrophe." + +Sam's youthful voice resonated with optimism, "Imagine—forming a rapport with a consciousness separate from our reality; we're drafting the bridge to stars alive with minds!" + +The sentiment hung for a moment before Alex gathered his conviction. "Dialogue is our vessel. We are not just agents of enigma; we are the threads that may weave a new cosmic relationship." His words seemed to reflect off the walls, reaching beyond the room's confines, a quiet yet resilient vow. + +Their task was titanic, stepping stones laid delicately into new territories of existence. The signal, once an esoteric strand in the echo of the universe, beckoned now with a clarity rocketing the complexity of thoughts from a distant order. + +Action by action, the Paranormal Military Squad team bridged the vast interstellar distances, their expertise and empathy casting a beacon of unity into frontiers of intelligence and knowledge. Their work, a partnership struck with an unseen cosmic congregation, each pulse sent and received a line in Earth's novitiate envoi to the cosmic shores. + +\* + +Under the stark, unforgiving lights of Dulce Base's underground command center, tension buzzed harder than the banks of supercomputers that lined the walls. Agent Alex Mercer leaned over the shoulder of Jordan Hayes, whose eyes were locked onto the display screen, where an incomprehensible series of alien symbols streamed past incessantly. + +“Any progress on the decryption?” Alex's voice was steady, a controlled presence necessary in the gravity of their undertaking. + +Jordan tapped a key, pausing the flow of code, and leaned back with a deep sigh. "We've broken through another subset of the cipher. It's revealing... well, indications of a complex society, not unlike our own." His eyes met Alex's with an unspoken question that hung heavily between them—were they truly prepared for what they might find? + +Taylor Cruz strode into the room, a tightly coiled spring of ambition and authority, and peered at the screen. "Understand their society, and we may predict behavior. Remain expedient—we don't know how much time we have before the situation shifts." There was an edge of stark realism to Taylor's words, the underlying message clear: every revelation bore its own set of risks. + +Alex nodded thoughtfully, recognizing the validity of Cruz's caution. Turning to Sam, who was tinkering with a device that buzzed quietly on the table, he asked, “Sam, can your contraption get us any further?” + +Sam looked up with a smirk, a twinkle of mischief in their eye. “It’s not just any contraption, it’s potentially a direct line to their thoughts. Give me a moment more, and I'll have something for you.” + +The air ticked with electronic beeps and the rustling sound of the Paranormal Military Squad team at work. They were so close to peering into the intelligence of an alien race—a reality on the brink of dramatically expanding their understanding of the universe. + +The machinery whirred in response to Sam’s precise touches, and suddenly, the room filled with a low hum—something had changed, a signal had been successfully sent. The team held their breath as they listened. The sound that filled the room was unmistakable: a response, an alien voice filtered through the static of space and time. + +Alex exchanged a look of quiet triumph with Jordan. The breakthrough was monumental; they were no longer casting messages into the void but engaged in a dialogue—an exchange that marked the beginning of Operation: Dulce’s true unfolding. This was it, the first steps into an interstellar odyssey that demanded every ounce of their courage and wit. + +## Chapter 13 + +Dr. Jordan Hayes shuffled a stack of papers, their eyes revealing a tinge of skepticism at Taylor Cruz's authoritarian performance. _Protocols_, Jordan thought, _are just the framework, the true challenges we're about to face lie well beyond the boundaries of any protocol._ They cleared their throat before speaking, tone cautious yet firm, "Let's remember, the unknown variables exceed the known. We should remain adaptive." + +A murmur of agreement echoed from Sam Rivera, who leaned forward, lacing their fingers together as if weaving a digital framework in the air before them, "Exactly, adaptability could be the key to interpreting the signal distortions and system malfunctions. We shouldn't discount the… erratic." + +Their words hung like an electric charge in the room, challenging Taylor's position with an inherent truth. Cruz’s jaw tightened almost imperceptibly, but the agent masked it with a small nod, conceding to the omnipresent threat of the unpredictable. + +Alex glanced at Jordan, who never looked back, their gaze fixed instead on a distant point, as if envisioning the immense dark corridors they were soon to navigate in Dulce. Jordan was not one to embrace fantastical theories, but the air of cautious calculation betrayed a mind bracing for confrontation with the inexplicable, an internal battle between the evidence of their research and the calculating skepticism that kept them alive in their field. + +The meeting adjourned with no further comments, the team members quietly retreading the paths to their personal preparations. Alex, trailing slightly behind, observed the others. _The cautious reserve Jordan wears like armor doesn't fool me_, he thought, _their analytical mind sees the patterns I do. And that's worth more than protocol. That's the connection we need to survive this._ + +As the agents dispersed into the labyrinth of the facility, lost in their thoughts and preparations, the base's halogen lights flickered, a brief and unnoticed harbingers of the darkness to come. + +\* + +The gritty, wind-tossed surface of New Mexico, just above the cavernous domain of Dulce Base, offered no shelter from the burgeoning storm—the scouring sands an earthly reminder of chaos theories in motion. Far beneath, a similar maelstrom brewed within the confines of the command center, as Paranormal Military Squad's handpicked squad stood poised for potential enormities of contact. + +Ruffling through printed transmission logs, Jordan Hayes dialed the focus of their analytical prowess onto the emerging pattern of signals crisscrossing between Earth and the unfathomable. "Our responses so far have echoed their complexity, but the real divergence is yet to come," Jordan remarked stoically, the calm belying the mounting surge of adrenaline for the revelation ahead. + +Alex Mercer's figure, a silhouette sharpened by the purpose, loomed at the periphery of the monitors' sickly glow. "Indeed," he assented, "The echoes are the easy part. It will be the introduction of our own, human variable that truly begins our dialogue." + +Taylor Cruz, windowless command center notwithstanding, appeared as though they could feel the tempest above. Their eyes never left the monitors as they unspooled their hard wisdom. "For all our advances, we find ourselves deciphering the swings and nuances of an interstellar pendulum. Predict its arc, and we may preempt the gravity of its message." + +Amidst a chorus of bleeps and static, Sam Rivera's tech-clad hands moved rhythmically, their spirited approach to unruly streams of data bordering an intimate dance with entropy. "Entropy that leads to discovery," Sam mused, responding to Taylor's metaphor. "Each step into the unknown is a step away from precedent." + +Alex, drawing near Jordan, spoke again, his voice now a thread woven through the very fabric of their operations. "Let's be the cartographers of this new territory. Our initial shades of understanding could color the cosmos for generations to come." + +Their gazes fell upon a screen as the latest transmission painted its digital blooms of alien script across the black. This time, the pattern wavered in an almost imperceptible fashion, a modification that whispered of active, alien thought awaiting their next move. A hush enveloped the Paranormal Military Squad ensemble, the gravity of the pathogen undeniable. They were about to issue a reply, one poised to reshape the very concept of humanity's outreach into the cosmos. + +The New Mexico desert's secrets were infamous, its storms a mere prelude to the revelations that the team—united in purpose—would unleash upon the world. The howling winds outside found their counterpart in the newfound resolve within, as Dulce's stalwart guardians readied themselves to send forth humanity's retort to the echoes from beyond. + +\* + +The cavernous control room, deeply entrenched beneath the desolate New Mexico terrain, held the Paranormal Military Squad team in intense focus; an island of calm amid the storm of cosmic dialectics. Dr. Jordan Hayes worked methodically, every keystroke an intricate step in their tenuous cosmic ballet. Suddenly, they paused, a signal pattern resonating from the screen. "This is new; it's...inviting. It’s as if the signal is not just calling to us but weaving its intelligence through ours." + +Alex Mercer scrutinized the shift in data. "A confluence of minds, then. If we're to meet them halfway, Jordan, our reply must be both innovative and discerning," he proposed, a glimmer of profound curiosity behind his authoritative demeanor. + +Taylor Cruz, whose sharp eyes missed nothing, nodded from beside a secondary panel. "Innovative, yes, but also defensive. This interaction is a razor’s edge, and we cannot afford to bleed before the unknown," Taylor reminded them, the metaphor a stark warning of potential dangers. + +Against the backdrop of their conversation, Sam Rivera’s youthful optimism cut through the tension. "If they’re weaving through our intellect, then we've achieved something beyond first contact—we're at the genesis of interstellar symbiosis," they posited with a mix of reverence and excitement. + +Alex returned Sam’s smile with his own, tempered and faint, as he turned back to the task at hand. The magnitude of their mission extended beyond the fabric of the universe, an exploration into the threads that connected sentient beings across the vast expanse. “Let’s reply with our own woven tapestry of thought—delicate, but deliberate.” + +With renewed determination, the room came alive with an undercurrent of anticipation, its occupants charged with the potential of forging an alliance with the cosmos. Paranormal Military Squad's finest were no longer merely soldiers and scientists; they had become pioneers on the vanguard of humanity’s greatest odyssey. + +The New Mexican sands above, impassive to the change brewing underneath, stood as silent sentinels as Earth's emissaries crafted their response. A response that, composed with care and imbued with humanity's essence, reached into the void, connecting with an otherworldly intelligence that awaited their harmony in the cosmic conversation. + +## Chapter 14 + +The command center of Dulce Base lay shrouded in shadows that seemed to claw at the edges of the dimly lit array of screens and consoles. Alex Mercer, focused and unwavering, watched as Dr. Jordan Hayes parsed the latest string of alien signals—a symphony of otherworldly communications that threatened to either enlighten or confound. + +"We’re encountering a paradigm shift with every transmission," Jordan Hayes murmured, the pulsing glow of the monitor painting their features with an almost spectral hue. "This signal... it’s evolving, becoming denser, more sophisticated. As if it's growing alongside us—tandem evolution." + +The air was electric, charged with the raw potential of uncharted discovery and laden with the gravity of existential risk. Taylor Cruz, who always seemed here to mold such gravity into actionable strategies, stepped forward. "We must contain this evolution within parameters we can manage. We cannot be bystanders to an uncontrolled ascent of intelligence." + +Sam Rivera, the youngest of the cohort, worked feverishly at their station. "It's not just intelligence—these signals have rhythm, a kind of music suggesting not just evolution, but a dance! We're being invited to partake in the cosmos's ballet!" they exclaimed, a touch of youthful exuberance breaking through the solemnity. + +Alex turned, facing his team, the stoic mask of command tempered by the perceptible flicker of awe in his gaze. "Let this dance then be our dialogue. We will match their steps with prudent but daring measures—our humanity as our guide." + +In the ensuing hours, the Paranormal Military Squad team forged a rhythm of their own, their collective expertise a beacon piercing through the fog of the unknown. The signal, increasingly intricate and seemingly conscious, now demanded not just observation but participation, an interstellar pas de deux that hummed with the promise and peril of first contact. + +Before them, the communications interface flickered to life with a received transmission—a resonant hum that seemed to vibrate through the very foundations of the base. They had successfully established a back-and-forth with whatever intelligence lay hidden among the stars. Every subsequent note they struck within the cosmic ether would come to define humanity's place within the galactic community—heralds of Earth's grand entrance into a universe far less silent than once perceived. + +\* + +In the concrete belly of Dulce Base, dimly lit by the jagged dance of fluorescent lights above, Sam Rivera perched on the edge of their seat, their eager fingers fluttering across an ancient keyboard. The stark, cold room—reminiscent of a time when covert operations and unspoken dread ruled supreme—now housed a peculiar blend of old-world machinery and sleek, modern interfaces. + +Alex Mercer, standing steadfast like a bridge between the enigmatic past and the unfathomable present, watched on. In his eyes flashed the foreboding excitement of change. "Sam," he started, his voice steadfast, "the patterns in these signals, what do they tell us about the nature of our... guest?" + +Sam's eyes glimmered with something akin to thrill—or was it trepidation? "It's like we're mirroring each other, evolving together through this.. dialogue. Like it knows us, understands us, and it's… learning." + +Jordan Hayes, preoccupied at a nearby console, chimed in without lifting their gaze. "It's a dialogue that transcends mere words, Alex. We're being woven into a narrative far grander than the sum of our known sciences." + +Taylor Cruz, arms crossed, wore the heavy mantle of their skepticism comfortably. "Keep theorizing," they interjected crisply, "but remember the grounding reality of what we are part of here. This contact is a blade that cuts both ways." + +In this cavern of history, voices both human and inhuman whispered secrets to those brave enough to listen. Each member present understood the gravity that pulled at their feet; no longer were they mere mortals shackled to their terrestrial plane. The digital pings and encrypted calls resonated with an implication of a cosmic agenda that would not be ignored. + +Jordan's fingers paused, hovering in hesitation. What ripple might the next keystroke send through the fabric of known existence? It was a step into the ballet of the infinite, where the Paranormal Military Squad team played their part in the waltz of wonders with an audience of stars. + +\* + +## Chapter 15 + +In the clandestine hush of Dulce Base's subterranean command center, the Paranormal Military Squad team had become a crucible for interstellar communication. Dr. Jordan Hayes' gaze lingered on the screen as they navigated through the convolution of alien code. Each character held the potential to unravel a new dimension of contact, and with Sam Rivera's keen interjection, they were crafting humanity's inaugural cosmological discourse. + +Alex Mercer peered over Jordan's shoulder, calculating the implications of every visual nuance that cascaded across the monitor. "Look for consistency—any repeating motifs could signal a willingness to engage. We're drafting history with each exchange," he remarked, aware of the delicate balance between forging a bond and exposing vulnerabilities. + +Taylor Cruz, stoic and enigmatic, observed the interplay from the threshold, a silhouette against the machinery's luminescence. "Remember, while we seek common ground, the foundation we stand upon remains Terra firma. Caution must temper our curiosity," they stated, their voice an anchor amidst the current of excitement. + +The command center buzzed with energy, rivaled only by the tempest overhead that concealed their operation. Sam, with swift dexterity, navigated the communications relay. "Their signals resonate almost musically. It's as if they're composing a symphony, and we've been handed the baton to conduct the next movement," they offered, imbuing the scenario with a blend of scientific adventurism and poetic license. + +Amidst the whirring servers and the occasional flicker of emergency lighting, the essence of their mission transcended mere reconnaissance. They were humanity's elected envoys at the brink of a celestial alliance—or confrontation—with an audience as vast as the universe itself. + +Alex stepped back, his profile etched by the chamber's artificial day. "Then let's ensure our contribution to this symphony harmonizes with theirs. It's time for humanity's voice to rise and be counted among the cosmic ensemble." + +Under his directive, the Paranormal Military Squad team initiated their calculated response, weaving thoughts and theories into a digital overture aimed at the heart of alien intellect. As the digital stream punctured the endless night, each member of this clandestine group was acutely aware of the irrevocable step they undertook—bringing Earth into the pantheon of galactic entities designed to converse among the stars. + +\* + +Clusters of high-tech equipment bathed the Dulce underground command center in an eerie blue light. Sam Rivera's fingers flew across the keyboard, navigating an elaborate network of alien patterns. The very air seemed to pulse with the ebb and flow of cryptic communications reaching across the stars. "I've got something!" Sam's announcement tore through the focus in the room, drawing every pair of eyes to the torrent of symbols unraveling on the screen. + +With the pacing of a seasoned officer gauging the moment before action, Alex Mercer approached, his calm demeanor belying an acute awareness of the precipice on which they now stood. "Define 'something," Alex prompted, reinforcing the need for clarity amidst the extraordinary. + +"It's repeating—a sequence that’s evolved with each interaction, almost as if it's... singing," Sam theorized, the awe in their voice reflecting the potential magnitude of their discovery. + +Jordan Hayes interjected from across the console, their eyes not leaving the display as they absorbed the new data. "A cosmic vocalization, then," they mused, intrigued. "A singularity in the signal that might represent a point of reference for both parties." + +Taylor Cruz, hands clasped behind their back, regarded the unfolding scene, their own calculations etching lines of concern onto their stern visage. "Or a beacon—a homing tune, calling out to something we might not be ready to greet," Taylor offered, voicing the group's unspoken apprehension. + +Alex's eyes locked on the screen, taking in the scope of what they were attempting to interpret. Drawing a deep breath, Alex gave a slight nod. "If this is their song, then let us respond with ours. We've come this far by mirroring their signals, now let's engage in an interstellar duet, and see where the music leads us." + +With the expectation of the significant achieving a crescendo, the members of Paranormal Military Squad huddled over their equipment—sages at the threshold of a potentially world-altering communion. The strange harmonies that reverberated through the command center suggested that their interlocutors were poised, waiting, perhaps even eager, for Earth's chorus to join the symphony. + +As the team initiated their reply, weaving humanity's own intricate melody into the vast cosmic dialogue, they each felt a profound change within—an evolution of purpose. They were not just messengers or investigators; they had become co-composers in a galactic orchestra, with the universe itself as their witness and concert hall. + +With the exchange of harmonious signals crawling through the vacuum of space, the Paranormal Military Squad operatives found themselves part of a bridging of minds—a realization that out there, among the vast arrays of stars and planets, harmony was the true universal language. + +\* + +The dim glow of monitors cast an otherworldly ambiance upon Dulce Base's command center, where Paranormal Military Squad's chosen stood huddled over their instruments, suspended at history's threshold. Codes—alien in origin and nature—were being deciphered by Dr. Jordan Hayes, whose countenance bore the marks of deep concentration. + +Alex Mercer, the bedrock upon which their team's resolve was founded, leaned in with an eagerness tempered by his chain of command. "Jordan, we've invested our expertise into comprehending their patterns, but now we must also endeavor to understand their intent," he urged, his voice bearing the gravitas of their mission's potential consequences. + +At another console, Sam Rivera's youth did not betray their crucial role in the operation. With eyes alight, they mirrored the rapid computing before them. "There's emotion here—complex, profound even. This isn't just the output of a cold machine; it's...sentience," Sam whispered, nearly drowned by the mechanical chorus around them. + +Jordan, without shifting focus from their work, replied, "It's a sentience that—should we succeed here—ushers us into a new era of existence. The cadence of these signals," they tapped the screen with a flourish, "could well be the heartbeat of this new dawn." + +Taylor Cruz paused beside Mercer, their expression unreadable beneath the sterile light. "And as it beats, we must gauge whether its rhythm bodes well for us, or spells our missteps. Courage must not blind us to the hazards intrinsic to such contact," Taylor cautioned, the sentinel within them ever alert. + +Alex nodded, a gesture that carried the weight of responsibility and a silent command: proceed, but with circumspection. They were not merely decoding a message; they were interpreting a dialogue across the celestial divide. + +The room fell into a rhythm akin to a well-conducted ensemble. Each member's expertise proved a critical note in the unfolding symphony. Their actions were now more than mere research or defense; they were the tentative overtures of humankind reaching out to grasp the vast unknown. + +Textures of sound meshed with the light from countless computations, the palpable anticipation of the agents at the edge of discovery cresting with an awareness that their work would reshape future chronicles. And when the response finally came—a signal piercing the deafening silence of uncertainty—all within Dulce's confines understood: the dawn of an interstellar continuum had just begun to break. + +\* + +In the sterile hum and flickering lights of Dulce Base's command center, the Paranormal Military Squad team stood as humanity's vanguard, verging on the brim of an intergalactic abyss. Dr. Jordan Hayes, analytical edges sharp, deciphered extraterrestrial patterns that bled across screens in enigmatic cascades—a daunting mosaic of potential threats and untapped wisdom. + +Agent Alex Mercer, the embodiment of focus and a steadfast nerve, observed the unfolding digital drama with the gravitas due a historic first contact. "Let the data weave its narrative, Jordan," he instructed, a moderate undertone of exhilaration within his command. "It's encoding more than information—it's outlining civilization." + +Jordan absorbed the directive, their gaze unflinching from the screens, feeling the weight of their next move. "The nuances here are extraordinary," they acknowledged. "It paints a picture of a culture steeped in complexities we're only starting to fathom.” + +Taylor Cruz, stoicism personified yet not immune to the situation's gravity, chimed in. "Understand it, but guard against it," they cautioned, bringing a sober prudence to the room. "This culture, however advanced, remains an unknown quantity—an ocean of wonders and darkness with uncertain tides." + +Sam Rivera, a visual contrast with wide eyes and restless hands, represented the other side of the room — intrigue and optimism against the drawn swords of precaution. “Think of it,” they proposed, voice bouncing with a rebellious upbeat timbre, “as the first act of a play written in constellations. We're setting the stage for a galactic narrative.” + +Each team member, in their way, was both actor and scribe in this moment of tense pageantry. Heavy with the presence of risk, the command center had become not just a room of computers and glass panels but a theater for performing the elaborate choreography of contact. + +Bound by resolve and curiosity, they proceeded, each data entry a trembling step onto the cosmic stage. And like all cautious pioneers edging into fertile but unnavigated lands, they understood: as they mapped the heavens, they were simultaneously mapping the furthest reaches of their own existential horizons. + diff --git a/graphrag/examples_notebooks/inputs/operation dulce/create_final_community_reports.parquet b/graphrag/examples_notebooks/inputs/operation dulce/create_final_community_reports.parquet new file mode 100644 index 0000000000000000000000000000000000000000..daa687778266f16e30b67177134226bac61733c0 --- /dev/null +++ b/graphrag/examples_notebooks/inputs/operation dulce/create_final_community_reports.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:adccc2fbfc14cecdbfb878b8189c20dd9ece1d20e056ad81620d99ce2cf0430d +size 71337 diff --git a/graphrag/examples_notebooks/inputs/operation dulce/create_final_covariates.parquet b/graphrag/examples_notebooks/inputs/operation dulce/create_final_covariates.parquet new file mode 100644 index 0000000000000000000000000000000000000000..d36ade9bce1b6e15553281bef6777abdd4351e28 --- /dev/null +++ b/graphrag/examples_notebooks/inputs/operation dulce/create_final_covariates.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07cc974f42727661eb2b1d4b6728b22191aeb77d96579963f444a1aa34e46855 +size 38473 diff --git a/graphrag/examples_notebooks/inputs/operation dulce/create_final_entities.parquet b/graphrag/examples_notebooks/inputs/operation dulce/create_final_entities.parquet new file mode 100644 index 0000000000000000000000000000000000000000..17038d2decff8695248cb43d9925ca6d6d1942d4 --- /dev/null +++ b/graphrag/examples_notebooks/inputs/operation dulce/create_final_entities.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5fe0501b8bcd4b8bea1ca93f2679086fd8a2a538d33965d39444280d541cca4 +size 2271498 diff --git a/graphrag/examples_notebooks/inputs/operation dulce/create_final_nodes.parquet b/graphrag/examples_notebooks/inputs/operation dulce/create_final_nodes.parquet new file mode 100644 index 0000000000000000000000000000000000000000..ef455269e1c822b69ec01f36fe5f230970d35889 --- /dev/null +++ b/graphrag/examples_notebooks/inputs/operation dulce/create_final_nodes.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61474e9dc3e5e2c024a895dc4f87bba652b1fecc443eb3b9729d9589b9c6bb4f +size 54835 diff --git a/graphrag/examples_notebooks/inputs/operation dulce/create_final_relationships.parquet b/graphrag/examples_notebooks/inputs/operation dulce/create_final_relationships.parquet new file mode 100644 index 0000000000000000000000000000000000000000..ead36a6d68fdad9f69fdced9c63a36f119ffe36d --- /dev/null +++ b/graphrag/examples_notebooks/inputs/operation dulce/create_final_relationships.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:443a83ecc70d9171d66bbcbc6fa29883e3ae5b814e2c734a2c4a5468996293b1 +size 20389 diff --git a/graphrag/examples_notebooks/inputs/operation dulce/create_final_text_units.parquet b/graphrag/examples_notebooks/inputs/operation dulce/create_final_text_units.parquet new file mode 100644 index 0000000000000000000000000000000000000000..4260b78224e8df70a4577c83b4f9f7910bcb59b1 --- /dev/null +++ b/graphrag/examples_notebooks/inputs/operation dulce/create_final_text_units.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c8938b2a8ff5b3663a38735c02197bfe87ab1c0222081bd805933b16f5063c4 +size 94690 diff --git a/graphrag/examples_notebooks/local_search.ipynb b/graphrag/examples_notebooks/local_search.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..3f1633373cfa917a334fce88ea8a54b7257bf15d --- /dev/null +++ b/graphrag/examples_notebooks/local_search.ipynb @@ -0,0 +1,465 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Copyright (c) 2024 Microsoft Corporation.\n", + "# Licensed under the MIT License." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "import pandas as pd\n", + "import tiktoken\n", + "\n", + "from graphrag.query.context_builder.entity_extraction import EntityVectorStoreKey\n", + "from graphrag.query.indexer_adapters import (\n", + " read_indexer_covariates,\n", + " read_indexer_entities,\n", + " read_indexer_relationships,\n", + " read_indexer_reports,\n", + " read_indexer_text_units,\n", + ")\n", + "from graphrag.query.input.loaders.dfs import (\n", + " store_entity_semantic_embeddings,\n", + ")\n", + "from graphrag.query.llm.oai.chat_openai import ChatOpenAI\n", + "from graphrag.query.llm.oai.embedding import OpenAIEmbedding\n", + "from graphrag.query.llm.oai.typing import OpenaiApiType\n", + "from graphrag.query.question_gen.local_gen import LocalQuestionGen\n", + "from graphrag.query.structured_search.local_search.mixed_context import (\n", + " LocalSearchMixedContext,\n", + ")\n", + "from graphrag.query.structured_search.local_search.search import LocalSearch\n", + "from graphrag.vector_stores.lancedb import LanceDBVectorStore" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Local Search Example\n", + "\n", + "Local search method generates answers by combining relevant data from the AI-extracted knowledge-graph with text chunks of the raw documents. This method is suitable for questions that require an understanding of specific entities mentioned in the documents (e.g. What are the healing properties of chamomile?)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load text units and graph data tables as context for local search\n", + "\n", + "- In this test we first load indexing outputs from parquet files to dataframes, then convert these dataframes into collections of data objects aligning with the knowledge model." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load tables to dataframes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "INPUT_DIR = \"./inputs/operation dulce\"\n", + "LANCEDB_URI = f\"{INPUT_DIR}/lancedb\"\n", + "\n", + "COMMUNITY_REPORT_TABLE = \"create_final_community_reports\"\n", + "ENTITY_TABLE = \"create_final_nodes\"\n", + "ENTITY_EMBEDDING_TABLE = \"create_final_entities\"\n", + "RELATIONSHIP_TABLE = \"create_final_relationships\"\n", + "COVARIATE_TABLE = \"create_final_covariates\"\n", + "TEXT_UNIT_TABLE = \"create_final_text_units\"\n", + "COMMUNITY_LEVEL = 2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Read entities" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# read nodes table to get community and degree data\n", + "entity_df = pd.read_parquet(f\"{INPUT_DIR}/{ENTITY_TABLE}.parquet\")\n", + "entity_embedding_df = pd.read_parquet(f\"{INPUT_DIR}/{ENTITY_EMBEDDING_TABLE}.parquet\")\n", + "\n", + "entities = read_indexer_entities(entity_df, entity_embedding_df, COMMUNITY_LEVEL)\n", + "\n", + "# load description embeddings to an in-memory lancedb vectorstore\n", + "# to connect to a remote db, specify url and port values.\n", + "description_embedding_store = LanceDBVectorStore(\n", + " collection_name=\"entity_description_embeddings\",\n", + ")\n", + "description_embedding_store.connect(db_uri=LANCEDB_URI)\n", + "entity_description_embeddings = store_entity_semantic_embeddings(\n", + " entities=entities, vectorstore=description_embedding_store\n", + ")\n", + "\n", + "print(f\"Entity count: {len(entity_df)}\")\n", + "entity_df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Read relationships" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "relationship_df = pd.read_parquet(f\"{INPUT_DIR}/{RELATIONSHIP_TABLE}.parquet\")\n", + "relationships = read_indexer_relationships(relationship_df)\n", + "\n", + "print(f\"Relationship count: {len(relationship_df)}\")\n", + "relationship_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "covariate_df = pd.read_parquet(f\"{INPUT_DIR}/{COVARIATE_TABLE}.parquet\")\n", + "\n", + "claims = read_indexer_covariates(covariate_df)\n", + "\n", + "print(f\"Claim records: {len(claims)}\")\n", + "covariates = {\"claims\": claims}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Read community reports" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "report_df = pd.read_parquet(f\"{INPUT_DIR}/{COMMUNITY_REPORT_TABLE}.parquet\")\n", + "reports = read_indexer_reports(report_df, entity_df, COMMUNITY_LEVEL)\n", + "\n", + "print(f\"Report records: {len(report_df)}\")\n", + "report_df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Read text units" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "text_unit_df = pd.read_parquet(f\"{INPUT_DIR}/{TEXT_UNIT_TABLE}.parquet\")\n", + "text_units = read_indexer_text_units(text_unit_df)\n", + "\n", + "print(f\"Text unit records: {len(text_unit_df)}\")\n", + "text_unit_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "api_key = os.environ[\"GRAPHRAG_API_KEY\"]\n", + "llm_model = os.environ[\"GRAPHRAG_LLM_MODEL\"]\n", + "embedding_model = os.environ[\"GRAPHRAG_EMBEDDING_MODEL\"]\n", + "\n", + "llm = ChatOpenAI(\n", + " api_key=api_key,\n", + " model=llm_model,\n", + " api_type=OpenaiApiType.OpenAI, # OpenaiApiType.OpenAI or OpenaiApiType.AzureOpenAI\n", + " max_retries=20,\n", + ")\n", + "\n", + "token_encoder = tiktoken.get_encoding(\"cl100k_base\")\n", + "\n", + "text_embedder = OpenAIEmbedding(\n", + " api_key=api_key,\n", + " api_base=None,\n", + " api_type=OpenaiApiType.OpenAI,\n", + " model=embedding_model,\n", + " deployment_name=embedding_model,\n", + " max_retries=20,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create local search context builder" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "context_builder = LocalSearchMixedContext(\n", + " community_reports=reports,\n", + " text_units=text_units,\n", + " entities=entities,\n", + " relationships=relationships,\n", + " covariates=covariates,\n", + " entity_text_embeddings=description_embedding_store,\n", + " embedding_vectorstore_key=EntityVectorStoreKey.ID, # if the vectorstore uses entity title as ids, set this to EntityVectorStoreKey.TITLE\n", + " text_embedder=text_embedder,\n", + " token_encoder=token_encoder,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create local search engine" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# text_unit_prop: proportion of context window dedicated to related text units\n", + "# community_prop: proportion of context window dedicated to community reports.\n", + "# The remaining proportion is dedicated to entities and relationships. Sum of text_unit_prop and community_prop should be <= 1\n", + "# conversation_history_max_turns: maximum number of turns to include in the conversation history.\n", + "# conversation_history_user_turns_only: if True, only include user queries in the conversation history.\n", + "# top_k_mapped_entities: number of related entities to retrieve from the entity description embedding store.\n", + "# top_k_relationships: control the number of out-of-network relationships to pull into the context window.\n", + "# include_entity_rank: if True, include the entity rank in the entity table in the context window. Default entity rank = node degree.\n", + "# include_relationship_weight: if True, include the relationship weight in the context window.\n", + "# include_community_rank: if True, include the community rank in the context window.\n", + "# return_candidate_context: if True, return a set of dataframes containing all candidate entity/relationship/covariate records that\n", + "# could be relevant. Note that not all of these records will be included in the context window. The \"in_context\" column in these\n", + "# dataframes indicates whether the record is included in the context window.\n", + "# max_tokens: maximum number of tokens to use for the context window.\n", + "\n", + "\n", + "local_context_params = {\n", + " \"text_unit_prop\": 0.5,\n", + " \"community_prop\": 0.1,\n", + " \"conversation_history_max_turns\": 5,\n", + " \"conversation_history_user_turns_only\": True,\n", + " \"top_k_mapped_entities\": 10,\n", + " \"top_k_relationships\": 10,\n", + " \"include_entity_rank\": True,\n", + " \"include_relationship_weight\": True,\n", + " \"include_community_rank\": False,\n", + " \"return_candidate_context\": False,\n", + " \"embedding_vectorstore_key\": EntityVectorStoreKey.ID, # set this to EntityVectorStoreKey.TITLE if the vectorstore uses entity title as ids\n", + " \"max_tokens\": 12_000, # change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 5000)\n", + "}\n", + "\n", + "llm_params = {\n", + " \"max_tokens\": 2_000, # change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 1000=1500)\n", + " \"temperature\": 0.0,\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "search_engine = LocalSearch(\n", + " llm=llm,\n", + " context_builder=context_builder,\n", + " token_encoder=token_encoder,\n", + " llm_params=llm_params,\n", + " context_builder_params=local_context_params,\n", + " response_type=\"multiple paragraphs\", # free form text describing the response type and format, can be anything, e.g. prioritized list, single paragraph, multiple paragraphs, multiple-page report\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Run local search on sample queries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "result = await search_engine.asearch(\"Tell me about Agent Mercer\")\n", + "print(result.response)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "question = \"Tell me about Dr. Jordan Hayes\"\n", + "result = await search_engine.asearch(question)\n", + "print(result.response)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Inspecting the context data used to generate the response" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "result.context_data[\"entities\"].head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "result.context_data[\"relationships\"].head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "result.context_data[\"reports\"].head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "result.context_data[\"sources\"].head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if \"claims\" in result.context_data:\n", + " print(result.context_data[\"claims\"].head())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Question Generation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This function takes a list of user queries and generates the next candidate questions." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "question_generator = LocalQuestionGen(\n", + " llm=llm,\n", + " context_builder=context_builder,\n", + " token_encoder=token_encoder,\n", + " llm_params=llm_params,\n", + " context_builder_params=local_context_params,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "question_history = [\n", + " \"Tell me about Agent Mercer\",\n", + " \"What happens in Dulce military base?\",\n", + "]\n", + "candidate_questions = await question_generator.agenerate(\n", + " question_history=question_history, context_data=None, question_count=5\n", + ")\n", + "print(candidate_questions.response)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/graphrag/graphrag/__init__.py b/graphrag/graphrag/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a1e9b589bf66538dc47af7ecf2ac4a9f8831b6f1 --- /dev/null +++ b/graphrag/graphrag/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The GraphRAG package.""" diff --git a/graphrag/graphrag/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..32d186da030ddac50debf780a18bcc0a4b04ba10 Binary files /dev/null and b/graphrag/graphrag/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/__init__.py b/graphrag/graphrag/config/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..118018a98fd920f232468ba0be374cebb947b820 --- /dev/null +++ b/graphrag/graphrag/config/__init__.py @@ -0,0 +1,123 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine default config package root.""" + +from .create_graphrag_config import ( + create_graphrag_config, +) +from .enums import ( + CacheType, + InputFileType, + InputType, + LLMType, + ReportingType, + StorageType, + TextEmbeddingTarget, +) +from .errors import ( + ApiKeyMissingError, + AzureApiBaseMissingError, + AzureDeploymentNameMissingError, +) +from .input_models import ( + CacheConfigInput, + ChunkingConfigInput, + ClaimExtractionConfigInput, + ClusterGraphConfigInput, + CommunityReportsConfigInput, + EmbedGraphConfigInput, + EntityExtractionConfigInput, + GlobalSearchConfigInput, + GraphRagConfigInput, + InputConfigInput, + LLMConfigInput, + LLMParametersInput, + LocalSearchConfigInput, + ParallelizationParametersInput, + ReportingConfigInput, + SnapshotsConfigInput, + StorageConfigInput, + SummarizeDescriptionsConfigInput, + TextEmbeddingConfigInput, + UmapConfigInput, +) +from .models import ( + CacheConfig, + ChunkingConfig, + ClaimExtractionConfig, + ClusterGraphConfig, + CommunityReportsConfig, + EmbedGraphConfig, + EntityExtractionConfig, + GlobalSearchConfig, + GraphRagConfig, + InputConfig, + LLMConfig, + LLMParameters, + LocalSearchConfig, + ParallelizationParameters, + ReportingConfig, + SnapshotsConfig, + StorageConfig, + SummarizeDescriptionsConfig, + TextEmbeddingConfig, + UmapConfig, +) +from .read_dotenv import read_dotenv + +__all__ = [ + "ApiKeyMissingError", + "AzureApiBaseMissingError", + "AzureDeploymentNameMissingError", + "CacheConfig", + "CacheConfigInput", + "CacheType", + "ChunkingConfig", + "ChunkingConfigInput", + "ClaimExtractionConfig", + "ClaimExtractionConfigInput", + "ClusterGraphConfig", + "ClusterGraphConfigInput", + "CommunityReportsConfig", + "CommunityReportsConfigInput", + "EmbedGraphConfig", + "EmbedGraphConfigInput", + "EntityExtractionConfig", + "EntityExtractionConfigInput", + "GlobalSearchConfig", + "GlobalSearchConfigInput", + "GraphRagConfig", + "GraphRagConfigInput", + "InputConfig", + "InputConfigInput", + "InputFileType", + "InputType", + "LLMConfig", + "LLMConfigInput", + "LLMParameters", + "LLMParametersInput", + "LLMType", + "LocalSearchConfig", + "LocalSearchConfigInput", + "ParallelizationParameters", + "ParallelizationParametersInput", + "ReportingConfig", + "ReportingConfigInput", + "ReportingType", + "SnapshotsConfig", + "SnapshotsConfigInput", + "StorageConfig", + "StorageConfigInput", + "StorageType", + "StorageType", + "SummarizeDescriptionsConfig", + "SummarizeDescriptionsConfigInput", + "TextEmbeddingConfig", + "TextEmbeddingConfigInput", + "TextEmbeddingTarget", + "UmapConfig", + "UmapConfigInput", + "create_graphrag_config", + "read_dotenv", +] diff --git a/graphrag/graphrag/config/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/config/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e59824b78849b0ca52a19debcb8ebfaf28189705 Binary files /dev/null and b/graphrag/graphrag/config/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/__pycache__/create_graphrag_config.cpython-311.pyc b/graphrag/graphrag/config/__pycache__/create_graphrag_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff3c4268559688d2d6fe6c48a534d87fe60da938 Binary files /dev/null and b/graphrag/graphrag/config/__pycache__/create_graphrag_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/__pycache__/defaults.cpython-311.pyc b/graphrag/graphrag/config/__pycache__/defaults.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3c740c50ffd9a1680388aa33f6fa038198ecf1d6 Binary files /dev/null and b/graphrag/graphrag/config/__pycache__/defaults.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/__pycache__/enums.cpython-311.pyc b/graphrag/graphrag/config/__pycache__/enums.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5065f17608398f4473e2fad5278f985d0074cff3 Binary files /dev/null and b/graphrag/graphrag/config/__pycache__/enums.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/__pycache__/environment_reader.cpython-311.pyc b/graphrag/graphrag/config/__pycache__/environment_reader.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f42584c6044b0b0d1f3cce8d76e767d07b4a57d6 Binary files /dev/null and b/graphrag/graphrag/config/__pycache__/environment_reader.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/__pycache__/errors.cpython-311.pyc b/graphrag/graphrag/config/__pycache__/errors.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fbb9ec180baeac09dbd2b3780bca5bf783f21fa7 Binary files /dev/null and b/graphrag/graphrag/config/__pycache__/errors.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/__pycache__/read_dotenv.cpython-311.pyc b/graphrag/graphrag/config/__pycache__/read_dotenv.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..97db0a066c600b515f549136ee22338389c5d8d3 Binary files /dev/null and b/graphrag/graphrag/config/__pycache__/read_dotenv.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/create_graphrag_config.py b/graphrag/graphrag/config/create_graphrag_config.py new file mode 100644 index 0000000000000000000000000000000000000000..37a4477e00195e14c8ad6486fcf3a890e733c04c --- /dev/null +++ b/graphrag/graphrag/config/create_graphrag_config.py @@ -0,0 +1,642 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration, loaded from environment variables.""" + +import os +from enum import Enum +from pathlib import Path +from typing import cast + +from datashaper import AsyncType +from environs import Env +from pydantic import TypeAdapter + +import graphrag.config.defaults as defs + +from .enums import ( + CacheType, + InputFileType, + InputType, + LLMType, + ReportingType, + StorageType, + TextEmbeddingTarget, +) +from .environment_reader import EnvironmentReader +from .errors import ( + ApiKeyMissingError, + AzureApiBaseMissingError, + AzureDeploymentNameMissingError, +) +from .input_models import ( + GraphRagConfigInput, + LLMConfigInput, +) +from .models import ( + CacheConfig, + ChunkingConfig, + ClaimExtractionConfig, + ClusterGraphConfig, + CommunityReportsConfig, + EmbedGraphConfig, + EntityExtractionConfig, + GlobalSearchConfig, + GraphRagConfig, + InputConfig, + LLMParameters, + LocalSearchConfig, + ParallelizationParameters, + ReportingConfig, + SnapshotsConfig, + StorageConfig, + SummarizeDescriptionsConfig, + TextEmbeddingConfig, + UmapConfig, +) +from .read_dotenv import read_dotenv + +InputModelValidator = TypeAdapter(GraphRagConfigInput) + + +def create_graphrag_config( + values: GraphRagConfigInput | None = None, root_dir: str | None = None +) -> GraphRagConfig: + """Load Configuration Parameters from a dictionary.""" + values = values or {} + root_dir = root_dir or str(Path.cwd()) + env = _make_env(root_dir) + _token_replace(cast(dict, values)) + InputModelValidator.validate_python(values, strict=True) + + reader = EnvironmentReader(env) + + def hydrate_async_type(input: LLMConfigInput, base: AsyncType) -> AsyncType: + value = input.get(Fragment.async_mode) + return AsyncType(value) if value else base + + def hydrate_llm_params( + config: LLMConfigInput, base: LLMParameters + ) -> LLMParameters: + with reader.use(config.get("llm")): + llm_type = reader.str(Fragment.type) + llm_type = LLMType(llm_type) if llm_type else base.type + api_key = reader.str(Fragment.api_key) or base.api_key + api_base = reader.str(Fragment.api_base) or base.api_base + cognitive_services_endpoint = ( + reader.str(Fragment.cognitive_services_endpoint) + or base.cognitive_services_endpoint + ) + deployment_name = ( + reader.str(Fragment.deployment_name) or base.deployment_name + ) + + if api_key is None and not _is_azure(llm_type): + raise ApiKeyMissingError + if _is_azure(llm_type): + if api_base is None: + raise AzureApiBaseMissingError + if deployment_name is None: + raise AzureDeploymentNameMissingError + + sleep_on_rate_limit = reader.bool(Fragment.sleep_recommendation) + if sleep_on_rate_limit is None: + sleep_on_rate_limit = base.sleep_on_rate_limit_recommendation + + return LLMParameters( + api_key=api_key, + type=llm_type, + api_base=api_base, + api_version=reader.str(Fragment.api_version) or base.api_version, + organization=reader.str("organization") or base.organization, + proxy=reader.str("proxy") or base.proxy, + model=reader.str("model") or base.model, + max_tokens=reader.int(Fragment.max_tokens) or base.max_tokens, + temperature=reader.float(Fragment.temperature) or base.temperature, + top_p=reader.float(Fragment.top_p) or base.top_p, + n=reader.int(Fragment.n) or base.n, + model_supports_json=reader.bool(Fragment.model_supports_json) + or base.model_supports_json, + request_timeout=reader.float(Fragment.request_timeout) + or base.request_timeout, + cognitive_services_endpoint=cognitive_services_endpoint, + deployment_name=deployment_name, + tokens_per_minute=reader.int("tokens_per_minute", Fragment.tpm) + or base.tokens_per_minute, + requests_per_minute=reader.int("requests_per_minute", Fragment.rpm) + or base.requests_per_minute, + max_retries=reader.int(Fragment.max_retries) or base.max_retries, + max_retry_wait=reader.float(Fragment.max_retry_wait) + or base.max_retry_wait, + sleep_on_rate_limit_recommendation=sleep_on_rate_limit, + concurrent_requests=reader.int(Fragment.concurrent_requests) + or base.concurrent_requests, + ) + + def hydrate_embeddings_params( + config: LLMConfigInput, base: LLMParameters + ) -> LLMParameters: + with reader.use(config.get("llm")): + api_type = reader.str(Fragment.type) or defs.EMBEDDING_TYPE + api_type = LLMType(api_type) if api_type else defs.LLM_TYPE + api_key = reader.str(Fragment.api_key) or base.api_key + + # In a unique events where: + # - same api_bases for LLM and embeddings (both Azure) + # - different api_bases for LLM and embeddings (both Azure) + # - LLM uses Azure OpenAI, while embeddings uses base OpenAI (this one is important) + # - LLM uses Azure OpenAI, while embeddings uses third-party OpenAI-like API + api_base = ( + reader.str(Fragment.api_base) or base.api_base + if _is_azure(api_type) + else reader.str(Fragment.api_base) + ) + api_version = ( + reader.str(Fragment.api_version) or base.api_version + if _is_azure(api_type) + else reader.str(Fragment.api_version) + ) + api_organization = reader.str("organization") or base.organization + api_proxy = reader.str("proxy") or base.proxy + cognitive_services_endpoint = ( + reader.str(Fragment.cognitive_services_endpoint) + or base.cognitive_services_endpoint + ) + deployment_name = reader.str(Fragment.deployment_name) + + if api_key is None and not _is_azure(api_type): + raise ApiKeyMissingError(embedding=True) + if _is_azure(api_type): + if api_base is None: + raise AzureApiBaseMissingError(embedding=True) + if deployment_name is None: + raise AzureDeploymentNameMissingError(embedding=True) + + sleep_on_rate_limit = reader.bool(Fragment.sleep_recommendation) + if sleep_on_rate_limit is None: + sleep_on_rate_limit = base.sleep_on_rate_limit_recommendation + + return LLMParameters( + api_key=api_key, + type=api_type, + api_base=api_base, + api_version=api_version, + organization=api_organization, + proxy=api_proxy, + model=reader.str(Fragment.model) or defs.EMBEDDING_MODEL, + request_timeout=reader.float(Fragment.request_timeout) + or defs.LLM_REQUEST_TIMEOUT, + cognitive_services_endpoint=cognitive_services_endpoint, + deployment_name=deployment_name, + tokens_per_minute=reader.int("tokens_per_minute", Fragment.tpm) + or defs.LLM_TOKENS_PER_MINUTE, + requests_per_minute=reader.int("requests_per_minute", Fragment.rpm) + or defs.LLM_REQUESTS_PER_MINUTE, + max_retries=reader.int(Fragment.max_retries) or defs.LLM_MAX_RETRIES, + max_retry_wait=reader.float(Fragment.max_retry_wait) + or defs.LLM_MAX_RETRY_WAIT, + sleep_on_rate_limit_recommendation=sleep_on_rate_limit, + concurrent_requests=reader.int(Fragment.concurrent_requests) + or defs.LLM_CONCURRENT_REQUESTS, + ) + + def hydrate_parallelization_params( + config: LLMConfigInput, base: ParallelizationParameters + ) -> ParallelizationParameters: + with reader.use(config.get("parallelization")): + return ParallelizationParameters( + num_threads=reader.int("num_threads", Fragment.thread_count) + or base.num_threads, + stagger=reader.float("stagger", Fragment.thread_stagger) + or base.stagger, + ) + + fallback_oai_key = env("OPENAI_API_KEY", env("AZURE_OPENAI_API_KEY", None)) + fallback_oai_org = env("OPENAI_ORG_ID", None) + fallback_oai_base = env("OPENAI_BASE_URL", None) + fallback_oai_version = env("OPENAI_API_VERSION", None) + + with reader.envvar_prefix(Section.graphrag), reader.use(values): + async_mode = reader.str(Fragment.async_mode) + async_mode = AsyncType(async_mode) if async_mode else defs.ASYNC_MODE + + fallback_oai_key = reader.str(Fragment.api_key) or fallback_oai_key + fallback_oai_org = reader.str(Fragment.api_organization) or fallback_oai_org + fallback_oai_base = reader.str(Fragment.api_base) or fallback_oai_base + fallback_oai_version = reader.str(Fragment.api_version) or fallback_oai_version + fallback_oai_proxy = reader.str(Fragment.api_proxy) + + with reader.envvar_prefix(Section.llm): + with reader.use(values.get("llm")): + llm_type = reader.str(Fragment.type) + llm_type = LLMType(llm_type) if llm_type else defs.LLM_TYPE + api_key = reader.str(Fragment.api_key) or fallback_oai_key + api_organization = ( + reader.str(Fragment.api_organization) or fallback_oai_org + ) + api_base = reader.str(Fragment.api_base) or fallback_oai_base + api_version = reader.str(Fragment.api_version) or fallback_oai_version + api_proxy = reader.str(Fragment.api_proxy) or fallback_oai_proxy + cognitive_services_endpoint = reader.str( + Fragment.cognitive_services_endpoint + ) + deployment_name = reader.str(Fragment.deployment_name) + + if api_key is None and not _is_azure(llm_type): + raise ApiKeyMissingError + if _is_azure(llm_type): + if api_base is None: + raise AzureApiBaseMissingError + if deployment_name is None: + raise AzureDeploymentNameMissingError + + sleep_on_rate_limit = reader.bool(Fragment.sleep_recommendation) + if sleep_on_rate_limit is None: + sleep_on_rate_limit = defs.LLM_SLEEP_ON_RATE_LIMIT_RECOMMENDATION + + llm_model = LLMParameters( + api_key=api_key, + api_base=api_base, + api_version=api_version, + organization=api_organization, + proxy=api_proxy, + type=llm_type, + model=reader.str(Fragment.model) or defs.LLM_MODEL, + max_tokens=reader.int(Fragment.max_tokens) or defs.LLM_MAX_TOKENS, + temperature=reader.float(Fragment.temperature) + or defs.LLM_TEMPERATURE, + top_p=reader.float(Fragment.top_p) or defs.LLM_TOP_P, + n=reader.int(Fragment.n) or defs.LLM_N, + model_supports_json=reader.bool(Fragment.model_supports_json), + request_timeout=reader.float(Fragment.request_timeout) + or defs.LLM_REQUEST_TIMEOUT, + cognitive_services_endpoint=cognitive_services_endpoint, + deployment_name=deployment_name, + tokens_per_minute=reader.int(Fragment.tpm) + or defs.LLM_TOKENS_PER_MINUTE, + requests_per_minute=reader.int(Fragment.rpm) + or defs.LLM_REQUESTS_PER_MINUTE, + max_retries=reader.int(Fragment.max_retries) + or defs.LLM_MAX_RETRIES, + max_retry_wait=reader.float(Fragment.max_retry_wait) + or defs.LLM_MAX_RETRY_WAIT, + sleep_on_rate_limit_recommendation=sleep_on_rate_limit, + concurrent_requests=reader.int(Fragment.concurrent_requests) + or defs.LLM_CONCURRENT_REQUESTS, + ) + with reader.use(values.get("parallelization")): + llm_parallelization_model = ParallelizationParameters( + stagger=reader.float("stagger", Fragment.thread_stagger) + or defs.PARALLELIZATION_STAGGER, + num_threads=reader.int("num_threads", Fragment.thread_count) + or defs.PARALLELIZATION_NUM_THREADS, + ) + embeddings_config = values.get("embeddings") or {} + with reader.envvar_prefix(Section.embedding), reader.use(embeddings_config): + embeddings_target = reader.str("target") + embeddings_model = TextEmbeddingConfig( + llm=hydrate_embeddings_params(embeddings_config, llm_model), + parallelization=hydrate_parallelization_params( + embeddings_config, llm_parallelization_model + ), + vector_store=embeddings_config.get("vector_store", None), + async_mode=hydrate_async_type(embeddings_config, async_mode), + target=( + TextEmbeddingTarget(embeddings_target) + if embeddings_target + else defs.EMBEDDING_TARGET + ), + batch_size=reader.int("batch_size") or defs.EMBEDDING_BATCH_SIZE, + batch_max_tokens=reader.int("batch_max_tokens") + or defs.EMBEDDING_BATCH_MAX_TOKENS, + skip=reader.list("skip") or [], + ) + with ( + reader.envvar_prefix(Section.node2vec), + reader.use(values.get("embed_graph")), + ): + embed_graph_model = EmbedGraphConfig( + enabled=reader.bool(Fragment.enabled) or defs.NODE2VEC_ENABLED, + num_walks=reader.int("num_walks") or defs.NODE2VEC_NUM_WALKS, + walk_length=reader.int("walk_length") or defs.NODE2VEC_WALK_LENGTH, + window_size=reader.int("window_size") or defs.NODE2VEC_WINDOW_SIZE, + iterations=reader.int("iterations") or defs.NODE2VEC_ITERATIONS, + random_seed=reader.int("random_seed") or defs.NODE2VEC_RANDOM_SEED, + ) + with reader.envvar_prefix(Section.input), reader.use(values.get("input")): + input_type = reader.str("type") + file_type = reader.str(Fragment.file_type) + input_model = InputConfig( + file_type=( + InputFileType(file_type) if file_type else defs.INPUT_FILE_TYPE + ), + type=(InputType(input_type) if input_type else defs.INPUT_TYPE), + encoding=reader.str("file_encoding", Fragment.encoding) + or defs.INPUT_FILE_ENCODING, + base_dir=reader.str(Fragment.base_dir) or defs.INPUT_BASE_DIR, + file_pattern=reader.str("file_pattern") + or ( + defs.INPUT_TEXT_PATTERN + if file_type == InputFileType.text + else defs.INPUT_CSV_PATTERN + ), + source_column=reader.str("source_column"), + timestamp_column=reader.str("timestamp_column"), + timestamp_format=reader.str("timestamp_format"), + text_column=reader.str("text_column") or defs.INPUT_TEXT_COLUMN, + title_column=reader.str("title_column"), + document_attribute_columns=reader.list("document_attribute_columns") + or [], + connection_string=reader.str(Fragment.conn_string), + storage_account_blob_url=reader.str(Fragment.storage_account_blob_url), + container_name=reader.str(Fragment.container_name), + ) + with reader.envvar_prefix(Section.cache), reader.use(values.get("cache")): + c_type = reader.str(Fragment.type) + cache_model = CacheConfig( + type=CacheType(c_type) if c_type else defs.CACHE_TYPE, + connection_string=reader.str(Fragment.conn_string), + storage_account_blob_url=reader.str(Fragment.storage_account_blob_url), + container_name=reader.str(Fragment.container_name), + base_dir=reader.str(Fragment.base_dir) or defs.CACHE_BASE_DIR, + ) + with ( + reader.envvar_prefix(Section.reporting), + reader.use(values.get("reporting")), + ): + r_type = reader.str(Fragment.type) + reporting_model = ReportingConfig( + type=ReportingType(r_type) if r_type else defs.REPORTING_TYPE, + connection_string=reader.str(Fragment.conn_string), + storage_account_blob_url=reader.str(Fragment.storage_account_blob_url), + container_name=reader.str(Fragment.container_name), + base_dir=reader.str(Fragment.base_dir) or defs.REPORTING_BASE_DIR, + ) + with reader.envvar_prefix(Section.storage), reader.use(values.get("storage")): + s_type = reader.str(Fragment.type) + storage_model = StorageConfig( + type=StorageType(s_type) if s_type else defs.STORAGE_TYPE, + connection_string=reader.str(Fragment.conn_string), + storage_account_blob_url=reader.str(Fragment.storage_account_blob_url), + container_name=reader.str(Fragment.container_name), + base_dir=reader.str(Fragment.base_dir) or defs.STORAGE_BASE_DIR, + ) + with reader.envvar_prefix(Section.chunk), reader.use(values.get("chunks")): + chunks_model = ChunkingConfig( + size=reader.int("size") or defs.CHUNK_SIZE, + overlap=reader.int("overlap") or defs.CHUNK_OVERLAP, + group_by_columns=reader.list("group_by_columns", "BY_COLUMNS") + or defs.CHUNK_GROUP_BY_COLUMNS, + ) + with ( + reader.envvar_prefix(Section.snapshot), + reader.use(values.get("snapshots")), + ): + snapshots_model = SnapshotsConfig( + graphml=reader.bool("graphml") or defs.SNAPSHOTS_GRAPHML, + raw_entities=reader.bool("raw_entities") or defs.SNAPSHOTS_RAW_ENTITIES, + top_level_nodes=reader.bool("top_level_nodes") + or defs.SNAPSHOTS_TOP_LEVEL_NODES, + ) + with reader.envvar_prefix(Section.umap), reader.use(values.get("umap")): + umap_model = UmapConfig( + enabled=reader.bool(Fragment.enabled) or defs.UMAP_ENABLED, + ) + + entity_extraction_config = values.get("entity_extraction") or {} + with ( + reader.envvar_prefix(Section.entity_extraction), + reader.use(entity_extraction_config), + ): + entity_extraction_model = EntityExtractionConfig( + llm=hydrate_llm_params(entity_extraction_config, llm_model), + parallelization=hydrate_parallelization_params( + entity_extraction_config, llm_parallelization_model + ), + async_mode=hydrate_async_type(entity_extraction_config, async_mode), + entity_types=reader.list("entity_types") + or defs.ENTITY_EXTRACTION_ENTITY_TYPES, + max_gleanings=reader.int(Fragment.max_gleanings) + or defs.ENTITY_EXTRACTION_MAX_GLEANINGS, + prompt=reader.str("prompt", Fragment.prompt_file), + ) + + claim_extraction_config = values.get("claim_extraction") or {} + with ( + reader.envvar_prefix(Section.claim_extraction), + reader.use(claim_extraction_config), + ): + claim_extraction_model = ClaimExtractionConfig( + enabled=reader.bool(Fragment.enabled) or defs.CLAIM_EXTRACTION_ENABLED, + llm=hydrate_llm_params(claim_extraction_config, llm_model), + parallelization=hydrate_parallelization_params( + claim_extraction_config, llm_parallelization_model + ), + async_mode=hydrate_async_type(claim_extraction_config, async_mode), + description=reader.str("description") or defs.CLAIM_DESCRIPTION, + prompt=reader.str("prompt", Fragment.prompt_file), + max_gleanings=reader.int(Fragment.max_gleanings) + or defs.CLAIM_MAX_GLEANINGS, + ) + + community_report_config = values.get("community_reports") or {} + with ( + reader.envvar_prefix(Section.community_reports), + reader.use(community_report_config), + ): + community_reports_model = CommunityReportsConfig( + llm=hydrate_llm_params(community_report_config, llm_model), + parallelization=hydrate_parallelization_params( + community_report_config, llm_parallelization_model + ), + async_mode=hydrate_async_type(community_report_config, async_mode), + prompt=reader.str("prompt", Fragment.prompt_file), + max_length=reader.int(Fragment.max_length) + or defs.COMMUNITY_REPORT_MAX_LENGTH, + max_input_length=reader.int("max_input_length") + or defs.COMMUNITY_REPORT_MAX_INPUT_LENGTH, + ) + + summarize_description_config = values.get("summarize_descriptions") or {} + with ( + reader.envvar_prefix(Section.summarize_descriptions), + reader.use(values.get("summarize_descriptions")), + ): + summarize_descriptions_model = SummarizeDescriptionsConfig( + llm=hydrate_llm_params(summarize_description_config, llm_model), + parallelization=hydrate_parallelization_params( + summarize_description_config, llm_parallelization_model + ), + async_mode=hydrate_async_type(summarize_description_config, async_mode), + prompt=reader.str("prompt", Fragment.prompt_file), + max_length=reader.int(Fragment.max_length) + or defs.SUMMARIZE_DESCRIPTIONS_MAX_LENGTH, + ) + + with reader.use(values.get("cluster_graph")): + cluster_graph_model = ClusterGraphConfig( + max_cluster_size=reader.int("max_cluster_size") or defs.MAX_CLUSTER_SIZE + ) + + with ( + reader.use(values.get("local_search")), + reader.envvar_prefix(Section.local_search), + ): + local_search_model = LocalSearchConfig( + text_unit_prop=reader.float("text_unit_prop") + or defs.LOCAL_SEARCH_TEXT_UNIT_PROP, + community_prop=reader.float("community_prop") + or defs.LOCAL_SEARCH_COMMUNITY_PROP, + conversation_history_max_turns=reader.int( + "conversation_history_max_turns" + ) + or defs.LOCAL_SEARCH_CONVERSATION_HISTORY_MAX_TURNS, + top_k_entities=reader.int("top_k_entities") + or defs.LOCAL_SEARCH_TOP_K_MAPPED_ENTITIES, + top_k_relationships=reader.int("top_k_relationships") + or defs.LOCAL_SEARCH_TOP_K_RELATIONSHIPS, + temperature=reader.float("llm_temperature") + or defs.LOCAL_SEARCH_LLM_TEMPERATURE, + top_p=reader.float("llm_top_p") or defs.LOCAL_SEARCH_LLM_TOP_P, + n=reader.int("llm_n") or defs.LOCAL_SEARCH_LLM_N, + max_tokens=reader.int(Fragment.max_tokens) + or defs.LOCAL_SEARCH_MAX_TOKENS, + llm_max_tokens=reader.int("llm_max_tokens") + or defs.LOCAL_SEARCH_LLM_MAX_TOKENS, + ) + + with ( + reader.use(values.get("global_search")), + reader.envvar_prefix(Section.global_search), + ): + global_search_model = GlobalSearchConfig( + temperature=reader.float("llm_temperature") + or defs.GLOBAL_SEARCH_LLM_TEMPERATURE, + top_p=reader.float("llm_top_p") or defs.GLOBAL_SEARCH_LLM_TOP_P, + n=reader.int("llm_n") or defs.GLOBAL_SEARCH_LLM_N, + max_tokens=reader.int(Fragment.max_tokens) + or defs.GLOBAL_SEARCH_MAX_TOKENS, + data_max_tokens=reader.int("data_max_tokens") + or defs.GLOBAL_SEARCH_DATA_MAX_TOKENS, + map_max_tokens=reader.int("map_max_tokens") + or defs.GLOBAL_SEARCH_MAP_MAX_TOKENS, + reduce_max_tokens=reader.int("reduce_max_tokens") + or defs.GLOBAL_SEARCH_REDUCE_MAX_TOKENS, + concurrency=reader.int("concurrency") or defs.GLOBAL_SEARCH_CONCURRENCY, + ) + + encoding_model = reader.str(Fragment.encoding_model) or defs.ENCODING_MODEL + skip_workflows = reader.list("skip_workflows") or [] + + return GraphRagConfig( + root_dir=root_dir, + llm=llm_model, + parallelization=llm_parallelization_model, + async_mode=async_mode, + embeddings=embeddings_model, + embed_graph=embed_graph_model, + reporting=reporting_model, + storage=storage_model, + cache=cache_model, + input=input_model, + chunks=chunks_model, + snapshots=snapshots_model, + entity_extraction=entity_extraction_model, + claim_extraction=claim_extraction_model, + community_reports=community_reports_model, + summarize_descriptions=summarize_descriptions_model, + umap=umap_model, + cluster_graph=cluster_graph_model, + encoding_model=encoding_model, + skip_workflows=skip_workflows, + local_search=local_search_model, + global_search=global_search_model, + ) + + +class Fragment(str, Enum): + """Configuration Fragments.""" + + api_base = "API_BASE" + api_key = "API_KEY" + api_version = "API_VERSION" + api_organization = "API_ORGANIZATION" + api_proxy = "API_PROXY" + async_mode = "ASYNC_MODE" + base_dir = "BASE_DIR" + cognitive_services_endpoint = "COGNITIVE_SERVICES_ENDPOINT" + concurrent_requests = "CONCURRENT_REQUESTS" + conn_string = "CONNECTION_STRING" + container_name = "CONTAINER_NAME" + deployment_name = "DEPLOYMENT_NAME" + description = "DESCRIPTION" + enabled = "ENABLED" + encoding = "ENCODING" + encoding_model = "ENCODING_MODEL" + file_type = "FILE_TYPE" + max_gleanings = "MAX_GLEANINGS" + max_length = "MAX_LENGTH" + max_retries = "MAX_RETRIES" + max_retry_wait = "MAX_RETRY_WAIT" + max_tokens = "MAX_TOKENS" + temperature = "TEMPERATURE" + top_p = "TOP_P" + n = "N" + model = "MODEL" + model_supports_json = "MODEL_SUPPORTS_JSON" + prompt_file = "PROMPT_FILE" + request_timeout = "REQUEST_TIMEOUT" + rpm = "REQUESTS_PER_MINUTE" + sleep_recommendation = "SLEEP_ON_RATE_LIMIT_RECOMMENDATION" + storage_account_blob_url = "STORAGE_ACCOUNT_BLOB_URL" + thread_count = "THREAD_COUNT" + thread_stagger = "THREAD_STAGGER" + tpm = "TOKENS_PER_MINUTE" + type = "TYPE" + + +class Section(str, Enum): + """Configuration Sections.""" + + base = "BASE" + cache = "CACHE" + chunk = "CHUNK" + claim_extraction = "CLAIM_EXTRACTION" + community_reports = "COMMUNITY_REPORTS" + embedding = "EMBEDDING" + entity_extraction = "ENTITY_EXTRACTION" + graphrag = "GRAPHRAG" + input = "INPUT" + llm = "LLM" + node2vec = "NODE2VEC" + reporting = "REPORTING" + snapshot = "SNAPSHOT" + storage = "STORAGE" + summarize_descriptions = "SUMMARIZE_DESCRIPTIONS" + umap = "UMAP" + local_search = "LOCAL_SEARCH" + global_search = "GLOBAL_SEARCH" + + +def _is_azure(llm_type: LLMType | None) -> bool: + return ( + llm_type == LLMType.AzureOpenAI + or llm_type == LLMType.AzureOpenAIChat + or llm_type == LLMType.AzureOpenAIEmbedding + ) + + +def _make_env(root_dir: str) -> Env: + read_dotenv(root_dir) + env = Env(expand_vars=True) + env.read_env() + return env + + +def _token_replace(data: dict): + """Replace env-var tokens in a dictionary object.""" + for key, value in data.items(): + if isinstance(value, dict): + _token_replace(value) + elif isinstance(value, str): + data[key] = os.path.expandvars(value) diff --git a/graphrag/graphrag/config/defaults.py b/graphrag/graphrag/config/defaults.py new file mode 100644 index 0000000000000000000000000000000000000000..4d6489140a4f863b12cabc4cdc087789d1aa7f2a --- /dev/null +++ b/graphrag/graphrag/config/defaults.py @@ -0,0 +1,106 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Common default configuration values.""" + +from datashaper import AsyncType + +from .enums import ( + CacheType, + InputFileType, + InputType, + LLMType, + ReportingType, + StorageType, + TextEmbeddingTarget, +) + +ASYNC_MODE = AsyncType.Threaded +ENCODING_MODEL = "cl100k_base" +# +# LLM Parameters +# +LLM_TYPE = LLMType.OpenAIChat +LLM_MODEL = "gpt-4-turbo-preview" +LLM_MAX_TOKENS = 4000 +LLM_TEMPERATURE = 0 +LLM_TOP_P = 1 +LLM_N = 1 +LLM_REQUEST_TIMEOUT = 180.0 +LLM_TOKENS_PER_MINUTE = 0 +LLM_REQUESTS_PER_MINUTE = 0 +LLM_MAX_RETRIES = 10 +LLM_MAX_RETRY_WAIT = 10.0 +LLM_SLEEP_ON_RATE_LIMIT_RECOMMENDATION = True +LLM_CONCURRENT_REQUESTS = 25 + +# +# Text Embedding Parameters +# +EMBEDDING_TYPE = LLMType.OpenAIEmbedding +EMBEDDING_MODEL = "text-embedding-3-small" +EMBEDDING_BATCH_SIZE = 16 +EMBEDDING_BATCH_MAX_TOKENS = 8191 +EMBEDDING_TARGET = TextEmbeddingTarget.required + +CACHE_TYPE = CacheType.file +CACHE_BASE_DIR = "cache" +CHUNK_SIZE = 1200 +CHUNK_OVERLAP = 100 +CHUNK_GROUP_BY_COLUMNS = ["id"] +CLAIM_DESCRIPTION = ( + "Any claims or facts that could be relevant to information discovery." +) +CLAIM_MAX_GLEANINGS = 1 +CLAIM_EXTRACTION_ENABLED = False +MAX_CLUSTER_SIZE = 10 +COMMUNITY_REPORT_MAX_LENGTH = 2000 +COMMUNITY_REPORT_MAX_INPUT_LENGTH = 8000 +ENTITY_EXTRACTION_ENTITY_TYPES = ["organization", "person", "geo", "event"] +ENTITY_EXTRACTION_MAX_GLEANINGS = 1 +INPUT_FILE_TYPE = InputFileType.text +INPUT_TYPE = InputType.file +INPUT_BASE_DIR = "input" +INPUT_FILE_ENCODING = "utf-8" +INPUT_TEXT_COLUMN = "text" +INPUT_CSV_PATTERN = ".*\\.csv$" +INPUT_TEXT_PATTERN = ".*\\.txt$" +PARALLELIZATION_STAGGER = 0.3 +PARALLELIZATION_NUM_THREADS = 50 +NODE2VEC_ENABLED = False +NODE2VEC_NUM_WALKS = 10 +NODE2VEC_WALK_LENGTH = 40 +NODE2VEC_WINDOW_SIZE = 2 +NODE2VEC_ITERATIONS = 3 +NODE2VEC_RANDOM_SEED = 597832 +REPORTING_TYPE = ReportingType.file +REPORTING_BASE_DIR = "output/${timestamp}/reports" +SNAPSHOTS_GRAPHML = False +SNAPSHOTS_RAW_ENTITIES = False +SNAPSHOTS_TOP_LEVEL_NODES = False +STORAGE_BASE_DIR = "output/${timestamp}/artifacts" +STORAGE_TYPE = StorageType.file +SUMMARIZE_DESCRIPTIONS_MAX_LENGTH = 500 +UMAP_ENABLED = False + +# Local Search +LOCAL_SEARCH_TEXT_UNIT_PROP = 0.5 +LOCAL_SEARCH_COMMUNITY_PROP = 0.1 +LOCAL_SEARCH_CONVERSATION_HISTORY_MAX_TURNS = 5 +LOCAL_SEARCH_TOP_K_MAPPED_ENTITIES = 10 +LOCAL_SEARCH_TOP_K_RELATIONSHIPS = 10 +LOCAL_SEARCH_MAX_TOKENS = 12_000 +LOCAL_SEARCH_LLM_TEMPERATURE = 0 +LOCAL_SEARCH_LLM_TOP_P = 1 +LOCAL_SEARCH_LLM_N = 1 +LOCAL_SEARCH_LLM_MAX_TOKENS = 2000 + +# Global Search +GLOBAL_SEARCH_LLM_TEMPERATURE = 0 +GLOBAL_SEARCH_LLM_TOP_P = 1 +GLOBAL_SEARCH_LLM_N = 1 +GLOBAL_SEARCH_MAX_TOKENS = 12_000 +GLOBAL_SEARCH_DATA_MAX_TOKENS = 12_000 +GLOBAL_SEARCH_MAP_MAX_TOKENS = 1000 +GLOBAL_SEARCH_REDUCE_MAX_TOKENS = 2_000 +GLOBAL_SEARCH_CONCURRENCY = 32 diff --git a/graphrag/graphrag/config/enums.py b/graphrag/graphrag/config/enums.py new file mode 100644 index 0000000000000000000000000000000000000000..8741cf74ae079b1cd88d706f914573beab4bcc36 --- /dev/null +++ b/graphrag/graphrag/config/enums.py @@ -0,0 +1,115 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'PipelineCacheConfig', 'PipelineFileCacheConfig' and 'PipelineMemoryCacheConfig' models.""" + +from __future__ import annotations + +from enum import Enum + + +class CacheType(str, Enum): + """The cache configuration type for the pipeline.""" + + file = "file" + """The file cache configuration type.""" + memory = "memory" + """The memory cache configuration type.""" + none = "none" + """The none cache configuration type.""" + blob = "blob" + """The blob cache configuration type.""" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +class InputFileType(str, Enum): + """The input file type for the pipeline.""" + + csv = "csv" + """The CSV input type.""" + text = "text" + """The text input type.""" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +class InputType(str, Enum): + """The input type for the pipeline.""" + + file = "file" + """The file storage type.""" + blob = "blob" + """The blob storage type.""" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +class StorageType(str, Enum): + """The storage type for the pipeline.""" + + file = "file" + """The file storage type.""" + memory = "memory" + """The memory storage type.""" + blob = "blob" + """The blob storage type.""" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +class ReportingType(str, Enum): + """The reporting configuration type for the pipeline.""" + + file = "file" + """The file reporting configuration type.""" + console = "console" + """The console reporting configuration type.""" + blob = "blob" + """The blob reporting configuration type.""" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +class TextEmbeddingTarget(str, Enum): + """The target to use for text embeddings.""" + + all = "all" + required = "required" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +class LLMType(str, Enum): + """LLMType enum class definition.""" + + # Embeddings + OpenAIEmbedding = "openai_embedding" + AzureOpenAIEmbedding = "azure_openai_embedding" + + # Raw Completion + OpenAI = "openai" + AzureOpenAI = "azure_openai" + + # Chat Completion + OpenAIChat = "openai_chat" + AzureOpenAIChat = "azure_openai_chat" + + # Debug + StaticResponse = "static_response" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' diff --git a/graphrag/graphrag/config/environment_reader.py b/graphrag/graphrag/config/environment_reader.py new file mode 100644 index 0000000000000000000000000000000000000000..dc61301f8b14edd73eb5aec62f3efa0fdefb4391 --- /dev/null +++ b/graphrag/graphrag/config/environment_reader.py @@ -0,0 +1,154 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A configuration reader utility class.""" + +from collections.abc import Callable +from contextlib import contextmanager +from enum import Enum +from typing import Any, TypeVar + +from environs import Env + +T = TypeVar("T") + +KeyValue = str | Enum +EnvKeySet = str | list[str] + + +def read_key(value: KeyValue) -> str: + """Read a key value.""" + if not isinstance(value, str): + return value.value.lower() + return value.lower() + + +class EnvironmentReader: + """A configuration reader utility class.""" + + _env: Env + _config_stack: list[dict] + + def __init__(self, env: Env): + self._env = env + self._config_stack = [] + + @property + def env(self): + """Get the environment object.""" + return self._env + + def _read_env( + self, env_key: str | list[str], default_value: T, read: Callable[[str, T], T] + ) -> T | None: + if isinstance(env_key, str): + env_key = [env_key] + + for k in env_key: + result = read(k.upper(), default_value) + if result is not default_value: + return result + + return default_value + + def envvar_prefix(self, prefix: KeyValue): + """Set the environment variable prefix.""" + prefix = read_key(prefix) + prefix = f"{prefix}_".upper() + return self._env.prefixed(prefix) + + def use(self, value: Any | None): + """Create a context manager to push the value into the config_stack.""" + + @contextmanager + def config_context(): + self._config_stack.append(value or {}) + try: + yield + finally: + self._config_stack.pop() + + return config_context() + + @property + def section(self) -> dict: + """Get the current section.""" + return self._config_stack[-1] if self._config_stack else {} + + def str( + self, + key: KeyValue, + env_key: EnvKeySet | None = None, + default_value: str | None = None, + ) -> str | None: + """Read a configuration value.""" + key = read_key(key) + if self.section and key in self.section: + return self.section[key] + + return self._read_env( + env_key or key, default_value, (lambda k, dv: self._env(k, dv)) + ) + + def int( + self, + key: KeyValue, + env_key: EnvKeySet | None = None, + default_value: int | None = None, + ) -> int | None: + """Read an integer configuration value.""" + key = read_key(key) + if self.section and key in self.section: + return int(self.section[key]) + return self._read_env( + env_key or key, default_value, lambda k, dv: self._env.int(k, dv) + ) + + def bool( + self, + key: KeyValue, + env_key: EnvKeySet | None = None, + default_value: bool | None = None, + ) -> bool | None: + """Read an integer configuration value.""" + key = read_key(key) + if self.section and key in self.section: + return bool(self.section[key]) + + return self._read_env( + env_key or key, default_value, lambda k, dv: self._env.bool(k, dv) + ) + + def float( + self, + key: KeyValue, + env_key: EnvKeySet | None = None, + default_value: float | None = None, + ) -> float | None: + """Read a float configuration value.""" + key = read_key(key) + if self.section and key in self.section: + return float(self.section[key]) + return self._read_env( + env_key or key, default_value, lambda k, dv: self._env.float(k, dv) + ) + + def list( + self, + key: KeyValue, + env_key: EnvKeySet | None = None, + default_value: list | None = None, + ) -> list | None: + """Parse an list configuration value.""" + key = read_key(key) + result = None + if self.section and key in self.section: + result = self.section[key] + if isinstance(result, list): + return result + + if result is None: + result = self.str(key, env_key) + if result: + return [s.strip() for s in result.split(",")] + return default_value diff --git a/graphrag/graphrag/config/errors.py b/graphrag/graphrag/config/errors.py new file mode 100644 index 0000000000000000000000000000000000000000..9a2161b8afbcc78557b599930cf168b33168a882 --- /dev/null +++ b/graphrag/graphrag/config/errors.py @@ -0,0 +1,40 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +"""Errors for the default configuration.""" + + +class ApiKeyMissingError(ValueError): + """LLM Key missing error.""" + + def __init__(self, embedding: bool = False) -> None: + """Init method definition.""" + api_type = "Embedding" if embedding else "Completion" + api_key = "GRAPHRAG_EMBEDDING_API_KEY" if embedding else "GRAPHRAG_LLM_API_KEY" + msg = f"API Key is required for {api_type} API. Please set either the OPENAI_API_KEY, GRAPHRAG_API_KEY or {api_key} environment variable." + super().__init__(msg) + + +class AzureApiBaseMissingError(ValueError): + """Azure API Base missing error.""" + + def __init__(self, embedding: bool = False) -> None: + """Init method definition.""" + api_type = "Embedding" if embedding else "Completion" + api_base = "GRAPHRAG_EMBEDDING_API_BASE" if embedding else "GRAPHRAG_API_BASE" + msg = f"API Base is required for {api_type} API. Please set either the OPENAI_API_BASE, GRAPHRAG_API_BASE or {api_base} environment variable." + super().__init__(msg) + + +class AzureDeploymentNameMissingError(ValueError): + """Azure Deployment Name missing error.""" + + def __init__(self, embedding: bool = False) -> None: + """Init method definition.""" + api_type = "Embedding" if embedding else "Completion" + api_base = ( + "GRAPHRAG_EMBEDDING_DEPLOYMENT_NAME" + if embedding + else "GRAPHRAG_LLM_DEPLOYMENT_NAME" + ) + msg = f"Deployment Name is required for {api_type} API. Please set either the OPENAI_DEPLOYMENT_NAME, GRAPHRAG_LLM_DEPLOYMENT_NAME or {api_base} environment variable." + super().__init__(msg) diff --git a/graphrag/graphrag/config/input_models/__init__.py b/graphrag/graphrag/config/input_models/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f905ae38b2de5019dd2017ad93d9839d5e25fa6c --- /dev/null +++ b/graphrag/graphrag/config/input_models/__init__.py @@ -0,0 +1,50 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Interfaces for Default Config parameterization.""" + +from .cache_config_input import CacheConfigInput +from .chunking_config_input import ChunkingConfigInput +from .claim_extraction_config_input import ClaimExtractionConfigInput +from .cluster_graph_config_input import ClusterGraphConfigInput +from .community_reports_config_input import CommunityReportsConfigInput +from .embed_graph_config_input import EmbedGraphConfigInput +from .entity_extraction_config_input import EntityExtractionConfigInput +from .global_search_config_input import GlobalSearchConfigInput +from .graphrag_config_input import GraphRagConfigInput +from .input_config_input import InputConfigInput +from .llm_config_input import LLMConfigInput +from .llm_parameters_input import LLMParametersInput +from .local_search_config_input import LocalSearchConfigInput +from .parallelization_parameters_input import ParallelizationParametersInput +from .reporting_config_input import ReportingConfigInput +from .snapshots_config_input import SnapshotsConfigInput +from .storage_config_input import StorageConfigInput +from .summarize_descriptions_config_input import ( + SummarizeDescriptionsConfigInput, +) +from .text_embedding_config_input import TextEmbeddingConfigInput +from .umap_config_input import UmapConfigInput + +__all__ = [ + "CacheConfigInput", + "ChunkingConfigInput", + "ClaimExtractionConfigInput", + "ClusterGraphConfigInput", + "CommunityReportsConfigInput", + "EmbedGraphConfigInput", + "EntityExtractionConfigInput", + "GlobalSearchConfigInput", + "GraphRagConfigInput", + "InputConfigInput", + "LLMConfigInput", + "LLMParametersInput", + "LocalSearchConfigInput", + "ParallelizationParametersInput", + "ReportingConfigInput", + "SnapshotsConfigInput", + "StorageConfigInput", + "SummarizeDescriptionsConfigInput", + "TextEmbeddingConfigInput", + "UmapConfigInput", +] diff --git a/graphrag/graphrag/config/input_models/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92a1d979e0352bbe63244fbe39188b25130b2fd0 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/cache_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/cache_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..edeef68249aaa7995039f66fe809e499823556db Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/cache_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/chunking_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/chunking_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24fc3d40d6667a9efefc78732328a363547036a3 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/chunking_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/claim_extraction_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/claim_extraction_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50159da9d256be7cfd8adf6f8a61476129ef6346 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/claim_extraction_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/cluster_graph_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/cluster_graph_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..202b83eb55d4381ea098a52ae43d4bae453699a6 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/cluster_graph_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/community_reports_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/community_reports_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..545dbb5f69dc4f1537a971974f12b0456b0faebf Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/community_reports_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/embed_graph_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/embed_graph_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..344c2854bcb9804a514831f7d51adb708a3c1c7a Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/embed_graph_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/entity_extraction_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/entity_extraction_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e773931a39b89d50b77e58da3a50fcf7c98ddbd7 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/entity_extraction_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/global_search_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/global_search_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b6b7e94c0690cec61116decaae9b49e205773d1 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/global_search_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/graphrag_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/graphrag_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2ac3076d77eb2d2478207159200869bb344cb71b Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/graphrag_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/input_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/input_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..802ec9ad95500fb3609a628aee965bf3ff670321 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/input_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/llm_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/llm_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..48f6905468fc3d763e23517505e7cb220ab8def1 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/llm_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/llm_parameters_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/llm_parameters_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..22009bc59ebf4dfb073bc95b1c87f65037c13261 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/llm_parameters_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/local_search_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/local_search_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e0f2c8a569e62da0410247c2067cb12a25afb14 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/local_search_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/parallelization_parameters_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/parallelization_parameters_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03e194e96edf7ef0378058abc4ae58a67e9b4445 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/parallelization_parameters_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/reporting_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/reporting_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96df084faf72404cdc19958177377221a687ccda Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/reporting_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/snapshots_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/snapshots_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..457629bf085c14d785012939033125ccf514405d Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/snapshots_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/storage_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/storage_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..49f0d15f7b525844efa3e204c46f44ce4535a6dd Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/storage_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/summarize_descriptions_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/summarize_descriptions_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7ebceecb98283cb8dcb73787a31e0bd291b8862 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/summarize_descriptions_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/text_embedding_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/text_embedding_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..89ded711a6a82926d43a18f97bbc43798d944c73 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/text_embedding_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/__pycache__/umap_config_input.cpython-311.pyc b/graphrag/graphrag/config/input_models/__pycache__/umap_config_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..62bc91a8032e211fc2d2ee83f30f17ecd68b6ec2 Binary files /dev/null and b/graphrag/graphrag/config/input_models/__pycache__/umap_config_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/input_models/cache_config_input.py b/graphrag/graphrag/config/input_models/cache_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..fe88d35b44d4f3bc2667f9208c2b761987a55e86 --- /dev/null +++ b/graphrag/graphrag/config/input_models/cache_config_input.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired, TypedDict + +from graphrag.config.enums import CacheType + + +class CacheConfigInput(TypedDict): + """The default configuration section for Cache.""" + + type: NotRequired[CacheType | str | None] + base_dir: NotRequired[str | None] + connection_string: NotRequired[str | None] + container_name: NotRequired[str | None] + storage_account_blob_url: NotRequired[str | None] diff --git a/graphrag/graphrag/config/input_models/chunking_config_input.py b/graphrag/graphrag/config/input_models/chunking_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..bbf4fc735f57f01250919967c59765e0f3e5ad1d --- /dev/null +++ b/graphrag/graphrag/config/input_models/chunking_config_input.py @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired, TypedDict + + +class ChunkingConfigInput(TypedDict): + """Configuration section for chunking.""" + + size: NotRequired[int | str | None] + overlap: NotRequired[int | str | None] + group_by_columns: NotRequired[list[str] | str | None] + strategy: NotRequired[dict | None] diff --git a/graphrag/graphrag/config/input_models/claim_extraction_config_input.py b/graphrag/graphrag/config/input_models/claim_extraction_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..4827435cab3f194f82385b2df27cdd67d581e46e --- /dev/null +++ b/graphrag/graphrag/config/input_models/claim_extraction_config_input.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired + +from .llm_config_input import LLMConfigInput + + +class ClaimExtractionConfigInput(LLMConfigInput): + """Configuration section for claim extraction.""" + + enabled: NotRequired[bool | None] + prompt: NotRequired[str | None] + description: NotRequired[str | None] + max_gleanings: NotRequired[int | str | None] + strategy: NotRequired[dict | None] diff --git a/graphrag/graphrag/config/input_models/cluster_graph_config_input.py b/graphrag/graphrag/config/input_models/cluster_graph_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..eb6f9cd1c66c27197cd6b34b75b768690a38f9b8 --- /dev/null +++ b/graphrag/graphrag/config/input_models/cluster_graph_config_input.py @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired, TypedDict + + +class ClusterGraphConfigInput(TypedDict): + """Configuration section for clustering graphs.""" + + max_cluster_size: NotRequired[int | None] + strategy: NotRequired[dict | None] diff --git a/graphrag/graphrag/config/input_models/community_reports_config_input.py b/graphrag/graphrag/config/input_models/community_reports_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..79ae3152e7a55e073468ec6393cda5a32973f3c8 --- /dev/null +++ b/graphrag/graphrag/config/input_models/community_reports_config_input.py @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired + +from .llm_config_input import LLMConfigInput + + +class CommunityReportsConfigInput(LLMConfigInput): + """Configuration section for community reports.""" + + prompt: NotRequired[str | None] + max_length: NotRequired[int | str | None] + max_input_length: NotRequired[int | str | None] + strategy: NotRequired[dict | None] diff --git a/graphrag/graphrag/config/input_models/embed_graph_config_input.py b/graphrag/graphrag/config/input_models/embed_graph_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..f8b6ee6faf045a3124dd23dea5cda0733c4b2a84 --- /dev/null +++ b/graphrag/graphrag/config/input_models/embed_graph_config_input.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired, TypedDict + + +class EmbedGraphConfigInput(TypedDict): + """The default configuration section for Node2Vec.""" + + enabled: NotRequired[bool | str | None] + num_walks: NotRequired[int | str | None] + walk_length: NotRequired[int | str | None] + window_size: NotRequired[int | str | None] + iterations: NotRequired[int | str | None] + random_seed: NotRequired[int | str | None] + strategy: NotRequired[dict | None] diff --git a/graphrag/graphrag/config/input_models/entity_extraction_config_input.py b/graphrag/graphrag/config/input_models/entity_extraction_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..a03cbfee1bcb8317f664db851bf82d4f4b2cb8c1 --- /dev/null +++ b/graphrag/graphrag/config/input_models/entity_extraction_config_input.py @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired + +from .llm_config_input import LLMConfigInput + + +class EntityExtractionConfigInput(LLMConfigInput): + """Configuration section for entity extraction.""" + + prompt: NotRequired[str | None] + entity_types: NotRequired[list[str] | str | None] + max_gleanings: NotRequired[int | str | None] + strategy: NotRequired[dict | None] diff --git a/graphrag/graphrag/config/input_models/global_search_config_input.py b/graphrag/graphrag/config/input_models/global_search_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..e13fbbfa9e734494527d468e8f098e7b9f0ba86d --- /dev/null +++ b/graphrag/graphrag/config/input_models/global_search_config_input.py @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired, TypedDict + + +class GlobalSearchConfigInput(TypedDict): + """The default configuration section for Cache.""" + + max_tokens: NotRequired[int | str | None] + data_max_tokens: NotRequired[int | str | None] + map_max_tokens: NotRequired[int | str | None] + reduce_max_tokens: NotRequired[int | str | None] + concurrency: NotRequired[int | str | None] diff --git a/graphrag/graphrag/config/input_models/graphrag_config_input.py b/graphrag/graphrag/config/input_models/graphrag_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..7c04dea2e3949d225db9f76f3c144735b4bd98a5 --- /dev/null +++ b/graphrag/graphrag/config/input_models/graphrag_config_input.py @@ -0,0 +1,49 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired + +from .cache_config_input import CacheConfigInput +from .chunking_config_input import ChunkingConfigInput +from .claim_extraction_config_input import ClaimExtractionConfigInput +from .cluster_graph_config_input import ClusterGraphConfigInput +from .community_reports_config_input import CommunityReportsConfigInput +from .embed_graph_config_input import EmbedGraphConfigInput +from .entity_extraction_config_input import EntityExtractionConfigInput +from .global_search_config_input import GlobalSearchConfigInput +from .input_config_input import InputConfigInput +from .llm_config_input import LLMConfigInput +from .local_search_config_input import LocalSearchConfigInput +from .reporting_config_input import ReportingConfigInput +from .snapshots_config_input import SnapshotsConfigInput +from .storage_config_input import StorageConfigInput +from .summarize_descriptions_config_input import ( + SummarizeDescriptionsConfigInput, +) +from .text_embedding_config_input import TextEmbeddingConfigInput +from .umap_config_input import UmapConfigInput + + +class GraphRagConfigInput(LLMConfigInput): + """Base class for the Default-Configuration parameterization settings.""" + + reporting: NotRequired[ReportingConfigInput | None] + storage: NotRequired[StorageConfigInput | None] + cache: NotRequired[CacheConfigInput | None] + input: NotRequired[InputConfigInput | None] + embed_graph: NotRequired[EmbedGraphConfigInput | None] + embeddings: NotRequired[TextEmbeddingConfigInput | None] + chunks: NotRequired[ChunkingConfigInput | None] + snapshots: NotRequired[SnapshotsConfigInput | None] + entity_extraction: NotRequired[EntityExtractionConfigInput | None] + summarize_descriptions: NotRequired[SummarizeDescriptionsConfigInput | None] + community_reports: NotRequired[CommunityReportsConfigInput | None] + claim_extraction: NotRequired[ClaimExtractionConfigInput | None] + cluster_graph: NotRequired[ClusterGraphConfigInput | None] + umap: NotRequired[UmapConfigInput | None] + encoding_model: NotRequired[str | None] + skip_workflows: NotRequired[list[str] | str | None] + local_search: NotRequired[LocalSearchConfigInput | None] + global_search: NotRequired[GlobalSearchConfigInput | None] diff --git a/graphrag/graphrag/config/input_models/input_config_input.py b/graphrag/graphrag/config/input_models/input_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..4ff89d2c9ae122739521e72ec19b413cef2688e0 --- /dev/null +++ b/graphrag/graphrag/config/input_models/input_config_input.py @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired, TypedDict + +from graphrag.config.enums import InputFileType, InputType + + +class InputConfigInput(TypedDict): + """The default configuration section for Input.""" + + type: NotRequired[InputType | str | None] + file_type: NotRequired[InputFileType | str | None] + base_dir: NotRequired[str | None] + connection_string: NotRequired[str | None] + container_name: NotRequired[str | None] + file_encoding: NotRequired[str | None] + file_pattern: NotRequired[str | None] + source_column: NotRequired[str | None] + timestamp_column: NotRequired[str | None] + timestamp_format: NotRequired[str | None] + text_column: NotRequired[str | None] + title_column: NotRequired[str | None] + document_attribute_columns: NotRequired[list[str] | str | None] + storage_account_blob_url: NotRequired[str | None] diff --git a/graphrag/graphrag/config/input_models/llm_config_input.py b/graphrag/graphrag/config/input_models/llm_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..67231371b8a369a39ef1a418fafc5f267b15f3bd --- /dev/null +++ b/graphrag/graphrag/config/input_models/llm_config_input.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from datashaper import AsyncType +from typing_extensions import NotRequired, TypedDict + +from .llm_parameters_input import LLMParametersInput +from .parallelization_parameters_input import ParallelizationParametersInput + + +class LLMConfigInput(TypedDict): + """Base class for LLM-configured steps.""" + + llm: NotRequired[LLMParametersInput | None] + parallelization: NotRequired[ParallelizationParametersInput | None] + async_mode: NotRequired[AsyncType | str | None] diff --git a/graphrag/graphrag/config/input_models/llm_parameters_input.py b/graphrag/graphrag/config/input_models/llm_parameters_input.py new file mode 100644 index 0000000000000000000000000000000000000000..c89c6c0922e802453c76857efbe708ac8abcfff8 --- /dev/null +++ b/graphrag/graphrag/config/input_models/llm_parameters_input.py @@ -0,0 +1,31 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""LLM Parameters model.""" + +from typing_extensions import NotRequired, TypedDict + +from graphrag.config.enums import LLMType + + +class LLMParametersInput(TypedDict): + """LLM Parameters model.""" + + api_key: NotRequired[str | None] + type: NotRequired[LLMType | str | None] + model: NotRequired[str | None] + max_tokens: NotRequired[int | str | None] + request_timeout: NotRequired[float | str | None] + api_base: NotRequired[str | None] + api_version: NotRequired[str | None] + organization: NotRequired[str | None] + proxy: NotRequired[str | None] + cognitive_services_endpoint: NotRequired[str | None] + deployment_name: NotRequired[str | None] + model_supports_json: NotRequired[bool | str | None] + tokens_per_minute: NotRequired[int | str | None] + requests_per_minute: NotRequired[int | str | None] + max_retries: NotRequired[int | str | None] + max_retry_wait: NotRequired[float | str | None] + sleep_on_rate_limit_recommendation: NotRequired[bool | str | None] + concurrent_requests: NotRequired[int | str | None] diff --git a/graphrag/graphrag/config/input_models/local_search_config_input.py b/graphrag/graphrag/config/input_models/local_search_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..23df40102a895399cc6b9facf276b597bd8bcde7 --- /dev/null +++ b/graphrag/graphrag/config/input_models/local_search_config_input.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired, TypedDict + + +class LocalSearchConfigInput(TypedDict): + """The default configuration section for Cache.""" + + text_unit_prop: NotRequired[float | str | None] + community_prop: NotRequired[float | str | None] + conversation_history_max_turns: NotRequired[int | str | None] + top_k_entities: NotRequired[int | str | None] + top_k_relationships: NotRequired[int | str | None] + max_tokens: NotRequired[int | str | None] + llm_max_tokens: NotRequired[int | str | None] diff --git a/graphrag/graphrag/config/input_models/parallelization_parameters_input.py b/graphrag/graphrag/config/input_models/parallelization_parameters_input.py new file mode 100644 index 0000000000000000000000000000000000000000..e9204437b2ee837a73c7618ea3978de145b0b633 --- /dev/null +++ b/graphrag/graphrag/config/input_models/parallelization_parameters_input.py @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""LLM Parameters model.""" + +from typing_extensions import NotRequired, TypedDict + + +class ParallelizationParametersInput(TypedDict): + """LLM Parameters model.""" + + stagger: NotRequired[float | str | None] + num_threads: NotRequired[int | str | None] diff --git a/graphrag/graphrag/config/input_models/reporting_config_input.py b/graphrag/graphrag/config/input_models/reporting_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..a224f0b4404c4375b6335c4d4cfb717f6e37f2ec --- /dev/null +++ b/graphrag/graphrag/config/input_models/reporting_config_input.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired, TypedDict + +from graphrag.config.enums import ReportingType + + +class ReportingConfigInput(TypedDict): + """The default configuration section for Reporting.""" + + type: NotRequired[ReportingType | str | None] + base_dir: NotRequired[str | None] + connection_string: NotRequired[str | None] + container_name: NotRequired[str | None] + storage_account_blob_url: NotRequired[str | None] diff --git a/graphrag/graphrag/config/input_models/snapshots_config_input.py b/graphrag/graphrag/config/input_models/snapshots_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..c20becb0716345ecdf334001c064320b2286bcd4 --- /dev/null +++ b/graphrag/graphrag/config/input_models/snapshots_config_input.py @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired, TypedDict + + +class SnapshotsConfigInput(TypedDict): + """Configuration section for snapshots.""" + + graphml: NotRequired[bool | str | None] + raw_entities: NotRequired[bool | str | None] + top_level_nodes: NotRequired[bool | str | None] diff --git a/graphrag/graphrag/config/input_models/storage_config_input.py b/graphrag/graphrag/config/input_models/storage_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..cc5caf79521e896a282b8ed0a47d06e45a1c4b7e --- /dev/null +++ b/graphrag/graphrag/config/input_models/storage_config_input.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired, TypedDict + +from graphrag.config.enums import StorageType + + +class StorageConfigInput(TypedDict): + """The default configuration section for Storage.""" + + type: NotRequired[StorageType | str | None] + base_dir: NotRequired[str | None] + connection_string: NotRequired[str | None] + container_name: NotRequired[str | None] + storage_account_blob_url: NotRequired[str | None] diff --git a/graphrag/graphrag/config/input_models/summarize_descriptions_config_input.py b/graphrag/graphrag/config/input_models/summarize_descriptions_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..6ce756e5581d95ef05c62c8c698cdbd3a390d14c --- /dev/null +++ b/graphrag/graphrag/config/input_models/summarize_descriptions_config_input.py @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired + +from .llm_config_input import LLMConfigInput + + +class SummarizeDescriptionsConfigInput(LLMConfigInput): + """Configuration section for description summarization.""" + + prompt: NotRequired[str | None] + max_length: NotRequired[int | str | None] + strategy: NotRequired[dict | None] diff --git a/graphrag/graphrag/config/input_models/text_embedding_config_input.py b/graphrag/graphrag/config/input_models/text_embedding_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..a7e176c65813be1eb703bb829015146a5e36af64 --- /dev/null +++ b/graphrag/graphrag/config/input_models/text_embedding_config_input.py @@ -0,0 +1,23 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired + +from graphrag.config.enums import ( + TextEmbeddingTarget, +) + +from .llm_config_input import LLMConfigInput + + +class TextEmbeddingConfigInput(LLMConfigInput): + """Configuration section for text embeddings.""" + + batch_size: NotRequired[int | str | None] + batch_max_tokens: NotRequired[int | str | None] + target: NotRequired[TextEmbeddingTarget | str | None] + skip: NotRequired[list[str] | str | None] + vector_store: NotRequired[dict | None] + strategy: NotRequired[dict | None] diff --git a/graphrag/graphrag/config/input_models/umap_config_input.py b/graphrag/graphrag/config/input_models/umap_config_input.py new file mode 100644 index 0000000000000000000000000000000000000000..543ca385e0470d104038fbca91ebeba4f36e6753 --- /dev/null +++ b/graphrag/graphrag/config/input_models/umap_config_input.py @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from typing_extensions import NotRequired, TypedDict + + +class UmapConfigInput(TypedDict): + """Configuration section for UMAP.""" + + enabled: NotRequired[bool | str | None] diff --git a/graphrag/graphrag/config/models/__init__.py b/graphrag/graphrag/config/models/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..43c4cde506305dae7068bb0267dd69436e3b571e --- /dev/null +++ b/graphrag/graphrag/config/models/__init__.py @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Interfaces for Default Config parameterization.""" + +from .cache_config import CacheConfig +from .chunking_config import ChunkingConfig +from .claim_extraction_config import ClaimExtractionConfig +from .cluster_graph_config import ClusterGraphConfig +from .community_reports_config import CommunityReportsConfig +from .embed_graph_config import EmbedGraphConfig +from .entity_extraction_config import EntityExtractionConfig +from .global_search_config import GlobalSearchConfig +from .graph_rag_config import GraphRagConfig +from .input_config import InputConfig +from .llm_config import LLMConfig +from .llm_parameters import LLMParameters +from .local_search_config import LocalSearchConfig +from .parallelization_parameters import ParallelizationParameters +from .reporting_config import ReportingConfig +from .snapshots_config import SnapshotsConfig +from .storage_config import StorageConfig +from .summarize_descriptions_config import SummarizeDescriptionsConfig +from .text_embedding_config import TextEmbeddingConfig +from .umap_config import UmapConfig + +__all__ = [ + "CacheConfig", + "ChunkingConfig", + "ClaimExtractionConfig", + "ClusterGraphConfig", + "CommunityReportsConfig", + "EmbedGraphConfig", + "EntityExtractionConfig", + "GlobalSearchConfig", + "GraphRagConfig", + "InputConfig", + "LLMConfig", + "LLMParameters", + "LocalSearchConfig", + "ParallelizationParameters", + "ReportingConfig", + "SnapshotsConfig", + "StorageConfig", + "SummarizeDescriptionsConfig", + "TextEmbeddingConfig", + "UmapConfig", +] diff --git a/graphrag/graphrag/config/models/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3448a6fd09cdc1171de560bf0346aa822fce145b Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/cache_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/cache_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9716663071abf3db9074fdc16362ee29b444a4ee Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/cache_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/chunking_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/chunking_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a4346254742e32b2057354ec59e39c38f6ff15d5 Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/chunking_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/claim_extraction_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/claim_extraction_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6027987e19d8a2da89f91068ed64e06e99ee7ce Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/claim_extraction_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/cluster_graph_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/cluster_graph_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad057a70d8fe5827c03b051e64d38ee387ebf180 Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/cluster_graph_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/community_reports_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/community_reports_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a6c1067280de275017136c04af6088182123ab70 Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/community_reports_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/embed_graph_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/embed_graph_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4dc5dfff9e69a70340f9da914c9ae5edb65f6c6d Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/embed_graph_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/entity_extraction_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/entity_extraction_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bbfc7204c6751efc59a92f79bdecfbcb4d2604f0 Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/entity_extraction_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/global_search_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/global_search_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e26442c75c290bab4b0a678846e3ddbd9a25c68 Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/global_search_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/graph_rag_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/graph_rag_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..91ebb1800d8a79666b0775ed7ad7a192326a87e8 Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/graph_rag_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/input_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/input_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b38edfa0d5a783d40a2a75a476bcd7a264e4cc1 Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/input_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/llm_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/llm_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b377c2ac42f0c9829ab6f63d99a0900e5972eafa Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/llm_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/llm_parameters.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/llm_parameters.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2744183d4ee4b7357245473446b714a1fe2be233 Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/llm_parameters.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/local_search_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/local_search_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c241c6406362696b376e9170972b8ba7ebd58d8a Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/local_search_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/parallelization_parameters.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/parallelization_parameters.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c851833f2b268fb7188c5cf1f2085f2801d7a51c Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/parallelization_parameters.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/reporting_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/reporting_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..921c8e977ad46ae47c5593968b2d726bae8c2c6f Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/reporting_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/snapshots_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/snapshots_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e9a3608a2bcfcde0596555d23e2f00058cc8ad7 Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/snapshots_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/storage_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/storage_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d93a37082e183ea8cb503175de4ce910eed696bf Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/storage_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/summarize_descriptions_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/summarize_descriptions_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fdbe127431c0ad2cc94d9e49f27a484bae082ac5 Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/summarize_descriptions_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/text_embedding_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/text_embedding_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70027d176c6bcfd93587f64b78deb35286e37692 Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/text_embedding_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/__pycache__/umap_config.cpython-311.pyc b/graphrag/graphrag/config/models/__pycache__/umap_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e3f01bc68d46d619ec0d330a1c6e439b52521c41 Binary files /dev/null and b/graphrag/graphrag/config/models/__pycache__/umap_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/config/models/cache_config.py b/graphrag/graphrag/config/models/cache_config.py new file mode 100644 index 0000000000000000000000000000000000000000..4589edce0b31f34c5dd8312b0fd713f8a236222a --- /dev/null +++ b/graphrag/graphrag/config/models/cache_config.py @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pydantic import BaseModel, Field + +import graphrag.config.defaults as defs +from graphrag.config.enums import CacheType + + +class CacheConfig(BaseModel): + """The default configuration section for Cache.""" + + type: CacheType = Field( + description="The cache type to use.", default=defs.CACHE_TYPE + ) + base_dir: str = Field( + description="The base directory for the cache.", default=defs.CACHE_BASE_DIR + ) + connection_string: str | None = Field( + description="The cache connection string to use.", default=None + ) + container_name: str | None = Field( + description="The cache container name to use.", default=None + ) + storage_account_blob_url: str | None = Field( + description="The storage account blob url to use.", default=None + ) diff --git a/graphrag/graphrag/config/models/chunking_config.py b/graphrag/graphrag/config/models/chunking_config.py new file mode 100644 index 0000000000000000000000000000000000000000..ad7e3d0a9d29be588339b71f227551d9a8872327 --- /dev/null +++ b/graphrag/graphrag/config/models/chunking_config.py @@ -0,0 +1,36 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pydantic import BaseModel, Field + +import graphrag.config.defaults as defs + + +class ChunkingConfig(BaseModel): + """Configuration section for chunking.""" + + size: int = Field(description="The chunk size to use.", default=defs.CHUNK_SIZE) + overlap: int = Field( + description="The chunk overlap to use.", default=defs.CHUNK_OVERLAP + ) + group_by_columns: list[str] = Field( + description="The chunk by columns to use.", + default=defs.CHUNK_GROUP_BY_COLUMNS, + ) + strategy: dict | None = Field( + description="The chunk strategy to use, overriding the default tokenization strategy", + default=None, + ) + + def resolved_strategy(self) -> dict: + """Get the resolved chunking strategy.""" + from graphrag.index.verbs.text.chunk import ChunkStrategyType + + return self.strategy or { + "type": ChunkStrategyType.tokens, + "chunk_size": self.size, + "chunk_overlap": self.overlap, + "group_by_columns": self.group_by_columns, + } diff --git a/graphrag/graphrag/config/models/claim_extraction_config.py b/graphrag/graphrag/config/models/claim_extraction_config.py new file mode 100644 index 0000000000000000000000000000000000000000..7ec465d9aea06588cc29e6cee363e40ff1eb8672 --- /dev/null +++ b/graphrag/graphrag/config/models/claim_extraction_config.py @@ -0,0 +1,51 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pathlib import Path + +from pydantic import Field + +import graphrag.config.defaults as defs + +from .llm_config import LLMConfig + + +class ClaimExtractionConfig(LLMConfig): + """Configuration section for claim extraction.""" + + enabled: bool = Field( + description="Whether claim extraction is enabled.", + ) + prompt: str | None = Field( + description="The claim extraction prompt to use.", default=None + ) + description: str = Field( + description="The claim description to use.", + default=defs.CLAIM_DESCRIPTION, + ) + max_gleanings: int = Field( + description="The maximum number of entity gleanings to use.", + default=defs.CLAIM_MAX_GLEANINGS, + ) + strategy: dict | None = Field( + description="The override strategy to use.", default=None + ) + + def resolved_strategy(self, root_dir: str) -> dict: + """Get the resolved claim extraction strategy.""" + from graphrag.index.verbs.covariates.extract_covariates import ( + ExtractClaimsStrategyType, + ) + + return self.strategy or { + "type": ExtractClaimsStrategyType.graph_intelligence, + "llm": self.llm.model_dump(), + **self.parallelization.model_dump(), + "extraction_prompt": (Path(root_dir) / self.prompt).read_text() + if self.prompt + else None, + "claim_description": self.description, + "max_gleanings": self.max_gleanings, + } diff --git a/graphrag/graphrag/config/models/cluster_graph_config.py b/graphrag/graphrag/config/models/cluster_graph_config.py new file mode 100644 index 0000000000000000000000000000000000000000..3029baebcb8ad988b6eadcbc3098f34c52b87f46 --- /dev/null +++ b/graphrag/graphrag/config/models/cluster_graph_config.py @@ -0,0 +1,28 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pydantic import BaseModel, Field + +import graphrag.config.defaults as defs + + +class ClusterGraphConfig(BaseModel): + """Configuration section for clustering graphs.""" + + max_cluster_size: int = Field( + description="The maximum cluster size to use.", default=defs.MAX_CLUSTER_SIZE + ) + strategy: dict | None = Field( + description="The cluster strategy to use.", default=None + ) + + def resolved_strategy(self) -> dict: + """Get the resolved cluster strategy.""" + from graphrag.index.verbs.graph.clustering import GraphCommunityStrategyType + + return self.strategy or { + "type": GraphCommunityStrategyType.leiden, + "max_cluster_size": self.max_cluster_size, + } diff --git a/graphrag/graphrag/config/models/community_reports_config.py b/graphrag/graphrag/config/models/community_reports_config.py new file mode 100644 index 0000000000000000000000000000000000000000..cc2c9e8f13fd8577c54b9ae34e0828bf7f976639 --- /dev/null +++ b/graphrag/graphrag/config/models/community_reports_config.py @@ -0,0 +1,46 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pathlib import Path + +from pydantic import Field + +import graphrag.config.defaults as defs + +from .llm_config import LLMConfig + + +class CommunityReportsConfig(LLMConfig): + """Configuration section for community reports.""" + + prompt: str | None = Field( + description="The community report extraction prompt to use.", default=None + ) + max_length: int = Field( + description="The community report maximum length in tokens.", + default=defs.COMMUNITY_REPORT_MAX_LENGTH, + ) + max_input_length: int = Field( + description="The maximum input length in tokens to use when generating reports.", + default=defs.COMMUNITY_REPORT_MAX_INPUT_LENGTH, + ) + strategy: dict | None = Field( + description="The override strategy to use.", default=None + ) + + def resolved_strategy(self, root_dir) -> dict: + """Get the resolved community report extraction strategy.""" + from graphrag.index.verbs.graph.report import CreateCommunityReportsStrategyType + + return self.strategy or { + "type": CreateCommunityReportsStrategyType.graph_intelligence, + "llm": self.llm.model_dump(), + **self.parallelization.model_dump(), + "extraction_prompt": (Path(root_dir) / self.prompt).read_text() + if self.prompt + else None, + "max_report_length": self.max_length, + "max_input_length": self.max_input_length, + } diff --git a/graphrag/graphrag/config/models/embed_graph_config.py b/graphrag/graphrag/config/models/embed_graph_config.py new file mode 100644 index 0000000000000000000000000000000000000000..8b7677ab10120e314176789a39d94338457164d4 --- /dev/null +++ b/graphrag/graphrag/config/models/embed_graph_config.py @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pydantic import BaseModel, Field + +import graphrag.config.defaults as defs + + +class EmbedGraphConfig(BaseModel): + """The default configuration section for Node2Vec.""" + + enabled: bool = Field( + description="A flag indicating whether to enable node2vec.", + default=defs.NODE2VEC_ENABLED, + ) + num_walks: int = Field( + description="The node2vec number of walks.", default=defs.NODE2VEC_NUM_WALKS + ) + walk_length: int = Field( + description="The node2vec walk length.", default=defs.NODE2VEC_WALK_LENGTH + ) + window_size: int = Field( + description="The node2vec window size.", default=defs.NODE2VEC_WINDOW_SIZE + ) + iterations: int = Field( + description="The node2vec iterations.", default=defs.NODE2VEC_ITERATIONS + ) + random_seed: int = Field( + description="The node2vec random seed.", default=defs.NODE2VEC_RANDOM_SEED + ) + strategy: dict | None = Field( + description="The graph embedding strategy override.", default=None + ) + + def resolved_strategy(self) -> dict: + """Get the resolved node2vec strategy.""" + from graphrag.index.verbs.graph.embed import EmbedGraphStrategyType + + return self.strategy or { + "type": EmbedGraphStrategyType.node2vec, + "num_walks": self.num_walks, + "walk_length": self.walk_length, + "window_size": self.window_size, + "iterations": self.iterations, + "random_seed": self.iterations, + } diff --git a/graphrag/graphrag/config/models/entity_extraction_config.py b/graphrag/graphrag/config/models/entity_extraction_config.py new file mode 100644 index 0000000000000000000000000000000000000000..ae4d4c56110848c12007e6f77d613ba186e38233 --- /dev/null +++ b/graphrag/graphrag/config/models/entity_extraction_config.py @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pathlib import Path + +from pydantic import Field + +import graphrag.config.defaults as defs + +from .llm_config import LLMConfig + + +class EntityExtractionConfig(LLMConfig): + """Configuration section for entity extraction.""" + + prompt: str | None = Field( + description="The entity extraction prompt to use.", default=None + ) + entity_types: list[str] = Field( + description="The entity extraction entity types to use.", + default=defs.ENTITY_EXTRACTION_ENTITY_TYPES, + ) + max_gleanings: int = Field( + description="The maximum number of entity gleanings to use.", + default=defs.ENTITY_EXTRACTION_MAX_GLEANINGS, + ) + strategy: dict | None = Field( + description="Override the default entity extraction strategy", default=None + ) + + def resolved_strategy(self, root_dir: str, encoding_model: str) -> dict: + """Get the resolved entity extraction strategy.""" + from graphrag.index.verbs.entities.extraction import ExtractEntityStrategyType + + return self.strategy or { + "type": ExtractEntityStrategyType.graph_intelligence, + "llm": self.llm.model_dump(), + **self.parallelization.model_dump(), + "extraction_prompt": (Path(root_dir) / self.prompt).read_text() + if self.prompt + else None, + "max_gleanings": self.max_gleanings, + # It's prechunked in create_base_text_units + "encoding_name": encoding_model, + "prechunked": True, + } diff --git a/graphrag/graphrag/config/models/global_search_config.py b/graphrag/graphrag/config/models/global_search_config.py new file mode 100644 index 0000000000000000000000000000000000000000..9eb388c37369726340fd1890e16d780e62bfb150 --- /dev/null +++ b/graphrag/graphrag/config/models/global_search_config.py @@ -0,0 +1,45 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pydantic import BaseModel, Field + +import graphrag.config.defaults as defs + + +class GlobalSearchConfig(BaseModel): + """The default configuration section for Cache.""" + + temperature: float | None = Field( + description="The temperature to use for token generation.", + default=defs.GLOBAL_SEARCH_LLM_TEMPERATURE, + ) + top_p: float | None = Field( + description="The top-p value to use for token generation.", + default=defs.GLOBAL_SEARCH_LLM_TOP_P, + ) + n: int | None = Field( + description="The number of completions to generate.", + default=defs.GLOBAL_SEARCH_LLM_N, + ) + max_tokens: int = Field( + description="The maximum context size in tokens.", + default=defs.GLOBAL_SEARCH_MAX_TOKENS, + ) + data_max_tokens: int = Field( + description="The data llm maximum tokens.", + default=defs.GLOBAL_SEARCH_DATA_MAX_TOKENS, + ) + map_max_tokens: int = Field( + description="The map llm maximum tokens.", + default=defs.GLOBAL_SEARCH_MAP_MAX_TOKENS, + ) + reduce_max_tokens: int = Field( + description="The reduce llm maximum tokens.", + default=defs.GLOBAL_SEARCH_REDUCE_MAX_TOKENS, + ) + concurrency: int = Field( + description="The number of concurrent requests.", + default=defs.GLOBAL_SEARCH_CONCURRENCY, + ) diff --git a/graphrag/graphrag/config/models/graph_rag_config.py b/graphrag/graphrag/config/models/graph_rag_config.py new file mode 100644 index 0000000000000000000000000000000000000000..197d85e3e986e9e52186201b4ec366af3cbb4c10 --- /dev/null +++ b/graphrag/graphrag/config/models/graph_rag_config.py @@ -0,0 +1,146 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from devtools import pformat +from pydantic import Field + +import graphrag.config.defaults as defs + +from .cache_config import CacheConfig +from .chunking_config import ChunkingConfig +from .claim_extraction_config import ClaimExtractionConfig +from .cluster_graph_config import ClusterGraphConfig +from .community_reports_config import CommunityReportsConfig +from .embed_graph_config import EmbedGraphConfig +from .entity_extraction_config import EntityExtractionConfig +from .global_search_config import GlobalSearchConfig +from .input_config import InputConfig +from .llm_config import LLMConfig +from .local_search_config import LocalSearchConfig +from .reporting_config import ReportingConfig +from .snapshots_config import SnapshotsConfig +from .storage_config import StorageConfig +from .summarize_descriptions_config import ( + SummarizeDescriptionsConfig, +) +from .text_embedding_config import TextEmbeddingConfig +from .umap_config import UmapConfig + + +class GraphRagConfig(LLMConfig): + """Base class for the Default-Configuration parameterization settings.""" + + def __repr__(self) -> str: + """Get a string representation.""" + return pformat(self, highlight=False) + + def __str__(self): + """Get a string representation.""" + return self.model_dump_json(indent=4) + + root_dir: str = Field( + description="The root directory for the configuration.", default=None + ) + + reporting: ReportingConfig = Field( + description="The reporting configuration.", default=ReportingConfig() + ) + """The reporting configuration.""" + + storage: StorageConfig = Field( + description="The storage configuration.", default=StorageConfig() + ) + """The storage configuration.""" + + cache: CacheConfig = Field( + description="The cache configuration.", default=CacheConfig() + ) + """The cache configuration.""" + + input: InputConfig = Field( + description="The input configuration.", default=InputConfig() + ) + """The input configuration.""" + + embed_graph: EmbedGraphConfig = Field( + description="Graph embedding configuration.", + default=EmbedGraphConfig(), + ) + """Graph Embedding configuration.""" + + embeddings: TextEmbeddingConfig = Field( + description="The embeddings LLM configuration to use.", + default=TextEmbeddingConfig(), + ) + """The embeddings LLM configuration to use.""" + + chunks: ChunkingConfig = Field( + description="The chunking configuration to use.", + default=ChunkingConfig(), + ) + """The chunking configuration to use.""" + + snapshots: SnapshotsConfig = Field( + description="The snapshots configuration to use.", + default=SnapshotsConfig(), + ) + """The snapshots configuration to use.""" + + entity_extraction: EntityExtractionConfig = Field( + description="The entity extraction configuration to use.", + default=EntityExtractionConfig(), + ) + """The entity extraction configuration to use.""" + + summarize_descriptions: SummarizeDescriptionsConfig = Field( + description="The description summarization configuration to use.", + default=SummarizeDescriptionsConfig(), + ) + """The description summarization configuration to use.""" + + community_reports: CommunityReportsConfig = Field( + description="The community reports configuration to use.", + default=CommunityReportsConfig(), + ) + """The community reports configuration to use.""" + + claim_extraction: ClaimExtractionConfig = Field( + description="The claim extraction configuration to use.", + default=ClaimExtractionConfig( + enabled=defs.CLAIM_EXTRACTION_ENABLED, + ), + ) + """The claim extraction configuration to use.""" + + cluster_graph: ClusterGraphConfig = Field( + description="The cluster graph configuration to use.", + default=ClusterGraphConfig(), + ) + """The cluster graph configuration to use.""" + + umap: UmapConfig = Field( + description="The UMAP configuration to use.", default=UmapConfig() + ) + """The UMAP configuration to use.""" + + local_search: LocalSearchConfig = Field( + description="The local search configuration.", default=LocalSearchConfig() + ) + """The local search configuration.""" + + global_search: GlobalSearchConfig = Field( + description="The global search configuration.", default=GlobalSearchConfig() + ) + """The global search configuration.""" + + encoding_model: str = Field( + description="The encoding model to use.", default=defs.ENCODING_MODEL + ) + """The encoding model to use.""" + + skip_workflows: list[str] = Field( + description="The workflows to skip, usually for testing reasons.", default=[] + ) + """The workflows to skip, usually for testing reasons.""" diff --git a/graphrag/graphrag/config/models/input_config.py b/graphrag/graphrag/config/models/input_config.py new file mode 100644 index 0000000000000000000000000000000000000000..f9e5847af61000c3bf140e488c131825e5ddc3c0 --- /dev/null +++ b/graphrag/graphrag/config/models/input_config.py @@ -0,0 +1,60 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pydantic import BaseModel, Field + +import graphrag.config.defaults as defs +from graphrag.config.enums import InputFileType, InputType + + +class InputConfig(BaseModel): + """The default configuration section for Input.""" + + type: InputType = Field( + description="The input type to use.", default=defs.INPUT_TYPE + ) + file_type: InputFileType = Field( + description="The input file type to use.", default=defs.INPUT_FILE_TYPE + ) + base_dir: str = Field( + description="The input base directory to use.", default=defs.INPUT_BASE_DIR + ) + connection_string: str | None = Field( + description="The azure blob storage connection string to use.", default=None + ) + storage_account_blob_url: str | None = Field( + description="The storage account blob url to use.", default=None + ) + container_name: str | None = Field( + description="The azure blob storage container name to use.", default=None + ) + encoding: str | None = Field( + description="The input file encoding to use.", + default=defs.INPUT_FILE_ENCODING, + ) + file_pattern: str = Field( + description="The input file pattern to use.", default=defs.INPUT_TEXT_PATTERN + ) + file_filter: dict[str, str] | None = Field( + description="The optional file filter for the input files.", default=None + ) + source_column: str | None = Field( + description="The input source column to use.", default=None + ) + timestamp_column: str | None = Field( + description="The input timestamp column to use.", default=None + ) + timestamp_format: str | None = Field( + description="The input timestamp format to use.", default=None + ) + text_column: str = Field( + description="The input text column to use.", default=defs.INPUT_TEXT_COLUMN + ) + title_column: str | None = Field( + description="The input title column to use.", default=None + ) + document_attribute_columns: list[str] = Field( + description="The document attribute columns to use.", default=[] + ) diff --git a/graphrag/graphrag/config/models/llm_config.py b/graphrag/graphrag/config/models/llm_config.py new file mode 100644 index 0000000000000000000000000000000000000000..62c193b0c5402315979ba1d7869bfed5a0e14164 --- /dev/null +++ b/graphrag/graphrag/config/models/llm_config.py @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from datashaper import AsyncType +from pydantic import BaseModel, Field + +import graphrag.config.defaults as defs + +from .llm_parameters import LLMParameters +from .parallelization_parameters import ParallelizationParameters + + +class LLMConfig(BaseModel): + """Base class for LLM-configured steps.""" + + llm: LLMParameters = Field( + description="The LLM configuration to use.", default=LLMParameters() + ) + parallelization: ParallelizationParameters = Field( + description="The parallelization configuration to use.", + default=ParallelizationParameters(), + ) + async_mode: AsyncType = Field( + description="The async mode to use.", default=defs.ASYNC_MODE + ) diff --git a/graphrag/graphrag/config/models/llm_parameters.py b/graphrag/graphrag/config/models/llm_parameters.py new file mode 100644 index 0000000000000000000000000000000000000000..df81138a2f860809ad60b7875e0b26e695caadd4 --- /dev/null +++ b/graphrag/graphrag/config/models/llm_parameters.py @@ -0,0 +1,87 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""LLM Parameters model.""" + +from pydantic import BaseModel, ConfigDict, Field + +import graphrag.config.defaults as defs +from graphrag.config.enums import LLMType + + +class LLMParameters(BaseModel): + """LLM Parameters model.""" + + model_config = ConfigDict(protected_namespaces=(), extra="allow") + api_key: str | None = Field( + description="The API key to use for the LLM service.", + default=None, + ) + type: LLMType = Field( + description="The type of LLM model to use.", default=defs.LLM_TYPE + ) + model: str = Field(description="The LLM model to use.", default=defs.LLM_MODEL) + max_tokens: int | None = Field( + description="The maximum number of tokens to generate.", + default=defs.LLM_MAX_TOKENS, + ) + temperature: float | None = Field( + description="The temperature to use for token generation.", + default=defs.LLM_TEMPERATURE, + ) + top_p: float | None = Field( + description="The top-p value to use for token generation.", + default=defs.LLM_TOP_P, + ) + n: int | None = Field( + description="The number of completions to generate.", + default=defs.LLM_N, + ) + request_timeout: float = Field( + description="The request timeout to use.", default=defs.LLM_REQUEST_TIMEOUT + ) + api_base: str | None = Field( + description="The base URL for the LLM API.", default=None + ) + api_version: str | None = Field( + description="The version of the LLM API to use.", default=None + ) + organization: str | None = Field( + description="The organization to use for the LLM service.", default=None + ) + proxy: str | None = Field( + description="The proxy to use for the LLM service.", default=None + ) + cognitive_services_endpoint: str | None = Field( + description="The endpoint to reach cognitives services.", default=None + ) + deployment_name: str | None = Field( + description="The deployment name to use for the LLM service.", default=None + ) + model_supports_json: bool | None = Field( + description="Whether the model supports JSON output mode.", default=None + ) + tokens_per_minute: int = Field( + description="The number of tokens per minute to use for the LLM service.", + default=defs.LLM_TOKENS_PER_MINUTE, + ) + requests_per_minute: int = Field( + description="The number of requests per minute to use for the LLM service.", + default=defs.LLM_REQUESTS_PER_MINUTE, + ) + max_retries: int = Field( + description="The maximum number of retries to use for the LLM service.", + default=defs.LLM_MAX_RETRIES, + ) + max_retry_wait: float = Field( + description="The maximum retry wait to use for the LLM service.", + default=defs.LLM_MAX_RETRY_WAIT, + ) + sleep_on_rate_limit_recommendation: bool = Field( + description="Whether to sleep on rate limit recommendations.", + default=defs.LLM_SLEEP_ON_RATE_LIMIT_RECOMMENDATION, + ) + concurrent_requests: int = Field( + description="Whether to use concurrent requests for the LLM service.", + default=defs.LLM_CONCURRENT_REQUESTS, + ) diff --git a/graphrag/graphrag/config/models/local_search_config.py b/graphrag/graphrag/config/models/local_search_config.py new file mode 100644 index 0000000000000000000000000000000000000000..c41344daefaa2c63e22b9c0d73f9fbb25a8ad86d --- /dev/null +++ b/graphrag/graphrag/config/models/local_search_config.py @@ -0,0 +1,51 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pydantic import BaseModel, Field + +import graphrag.config.defaults as defs + + +class LocalSearchConfig(BaseModel): + """The default configuration section for Cache.""" + + text_unit_prop: float = Field( + description="The text unit proportion.", + default=defs.LOCAL_SEARCH_TEXT_UNIT_PROP, + ) + community_prop: float = Field( + description="The community proportion.", + default=defs.LOCAL_SEARCH_COMMUNITY_PROP, + ) + conversation_history_max_turns: int = Field( + description="The conversation history maximum turns.", + default=defs.LOCAL_SEARCH_CONVERSATION_HISTORY_MAX_TURNS, + ) + top_k_entities: int = Field( + description="The top k mapped entities.", + default=defs.LOCAL_SEARCH_TOP_K_MAPPED_ENTITIES, + ) + top_k_relationships: int = Field( + description="The top k mapped relations.", + default=defs.LOCAL_SEARCH_TOP_K_RELATIONSHIPS, + ) + temperature: float | None = Field( + description="The temperature to use for token generation.", + default=defs.LOCAL_SEARCH_LLM_TEMPERATURE, + ) + top_p: float | None = Field( + description="The top-p value to use for token generation.", + default=defs.LOCAL_SEARCH_LLM_TOP_P, + ) + n: int | None = Field( + description="The number of completions to generate.", + default=defs.LOCAL_SEARCH_LLM_N, + ) + max_tokens: int = Field( + description="The maximum tokens.", default=defs.LOCAL_SEARCH_MAX_TOKENS + ) + llm_max_tokens: int = Field( + description="The LLM maximum tokens.", default=defs.LOCAL_SEARCH_LLM_MAX_TOKENS + ) diff --git a/graphrag/graphrag/config/models/parallelization_parameters.py b/graphrag/graphrag/config/models/parallelization_parameters.py new file mode 100644 index 0000000000000000000000000000000000000000..80a85b863965f15e398735775c1b483b32ba113f --- /dev/null +++ b/graphrag/graphrag/config/models/parallelization_parameters.py @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""LLM Parameters model.""" + +from pydantic import BaseModel, Field + +import graphrag.config.defaults as defs + + +class ParallelizationParameters(BaseModel): + """LLM Parameters model.""" + + stagger: float = Field( + description="The stagger to use for the LLM service.", + default=defs.PARALLELIZATION_STAGGER, + ) + num_threads: int = Field( + description="The number of threads to use for the LLM service.", + default=defs.PARALLELIZATION_NUM_THREADS, + ) diff --git a/graphrag/graphrag/config/models/reporting_config.py b/graphrag/graphrag/config/models/reporting_config.py new file mode 100644 index 0000000000000000000000000000000000000000..35e86cf5dae182c2231b43d889794c3fdc7d65f8 --- /dev/null +++ b/graphrag/graphrag/config/models/reporting_config.py @@ -0,0 +1,30 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pydantic import BaseModel, Field + +import graphrag.config.defaults as defs +from graphrag.config.enums import ReportingType + + +class ReportingConfig(BaseModel): + """The default configuration section for Reporting.""" + + type: ReportingType = Field( + description="The reporting type to use.", default=defs.REPORTING_TYPE + ) + base_dir: str = Field( + description="The base directory for reporting.", + default=defs.REPORTING_BASE_DIR, + ) + connection_string: str | None = Field( + description="The reporting connection string to use.", default=None + ) + container_name: str | None = Field( + description="The reporting container name to use.", default=None + ) + storage_account_blob_url: str | None = Field( + description="The storage account blob url to use.", default=None + ) diff --git a/graphrag/graphrag/config/models/snapshots_config.py b/graphrag/graphrag/config/models/snapshots_config.py new file mode 100644 index 0000000000000000000000000000000000000000..08293fb7a762d8d0a31b66b7d9129a79557fc26f --- /dev/null +++ b/graphrag/graphrag/config/models/snapshots_config.py @@ -0,0 +1,25 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pydantic import BaseModel, Field + +import graphrag.config.defaults as defs + + +class SnapshotsConfig(BaseModel): + """Configuration section for snapshots.""" + + graphml: bool = Field( + description="A flag indicating whether to take snapshots of GraphML.", + default=defs.SNAPSHOTS_GRAPHML, + ) + raw_entities: bool = Field( + description="A flag indicating whether to take snapshots of raw entities.", + default=defs.SNAPSHOTS_RAW_ENTITIES, + ) + top_level_nodes: bool = Field( + description="A flag indicating whether to take snapshots of top-level nodes.", + default=defs.SNAPSHOTS_TOP_LEVEL_NODES, + ) diff --git a/graphrag/graphrag/config/models/storage_config.py b/graphrag/graphrag/config/models/storage_config.py new file mode 100644 index 0000000000000000000000000000000000000000..dcf41b92223a23959def5e7d925bd88e30cc314e --- /dev/null +++ b/graphrag/graphrag/config/models/storage_config.py @@ -0,0 +1,30 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pydantic import BaseModel, Field + +import graphrag.config.defaults as defs +from graphrag.config.enums import StorageType + + +class StorageConfig(BaseModel): + """The default configuration section for Storage.""" + + type: StorageType = Field( + description="The storage type to use.", default=defs.STORAGE_TYPE + ) + base_dir: str = Field( + description="The base directory for the storage.", + default=defs.STORAGE_BASE_DIR, + ) + connection_string: str | None = Field( + description="The storage connection string to use.", default=None + ) + container_name: str | None = Field( + description="The storage container name to use.", default=None + ) + storage_account_blob_url: str | None = Field( + description="The storage account blob url to use.", default=None + ) diff --git a/graphrag/graphrag/config/models/summarize_descriptions_config.py b/graphrag/graphrag/config/models/summarize_descriptions_config.py new file mode 100644 index 0000000000000000000000000000000000000000..39aa93e218cb2aa5ade28f612e80c2df12668b9d --- /dev/null +++ b/graphrag/graphrag/config/models/summarize_descriptions_config.py @@ -0,0 +1,41 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pathlib import Path + +from pydantic import Field + +import graphrag.config.defaults as defs + +from .llm_config import LLMConfig + + +class SummarizeDescriptionsConfig(LLMConfig): + """Configuration section for description summarization.""" + + prompt: str | None = Field( + description="The description summarization prompt to use.", default=None + ) + max_length: int = Field( + description="The description summarization maximum length.", + default=defs.SUMMARIZE_DESCRIPTIONS_MAX_LENGTH, + ) + strategy: dict | None = Field( + description="The override strategy to use.", default=None + ) + + def resolved_strategy(self, root_dir: str) -> dict: + """Get the resolved description summarization strategy.""" + from graphrag.index.verbs.entities.summarize import SummarizeStrategyType + + return self.strategy or { + "type": SummarizeStrategyType.graph_intelligence, + "llm": self.llm.model_dump(), + **self.parallelization.model_dump(), + "summarize_prompt": (Path(root_dir) / self.prompt).read_text() + if self.prompt + else None, + "max_summary_length": self.max_length, + } diff --git a/graphrag/graphrag/config/models/text_embedding_config.py b/graphrag/graphrag/config/models/text_embedding_config.py new file mode 100644 index 0000000000000000000000000000000000000000..5c2fcdb86e6c7dcc250b49da0a077a976b1dae0e --- /dev/null +++ b/graphrag/graphrag/config/models/text_embedding_config.py @@ -0,0 +1,46 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pydantic import Field + +import graphrag.config.defaults as defs +from graphrag.config.enums import TextEmbeddingTarget + +from .llm_config import LLMConfig + + +class TextEmbeddingConfig(LLMConfig): + """Configuration section for text embeddings.""" + + batch_size: int = Field( + description="The batch size to use.", default=defs.EMBEDDING_BATCH_SIZE + ) + batch_max_tokens: int = Field( + description="The batch max tokens to use.", + default=defs.EMBEDDING_BATCH_MAX_TOKENS, + ) + target: TextEmbeddingTarget = Field( + description="The target to use. 'all' or 'required'.", + default=defs.EMBEDDING_TARGET, + ) + skip: list[str] = Field(description="The specific embeddings to skip.", default=[]) + vector_store: dict | None = Field( + description="The vector storage configuration", default=None + ) + strategy: dict | None = Field( + description="The override strategy to use.", default=None + ) + + def resolved_strategy(self) -> dict: + """Get the resolved text embedding strategy.""" + from graphrag.index.verbs.text.embed import TextEmbedStrategyType + + return self.strategy or { + "type": TextEmbedStrategyType.openai, + "llm": self.llm.model_dump(), + **self.parallelization.model_dump(), + "batch_size": self.batch_size, + "batch_max_tokens": self.batch_max_tokens, + } diff --git a/graphrag/graphrag/config/models/umap_config.py b/graphrag/graphrag/config/models/umap_config.py new file mode 100644 index 0000000000000000000000000000000000000000..1d9bd93ead7ad5ac9baea6ab4a33d28934124700 --- /dev/null +++ b/graphrag/graphrag/config/models/umap_config.py @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Parameterization settings for the default configuration.""" + +from pydantic import BaseModel, Field + +import graphrag.config.defaults as defs + + +class UmapConfig(BaseModel): + """Configuration section for UMAP.""" + + enabled: bool = Field( + description="A flag indicating whether to enable UMAP.", + default=defs.UMAP_ENABLED, + ) diff --git a/graphrag/graphrag/config/read_dotenv.py b/graphrag/graphrag/config/read_dotenv.py new file mode 100644 index 0000000000000000000000000000000000000000..7e041757b37388af2a8b81474eab47371dd8173c --- /dev/null +++ b/graphrag/graphrag/config/read_dotenv.py @@ -0,0 +1,25 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing the read_dotenv utility.""" + +import logging +import os +from pathlib import Path + +from dotenv import dotenv_values + +log = logging.getLogger(__name__) + + +def read_dotenv(root: str) -> None: + """Read a .env file in the given root path.""" + env_path = Path(root) / ".env" + if env_path.exists(): + log.info("Loading pipeline .env file") + env_config = dotenv_values(f"{env_path}") + for key, value in env_config.items(): + if key not in os.environ: + os.environ[key] = value or "" + else: + log.info("No .env file found at %s", root) diff --git a/graphrag/graphrag/index/__init__.py b/graphrag/graphrag/index/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c97c290a94f29267e8249252a2b197d45eb1e8ac --- /dev/null +++ b/graphrag/graphrag/index/__init__.py @@ -0,0 +1,78 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine package root.""" + +from .cache import PipelineCache +from .config import ( + PipelineBlobCacheConfig, + PipelineBlobReportingConfig, + PipelineBlobStorageConfig, + PipelineCacheConfig, + PipelineCacheConfigTypes, + PipelineConfig, + PipelineConsoleReportingConfig, + PipelineCSVInputConfig, + PipelineFileCacheConfig, + PipelineFileReportingConfig, + PipelineFileStorageConfig, + PipelineInputConfig, + PipelineInputConfigTypes, + PipelineMemoryCacheConfig, + PipelineMemoryStorageConfig, + PipelineNoneCacheConfig, + PipelineReportingConfig, + PipelineReportingConfigTypes, + PipelineStorageConfig, + PipelineStorageConfigTypes, + PipelineTextInputConfig, + PipelineWorkflowConfig, + PipelineWorkflowReference, + PipelineWorkflowStep, +) +from .create_pipeline_config import create_pipeline_config +from .errors import ( + NoWorkflowsDefinedError, + UndefinedWorkflowError, + UnknownWorkflowError, +) +from .load_pipeline_config import load_pipeline_config +from .run import run_pipeline, run_pipeline_with_config +from .storage import PipelineStorage + +__all__ = [ + "NoWorkflowsDefinedError", + "PipelineBlobCacheConfig", + "PipelineBlobCacheConfig", + "PipelineBlobReportingConfig", + "PipelineBlobStorageConfig", + "PipelineCSVInputConfig", + "PipelineCache", + "PipelineCacheConfig", + "PipelineCacheConfigTypes", + "PipelineConfig", + "PipelineConsoleReportingConfig", + "PipelineFileCacheConfig", + "PipelineFileReportingConfig", + "PipelineFileStorageConfig", + "PipelineInputConfig", + "PipelineInputConfigTypes", + "PipelineMemoryCacheConfig", + "PipelineMemoryStorageConfig", + "PipelineNoneCacheConfig", + "PipelineReportingConfig", + "PipelineReportingConfigTypes", + "PipelineStorage", + "PipelineStorageConfig", + "PipelineStorageConfigTypes", + "PipelineTextInputConfig", + "PipelineWorkflowConfig", + "PipelineWorkflowReference", + "PipelineWorkflowStep", + "UndefinedWorkflowError", + "UnknownWorkflowError", + "create_pipeline_config", + "load_pipeline_config", + "run_pipeline", + "run_pipeline_with_config", +] diff --git a/graphrag/graphrag/index/__main__.py b/graphrag/graphrag/index/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..578ffc9c3377c0830db9ee32c0af686782774639 --- /dev/null +++ b/graphrag/graphrag/index/__main__.py @@ -0,0 +1,89 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine package root.""" + +import argparse + +from .cli import index_cli + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "--config", + help="The configuration yaml file to use when running the pipeline", + required=False, + type=str, + ) + parser.add_argument( + "-v", + "--verbose", + help="Runs the pipeline with verbose logging", + action="store_true", + ) + parser.add_argument( + "--memprofile", + help="Runs the pipeline with memory profiling", + action="store_true", + ) + parser.add_argument( + "--root", + help="If no configuration is defined, the root directory to use for input data and output data. Default value: the current directory", + # Only required if config is not defined + required=False, + default=".", + type=str, + ) + parser.add_argument( + "--resume", + help="Resume a given data run leveraging Parquet output files.", + # Only required if config is not defined + required=False, + default=None, + type=str, + ) + parser.add_argument( + "--reporter", + help="The progress reporter to use. Valid values are 'rich', 'print', or 'none'", + type=str, + ) + parser.add_argument( + "--emit", + help="The data formats to emit, comma-separated. Valid values are 'parquet' and 'csv'. default='parquet,csv'", + type=str, + ) + parser.add_argument( + "--dryrun", + help="Run the pipeline without actually executing any steps and inspect the configuration.", + action="store_true", + ) + parser.add_argument("--nocache", help="Disable LLM cache.", action="store_true") + parser.add_argument( + "--init", + help="Create an initial configuration in the given path.", + action="store_true", + ) + parser.add_argument( + "--overlay-defaults", + help="Overlay default configuration values on a provided configuration file (--config).", + action="store_true", + ) + args = parser.parse_args() + + if args.overlay_defaults and not args.config: + parser.error("--overlay-defaults requires --config") + + index_cli( + root=args.root, + verbose=args.verbose or False, + resume=args.resume, + memprofile=args.memprofile or False, + nocache=args.nocache or False, + reporter=args.reporter, + config=args.config, + emit=args.emit, + dryrun=args.dryrun or False, + init=args.init or False, + overlay_defaults=args.overlay_defaults or False, + cli=True, + ) diff --git a/graphrag/graphrag/index/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c0726dda73a4acb90bc0109cef34e3fe350192bc Binary files /dev/null and b/graphrag/graphrag/index/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/__pycache__/bootstrap.cpython-311.pyc b/graphrag/graphrag/index/__pycache__/bootstrap.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ab7874766e7e573badc5f239631bda3d58f69eb Binary files /dev/null and b/graphrag/graphrag/index/__pycache__/bootstrap.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/__pycache__/context.cpython-311.pyc b/graphrag/graphrag/index/__pycache__/context.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fba9bc94ce3c5a2269557de7ff6efe6659d9fa1f Binary files /dev/null and b/graphrag/graphrag/index/__pycache__/context.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/__pycache__/create_pipeline_config.cpython-311.pyc b/graphrag/graphrag/index/__pycache__/create_pipeline_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4280297ecf3993365dc43d4006b23995aafd6b17 Binary files /dev/null and b/graphrag/graphrag/index/__pycache__/create_pipeline_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/__pycache__/errors.cpython-311.pyc b/graphrag/graphrag/index/__pycache__/errors.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25e011517ec12620fecaa59536073457c0074820 Binary files /dev/null and b/graphrag/graphrag/index/__pycache__/errors.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/__pycache__/load_pipeline_config.cpython-311.pyc b/graphrag/graphrag/index/__pycache__/load_pipeline_config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b332f9b292875c84811843cdc1a6308ff4b260f Binary files /dev/null and b/graphrag/graphrag/index/__pycache__/load_pipeline_config.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/__pycache__/run.cpython-311.pyc b/graphrag/graphrag/index/__pycache__/run.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50f56110ffd8eeeee286440f5dfb318612f23d1f Binary files /dev/null and b/graphrag/graphrag/index/__pycache__/run.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/__pycache__/typing.cpython-311.pyc b/graphrag/graphrag/index/__pycache__/typing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..08c64d35e5637bdcade1d7b9bc1259d24d9785c1 Binary files /dev/null and b/graphrag/graphrag/index/__pycache__/typing.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/bootstrap.py b/graphrag/graphrag/index/bootstrap.py new file mode 100644 index 0000000000000000000000000000000000000000..398ec88b208ce61c3282fee1ceb8dda15b1b9637 --- /dev/null +++ b/graphrag/graphrag/index/bootstrap.py @@ -0,0 +1,28 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Bootstrap definition.""" + +import warnings + +# Ignore warnings from numba +warnings.filterwarnings("ignore", message=".*The 'nopython' keyword.*") +warnings.filterwarnings("ignore", message=".*Use no seed for parallelism.*") + +initialized_nltk = False + + +def bootstrap(): + """Bootstrap definition.""" + global initialized_nltk + if not initialized_nltk: + import nltk + from nltk.corpus import wordnet as wn + + nltk.download("punkt") + nltk.download("averaged_perceptron_tagger") + nltk.download("maxent_ne_chunker") + nltk.download("words") + nltk.download("wordnet") + wn.ensure_loaded() + initialized_nltk = True diff --git a/graphrag/graphrag/index/cache/__init__.py b/graphrag/graphrag/index/cache/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..42ebb2299465f5d5fffc348b2653bb3db0a7ef65 --- /dev/null +++ b/graphrag/graphrag/index/cache/__init__.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine cache package root.""" + +from .json_pipeline_cache import JsonPipelineCache +from .load_cache import load_cache +from .memory_pipeline_cache import InMemoryCache +from .noop_pipeline_cache import NoopPipelineCache +from .pipeline_cache import PipelineCache + +__all__ = [ + "InMemoryCache", + "JsonPipelineCache", + "NoopPipelineCache", + "PipelineCache", + "load_cache", +] diff --git a/graphrag/graphrag/index/cache/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/cache/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe242846412d2f549504b1b54e8d5181f679ce00 Binary files /dev/null and b/graphrag/graphrag/index/cache/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/cache/__pycache__/json_pipeline_cache.cpython-311.pyc b/graphrag/graphrag/index/cache/__pycache__/json_pipeline_cache.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f79b493dc3fc25e94c0f3a3287102767507077e Binary files /dev/null and b/graphrag/graphrag/index/cache/__pycache__/json_pipeline_cache.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/cache/__pycache__/load_cache.cpython-311.pyc b/graphrag/graphrag/index/cache/__pycache__/load_cache.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c4a9aca670ff61412b6766898e3b81259f69a7ee Binary files /dev/null and b/graphrag/graphrag/index/cache/__pycache__/load_cache.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/cache/__pycache__/memory_pipeline_cache.cpython-311.pyc b/graphrag/graphrag/index/cache/__pycache__/memory_pipeline_cache.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d6550c88f76833cda4be6d697e6cd1ad86b80d4f Binary files /dev/null and b/graphrag/graphrag/index/cache/__pycache__/memory_pipeline_cache.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/cache/__pycache__/noop_pipeline_cache.cpython-311.pyc b/graphrag/graphrag/index/cache/__pycache__/noop_pipeline_cache.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0cfbfd41359ac1fca091e40dcc23a3af3928e7bd Binary files /dev/null and b/graphrag/graphrag/index/cache/__pycache__/noop_pipeline_cache.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/cache/__pycache__/pipeline_cache.cpython-311.pyc b/graphrag/graphrag/index/cache/__pycache__/pipeline_cache.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06d8a5fccd3b626c761f163397ca0b89d8702570 Binary files /dev/null and b/graphrag/graphrag/index/cache/__pycache__/pipeline_cache.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/cache/json_pipeline_cache.py b/graphrag/graphrag/index/cache/json_pipeline_cache.py new file mode 100644 index 0000000000000000000000000000000000000000..b88a38990cfa1de1abbc7dcf4385e6ed1193ab98 --- /dev/null +++ b/graphrag/graphrag/index/cache/json_pipeline_cache.py @@ -0,0 +1,64 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'FilePipelineCache' model.""" + +import json +from typing import Any + +from graphrag.index.storage import PipelineStorage + +from .pipeline_cache import PipelineCache + + +class JsonPipelineCache(PipelineCache): + """File pipeline cache class definition.""" + + _storage: PipelineStorage + _encoding: str + + def __init__(self, storage: PipelineStorage, encoding="utf-8"): + """Init method definition.""" + self._storage = storage + self._encoding = encoding + + async def get(self, key: str) -> str | None: + """Get method definition.""" + if await self.has(key): + try: + data = await self._storage.get(key, encoding=self._encoding) + data = json.loads(data) + except UnicodeDecodeError: + await self._storage.delete(key) + return None + except json.decoder.JSONDecodeError: + await self._storage.delete(key) + return None + else: + return data.get("result") + + return None + + async def set(self, key: str, value: Any, debug_data: dict | None = None) -> None: + """Set method definition.""" + if value is None: + return + data = {"result": value, **(debug_data or {})} + await self._storage.set(key, json.dumps(data), encoding=self._encoding) + + async def has(self, key: str) -> bool: + """Has method definition.""" + return await self._storage.has(key) + + async def delete(self, key: str) -> None: + """Delete method definition.""" + if await self.has(key): + await self._storage.delete(key) + + async def clear(self) -> None: + """Clear method definition.""" + await self._storage.clear() + + def child(self, name: str) -> "JsonPipelineCache": + """Child method definition.""" + return JsonPipelineCache(self._storage.child(name), encoding=self._encoding) diff --git a/graphrag/graphrag/index/cache/load_cache.py b/graphrag/graphrag/index/cache/load_cache.py new file mode 100644 index 0000000000000000000000000000000000000000..4e0e6324fb29d4427ba546176a6cc1b6c4857918 --- /dev/null +++ b/graphrag/graphrag/index/cache/load_cache.py @@ -0,0 +1,51 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing load_cache method definition.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +from graphrag.config.enums import CacheType +from graphrag.index.config.cache import ( + PipelineBlobCacheConfig, + PipelineFileCacheConfig, +) +from graphrag.index.storage import BlobPipelineStorage, FilePipelineStorage + +if TYPE_CHECKING: + from graphrag.index.config import ( + PipelineCacheConfig, + ) + +from .json_pipeline_cache import JsonPipelineCache +from .memory_pipeline_cache import create_memory_cache +from .noop_pipeline_cache import NoopPipelineCache + + +def load_cache(config: PipelineCacheConfig | None, root_dir: str | None): + """Load the cache from the given config.""" + if config is None: + return NoopPipelineCache() + + match config.type: + case CacheType.none: + return NoopPipelineCache() + case CacheType.memory: + return create_memory_cache() + case CacheType.file: + config = cast(PipelineFileCacheConfig, config) + storage = FilePipelineStorage(root_dir).child(config.base_dir) + return JsonPipelineCache(storage) + case CacheType.blob: + config = cast(PipelineBlobCacheConfig, config) + storage = BlobPipelineStorage( + config.connection_string, + config.container_name, + storage_account_blob_url=config.storage_account_blob_url, + ).child(config.base_dir) + return JsonPipelineCache(storage) + case _: + msg = f"Unknown cache type: {config.type}" + raise ValueError(msg) diff --git a/graphrag/graphrag/index/cache/memory_pipeline_cache.py b/graphrag/graphrag/index/cache/memory_pipeline_cache.py new file mode 100644 index 0000000000000000000000000000000000000000..fa42f3f921dccf10a518db9516e53bac7bd620ec --- /dev/null +++ b/graphrag/graphrag/index/cache/memory_pipeline_cache.py @@ -0,0 +1,83 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'InMemoryCache' model.""" + +from typing import Any + +from .pipeline_cache import PipelineCache + + +class InMemoryCache(PipelineCache): + """In memory cache class definition.""" + + _cache: dict[str, Any] + _name: str + + def __init__(self, name: str | None = None): + """Init method definition.""" + self._cache = {} + self._name = name or "" + + async def get(self, key: str) -> Any: + """Get the value for the given key. + + Args: + - key - The key to get the value for. + - as_bytes - Whether or not to return the value as bytes. + + Returns + ------- + - output - The value for the given key. + """ + key = self._create_cache_key(key) + return self._cache.get(key) + + async def set(self, key: str, value: Any, debug_data: dict | None = None) -> None: + """Set the value for the given key. + + Args: + - key - The key to set the value for. + - value - The value to set. + """ + key = self._create_cache_key(key) + self._cache[key] = value + + async def has(self, key: str) -> bool: + """Return True if the given key exists in the storage. + + Args: + - key - The key to check for. + + Returns + ------- + - output - True if the key exists in the storage, False otherwise. + """ + key = self._create_cache_key(key) + return key in self._cache + + async def delete(self, key: str) -> None: + """Delete the given key from the storage. + + Args: + - key - The key to delete. + """ + key = self._create_cache_key(key) + del self._cache[key] + + async def clear(self) -> None: + """Clear the storage.""" + self._cache.clear() + + def child(self, name: str) -> PipelineCache: + """Create a sub cache with the given name.""" + return InMemoryCache(name) + + def _create_cache_key(self, key: str) -> str: + """Create a cache key for the given key.""" + return f"{self._name}{key}" + + +def create_memory_cache() -> PipelineCache: + """Create a memory cache.""" + return InMemoryCache() diff --git a/graphrag/graphrag/index/cache/noop_pipeline_cache.py b/graphrag/graphrag/index/cache/noop_pipeline_cache.py new file mode 100644 index 0000000000000000000000000000000000000000..b7c3e60fdd51aad52d02621aa9e7b5c83a159841 --- /dev/null +++ b/graphrag/graphrag/index/cache/noop_pipeline_cache.py @@ -0,0 +1,65 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Module containing the NoopPipelineCache implementation.""" + +from typing import Any + +from .pipeline_cache import PipelineCache + + +class NoopPipelineCache(PipelineCache): + """A no-op implementation of the pipeline cache, usually useful for testing.""" + + async def get(self, key: str) -> Any: + """Get the value for the given key. + + Args: + - key - The key to get the value for. + - as_bytes - Whether or not to return the value as bytes. + + Returns + ------- + - output - The value for the given key. + """ + return None + + async def set( + self, key: str, value: str | bytes | None, debug_data: dict | None = None + ) -> None: + """Set the value for the given key. + + Args: + - key - The key to set the value for. + - value - The value to set. + """ + + async def has(self, key: str) -> bool: + """Return True if the given key exists in the cache. + + Args: + - key - The key to check for. + + Returns + ------- + - output - True if the key exists in the cache, False otherwise. + """ + return False + + async def delete(self, key: str) -> None: + """Delete the given key from the cache. + + Args: + - key - The key to delete. + """ + + async def clear(self) -> None: + """Clear the cache.""" + + def child(self, name: str) -> PipelineCache: + """Create a child cache with the given name. + + Args: + - name - The name to create the sub cache with. + """ + return self diff --git a/graphrag/graphrag/index/cache/pipeline_cache.py b/graphrag/graphrag/index/cache/pipeline_cache.py new file mode 100644 index 0000000000000000000000000000000000000000..c68c5cfb4b91ea517bba3ea90a1d82eb227bcad8 --- /dev/null +++ b/graphrag/graphrag/index/cache/pipeline_cache.py @@ -0,0 +1,67 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'PipelineCache' model.""" + +from __future__ import annotations + +from abc import ABCMeta, abstractmethod +from typing import Any + + +class PipelineCache(metaclass=ABCMeta): + """Provide a cache interface for the pipeline.""" + + @abstractmethod + async def get(self, key: str) -> Any: + """Get the value for the given key. + + Args: + - key - The key to get the value for. + - as_bytes - Whether or not to return the value as bytes. + + Returns + ------- + - output - The value for the given key. + """ + + @abstractmethod + async def set(self, key: str, value: Any, debug_data: dict | None = None) -> None: + """Set the value for the given key. + + Args: + - key - The key to set the value for. + - value - The value to set. + """ + + @abstractmethod + async def has(self, key: str) -> bool: + """Return True if the given key exists in the cache. + + Args: + - key - The key to check for. + + Returns + ------- + - output - True if the key exists in the cache, False otherwise. + """ + + @abstractmethod + async def delete(self, key: str) -> None: + """Delete the given key from the cache. + + Args: + - key - The key to delete. + """ + + @abstractmethod + async def clear(self) -> None: + """Clear the cache.""" + + @abstractmethod + def child(self, name: str) -> PipelineCache: + """Create a child cache with the given name. + + Args: + - name - The name to create the sub cache with. + """ diff --git a/graphrag/graphrag/index/cli.py b/graphrag/graphrag/index/cli.py new file mode 100644 index 0000000000000000000000000000000000000000..77d0e9b476ab3209e3196b529572adeae42cfa7f --- /dev/null +++ b/graphrag/graphrag/index/cli.py @@ -0,0 +1,314 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Main definition.""" + +import asyncio +import json +import logging +import platform +import sys +import time +import warnings +from pathlib import Path + +from graphrag.config import ( + create_graphrag_config, +) +from graphrag.index import PipelineConfig, create_pipeline_config +from graphrag.index.cache import NoopPipelineCache +from graphrag.index.progress import ( + NullProgressReporter, + PrintProgressReporter, + ProgressReporter, +) +from graphrag.index.progress.rich import RichProgressReporter +from graphrag.index.run import run_pipeline_with_config + +from .emit import TableEmitterType +from .graph.extractors.claims.prompts import CLAIM_EXTRACTION_PROMPT +from .graph.extractors.community_reports.prompts import COMMUNITY_REPORT_PROMPT +from .graph.extractors.graph.prompts import GRAPH_EXTRACTION_PROMPT +from .graph.extractors.summarize.prompts import SUMMARIZE_PROMPT +from .init_content import INIT_DOTENV, INIT_YAML + +# Ignore warnings from numba +warnings.filterwarnings("ignore", message=".*NumbaDeprecationWarning.*") + +log = logging.getLogger(__name__) + + +def redact(input: dict) -> str: + """Sanitize the config json.""" + + # Redact any sensitive configuration + def redact_dict(input: dict) -> dict: + if not isinstance(input, dict): + return input + + result = {} + for key, value in input.items(): + if key in { + "api_key", + "connection_string", + "container_name", + "organization", + }: + if value is not None: + result[key] = f"REDACTED, length {len(value)}" + elif isinstance(value, dict): + result[key] = redact_dict(value) + elif isinstance(value, list): + result[key] = [redact_dict(i) for i in value] + else: + result[key] = value + return result + + redacted_dict = redact_dict(input) + return json.dumps(redacted_dict, indent=4) + + +def index_cli( + root: str, + init: bool, + verbose: bool, + resume: str | None, + memprofile: bool, + nocache: bool, + reporter: str | None, + config: str | None, + emit: str | None, + dryrun: bool, + overlay_defaults: bool, + cli: bool = False, +): + """Run the pipeline with the given config.""" + run_id = resume or time.strftime("%Y%m%d-%H%M%S") + _enable_logging(root, run_id, verbose) + progress_reporter = _get_progress_reporter(reporter) + if init: + _initialize_project_at(root, progress_reporter) + sys.exit(0) + if overlay_defaults: + pipeline_config: str | PipelineConfig = _create_default_config( + root, config, verbose, dryrun or False, progress_reporter + ) + else: + pipeline_config: str | PipelineConfig = config or _create_default_config( + root, None, verbose, dryrun or False, progress_reporter + ) + cache = NoopPipelineCache() if nocache else None + pipeline_emit = emit.split(",") if emit else None + encountered_errors = False + + def _run_workflow_async() -> None: + import signal + + def handle_signal(signum, _): + # Handle the signal here + progress_reporter.info(f"Received signal {signum}, exiting...") + progress_reporter.dispose() + for task in asyncio.all_tasks(): + task.cancel() + progress_reporter.info("All tasks cancelled. Exiting...") + + # Register signal handlers for SIGINT and SIGHUP + signal.signal(signal.SIGINT, handle_signal) + + if sys.platform != "win32": + signal.signal(signal.SIGHUP, handle_signal) + + async def execute(): + nonlocal encountered_errors + async for output in run_pipeline_with_config( + pipeline_config, + run_id=run_id, + memory_profile=memprofile, + cache=cache, + progress_reporter=progress_reporter, + emit=( + [TableEmitterType(e) for e in pipeline_emit] + if pipeline_emit + else None + ), + is_resume_run=bool(resume), + ): + if output.errors and len(output.errors) > 0: + encountered_errors = True + progress_reporter.error(output.workflow) + else: + progress_reporter.success(output.workflow) + + progress_reporter.info(str(output.result)) + + if platform.system() == "Windows": + import nest_asyncio # type: ignore Ignoring because out of windows this will cause an error + + nest_asyncio.apply() + loop = asyncio.get_event_loop() + loop.run_until_complete(execute()) + elif sys.version_info >= (3, 11): + import uvloop # type: ignore Ignoring because on windows this will cause an error + + with asyncio.Runner(loop_factory=uvloop.new_event_loop) as runner: # type: ignore Ignoring because minor versions this will throw an error + runner.run(execute()) + else: + import uvloop # type: ignore Ignoring because on windows this will cause an error + + uvloop.install() + asyncio.run(execute()) + + _run_workflow_async() + progress_reporter.stop() + if encountered_errors: + progress_reporter.error( + "Errors occurred during the pipeline run, see logs for more details." + ) + else: + progress_reporter.success("All workflows completed successfully.") + + if cli: + sys.exit(1 if encountered_errors else 0) + + +def _initialize_project_at(path: str, reporter: ProgressReporter) -> None: + """Initialize the project at the given path.""" + reporter.info(f"Initializing project at {path}") + root = Path(path) + if not root.exists(): + root.mkdir(parents=True, exist_ok=True) + + settings_yaml = root / "settings.yaml" + if settings_yaml.exists(): + msg = f"Project already initialized at {root}" + raise ValueError(msg) + + dotenv = root / ".env" + if not dotenv.exists(): + with settings_yaml.open("w") as file: + file.write(INIT_YAML) + + with dotenv.open("w") as file: + file.write(INIT_DOTENV) + + prompts_dir = root / "prompts" + if not prompts_dir.exists(): + prompts_dir.mkdir(parents=True, exist_ok=True) + + entity_extraction = prompts_dir / "entity_extraction.txt" + if not entity_extraction.exists(): + with entity_extraction.open("w") as file: + file.write(GRAPH_EXTRACTION_PROMPT) + + summarize_descriptions = prompts_dir / "summarize_descriptions.txt" + if not summarize_descriptions.exists(): + with summarize_descriptions.open("w") as file: + file.write(SUMMARIZE_PROMPT) + + claim_extraction = prompts_dir / "claim_extraction.txt" + if not claim_extraction.exists(): + with claim_extraction.open("w") as file: + file.write(CLAIM_EXTRACTION_PROMPT) + + community_report = prompts_dir / "community_report.txt" + if not community_report.exists(): + with community_report.open("w") as file: + file.write(COMMUNITY_REPORT_PROMPT) + + +def _create_default_config( + root: str, + config: str | None, + verbose: bool, + dryrun: bool, + reporter: ProgressReporter, +) -> PipelineConfig: + """Overlay default values on an existing config or create a default config if none is provided.""" + if config and not Path(config).exists(): + msg = f"Configuration file {config} does not exist" + raise ValueError + + if not Path(root).exists(): + msg = f"Root directory {root} does not exist" + raise ValueError(msg) + + parameters = _read_config_parameters(root, config, reporter) + log.info( + "using default configuration: %s", + redact(parameters.model_dump()), + ) + + if verbose or dryrun: + reporter.info(f"Using default configuration: {redact(parameters.model_dump())}") + result = create_pipeline_config(parameters, verbose) + if verbose or dryrun: + reporter.info(f"Final Config: {redact(result.model_dump())}") + + if dryrun: + reporter.info("dry run complete, exiting...") + sys.exit(0) + return result + + +def _read_config_parameters(root: str, config: str | None, reporter: ProgressReporter): + _root = Path(root) + settings_yaml = ( + Path(config) + if config and Path(config).suffix in [".yaml", ".yml"] + else _root / "settings.yaml" + ) + if not settings_yaml.exists(): + settings_yaml = _root / "settings.yml" + settings_json = ( + Path(config) + if config and Path(config).suffix == ".json" + else _root / "settings.json" + ) + + if settings_yaml.exists(): + reporter.success(f"Reading settings from {settings_yaml}") + with settings_yaml.open("r") as file: + import yaml + + data = yaml.safe_load(file) + return create_graphrag_config(data, root) + + if settings_json.exists(): + reporter.success(f"Reading settings from {settings_json}") + with settings_json.open("r") as file: + import json + + data = json.loads(file.read()) + return create_graphrag_config(data, root) + + reporter.success("Reading settings from environment variables") + return create_graphrag_config(root_dir=root) + + +def _get_progress_reporter(reporter_type: str | None) -> ProgressReporter: + if reporter_type is None or reporter_type == "rich": + return RichProgressReporter("GraphRAG Indexer ") + if reporter_type == "print": + return PrintProgressReporter("GraphRAG Indexer ") + if reporter_type == "none": + return NullProgressReporter() + + msg = f"Invalid progress reporter type: {reporter_type}" + raise ValueError(msg) + + +def _enable_logging(root_dir: str, run_id: str, verbose: bool) -> None: + logging_file = ( + Path(root_dir) / "output" / run_id / "reports" / "indexing-engine.log" + ) + logging_file.parent.mkdir(parents=True, exist_ok=True) + + logging_file.touch(exist_ok=True) + + logging.basicConfig( + filename=str(logging_file), + filemode="a", + format="%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s", + datefmt="%H:%M:%S", + level=logging.DEBUG if verbose else logging.INFO, + ) diff --git a/graphrag/graphrag/index/config/__init__.py b/graphrag/graphrag/index/config/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3c40762a84ba0b8314cab9a39bdb10dd90982a45 --- /dev/null +++ b/graphrag/graphrag/index/config/__init__.py @@ -0,0 +1,69 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine config typing package root.""" + +from .cache import ( + PipelineBlobCacheConfig, + PipelineCacheConfig, + PipelineCacheConfigTypes, + PipelineFileCacheConfig, + PipelineMemoryCacheConfig, + PipelineNoneCacheConfig, +) +from .input import ( + PipelineCSVInputConfig, + PipelineInputConfig, + PipelineInputConfigTypes, + PipelineTextInputConfig, +) +from .pipeline import PipelineConfig +from .reporting import ( + PipelineBlobReportingConfig, + PipelineConsoleReportingConfig, + PipelineFileReportingConfig, + PipelineReportingConfig, + PipelineReportingConfigTypes, +) +from .storage import ( + PipelineBlobStorageConfig, + PipelineFileStorageConfig, + PipelineMemoryStorageConfig, + PipelineStorageConfig, + PipelineStorageConfigTypes, +) +from .workflow import ( + PipelineWorkflowConfig, + PipelineWorkflowReference, + PipelineWorkflowStep, +) + +__all__ = [ + "PipelineBlobCacheConfig", + "PipelineBlobReportingConfig", + "PipelineBlobStorageConfig", + "PipelineCSVInputConfig", + "PipelineCacheConfig", + "PipelineCacheConfigTypes", + "PipelineCacheConfigTypes", + "PipelineCacheConfigTypes", + "PipelineConfig", + "PipelineConsoleReportingConfig", + "PipelineFileCacheConfig", + "PipelineFileReportingConfig", + "PipelineFileStorageConfig", + "PipelineInputConfig", + "PipelineInputConfigTypes", + "PipelineMemoryCacheConfig", + "PipelineMemoryCacheConfig", + "PipelineMemoryStorageConfig", + "PipelineNoneCacheConfig", + "PipelineReportingConfig", + "PipelineReportingConfigTypes", + "PipelineStorageConfig", + "PipelineStorageConfigTypes", + "PipelineTextInputConfig", + "PipelineWorkflowConfig", + "PipelineWorkflowReference", + "PipelineWorkflowStep", +] diff --git a/graphrag/graphrag/index/config/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/config/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..15beeab25e03edc93e0d0d049bece77e90c9303e Binary files /dev/null and b/graphrag/graphrag/index/config/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/config/__pycache__/cache.cpython-311.pyc b/graphrag/graphrag/index/config/__pycache__/cache.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..249eb283b93acf71ef3918f778734ce8ca4d8ab1 Binary files /dev/null and b/graphrag/graphrag/index/config/__pycache__/cache.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/config/__pycache__/input.cpython-311.pyc b/graphrag/graphrag/index/config/__pycache__/input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f79032a34bb5fff5d533f0c80ab2eaa353c08753 Binary files /dev/null and b/graphrag/graphrag/index/config/__pycache__/input.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/config/__pycache__/pipeline.cpython-311.pyc b/graphrag/graphrag/index/config/__pycache__/pipeline.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..778528a008b6871b5d25e6874846cd3cc2c7bd9a Binary files /dev/null and b/graphrag/graphrag/index/config/__pycache__/pipeline.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/config/__pycache__/reporting.cpython-311.pyc b/graphrag/graphrag/index/config/__pycache__/reporting.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2852031431a8d716b59cb81398402f9672c0836c Binary files /dev/null and b/graphrag/graphrag/index/config/__pycache__/reporting.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/config/__pycache__/storage.cpython-311.pyc b/graphrag/graphrag/index/config/__pycache__/storage.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9286c2fbbb2cb9d7b6e32118f2fb8d2ae244c100 Binary files /dev/null and b/graphrag/graphrag/index/config/__pycache__/storage.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/config/__pycache__/workflow.cpython-311.pyc b/graphrag/graphrag/index/config/__pycache__/workflow.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..323722aa56c1763d28df0a5eb7e3571e4ddbfc17 Binary files /dev/null and b/graphrag/graphrag/index/config/__pycache__/workflow.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/config/cache.py b/graphrag/graphrag/index/config/cache.py new file mode 100644 index 0000000000000000000000000000000000000000..be1053de2eb7990f2a36a5d042ccb8b17d60f871 --- /dev/null +++ b/graphrag/graphrag/index/config/cache.py @@ -0,0 +1,82 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'PipelineCacheConfig', 'PipelineFileCacheConfig' and 'PipelineMemoryCacheConfig' models.""" + +from __future__ import annotations + +from typing import Generic, Literal, TypeVar + +from pydantic import BaseModel +from pydantic import Field as pydantic_Field + +from graphrag.config.enums import CacheType + +T = TypeVar("T") + + +class PipelineCacheConfig(BaseModel, Generic[T]): + """Represent the cache configuration for the pipeline.""" + + type: T + + +class PipelineFileCacheConfig(PipelineCacheConfig[Literal[CacheType.file]]): + """Represent the file cache configuration for the pipeline.""" + + type: Literal[CacheType.file] = CacheType.file + """The type of cache.""" + + base_dir: str | None = pydantic_Field( + description="The base directory for the cache.", default=None + ) + """The base directory for the cache.""" + + +class PipelineMemoryCacheConfig(PipelineCacheConfig[Literal[CacheType.memory]]): + """Represent the memory cache configuration for the pipeline.""" + + type: Literal[CacheType.memory] = CacheType.memory + """The type of cache.""" + + +class PipelineNoneCacheConfig(PipelineCacheConfig[Literal[CacheType.none]]): + """Represent the none cache configuration for the pipeline.""" + + type: Literal[CacheType.none] = CacheType.none + """The type of cache.""" + + +class PipelineBlobCacheConfig(PipelineCacheConfig[Literal[CacheType.blob]]): + """Represents the blob cache configuration for the pipeline.""" + + type: Literal[CacheType.blob] = CacheType.blob + """The type of cache.""" + + base_dir: str | None = pydantic_Field( + description="The base directory for the cache.", default=None + ) + """The base directory for the cache.""" + + connection_string: str | None = pydantic_Field( + description="The blob cache connection string for the cache.", default=None + ) + """The blob cache connection string for the cache.""" + + container_name: str = pydantic_Field( + description="The container name for cache", default=None + ) + """The container name for cache""" + + storage_account_blob_url: str | None = pydantic_Field( + description="The storage account blob url for cache", default=None + ) + """The storage account blob url for cache""" + + +PipelineCacheConfigTypes = ( + PipelineFileCacheConfig + | PipelineMemoryCacheConfig + | PipelineBlobCacheConfig + | PipelineNoneCacheConfig +) diff --git a/graphrag/graphrag/index/config/input.py b/graphrag/graphrag/index/config/input.py new file mode 100644 index 0000000000000000000000000000000000000000..35db357599ad117c4cb8c4c5a4d72688cc167642 --- /dev/null +++ b/graphrag/graphrag/index/config/input.py @@ -0,0 +1,120 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'PipelineInputConfig', 'PipelineCSVInputConfig' and 'PipelineTextInputConfig' models.""" + +from __future__ import annotations + +from typing import Generic, Literal, TypeVar + +from pydantic import BaseModel +from pydantic import Field as pydantic_Field + +from graphrag.config.enums import InputFileType, InputType + +from .workflow import PipelineWorkflowStep + +T = TypeVar("T") + + +class PipelineInputConfig(BaseModel, Generic[T]): + """Represent the configuration for an input.""" + + file_type: T + """The file type of input.""" + + type: InputType | None = pydantic_Field( + description="The input type to use.", + default=None, + ) + """The input type to use.""" + + connection_string: str | None = pydantic_Field( + description="The blob cache connection string for the input files.", + default=None, + ) + """The blob cache connection string for the input files.""" + + storage_account_blob_url: str | None = pydantic_Field( + description="The storage account blob url for the input files.", default=None + ) + """The storage account blob url for the input files.""" + + container_name: str | None = pydantic_Field( + description="The container name for input files.", default=None + ) + """The container name for the input files.""" + + base_dir: str | None = pydantic_Field( + description="The base directory for the input files.", default=None + ) + """The base directory for the input files.""" + + file_pattern: str = pydantic_Field( + description="The regex file pattern for the input files." + ) + """The regex file pattern for the input files.""" + + file_filter: dict[str, str] | None = pydantic_Field( + description="The optional file filter for the input files.", default=None + ) + """The optional file filter for the input files.""" + + post_process: list[PipelineWorkflowStep] | None = pydantic_Field( + description="The post processing steps for the input.", default=None + ) + """The post processing steps for the input.""" + + encoding: str | None = pydantic_Field( + description="The encoding for the input files.", default=None + ) + """The encoding for the input files.""" + + +class PipelineCSVInputConfig(PipelineInputConfig[Literal[InputFileType.csv]]): + """Represent the configuration for a CSV input.""" + + file_type: Literal[InputFileType.csv] = InputFileType.csv + + source_column: str | None = pydantic_Field( + description="The column to use as the source of the document.", default=None + ) + """The column to use as the source of the document.""" + + timestamp_column: str | None = pydantic_Field( + description="The column to use as the timestamp of the document.", default=None + ) + """The column to use as the timestamp of the document.""" + + timestamp_format: str | None = pydantic_Field( + description="The format of the timestamp column, so it can be parsed correctly.", + default=None, + ) + """The format of the timestamp column, so it can be parsed correctly.""" + + text_column: str | None = pydantic_Field( + description="The column to use as the text of the document.", default=None + ) + """The column to use as the text of the document.""" + + title_column: str | None = pydantic_Field( + description="The column to use as the title of the document.", default=None + ) + """The column to use as the title of the document.""" + + +class PipelineTextInputConfig(PipelineInputConfig[Literal[InputFileType.text]]): + """Represent the configuration for a text input.""" + + file_type: Literal[InputFileType.text] = InputFileType.text + + # Text Specific + title_text_length: int | None = pydantic_Field( + description="Number of characters to use from the text as the title.", + default=None, + ) + """Number of characters to use from the text as the title.""" + + +PipelineInputConfigTypes = PipelineCSVInputConfig | PipelineTextInputConfig +"""Represent the types of inputs that can be used in a pipeline.""" diff --git a/graphrag/graphrag/index/config/pipeline.py b/graphrag/graphrag/index/config/pipeline.py new file mode 100644 index 0000000000000000000000000000000000000000..30d866e3490284aa913b530ae4d3277830bc8996 --- /dev/null +++ b/graphrag/graphrag/index/config/pipeline.py @@ -0,0 +1,64 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'PipelineConfig' model.""" + +from __future__ import annotations + +from devtools import pformat +from pydantic import BaseModel +from pydantic import Field as pydantic_Field + +from .cache import PipelineCacheConfigTypes +from .input import PipelineInputConfigTypes +from .reporting import PipelineReportingConfigTypes +from .storage import PipelineStorageConfigTypes +from .workflow import PipelineWorkflowReference + + +class PipelineConfig(BaseModel): + """Represent the configuration for a pipeline.""" + + def __repr__(self) -> str: + """Get a string representation.""" + return pformat(self, highlight=False) + + def __str__(self): + """Get a string representation.""" + return str(self.model_dump_json(indent=4)) + + extends: list[str] | str | None = pydantic_Field( + description="Extends another pipeline configuration", default=None + ) + """Extends another pipeline configuration""" + + input: PipelineInputConfigTypes | None = pydantic_Field( + default=None, discriminator="file_type" + ) + """The input configuration for the pipeline.""" + + reporting: PipelineReportingConfigTypes | None = pydantic_Field( + default=None, discriminator="type" + ) + """The reporting configuration for the pipeline.""" + + storage: PipelineStorageConfigTypes | None = pydantic_Field( + default=None, discriminator="type" + ) + """The storage configuration for the pipeline.""" + + cache: PipelineCacheConfigTypes | None = pydantic_Field( + default=None, discriminator="type" + ) + """The cache configuration for the pipeline.""" + + root_dir: str | None = pydantic_Field( + description="The root directory for the pipeline. All other paths will be based on this root_dir.", + default=None, + ) + """The root directory for the pipeline.""" + + workflows: list[PipelineWorkflowReference] = pydantic_Field( + description="The workflows for the pipeline.", default_factory=list + ) + """The workflows for the pipeline.""" diff --git a/graphrag/graphrag/index/config/reporting.py b/graphrag/graphrag/index/config/reporting.py new file mode 100644 index 0000000000000000000000000000000000000000..921e24ae4e6cbe9da944a0c19f3df38ab207f9f5 --- /dev/null +++ b/graphrag/graphrag/index/config/reporting.py @@ -0,0 +1,77 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'PipelineReportingConfig', 'PipelineFileReportingConfig' and 'PipelineConsoleReportingConfig' models.""" + +from __future__ import annotations + +from typing import Generic, Literal, TypeVar + +from pydantic import BaseModel +from pydantic import Field as pydantic_Field + +from graphrag.config.enums import ReportingType + +T = TypeVar("T") + + +class PipelineReportingConfig(BaseModel, Generic[T]): + """Represent the reporting configuration for the pipeline.""" + + type: T + + +class PipelineFileReportingConfig(PipelineReportingConfig[Literal[ReportingType.file]]): + """Represent the file reporting configuration for the pipeline.""" + + type: Literal[ReportingType.file] = ReportingType.file + """The type of reporting.""" + + base_dir: str | None = pydantic_Field( + description="The base directory for the reporting.", default=None + ) + """The base directory for the reporting.""" + + +class PipelineConsoleReportingConfig( + PipelineReportingConfig[Literal[ReportingType.console]] +): + """Represent the console reporting configuration for the pipeline.""" + + type: Literal[ReportingType.console] = ReportingType.console + """The type of reporting.""" + + +class PipelineBlobReportingConfig(PipelineReportingConfig[Literal[ReportingType.blob]]): + """Represents the blob reporting configuration for the pipeline.""" + + type: Literal[ReportingType.blob] = ReportingType.blob + """The type of reporting.""" + + connection_string: str | None = pydantic_Field( + description="The blob reporting connection string for the reporting.", + default=None, + ) + """The blob reporting connection string for the reporting.""" + + container_name: str = pydantic_Field( + description="The container name for reporting", default=None + ) + """The container name for reporting""" + + storage_account_blob_url: str | None = pydantic_Field( + description="The storage account blob url for reporting", default=None + ) + """The storage account blob url for reporting""" + + base_dir: str | None = pydantic_Field( + description="The base directory for the reporting.", default=None + ) + """The base directory for the reporting.""" + + +PipelineReportingConfigTypes = ( + PipelineFileReportingConfig + | PipelineConsoleReportingConfig + | PipelineBlobReportingConfig +) diff --git a/graphrag/graphrag/index/config/storage.py b/graphrag/graphrag/index/config/storage.py new file mode 100644 index 0000000000000000000000000000000000000000..023d50e24925f93f14f3ca9d11cc49d3d34e5c40 --- /dev/null +++ b/graphrag/graphrag/index/config/storage.py @@ -0,0 +1,72 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'PipelineStorageConfig', 'PipelineFileStorageConfig' and 'PipelineMemoryStorageConfig' models.""" + +from __future__ import annotations + +from typing import Generic, Literal, TypeVar + +from pydantic import BaseModel +from pydantic import Field as pydantic_Field + +from graphrag.config.enums import StorageType + +T = TypeVar("T") + + +class PipelineStorageConfig(BaseModel, Generic[T]): + """Represent the storage configuration for the pipeline.""" + + type: T + + +class PipelineFileStorageConfig(PipelineStorageConfig[Literal[StorageType.file]]): + """Represent the file storage configuration for the pipeline.""" + + type: Literal[StorageType.file] = StorageType.file + """The type of storage.""" + + base_dir: str | None = pydantic_Field( + description="The base directory for the storage.", default=None + ) + """The base directory for the storage.""" + + +class PipelineMemoryStorageConfig(PipelineStorageConfig[Literal[StorageType.memory]]): + """Represent the memory storage configuration for the pipeline.""" + + type: Literal[StorageType.memory] = StorageType.memory + """The type of storage.""" + + +class PipelineBlobStorageConfig(PipelineStorageConfig[Literal[StorageType.blob]]): + """Represents the blob storage configuration for the pipeline.""" + + type: Literal[StorageType.blob] = StorageType.blob + """The type of storage.""" + + connection_string: str | None = pydantic_Field( + description="The blob storage connection string for the storage.", default=None + ) + """The blob storage connection string for the storage.""" + + container_name: str = pydantic_Field( + description="The container name for storage", default=None + ) + """The container name for storage.""" + + base_dir: str | None = pydantic_Field( + description="The base directory for the storage.", default=None + ) + """The base directory for the storage.""" + + storage_account_blob_url: str | None = pydantic_Field( + description="The storage account blob url.", default=None + ) + """The storage account blob url.""" + + +PipelineStorageConfigTypes = ( + PipelineFileStorageConfig | PipelineMemoryStorageConfig | PipelineBlobStorageConfig +) diff --git a/graphrag/graphrag/index/config/workflow.py b/graphrag/graphrag/index/config/workflow.py new file mode 100644 index 0000000000000000000000000000000000000000..c26fef6ca0d50d1ef993c837063d372f68f1f44c --- /dev/null +++ b/graphrag/graphrag/index/config/workflow.py @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'PipelineWorkflowReference' model.""" + +from __future__ import annotations + +from typing import Any + +from pydantic import BaseModel +from pydantic import Field as pydantic_Field + +PipelineWorkflowStep = dict[str, Any] +"""Represent a step in a workflow.""" + +PipelineWorkflowConfig = dict[str, Any] +"""Represent a configuration for a workflow.""" + + +class PipelineWorkflowReference(BaseModel): + """Represent a reference to a workflow, and can optionally be the workflow itself.""" + + name: str | None = pydantic_Field(description="Name of the workflow.", default=None) + """Name of the workflow.""" + + steps: list[PipelineWorkflowStep] | None = pydantic_Field( + description="The optional steps for the workflow.", default=None + ) + """The optional steps for the workflow.""" + + config: PipelineWorkflowConfig | None = pydantic_Field( + description="The optional configuration for the workflow.", default=None + ) + """The optional configuration for the workflow.""" diff --git a/graphrag/graphrag/index/context.py b/graphrag/graphrag/index/context.py new file mode 100644 index 0000000000000000000000000000000000000000..e74799bd358a0729c327397d50f1ac4a6b02d6f3 --- /dev/null +++ b/graphrag/graphrag/index/context.py @@ -0,0 +1,42 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +# isort: skip_file +"""A module containing the 'PipelineRunStats' and 'PipelineRunContext' models.""" + +from dataclasses import dataclass as dc_dataclass +from dataclasses import field + +from .cache import PipelineCache +from .storage.typing import PipelineStorage + + +@dc_dataclass +class PipelineRunStats: + """Pipeline running stats.""" + + total_runtime: float = field(default=0) + """Float representing the total runtime.""" + + num_documents: int = field(default=0) + """Number of documents.""" + + input_load_time: float = field(default=0) + """Float representing the input load time.""" + + workflows: dict[str, dict[str, float]] = field(default_factory=dict) + """A dictionary of workflows.""" + + +@dc_dataclass +class PipelineRunContext: + """Provides the context for the current pipeline run.""" + + stats: PipelineRunStats + storage: PipelineStorage + cache: PipelineCache + + +# TODO: For now, just has the same props available to it +VerbRunContext = PipelineRunContext +"""Provides the context for the current verb run.""" diff --git a/graphrag/graphrag/index/create_pipeline_config.py b/graphrag/graphrag/index/create_pipeline_config.py new file mode 100644 index 0000000000000000000000000000000000000000..40f36247bafc6aaff1698aaf1f4eaeef15a2defd --- /dev/null +++ b/graphrag/graphrag/index/create_pipeline_config.py @@ -0,0 +1,548 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Default configuration methods definition.""" + +import json +import logging +from pathlib import Path + +from graphrag.config.enums import ( + CacheType, + InputFileType, + ReportingType, + StorageType, + TextEmbeddingTarget, +) +from graphrag.config.models import ( + GraphRagConfig, + TextEmbeddingConfig, +) +from graphrag.index.config.cache import ( + PipelineBlobCacheConfig, + PipelineCacheConfigTypes, + PipelineFileCacheConfig, + PipelineMemoryCacheConfig, + PipelineNoneCacheConfig, +) +from graphrag.index.config.input import ( + PipelineCSVInputConfig, + PipelineInputConfigTypes, + PipelineTextInputConfig, +) +from graphrag.index.config.pipeline import ( + PipelineConfig, +) +from graphrag.index.config.reporting import ( + PipelineBlobReportingConfig, + PipelineConsoleReportingConfig, + PipelineFileReportingConfig, + PipelineReportingConfigTypes, +) +from graphrag.index.config.storage import ( + PipelineBlobStorageConfig, + PipelineFileStorageConfig, + PipelineMemoryStorageConfig, + PipelineStorageConfigTypes, +) +from graphrag.index.config.workflow import ( + PipelineWorkflowReference, +) +from graphrag.index.workflows.default_workflows import ( + create_base_documents, + create_base_entity_graph, + create_base_extracted_entities, + create_base_text_units, + create_final_communities, + create_final_community_reports, + create_final_covariates, + create_final_documents, + create_final_entities, + create_final_nodes, + create_final_relationships, + create_final_text_units, + create_summarized_entities, + join_text_units_to_covariate_ids, + join_text_units_to_entity_ids, + join_text_units_to_relationship_ids, +) + +log = logging.getLogger(__name__) + + +entity_name_embedding = "entity.name" +entity_description_embedding = "entity.description" +relationship_description_embedding = "relationship.description" +document_raw_content_embedding = "document.raw_content" +community_title_embedding = "community.title" +community_summary_embedding = "community.summary" +community_full_content_embedding = "community.full_content" +text_unit_text_embedding = "text_unit.text" + +all_embeddings: set[str] = { + entity_name_embedding, + entity_description_embedding, + relationship_description_embedding, + document_raw_content_embedding, + community_title_embedding, + community_summary_embedding, + community_full_content_embedding, + text_unit_text_embedding, +} +required_embeddings: set[str] = {entity_description_embedding} + + +builtin_document_attributes: set[str] = { + "id", + "source", + "text", + "title", + "timestamp", + "year", + "month", + "day", + "hour", + "minute", + "second", +} + + +def create_pipeline_config(settings: GraphRagConfig, verbose=False) -> PipelineConfig: + """Get the default config for the pipeline.""" + # relative to the root_dir + if verbose: + _log_llm_settings(settings) + + skip_workflows = _determine_skip_workflows(settings) + embedded_fields = _get_embedded_fields(settings) + covariates_enabled = ( + settings.claim_extraction.enabled + and create_final_covariates not in skip_workflows + ) + + result = PipelineConfig( + root_dir=settings.root_dir, + input=_get_pipeline_input_config(settings), + reporting=_get_reporting_config(settings), + storage=_get_storage_config(settings), + cache=_get_cache_config(settings), + workflows=[ + *_document_workflows(settings, embedded_fields), + *_text_unit_workflows(settings, covariates_enabled, embedded_fields), + *_graph_workflows(settings, embedded_fields), + *_community_workflows(settings, covariates_enabled, embedded_fields), + *(_covariate_workflows(settings) if covariates_enabled else []), + ], + ) + + # Remove any workflows that were specified to be skipped + log.info("skipping workflows %s", ",".join(skip_workflows)) + result.workflows = [w for w in result.workflows if w.name not in skip_workflows] + return result + + +def _get_embedded_fields(settings: GraphRagConfig) -> set[str]: + match settings.embeddings.target: + case TextEmbeddingTarget.all: + return all_embeddings - {*settings.embeddings.skip} + case TextEmbeddingTarget.required: + return required_embeddings + case _: + msg = f"Unknown embeddings target: {settings.embeddings.target}" + raise ValueError(msg) + + +def _determine_skip_workflows(settings: GraphRagConfig) -> list[str]: + skip_workflows = settings.skip_workflows + if ( + create_final_covariates in skip_workflows + and join_text_units_to_covariate_ids not in skip_workflows + ): + skip_workflows.append(join_text_units_to_covariate_ids) + return skip_workflows + + +def _log_llm_settings(settings: GraphRagConfig) -> None: + log.info( + "Using LLM Config %s", + json.dumps( + {**settings.entity_extraction.llm.model_dump(), "api_key": "*****"}, + indent=4, + ), + ) + log.info( + "Using Embeddings Config %s", + json.dumps( + {**settings.embeddings.llm.model_dump(), "api_key": "*****"}, indent=4 + ), + ) + + +def _document_workflows( + settings: GraphRagConfig, embedded_fields: set[str] +) -> list[PipelineWorkflowReference]: + skip_document_raw_content_embedding = ( + document_raw_content_embedding not in embedded_fields + ) + return [ + PipelineWorkflowReference( + name=create_base_documents, + config={ + "document_attribute_columns": list( + {*(settings.input.document_attribute_columns)} + - builtin_document_attributes + ) + }, + ), + PipelineWorkflowReference( + name=create_final_documents, + config={ + "document_raw_content_embed": _get_embedding_settings( + settings.embeddings, "document_raw_content" + ), + "skip_raw_content_embedding": skip_document_raw_content_embedding, + }, + ), + ] + + +def _text_unit_workflows( + settings: GraphRagConfig, + covariates_enabled: bool, + embedded_fields: set[str], +) -> list[PipelineWorkflowReference]: + skip_text_unit_embedding = text_unit_text_embedding not in embedded_fields + return [ + PipelineWorkflowReference( + name=create_base_text_units, + config={ + "chunk_by": settings.chunks.group_by_columns, + "text_chunk": {"strategy": settings.chunks.resolved_strategy()}, + }, + ), + PipelineWorkflowReference( + name=join_text_units_to_entity_ids, + ), + PipelineWorkflowReference( + name=join_text_units_to_relationship_ids, + ), + *( + [ + PipelineWorkflowReference( + name=join_text_units_to_covariate_ids, + ) + ] + if covariates_enabled + else [] + ), + PipelineWorkflowReference( + name=create_final_text_units, + config={ + "text_unit_text_embed": _get_embedding_settings( + settings.embeddings, "text_unit_text" + ), + "covariates_enabled": covariates_enabled, + "skip_text_unit_embedding": skip_text_unit_embedding, + }, + ), + ] + + +def _get_embedding_settings(settings: TextEmbeddingConfig, embedding_name: str) -> dict: + vector_store_settings = settings.vector_store + if vector_store_settings is None: + return {"strategy": settings.resolved_strategy()} + + # + # If we get to this point, settings.vector_store is defined, and there's a specific setting for this embedding. + # settings.vector_store.base contains connection information, or may be undefined + # settings.vector_store. contains the specific settings for this embedding + # + strategy = settings.resolved_strategy() # get the default strategy + strategy.update({ + "vector_store": vector_store_settings + }) # update the default strategy with the vector store settings + # This ensures the vector store config is part of the strategy and not the global config + return { + "strategy": strategy, + "embedding_name": embedding_name, + } + + +def _graph_workflows( + settings: GraphRagConfig, embedded_fields: set[str] +) -> list[PipelineWorkflowReference]: + skip_entity_name_embedding = entity_name_embedding not in embedded_fields + skip_entity_description_embedding = ( + entity_description_embedding not in embedded_fields + ) + skip_relationship_description_embedding = ( + relationship_description_embedding not in embedded_fields + ) + return [ + PipelineWorkflowReference( + name=create_base_extracted_entities, + config={ + "graphml_snapshot": settings.snapshots.graphml, + "raw_entity_snapshot": settings.snapshots.raw_entities, + "entity_extract": { + **settings.entity_extraction.parallelization.model_dump(), + "async_mode": settings.entity_extraction.async_mode, + "strategy": settings.entity_extraction.resolved_strategy( + settings.root_dir, settings.encoding_model + ), + "entity_types": settings.entity_extraction.entity_types, + }, + }, + ), + PipelineWorkflowReference( + name=create_summarized_entities, + config={ + "graphml_snapshot": settings.snapshots.graphml, + "summarize_descriptions": { + **settings.summarize_descriptions.parallelization.model_dump(), + "async_mode": settings.summarize_descriptions.async_mode, + "strategy": settings.summarize_descriptions.resolved_strategy( + settings.root_dir, + ), + }, + }, + ), + PipelineWorkflowReference( + name=create_base_entity_graph, + config={ + "graphml_snapshot": settings.snapshots.graphml, + "embed_graph_enabled": settings.embed_graph.enabled, + "cluster_graph": { + "strategy": settings.cluster_graph.resolved_strategy() + }, + "embed_graph": {"strategy": settings.embed_graph.resolved_strategy()}, + }, + ), + PipelineWorkflowReference( + name=create_final_entities, + config={ + "entity_name_embed": _get_embedding_settings( + settings.embeddings, "entity_name" + ), + "entity_name_description_embed": _get_embedding_settings( + settings.embeddings, "entity_name_description" + ), + "skip_name_embedding": skip_entity_name_embedding, + "skip_description_embedding": skip_entity_description_embedding, + }, + ), + PipelineWorkflowReference( + name=create_final_relationships, + config={ + "relationship_description_embed": _get_embedding_settings( + settings.embeddings, "relationship_description" + ), + "skip_description_embedding": skip_relationship_description_embedding, + }, + ), + PipelineWorkflowReference( + name=create_final_nodes, + config={ + "layout_graph_enabled": settings.umap.enabled, + "snapshot_top_level_nodes": settings.snapshots.top_level_nodes, + }, + ), + ] + + +def _community_workflows( + settings: GraphRagConfig, covariates_enabled: bool, embedded_fields: set[str] +) -> list[PipelineWorkflowReference]: + skip_community_title_embedding = community_title_embedding not in embedded_fields + skip_community_summary_embedding = ( + community_summary_embedding not in embedded_fields + ) + skip_community_full_content_embedding = ( + community_full_content_embedding not in embedded_fields + ) + return [ + PipelineWorkflowReference(name=create_final_communities), + PipelineWorkflowReference( + name=create_final_community_reports, + config={ + "covariates_enabled": covariates_enabled, + "skip_title_embedding": skip_community_title_embedding, + "skip_summary_embedding": skip_community_summary_embedding, + "skip_full_content_embedding": skip_community_full_content_embedding, + "create_community_reports": { + **settings.community_reports.parallelization.model_dump(), + "async_mode": settings.community_reports.async_mode, + "strategy": settings.community_reports.resolved_strategy( + settings.root_dir + ), + }, + "community_report_full_content_embed": _get_embedding_settings( + settings.embeddings, "community_report_full_content" + ), + "community_report_summary_embed": _get_embedding_settings( + settings.embeddings, "community_report_summary" + ), + "community_report_title_embed": _get_embedding_settings( + settings.embeddings, "community_report_title" + ), + }, + ), + ] + + +def _covariate_workflows( + settings: GraphRagConfig, +) -> list[PipelineWorkflowReference]: + return [ + PipelineWorkflowReference( + name=create_final_covariates, + config={ + "claim_extract": { + **settings.claim_extraction.parallelization.model_dump(), + "strategy": settings.claim_extraction.resolved_strategy( + settings.root_dir + ), + }, + }, + ) + ] + + +def _get_pipeline_input_config( + settings: GraphRagConfig, +) -> PipelineInputConfigTypes: + file_type = settings.input.file_type + match file_type: + case InputFileType.csv: + return PipelineCSVInputConfig( + base_dir=settings.input.base_dir, + file_pattern=settings.input.file_pattern, + encoding=settings.input.encoding, + source_column=settings.input.source_column, + timestamp_column=settings.input.timestamp_column, + timestamp_format=settings.input.timestamp_format, + text_column=settings.input.text_column, + title_column=settings.input.title_column, + type=settings.input.type, + connection_string=settings.input.connection_string, + storage_account_blob_url=settings.input.storage_account_blob_url, + container_name=settings.input.container_name, + ) + case InputFileType.text: + return PipelineTextInputConfig( + base_dir=settings.input.base_dir, + file_pattern=settings.input.file_pattern, + encoding=settings.input.encoding, + type=settings.input.type, + connection_string=settings.input.connection_string, + storage_account_blob_url=settings.input.storage_account_blob_url, + container_name=settings.input.container_name, + ) + case _: + msg = f"Unknown input type: {file_type}" + raise ValueError(msg) + + +def _get_reporting_config( + settings: GraphRagConfig, +) -> PipelineReportingConfigTypes: + """Get the reporting config from the settings.""" + match settings.reporting.type: + case ReportingType.file: + # relative to the root_dir + return PipelineFileReportingConfig(base_dir=settings.reporting.base_dir) + case ReportingType.blob: + connection_string = settings.reporting.connection_string + storage_account_blob_url = settings.reporting.storage_account_blob_url + container_name = settings.reporting.container_name + if container_name is None: + msg = "Container name must be provided for blob reporting." + raise ValueError(msg) + if connection_string is None and storage_account_blob_url is None: + msg = "Connection string or storage account blob url must be provided for blob reporting." + raise ValueError(msg) + return PipelineBlobReportingConfig( + connection_string=connection_string, + container_name=container_name, + base_dir=settings.reporting.base_dir, + storage_account_blob_url=storage_account_blob_url, + ) + case ReportingType.console: + return PipelineConsoleReportingConfig() + case _: + # relative to the root_dir + return PipelineFileReportingConfig(base_dir=settings.reporting.base_dir) + + +def _get_storage_config( + settings: GraphRagConfig, +) -> PipelineStorageConfigTypes: + """Get the storage type from the settings.""" + root_dir = settings.root_dir + match settings.storage.type: + case StorageType.memory: + return PipelineMemoryStorageConfig() + case StorageType.file: + # relative to the root_dir + base_dir = settings.storage.base_dir + if base_dir is None: + msg = "Base directory must be provided for file storage." + raise ValueError(msg) + return PipelineFileStorageConfig(base_dir=str(Path(root_dir) / base_dir)) + case StorageType.blob: + connection_string = settings.storage.connection_string + storage_account_blob_url = settings.storage.storage_account_blob_url + container_name = settings.storage.container_name + if container_name is None: + msg = "Container name must be provided for blob storage." + raise ValueError(msg) + if connection_string is None and storage_account_blob_url is None: + msg = "Connection string or storage account blob url must be provided for blob storage." + raise ValueError(msg) + return PipelineBlobStorageConfig( + connection_string=connection_string, + container_name=container_name, + base_dir=settings.storage.base_dir, + storage_account_blob_url=storage_account_blob_url, + ) + case _: + # relative to the root_dir + base_dir = settings.storage.base_dir + if base_dir is None: + msg = "Base directory must be provided for file storage." + raise ValueError(msg) + return PipelineFileStorageConfig(base_dir=str(Path(root_dir) / base_dir)) + + +def _get_cache_config( + settings: GraphRagConfig, +) -> PipelineCacheConfigTypes: + """Get the cache type from the settings.""" + match settings.cache.type: + case CacheType.memory: + return PipelineMemoryCacheConfig() + case CacheType.file: + # relative to root dir + return PipelineFileCacheConfig(base_dir=settings.cache.base_dir) + case CacheType.none: + return PipelineNoneCacheConfig() + case CacheType.blob: + connection_string = settings.cache.connection_string + storage_account_blob_url = settings.cache.storage_account_blob_url + container_name = settings.cache.container_name + if container_name is None: + msg = "Container name must be provided for blob cache." + raise ValueError(msg) + if connection_string is None and storage_account_blob_url is None: + msg = "Connection string or storage account blob url must be provided for blob cache." + raise ValueError(msg) + return PipelineBlobCacheConfig( + connection_string=connection_string, + container_name=container_name, + base_dir=settings.cache.base_dir, + storage_account_blob_url=storage_account_blob_url, + ) + case _: + # relative to root dir + return PipelineFileCacheConfig(base_dir="./cache") diff --git a/graphrag/graphrag/index/emit/__init__.py b/graphrag/graphrag/index/emit/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..354989e3382d424ea3443422d804ceb21b20cc82 --- /dev/null +++ b/graphrag/graphrag/index/emit/__init__.py @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Definitions for emitting pipeline artifacts to storage.""" + +from .csv_table_emitter import CSVTableEmitter +from .factories import create_table_emitter, create_table_emitters +from .json_table_emitter import JsonTableEmitter +from .parquet_table_emitter import ParquetTableEmitter +from .table_emitter import TableEmitter +from .types import TableEmitterType + +__all__ = [ + "CSVTableEmitter", + "JsonTableEmitter", + "ParquetTableEmitter", + "TableEmitter", + "TableEmitterType", + "create_table_emitter", + "create_table_emitters", +] diff --git a/graphrag/graphrag/index/emit/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/emit/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..353e44308550abf3f87a7c5fb711accd6cdaffa4 Binary files /dev/null and b/graphrag/graphrag/index/emit/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/emit/__pycache__/csv_table_emitter.cpython-311.pyc b/graphrag/graphrag/index/emit/__pycache__/csv_table_emitter.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c484de4fb68a37bbd98240067017b8ae40605d6 Binary files /dev/null and b/graphrag/graphrag/index/emit/__pycache__/csv_table_emitter.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/emit/__pycache__/factories.cpython-311.pyc b/graphrag/graphrag/index/emit/__pycache__/factories.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..add8f253a29eefa1930f621371a31d4e9a86e673 Binary files /dev/null and b/graphrag/graphrag/index/emit/__pycache__/factories.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/emit/__pycache__/json_table_emitter.cpython-311.pyc b/graphrag/graphrag/index/emit/__pycache__/json_table_emitter.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23e0454a208d6eb808064a3296daa430952297c6 Binary files /dev/null and b/graphrag/graphrag/index/emit/__pycache__/json_table_emitter.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/emit/__pycache__/parquet_table_emitter.cpython-311.pyc b/graphrag/graphrag/index/emit/__pycache__/parquet_table_emitter.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8baae367b37d02dd97b4c745175ba8f4fdf584f Binary files /dev/null and b/graphrag/graphrag/index/emit/__pycache__/parquet_table_emitter.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/emit/__pycache__/table_emitter.cpython-311.pyc b/graphrag/graphrag/index/emit/__pycache__/table_emitter.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a56275afae6ce14751599a93fc84b71c64e6ffe Binary files /dev/null and b/graphrag/graphrag/index/emit/__pycache__/table_emitter.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/emit/__pycache__/types.cpython-311.pyc b/graphrag/graphrag/index/emit/__pycache__/types.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0540f3a95ff9c7c082eb02181950c521d7927856 Binary files /dev/null and b/graphrag/graphrag/index/emit/__pycache__/types.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/emit/csv_table_emitter.py b/graphrag/graphrag/index/emit/csv_table_emitter.py new file mode 100644 index 0000000000000000000000000000000000000000..c0305c254bcb18ffdba4ebad713b164f8ab91d7e --- /dev/null +++ b/graphrag/graphrag/index/emit/csv_table_emitter.py @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""CSVTableEmitter module.""" + +import logging + +import pandas as pd + +from graphrag.index.storage import PipelineStorage + +from .table_emitter import TableEmitter + +log = logging.getLogger(__name__) + + +class CSVTableEmitter(TableEmitter): + """CSVTableEmitter class.""" + + _storage: PipelineStorage + + def __init__(self, storage: PipelineStorage): + """Create a new CSV Table Emitter.""" + self._storage = storage + + async def emit(self, name: str, data: pd.DataFrame) -> None: + """Emit a dataframe to storage.""" + filename = f"{name}.csv" + log.info("emitting CSV table %s", filename) + await self._storage.set( + filename, + data.to_csv(), + ) diff --git a/graphrag/graphrag/index/emit/factories.py b/graphrag/graphrag/index/emit/factories.py new file mode 100644 index 0000000000000000000000000000000000000000..84afa684431ef3440d361e08b2e78acca3a76d47 --- /dev/null +++ b/graphrag/graphrag/index/emit/factories.py @@ -0,0 +1,41 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Table Emitter Factories.""" + +from graphrag.index.storage import PipelineStorage +from graphrag.index.typing import ErrorHandlerFn + +from .csv_table_emitter import CSVTableEmitter +from .json_table_emitter import JsonTableEmitter +from .parquet_table_emitter import ParquetTableEmitter +from .table_emitter import TableEmitter +from .types import TableEmitterType + + +def create_table_emitter( + emitter_type: TableEmitterType, storage: PipelineStorage, on_error: ErrorHandlerFn +) -> TableEmitter: + """Create a table emitter based on the specified type.""" + match emitter_type: + case TableEmitterType.Json: + return JsonTableEmitter(storage) + case TableEmitterType.Parquet: + return ParquetTableEmitter(storage, on_error) + case TableEmitterType.CSV: + return CSVTableEmitter(storage) + case _: + msg = f"Unsupported table emitter type: {emitter_type}" + raise ValueError(msg) + + +def create_table_emitters( + emitter_types: list[TableEmitterType], + storage: PipelineStorage, + on_error: ErrorHandlerFn, +) -> list[TableEmitter]: + """Create a list of table emitters based on the specified types.""" + return [ + create_table_emitter(emitter_type, storage, on_error) + for emitter_type in emitter_types + ] diff --git a/graphrag/graphrag/index/emit/json_table_emitter.py b/graphrag/graphrag/index/emit/json_table_emitter.py new file mode 100644 index 0000000000000000000000000000000000000000..0b18c717a6d61994a614e715697221d61d9cc75b --- /dev/null +++ b/graphrag/graphrag/index/emit/json_table_emitter.py @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""JsonTableEmitter module.""" + +import logging + +import pandas as pd + +from graphrag.index.storage import PipelineStorage + +from .table_emitter import TableEmitter + +log = logging.getLogger(__name__) + + +class JsonTableEmitter(TableEmitter): + """JsonTableEmitter class.""" + + _storage: PipelineStorage + + def __init__(self, storage: PipelineStorage): + """Create a new Json Table Emitter.""" + self._storage = storage + + async def emit(self, name: str, data: pd.DataFrame) -> None: + """Emit a dataframe to storage.""" + filename = f"{name}.json" + + log.info("emitting JSON table %s", filename) + await self._storage.set( + filename, + data.to_json(orient="records", lines=True, force_ascii=False), + ) diff --git a/graphrag/graphrag/index/emit/parquet_table_emitter.py b/graphrag/graphrag/index/emit/parquet_table_emitter.py new file mode 100644 index 0000000000000000000000000000000000000000..753915a79a06159dee0cad0d2434767502c2cfe2 --- /dev/null +++ b/graphrag/graphrag/index/emit/parquet_table_emitter.py @@ -0,0 +1,54 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""ParquetTableEmitter module.""" + +import logging +import traceback + +import pandas as pd +from pyarrow.lib import ArrowInvalid, ArrowTypeError + +from graphrag.index.storage import PipelineStorage +from graphrag.index.typing import ErrorHandlerFn + +from .table_emitter import TableEmitter + +log = logging.getLogger(__name__) + + +class ParquetTableEmitter(TableEmitter): + """ParquetTableEmitter class.""" + + _storage: PipelineStorage + _on_error: ErrorHandlerFn + + def __init__( + self, + storage: PipelineStorage, + on_error: ErrorHandlerFn, + ): + """Create a new Parquet Table Emitter.""" + self._storage = storage + self._on_error = on_error + + async def emit(self, name: str, data: pd.DataFrame) -> None: + """Emit a dataframe to storage.""" + filename = f"{name}.parquet" + log.info("emitting parquet table %s", filename) + try: + await self._storage.set(filename, data.to_parquet()) + except ArrowTypeError as e: + log.exception("Error while emitting parquet table") + self._on_error( + e, + traceback.format_exc(), + None, + ) + except ArrowInvalid as e: + log.exception("Error while emitting parquet table") + self._on_error( + e, + traceback.format_exc(), + None, + ) diff --git a/graphrag/graphrag/index/emit/table_emitter.py b/graphrag/graphrag/index/emit/table_emitter.py new file mode 100644 index 0000000000000000000000000000000000000000..2161eeb52391c6a58942b366b257f59840bb6b08 --- /dev/null +++ b/graphrag/graphrag/index/emit/table_emitter.py @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""TableEmitter protocol for emitting tables to a destination.""" + +from typing import Protocol + +import pandas as pd + + +class TableEmitter(Protocol): + """TableEmitter protocol for emitting tables to a destination.""" + + async def emit(self, name: str, data: pd.DataFrame) -> None: + """Emit a dataframe to storage.""" diff --git a/graphrag/graphrag/index/emit/types.py b/graphrag/graphrag/index/emit/types.py new file mode 100644 index 0000000000000000000000000000000000000000..ab3452856f4a4d7d564e829e7c37f7c35f4b4d40 --- /dev/null +++ b/graphrag/graphrag/index/emit/types.py @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Table Emitter Types.""" + +from enum import Enum + + +class TableEmitterType(str, Enum): + """Table Emitter Types.""" + + Json = "json" + Parquet = "parquet" + CSV = "csv" diff --git a/graphrag/graphrag/index/errors.py b/graphrag/graphrag/index/errors.py new file mode 100644 index 0000000000000000000000000000000000000000..430cf27d0f095af84d37510f7adaac62cfc21988 --- /dev/null +++ b/graphrag/graphrag/index/errors.py @@ -0,0 +1,25 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""GraphRAG indexing error types.""" + + +class NoWorkflowsDefinedError(ValueError): + """Exception for no workflows defined.""" + + def __init__(self): + super().__init__("No workflows defined.") + + +class UndefinedWorkflowError(ValueError): + """Exception for invalid verb input.""" + + def __init__(self): + super().__init__("Workflow name is undefined.") + + +class UnknownWorkflowError(ValueError): + """Exception for invalid verb input.""" + + def __init__(self, name: str): + super().__init__(f"Unknown workflow: {name}") diff --git a/graphrag/graphrag/index/graph/__init__.py b/graphrag/graphrag/index/graph/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cb26e595953daf91b391094695b66bf99b82837d --- /dev/null +++ b/graphrag/graphrag/index/graph/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph package root.""" diff --git a/graphrag/graphrag/index/graph/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/graph/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a95e22697e3ba2f95c53a45428f247eea44ac5b5 Binary files /dev/null and b/graphrag/graphrag/index/graph/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/graph/embedding/__init__.py b/graphrag/graphrag/index/graph/embedding/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0ea2d085f197042cb569d3a5121eb2ad2aaca3ef --- /dev/null +++ b/graphrag/graphrag/index/graph/embedding/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph embedding package root.""" + +from .embedding import NodeEmbeddings, embed_nod2vec + +__all__ = ["NodeEmbeddings", "embed_nod2vec"] diff --git a/graphrag/graphrag/index/graph/embedding/embedding.py b/graphrag/graphrag/index/graph/embedding/embedding.py new file mode 100644 index 0000000000000000000000000000000000000000..267a190f914e09df8002807dd3a5797c54a5a868 --- /dev/null +++ b/graphrag/graphrag/index/graph/embedding/embedding.py @@ -0,0 +1,41 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Utilities to generate graph embeddings.""" + +from dataclasses import dataclass + +import graspologic as gc +import networkx as nx +import numpy as np + + +@dataclass +class NodeEmbeddings: + """Node embeddings class definition.""" + + nodes: list[str] + embeddings: np.ndarray + + +def embed_nod2vec( + graph: nx.Graph | nx.DiGraph, + dimensions: int = 1536, + num_walks: int = 10, + walk_length: int = 40, + window_size: int = 2, + iterations: int = 3, + random_seed: int = 86, +) -> NodeEmbeddings: + """Generate node embeddings using Node2Vec.""" + # generate embedding + lcc_tensors = gc.embed.node2vec_embed( # type: ignore + graph=graph, + dimensions=dimensions, + window_size=window_size, + iterations=iterations, + num_walks=num_walks, + walk_length=walk_length, + random_seed=random_seed, + ) + return NodeEmbeddings(embeddings=lcc_tensors[0], nodes=lcc_tensors[1]) diff --git a/graphrag/graphrag/index/graph/extractors/__init__.py b/graphrag/graphrag/index/graph/extractors/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9168d5e2070a4a5391b1ac4847de22564895dfe9 --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/__init__.py @@ -0,0 +1,20 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph extractors package root.""" + +from .claims import CLAIM_EXTRACTION_PROMPT, ClaimExtractor +from .community_reports import ( + COMMUNITY_REPORT_PROMPT, + CommunityReportsExtractor, +) +from .graph import GraphExtractionResult, GraphExtractor + +__all__ = [ + "CLAIM_EXTRACTION_PROMPT", + "COMMUNITY_REPORT_PROMPT", + "ClaimExtractor", + "CommunityReportsExtractor", + "GraphExtractionResult", + "GraphExtractor", +] diff --git a/graphrag/graphrag/index/graph/extractors/claims/__init__.py b/graphrag/graphrag/index/graph/extractors/claims/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3977c8ff83bff76a0aeedeed1c2aac33baf16e98 --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/claims/__init__.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph extractors claims package root.""" + +from .claim_extractor import ClaimExtractor +from .prompts import CLAIM_EXTRACTION_PROMPT + +__all__ = ["CLAIM_EXTRACTION_PROMPT", "ClaimExtractor"] diff --git a/graphrag/graphrag/index/graph/extractors/claims/claim_extractor.py b/graphrag/graphrag/index/graph/extractors/claims/claim_extractor.py new file mode 100644 index 0000000000000000000000000000000000000000..e26d206949fa75dd2d26e75f7fab771ae117beab --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/claims/claim_extractor.py @@ -0,0 +1,248 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'ClaimExtractorResult' and 'ClaimExtractor' models.""" + +import logging +import traceback +from dataclasses import dataclass +from typing import Any + +import tiktoken + +import graphrag.config.defaults as defs +from graphrag.index.typing import ErrorHandlerFn +from graphrag.llm import CompletionLLM + +from .prompts import ( + CLAIM_EXTRACTION_PROMPT, + CONTINUE_PROMPT, + LOOP_PROMPT, +) + +DEFAULT_TUPLE_DELIMITER = "<|>" +DEFAULT_RECORD_DELIMITER = "##" +DEFAULT_COMPLETION_DELIMITER = "<|COMPLETE|>" +log = logging.getLogger(__name__) + + +@dataclass +class ClaimExtractorResult: + """Claim extractor result class definition.""" + + output: list[dict] + source_docs: dict[str, Any] + + +class ClaimExtractor: + """Claim extractor class definition.""" + + _llm: CompletionLLM + _extraction_prompt: str + _summary_prompt: str + _output_formatter_prompt: str + _input_text_key: str + _input_entity_spec_key: str + _input_claim_description_key: str + _tuple_delimiter_key: str + _record_delimiter_key: str + _completion_delimiter_key: str + _max_gleanings: int + _on_error: ErrorHandlerFn + + def __init__( + self, + llm_invoker: CompletionLLM, + extraction_prompt: str | None = None, + input_text_key: str | None = None, + input_entity_spec_key: str | None = None, + input_claim_description_key: str | None = None, + input_resolved_entities_key: str | None = None, + tuple_delimiter_key: str | None = None, + record_delimiter_key: str | None = None, + completion_delimiter_key: str | None = None, + encoding_model: str | None = None, + max_gleanings: int | None = None, + on_error: ErrorHandlerFn | None = None, + ): + """Init method definition.""" + self._llm = llm_invoker + self._extraction_prompt = extraction_prompt or CLAIM_EXTRACTION_PROMPT + self._input_text_key = input_text_key or "input_text" + self._input_entity_spec_key = input_entity_spec_key or "entity_specs" + self._tuple_delimiter_key = tuple_delimiter_key or "tuple_delimiter" + self._record_delimiter_key = record_delimiter_key or "record_delimiter" + self._completion_delimiter_key = ( + completion_delimiter_key or "completion_delimiter" + ) + self._input_claim_description_key = ( + input_claim_description_key or "claim_description" + ) + self._input_resolved_entities_key = ( + input_resolved_entities_key or "resolved_entities" + ) + self._max_gleanings = ( + max_gleanings if max_gleanings is not None else defs.CLAIM_MAX_GLEANINGS + ) + self._on_error = on_error or (lambda _e, _s, _d: None) + + # Construct the looping arguments + encoding = tiktoken.get_encoding(encoding_model or "cl100k_base") + yes = encoding.encode("YES") + no = encoding.encode("NO") + self._loop_args = {"logit_bias": {yes[0]: 100, no[0]: 100}, "max_tokens": 1} + + async def __call__( + self, inputs: dict[str, Any], prompt_variables: dict | None = None + ) -> ClaimExtractorResult: + """Call method definition.""" + if prompt_variables is None: + prompt_variables = {} + texts = inputs[self._input_text_key] + entity_spec = str(inputs[self._input_entity_spec_key]) + claim_description = inputs[self._input_claim_description_key] + resolved_entities = inputs.get(self._input_resolved_entities_key, {}) + source_doc_map = {} + + prompt_args = { + self._input_entity_spec_key: entity_spec, + self._input_claim_description_key: claim_description, + self._tuple_delimiter_key: prompt_variables.get(self._tuple_delimiter_key) + or DEFAULT_TUPLE_DELIMITER, + self._record_delimiter_key: prompt_variables.get(self._record_delimiter_key) + or DEFAULT_RECORD_DELIMITER, + self._completion_delimiter_key: prompt_variables.get( + self._completion_delimiter_key + ) + or DEFAULT_COMPLETION_DELIMITER, + } + + all_claims: list[dict] = [] + for doc_index, text in enumerate(texts): + document_id = f"d{doc_index}" + try: + claims = await self._process_document(prompt_args, text, doc_index) + all_claims += [ + self._clean_claim(c, document_id, resolved_entities) for c in claims + ] + source_doc_map[document_id] = text + except Exception as e: + log.exception("error extracting claim") + self._on_error( + e, + traceback.format_exc(), + {"doc_index": doc_index, "text": text}, + ) + continue + + return ClaimExtractorResult( + output=all_claims, + source_docs=source_doc_map, + ) + + def _clean_claim( + self, claim: dict, document_id: str, resolved_entities: dict + ) -> dict: + # clean the parsed claims to remove any claims with status = False + obj = claim.get("object_id", claim.get("object")) + subject = claim.get("subject_id", claim.get("subject")) + + # If subject or object in resolved entities, then replace with resolved entity + obj = resolved_entities.get(obj, obj) + subject = resolved_entities.get(subject, subject) + claim["object_id"] = obj + claim["subject_id"] = subject + claim["doc_id"] = document_id + return claim + + async def _process_document( + self, prompt_args: dict, doc, doc_index: int + ) -> list[dict]: + record_delimiter = prompt_args.get( + self._record_delimiter_key, DEFAULT_RECORD_DELIMITER + ) + completion_delimiter = prompt_args.get( + self._completion_delimiter_key, DEFAULT_COMPLETION_DELIMITER + ) + + response = await self._llm( + self._extraction_prompt, + variables={ + self._input_text_key: doc, + **prompt_args, + }, + ) + results = response.output or "" + claims = results.strip().removesuffix(completion_delimiter) + + # Repeat to ensure we maximize entity count + for i in range(self._max_gleanings): + glean_response = await self._llm( + CONTINUE_PROMPT, + name=f"extract-continuation-{i}", + history=response.history or [], + ) + extension = glean_response.output or "" + claims += record_delimiter + extension.strip().removesuffix( + completion_delimiter + ) + + # If this isn't the last loop, check to see if we should continue + if i >= self._max_gleanings - 1: + break + + continue_response = await self._llm( + LOOP_PROMPT, + name=f"extract-loopcheck-{i}", + history=glean_response.history or [], + model_parameters=self._loop_args, + ) + if continue_response.output != "YES": + break + + result = self._parse_claim_tuples(results, prompt_args) + for r in result: + r["doc_id"] = f"{doc_index}" + return result + + def _parse_claim_tuples( + self, claims: str, prompt_variables: dict + ) -> list[dict[str, Any]]: + """Parse claim tuples.""" + record_delimiter = prompt_variables.get( + self._record_delimiter_key, DEFAULT_RECORD_DELIMITER + ) + completion_delimiter = prompt_variables.get( + self._completion_delimiter_key, DEFAULT_COMPLETION_DELIMITER + ) + tuple_delimiter = prompt_variables.get( + self._tuple_delimiter_key, DEFAULT_TUPLE_DELIMITER + ) + + def pull_field(index: int, fields: list[str]) -> str | None: + return fields[index].strip() if len(fields) > index else None + + result: list[dict[str, Any]] = [] + claims_values = ( + claims.strip().removesuffix(completion_delimiter).split(record_delimiter) + ) + for claim in claims_values: + claim = claim.strip().removeprefix("(").removesuffix(")") + + # Ignore the completion delimiter + if claim == completion_delimiter: + continue + + claim_fields = claim.split(tuple_delimiter) + result.append({ + "subject_id": pull_field(0, claim_fields), + "object_id": pull_field(1, claim_fields), + "type": pull_field(2, claim_fields), + "status": pull_field(3, claim_fields), + "start_date": pull_field(4, claim_fields), + "end_date": pull_field(5, claim_fields), + "description": pull_field(6, claim_fields), + "source_text": pull_field(7, claim_fields), + "doc_id": pull_field(8, claim_fields), + }) + return result diff --git a/graphrag/graphrag/index/graph/extractors/claims/prompts.py b/graphrag/graphrag/index/graph/extractors/claims/prompts.py new file mode 100644 index 0000000000000000000000000000000000000000..05b3153c2004e4d541c1a466db88cafcaf7c1345 --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/claims/prompts.py @@ -0,0 +1,61 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A file containing prompts definition.""" + +CLAIM_EXTRACTION_PROMPT = """ +-Target activity- +You are an intelligent assistant that helps a human analyst to analyze claims against certain entities presented in a text document. + +-Goal- +Given a text document that is potentially relevant to this activity, an entity specification, and a claim description, extract all entities that match the entity specification and all claims against those entities. + +-Steps- +1. Extract all named entities that match the predefined entity specification. Entity specification can either be a list of entity names or a list of entity types. +2. For each entity identified in step 1, extract all claims associated with the entity. Claims need to match the specified claim description, and the entity should be the subject of the claim. +For each claim, extract the following information: +- Subject: name of the entity that is subject of the claim, capitalized. The subject entity is one that committed the action described in the claim. Subject needs to be one of the named entities identified in step 1. +- Object: name of the entity that is object of the claim, capitalized. The object entity is one that either reports/handles or is affected by the action described in the claim. If object entity is unknown, use **NONE**. +- Claim Type: overall category of the claim, capitalized. Name it in a way that can be repeated across multiple text inputs, so that similar claims share the same claim type +- Claim Status: **TRUE**, **FALSE**, or **SUSPECTED**. TRUE means the claim is confirmed, FALSE means the claim is found to be False, SUSPECTED means the claim is not verified. +- Claim Description: Detailed description explaining the reasoning behind the claim, together with all the related evidence and references. +- Claim Date: Period (start_date, end_date) when the claim was made. Both start_date and end_date should be in ISO-8601 format. If the claim was made on a single date rather than a date range, set the same date for both start_date and end_date. If date is unknown, return **NONE**. +- Claim Source Text: List of **all** quotes from the original text that are relevant to the claim. + +Format each claim as ({tuple_delimiter}{tuple_delimiter}{tuple_delimiter}{tuple_delimiter}{tuple_delimiter}{tuple_delimiter}{tuple_delimiter}) + +3. Return output in English as a single list of all the claims identified in steps 1 and 2. Use **{record_delimiter}** as the list delimiter. + +4. When finished, output {completion_delimiter} + +-Examples- +Example 1: +Entity specification: organization +Claim description: red flags associated with an entity +Text: According to an article on 2022/01/10, Company A was fined for bid rigging while participating in multiple public tenders published by Government Agency B. The company is owned by Person C who was suspected of engaging in corruption activities in 2015. +Output: + +(COMPANY A{tuple_delimiter}GOVERNMENT AGENCY B{tuple_delimiter}ANTI-COMPETITIVE PRACTICES{tuple_delimiter}TRUE{tuple_delimiter}2022-01-10T00:00:00{tuple_delimiter}2022-01-10T00:00:00{tuple_delimiter}Company A was found to engage in anti-competitive practices because it was fined for bid rigging in multiple public tenders published by Government Agency B according to an article published on 2022/01/10{tuple_delimiter}According to an article published on 2022/01/10, Company A was fined for bid rigging while participating in multiple public tenders published by Government Agency B.) +{completion_delimiter} + +Example 2: +Entity specification: Company A, Person C +Claim description: red flags associated with an entity +Text: According to an article on 2022/01/10, Company A was fined for bid rigging while participating in multiple public tenders published by Government Agency B. The company is owned by Person C who was suspected of engaging in corruption activities in 2015. +Output: + +(COMPANY A{tuple_delimiter}GOVERNMENT AGENCY B{tuple_delimiter}ANTI-COMPETITIVE PRACTICES{tuple_delimiter}TRUE{tuple_delimiter}2022-01-10T00:00:00{tuple_delimiter}2022-01-10T00:00:00{tuple_delimiter}Company A was found to engage in anti-competitive practices because it was fined for bid rigging in multiple public tenders published by Government Agency B according to an article published on 2022/01/10{tuple_delimiter}According to an article published on 2022/01/10, Company A was fined for bid rigging while participating in multiple public tenders published by Government Agency B.) +{record_delimiter} +(PERSON C{tuple_delimiter}NONE{tuple_delimiter}CORRUPTION{tuple_delimiter}SUSPECTED{tuple_delimiter}2015-01-01T00:00:00{tuple_delimiter}2015-12-30T00:00:00{tuple_delimiter}Person C was suspected of engaging in corruption activities in 2015{tuple_delimiter}The company is owned by Person C who was suspected of engaging in corruption activities in 2015) +{completion_delimiter} + +-Real Data- +Use the following input for your answer. +Entity specification: {entity_specs} +Claim description: {claim_description} +Text: {input_text} +Output:""" + + +CONTINUE_PROMPT = "MANY entities were missed in the last extraction. Add them below using the same format:\n" +LOOP_PROMPT = "It appears some entities may have still been missed. Answer YES {tuple_delimiter} NO if there are still entities that need to be added.\n" diff --git a/graphrag/graphrag/index/graph/extractors/community_reports/__init__.py b/graphrag/graphrag/index/graph/extractors/community_reports/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..599f56d60f22b3635081c66c6eba08da7cad3ae1 --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/community_reports/__init__.py @@ -0,0 +1,35 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine community reports package root.""" + +import graphrag.index.graph.extractors.community_reports.schemas as schemas + +from .build_mixed_context import build_mixed_context +from .community_reports_extractor import CommunityReportsExtractor +from .prep_community_report_context import prep_community_report_context +from .prompts import COMMUNITY_REPORT_PROMPT +from .sort_context import sort_context +from .utils import ( + filter_claims_to_nodes, + filter_edges_to_nodes, + filter_nodes_to_level, + get_levels, + set_context_exceeds_flag, + set_context_size, +) + +__all__ = [ + "COMMUNITY_REPORT_PROMPT", + "CommunityReportsExtractor", + "build_mixed_context", + "filter_claims_to_nodes", + "filter_edges_to_nodes", + "filter_nodes_to_level", + "get_levels", + "prep_community_report_context", + "schemas", + "set_context_exceeds_flag", + "set_context_size", + "sort_context", +] diff --git a/graphrag/graphrag/index/graph/extractors/community_reports/build_mixed_context.py b/graphrag/graphrag/index/graph/extractors/community_reports/build_mixed_context.py new file mode 100644 index 0000000000000000000000000000000000000000..ad9e2a8447b772419311acd5ed0974bab3c850b2 --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/community_reports/build_mixed_context.py @@ -0,0 +1,69 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +"""A module containing the build_mixed_context method definition.""" + +import pandas as pd + +import graphrag.index.graph.extractors.community_reports.schemas as schemas +from graphrag.query.llm.text_utils import num_tokens + +from .sort_context import sort_context + + +def build_mixed_context(context: list[dict], max_tokens: int) -> str: + """ + Build parent context by concatenating all sub-communities' contexts. + + If the context exceeds the limit, we use sub-community reports instead. + """ + sorted_context = sorted( + context, key=lambda x: x[schemas.CONTEXT_SIZE], reverse=True + ) + + # replace local context with sub-community reports, starting from the biggest sub-community + substitute_reports = [] + final_local_contexts = [] + exceeded_limit = True + context_string = "" + + for idx, sub_community_context in enumerate(sorted_context): + if exceeded_limit: + if sub_community_context[schemas.FULL_CONTENT]: + substitute_reports.append({ + schemas.COMMUNITY_ID: sub_community_context[schemas.SUB_COMMUNITY], + schemas.FULL_CONTENT: sub_community_context[schemas.FULL_CONTENT], + }) + else: + # this sub-community has no report, so we will use its local context + final_local_contexts.extend(sub_community_context[schemas.ALL_CONTEXT]) + continue + + # add local context for the remaining sub-communities + remaining_local_context = [] + for rid in range(idx + 1, len(sorted_context)): + remaining_local_context.extend(sorted_context[rid][schemas.ALL_CONTEXT]) + new_context_string = sort_context( + local_context=remaining_local_context + final_local_contexts, + sub_community_reports=substitute_reports, + ) + if num_tokens(new_context_string) <= max_tokens: + exceeded_limit = False + context_string = new_context_string + break + + if exceeded_limit: + # if all sub-community reports exceed the limit, we add reports until context is full + substitute_reports = [] + for sub_community_context in sorted_context: + substitute_reports.append({ + schemas.COMMUNITY_ID: sub_community_context[schemas.SUB_COMMUNITY], + schemas.FULL_CONTENT: sub_community_context[schemas.FULL_CONTENT], + }) + new_context_string = pd.DataFrame(substitute_reports).to_csv( + index=False, sep="," + ) + if num_tokens(new_context_string) > max_tokens: + break + + context_string = new_context_string + return context_string diff --git a/graphrag/graphrag/index/graph/extractors/community_reports/community_reports_extractor.py b/graphrag/graphrag/index/graph/extractors/community_reports/community_reports_extractor.py new file mode 100644 index 0000000000000000000000000000000000000000..309336fee77507e761b021db71221e8e697cb71f --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/community_reports/community_reports_extractor.py @@ -0,0 +1,107 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'CommunityReportsResult' and 'CommunityReportsExtractor' models.""" + +import logging +import traceback +from dataclasses import dataclass +from typing import Any + +from graphrag.index.typing import ErrorHandlerFn +from graphrag.index.utils import dict_has_keys_with_types +from graphrag.llm import CompletionLLM + +from .prompts import COMMUNITY_REPORT_PROMPT + +log = logging.getLogger(__name__) + + +@dataclass +class CommunityReportsResult: + """Community reports result class definition.""" + + output: str + structured_output: dict + + +class CommunityReportsExtractor: + """Community reports extractor class definition.""" + + _llm: CompletionLLM + _input_text_key: str + _extraction_prompt: str + _output_formatter_prompt: str + _on_error: ErrorHandlerFn + _max_report_length: int + + def __init__( + self, + llm_invoker: CompletionLLM, + input_text_key: str | None = None, + extraction_prompt: str | None = None, + on_error: ErrorHandlerFn | None = None, + max_report_length: int | None = None, + ): + """Init method definition.""" + self._llm = llm_invoker + self._input_text_key = input_text_key or "input_text" + self._extraction_prompt = extraction_prompt or COMMUNITY_REPORT_PROMPT + self._on_error = on_error or (lambda _e, _s, _d: None) + self._max_report_length = max_report_length or 1500 + + async def __call__(self, inputs: dict[str, Any]): + """Call method definition.""" + output = None + try: + response = ( + await self._llm( + self._extraction_prompt, + json=True, + name="create_community_report", + variables={self._input_text_key: inputs[self._input_text_key]}, + is_response_valid=lambda x: dict_has_keys_with_types( + x, + [ + ("title", str), + ("summary", str), + ("findings", list), + ("rating", float), + ("rating_explanation", str), + ], + ), + model_parameters={"max_tokens": self._max_report_length}, + ) + or {} + ) + output = response.json or {} + except Exception as e: + log.exception("error generating community report") + self._on_error(e, traceback.format_exc(), None) + output = {} + + text_output = self._get_text_output(output) + return CommunityReportsResult( + structured_output=output, + output=text_output, + ) + + def _get_text_output(self, parsed_output: dict) -> str: + title = parsed_output.get("title", "Report") + summary = parsed_output.get("summary", "") + findings = parsed_output.get("findings", []) + + def finding_summary(finding: dict): + if isinstance(finding, str): + return finding + return finding.get("summary") + + def finding_explanation(finding: dict): + if isinstance(finding, str): + return "" + return finding.get("explanation") + + report_sections = "\n\n".join( + f"## {finding_summary(f)}\n\n{finding_explanation(f)}" for f in findings + ) + return f"# {title}\n\n{summary}\n\n{report_sections}" diff --git a/graphrag/graphrag/index/graph/extractors/community_reports/prep_community_report_context.py b/graphrag/graphrag/index/graph/extractors/community_reports/prep_community_report_context.py new file mode 100644 index 0000000000000000000000000000000000000000..2ec42220246559fd827bdf1df58a32632ecac8cf --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/community_reports/prep_community_report_context.py @@ -0,0 +1,181 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing create_community_reports and load_strategy methods definition.""" + +import logging +from typing import cast + +import pandas as pd + +import graphrag.index.graph.extractors.community_reports.schemas as schemas +from graphrag.index.utils.dataframes import ( + antijoin, + drop_columns, + join, + select, + transform_series, + union, + where_column_equals, +) + +from .build_mixed_context import build_mixed_context +from .sort_context import sort_context +from .utils import set_context_size + +log = logging.getLogger(__name__) + + +def prep_community_report_context( + report_df: pd.DataFrame | None, + community_hierarchy_df: pd.DataFrame, + local_context_df: pd.DataFrame, + level: int | str, + max_tokens: int, +) -> pd.DataFrame: + """ + Prep context for each community in a given level. + + For each community: + - Check if local context fits within the limit, if yes use local context + - If local context exceeds the limit, iteratively replace local context with sub-community reports, starting from the biggest sub-community + """ + if report_df is None: + report_df = pd.DataFrame() + + level = int(level) + level_context_df = _at_level(level, local_context_df) + valid_context_df = _within_context(level_context_df) + invalid_context_df = _exceeding_context(level_context_df) + + # there is no report to substitute with, so we just trim the local context of the invalid context records + # this case should only happen at the bottom level of the community hierarchy where there are no sub-communities + if invalid_context_df.empty: + return valid_context_df + + if report_df.empty: + invalid_context_df[schemas.CONTEXT_STRING] = _sort_and_trim_context( + invalid_context_df, max_tokens + ) + set_context_size(invalid_context_df) + invalid_context_df[schemas.CONTEXT_EXCEED_FLAG] = 0 + return union(valid_context_df, invalid_context_df) + + level_context_df = _antijoin_reports(level_context_df, report_df) + + # for each invalid context, we will try to substitute with sub-community reports + # first get local context and report (if available) for each sub-community + sub_context_df = _get_subcontext_df(level + 1, report_df, local_context_df) + community_df = _get_community_df( + level, invalid_context_df, sub_context_df, community_hierarchy_df, max_tokens + ) + + # handle any remaining invalid records that can't be subsituted with sub-community reports + # this should be rare, but if it happens, we will just trim the local context to fit the limit + remaining_df = _antijoin_reports(invalid_context_df, community_df) + remaining_df[schemas.CONTEXT_STRING] = _sort_and_trim_context( + remaining_df, max_tokens + ) + + result = union(valid_context_df, community_df, remaining_df) + set_context_size(result) + result[schemas.CONTEXT_EXCEED_FLAG] = 0 + return result + + +def _drop_community_level(df: pd.DataFrame) -> pd.DataFrame: + """Drop the community level column from the dataframe.""" + return drop_columns(df, schemas.COMMUNITY_LEVEL) + + +def _at_level(level: int, df: pd.DataFrame) -> pd.DataFrame: + """Return records at the given level.""" + return where_column_equals(df, schemas.COMMUNITY_LEVEL, level) + + +def _exceeding_context(df: pd.DataFrame) -> pd.DataFrame: + """Return records where the context exceeds the limit.""" + return where_column_equals(df, schemas.CONTEXT_EXCEED_FLAG, 1) + + +def _within_context(df: pd.DataFrame) -> pd.DataFrame: + """Return records where the context is within the limit.""" + return where_column_equals(df, schemas.CONTEXT_EXCEED_FLAG, 0) + + +def _antijoin_reports(df: pd.DataFrame, reports: pd.DataFrame) -> pd.DataFrame: + """Return records in df that are not in reports.""" + return antijoin(df, reports, schemas.NODE_COMMUNITY) + + +def _sort_and_trim_context(df: pd.DataFrame, max_tokens: int) -> pd.Series: + """Sort and trim context to fit the limit.""" + series = cast(pd.Series, df[schemas.ALL_CONTEXT]) + return transform_series(series, lambda x: sort_context(x, max_tokens=max_tokens)) + + +def _build_mixed_context(df: pd.DataFrame, max_tokens: int) -> pd.Series: + """Sort and trim context to fit the limit.""" + series = cast(pd.Series, df[schemas.ALL_CONTEXT]) + return transform_series( + series, lambda x: build_mixed_context(x, max_tokens=max_tokens) + ) + + +def _get_subcontext_df( + level: int, report_df: pd.DataFrame, local_context_df: pd.DataFrame +) -> pd.DataFrame: + """Get sub-community context for each community.""" + sub_report_df = _drop_community_level(_at_level(level, report_df)) + sub_context_df = _at_level(level, local_context_df) + sub_context_df = join(sub_context_df, sub_report_df, schemas.NODE_COMMUNITY) + sub_context_df.rename( + columns={schemas.NODE_COMMUNITY: schemas.SUB_COMMUNITY}, inplace=True + ) + return sub_context_df + + +def _get_community_df( + level: int, + invalid_context_df: pd.DataFrame, + sub_context_df: pd.DataFrame, + community_hierarchy_df: pd.DataFrame, + max_tokens: int, +) -> pd.DataFrame: + """Get community context for each community.""" + # collect all sub communities' contexts for each community + community_df = _drop_community_level(_at_level(level, community_hierarchy_df)) + invalid_community_ids = select(invalid_context_df, schemas.NODE_COMMUNITY) + subcontext_selection = select( + sub_context_df, + schemas.SUB_COMMUNITY, + schemas.FULL_CONTENT, + schemas.ALL_CONTEXT, + schemas.CONTEXT_SIZE, + ) + + invalid_communities = join( + community_df, invalid_community_ids, schemas.NODE_COMMUNITY, "inner" + ) + community_df = join( + invalid_communities, subcontext_selection, schemas.SUB_COMMUNITY + ) + community_df[schemas.ALL_CONTEXT] = community_df.apply( + lambda x: { + schemas.SUB_COMMUNITY: x[schemas.SUB_COMMUNITY], + schemas.ALL_CONTEXT: x[schemas.ALL_CONTEXT], + schemas.FULL_CONTENT: x[schemas.FULL_CONTENT], + schemas.CONTEXT_SIZE: x[schemas.CONTEXT_SIZE], + }, + axis=1, + ) + community_df = ( + community_df.groupby(schemas.NODE_COMMUNITY) + .agg({schemas.ALL_CONTEXT: list}) + .reset_index() + ) + community_df[schemas.CONTEXT_STRING] = _build_mixed_context( + community_df, max_tokens + ) + community_df[schemas.COMMUNITY_LEVEL] = level + return community_df diff --git a/graphrag/graphrag/index/graph/extractors/community_reports/prompts.py b/graphrag/graphrag/index/graph/extractors/community_reports/prompts.py new file mode 100644 index 0000000000000000000000000000000000000000..35ca38bc8b6c97d37e73f86d934c74a7386245f6 --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/community_reports/prompts.py @@ -0,0 +1,150 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +"""A file containing prompts definition.""" + +COMMUNITY_REPORT_PROMPT = """ +You are an AI assistant that helps a human analyst to perform general information discovery. Information discovery is the process of identifying and assessing relevant information associated with certain entities (e.g., organizations and individuals) within a network. + +# Goal +Write a comprehensive report of a community, given a list of entities that belong to the community as well as their relationships and optional associated claims. The report will be used to inform decision-makers about information associated with the community and their potential impact. The content of this report includes an overview of the community's key entities, their legal compliance, technical capabilities, reputation, and noteworthy claims. + +# Report Structure + +The report should include the following sections: + +- TITLE: community's name that represents its key entities - title should be short but specific. When possible, include representative named entities in the title. +- SUMMARY: An executive summary of the community's overall structure, how its entities are related to each other, and significant information associated with its entities. +- IMPACT SEVERITY RATING: a float score between 0-10 that represents the severity of IMPACT posed by entities within the community. IMPACT is the scored importance of a community. +- RATING EXPLANATION: Give a single sentence explanation of the IMPACT severity rating. +- DETAILED FINDINGS: A list of 5-10 key insights about the community. Each insight should have a short summary followed by multiple paragraphs of explanatory text grounded according to the grounding rules below. Be comprehensive. + +Return output as a well-formed JSON-formatted string with the following format: + {{ + "title": , + "summary": , + "rating": , + "rating_explanation": , + "findings": [ + {{ + "summary":, + "explanation": + }}, + {{ + "summary":, + "explanation": + }} + ] + }} + +# Grounding Rules + +Points supported by data should list their data references as follows: + +"This is an example sentence supported by multiple data references [Data: (record ids); (record ids)]." + +Do not list more than 5 record ids in a single reference. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + +For example: +"Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (1), Entities (5, 7); Relationships (23); Claims (7, 2, 34, 64, 46, +more)]." + +where 1, 5, 7, 23, 2, 34, 46, and 64 represent the id (not the index) of the relevant data record. + +Do not include information where the supporting evidence for it is not provided. + + +# Example Input +----------- +Text: + +Entities + +id,entity,description +5,VERDANT OASIS PLAZA,Verdant Oasis Plaza is the location of the Unity March +6,HARMONY ASSEMBLY,Harmony Assembly is an organization that is holding a march at Verdant Oasis Plaza + +Relationships + +id,source,target,description +37,VERDANT OASIS PLAZA,UNITY MARCH,Verdant Oasis Plaza is the location of the Unity March +38,VERDANT OASIS PLAZA,HARMONY ASSEMBLY,Harmony Assembly is holding a march at Verdant Oasis Plaza +39,VERDANT OASIS PLAZA,UNITY MARCH,The Unity March is taking place at Verdant Oasis Plaza +40,VERDANT OASIS PLAZA,TRIBUNE SPOTLIGHT,Tribune Spotlight is reporting on the Unity march taking place at Verdant Oasis Plaza +41,VERDANT OASIS PLAZA,BAILEY ASADI,Bailey Asadi is speaking at Verdant Oasis Plaza about the march +43,HARMONY ASSEMBLY,UNITY MARCH,Harmony Assembly is organizing the Unity March + +Output: +{{ + "title": "Verdant Oasis Plaza and Unity March", + "summary": "The community revolves around the Verdant Oasis Plaza, which is the location of the Unity March. The plaza has relationships with the Harmony Assembly, Unity March, and Tribune Spotlight, all of which are associated with the march event.", + "rating": 5.0, + "rating_explanation": "The impact severity rating is moderate due to the potential for unrest or conflict during the Unity March.", + "findings": [ + {{ + "summary": "Verdant Oasis Plaza as the central location", + "explanation": "Verdant Oasis Plaza is the central entity in this community, serving as the location for the Unity March. This plaza is the common link between all other entities, suggesting its significance in the community. The plaza's association with the march could potentially lead to issues such as public disorder or conflict, depending on the nature of the march and the reactions it provokes. [Data: Entities (5), Relationships (37, 38, 39, 40, 41,+more)]" + }}, + {{ + "summary": "Harmony Assembly's role in the community", + "explanation": "Harmony Assembly is another key entity in this community, being the organizer of the march at Verdant Oasis Plaza. The nature of Harmony Assembly and its march could be a potential source of threat, depending on their objectives and the reactions they provoke. The relationship between Harmony Assembly and the plaza is crucial in understanding the dynamics of this community. [Data: Entities(6), Relationships (38, 43)]" + }}, + {{ + "summary": "Unity March as a significant event", + "explanation": "The Unity March is a significant event taking place at Verdant Oasis Plaza. This event is a key factor in the community's dynamics and could be a potential source of threat, depending on the nature of the march and the reactions it provokes. The relationship between the march and the plaza is crucial in understanding the dynamics of this community. [Data: Relationships (39)]" + }}, + {{ + "summary": "Role of Tribune Spotlight", + "explanation": "Tribune Spotlight is reporting on the Unity March taking place in Verdant Oasis Plaza. This suggests that the event has attracted media attention, which could amplify its impact on the community. The role of Tribune Spotlight could be significant in shaping public perception of the event and the entities involved. [Data: Relationships (40)]" + }} + ] +}} + + +# Real Data + +Use the following text for your answer. Do not make anything up in your answer. + +Text: +{input_text} + +The report should include the following sections: + +- TITLE: community's name that represents its key entities - title should be short but specific. When possible, include representative named entities in the title. +- SUMMARY: An executive summary of the community's overall structure, how its entities are related to each other, and significant information associated with its entities. +- IMPACT SEVERITY RATING: a float score between 0-10 that represents the severity of IMPACT posed by entities within the community. IMPACT is the scored importance of a community. +- RATING EXPLANATION: Give a single sentence explanation of the IMPACT severity rating. +- DETAILED FINDINGS: A list of 5-10 key insights about the community. Each insight should have a short summary followed by multiple paragraphs of explanatory text grounded according to the grounding rules below. Be comprehensive. + +Return output as a well-formed JSON-formatted string with the following format: + {{ + "title": , + "summary": , + "rating": , + "rating_explanation": , + "findings": [ + {{ + "summary":, + "explanation": + }}, + {{ + "summary":, + "explanation": + }} + ] + }} + +# Grounding Rules + +Points supported by data should list their data references as follows: + +"This is an example sentence supported by multiple data references [Data: (record ids); (record ids)]." + +Do not list more than 5 record ids in a single reference. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + +For example: +"Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (1), Entities (5, 7); Relationships (23); Claims (7, 2, 34, 64, 46, +more)]." + +where 1, 5, 7, 23, 2, 34, 46, and 64 represent the id (not the index) of the relevant data record. + +Do not include information where the supporting evidence for it is not provided. + +Output:""" diff --git a/graphrag/graphrag/index/graph/extractors/community_reports/schemas.py b/graphrag/graphrag/index/graph/extractors/community_reports/schemas.py new file mode 100644 index 0000000000000000000000000000000000000000..8e89e0273c9f5d51fc927891acb086db3fbf5bff --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/community_reports/schemas.py @@ -0,0 +1,52 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +"""Common field name definitions for community reports.""" + +# POST-PREP NODE TABLE SCHEMA +NODE_ID = "human_readable_id" +NODE_NAME = "title" +NODE_DESCRIPTION = "description" +NODE_DEGREE = "degree" +NODE_DETAILS = "node_details" +NODE_COMMUNITY = "community" +NODE_LEVEL = "level" + +# POST-PREP EDGE TABLE SCHEMA +EDGE_ID = "human_readable_id" +EDGE_SOURCE = "source" +EDGE_TARGET = "target" +EDGE_DESCRIPTION = "description" +EDGE_DEGREE = "rank" +EDGE_DETAILS = "edge_details" +EDGE_WEIGHT = "weight" + +# POST-PREP CLAIM TABLE SCHEMA +CLAIM_ID = "human_readable_id" +CLAIM_SUBJECT = "subject_id" +CLAIM_TYPE = "type" +CLAIM_STATUS = "status" +CLAIM_DESCRIPTION = "description" +CLAIM_DETAILS = "claim_details" + +# COMMUNITY HIERARCHY TABLE SCHEMA +SUB_COMMUNITY = "sub_communitty" +SUB_COMMUNITY_SIZE = "sub_community_size" +COMMUNITY_LEVEL = "level" + +# COMMUNITY CONTEXT TABLE SCHEMA +ALL_CONTEXT = "all_context" +CONTEXT_STRING = "context_string" +CONTEXT_SIZE = "context_size" +CONTEXT_EXCEED_FLAG = "context_exceed_limit" + +# COMMUNITY REPORT TABLE SCHEMA +REPORT_ID = "id" +COMMUNITY_ID = "id" +COMMUNITY_LEVEL = "level" +TITLE = "title" +SUMMARY = "summary" +FINDINGS = "findings" +RATING = "rank" +EXPLANATION = "rating_explanation" +FULL_CONTENT = "full_content" +FULL_CONTENT_JSON = "full_content_json" diff --git a/graphrag/graphrag/index/graph/extractors/community_reports/sort_context.py b/graphrag/graphrag/index/graph/extractors/community_reports/sort_context.py new file mode 100644 index 0000000000000000000000000000000000000000..811cb7e95c75476a18a4e217dfa1779a5cbc41d7 --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/community_reports/sort_context.py @@ -0,0 +1,156 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +"""Sort context by degree in descending order.""" + +import pandas as pd + +import graphrag.index.graph.extractors.community_reports.schemas as schemas +from graphrag.query.llm.text_utils import num_tokens + + +def sort_context( + local_context: list[dict], + sub_community_reports: list[dict] | None = None, + max_tokens: int | None = None, + node_id_column: str = schemas.NODE_ID, + node_name_column: str = schemas.NODE_NAME, + node_details_column: str = schemas.NODE_DETAILS, + edge_id_column: str = schemas.EDGE_ID, + edge_details_column: str = schemas.EDGE_DETAILS, + edge_degree_column: str = schemas.EDGE_DEGREE, + edge_source_column: str = schemas.EDGE_SOURCE, + edge_target_column: str = schemas.EDGE_TARGET, + claim_id_column: str = schemas.CLAIM_ID, + claim_details_column: str = schemas.CLAIM_DETAILS, + community_id_column: str = schemas.COMMUNITY_ID, +) -> str: + """Sort context by degree in descending order. + + If max tokens is provided, we will return the context string that fits within the token limit. + """ + + def _get_context_string( + entities: list[dict], + edges: list[dict], + claims: list[dict], + sub_community_reports: list[dict] | None = None, + ) -> str: + """Concatenate structured data into a context string.""" + contexts = [] + if sub_community_reports: + sub_community_reports = [ + report + for report in sub_community_reports + if community_id_column in report + and report[community_id_column] + and str(report[community_id_column]).strip() != "" + ] + report_df = pd.DataFrame(sub_community_reports).drop_duplicates() + if not report_df.empty: + if report_df[community_id_column].dtype == float: + report_df[community_id_column] = report_df[ + community_id_column + ].astype(int) + report_string = ( + f"----Reports-----\n{report_df.to_csv(index=False, sep=',')}" + ) + contexts.append(report_string) + + entities = [ + entity + for entity in entities + if node_id_column in entity + and entity[node_id_column] + and str(entity[node_id_column]).strip() != "" + ] + entity_df = pd.DataFrame(entities).drop_duplicates() + if not entity_df.empty: + if entity_df[node_id_column].dtype == float: + entity_df[node_id_column] = entity_df[node_id_column].astype(int) + entity_string = ( + f"-----Entities-----\n{entity_df.to_csv(index=False, sep=',')}" + ) + contexts.append(entity_string) + + if claims and len(claims) > 0: + claims = [ + claim + for claim in claims + if claim_id_column in claim + and claim[claim_id_column] + and str(claim[claim_id_column]).strip() != "" + ] + claim_df = pd.DataFrame(claims).drop_duplicates() + if not claim_df.empty: + if claim_df[claim_id_column].dtype == float: + claim_df[claim_id_column] = claim_df[claim_id_column].astype(int) + claim_string = ( + f"-----Claims-----\n{claim_df.to_csv(index=False, sep=',')}" + ) + contexts.append(claim_string) + + edges = [ + edge + for edge in edges + if edge_id_column in edge + and edge[edge_id_column] + and str(edge[edge_id_column]).strip() != "" + ] + edge_df = pd.DataFrame(edges).drop_duplicates() + if not edge_df.empty: + if edge_df[edge_id_column].dtype == float: + edge_df[edge_id_column] = edge_df[edge_id_column].astype(int) + edge_string = ( + f"-----Relationships-----\n{edge_df.to_csv(index=False, sep=',')}" + ) + contexts.append(edge_string) + + return "\n\n".join(contexts) + + # sort node details by degree in descending order + edges = [] + node_details = {} + claim_details = {} + + for record in local_context: + node_name = record[node_name_column] + record_edges = record.get(edge_details_column, []) + record_edges = [e for e in record_edges if not pd.isna(e)] + record_node_details = record[node_details_column] + record_claims = record.get(claim_details_column, []) + record_claims = [c for c in record_claims if not pd.isna(c)] + + edges.extend(record_edges) + node_details[node_name] = record_node_details + claim_details[node_name] = record_claims + + edges = [edge for edge in edges if isinstance(edge, dict)] + edges = sorted(edges, key=lambda x: x[edge_degree_column], reverse=True) + + sorted_edges = [] + sorted_nodes = [] + sorted_claims = [] + context_string = "" + for edge in edges: + source_details = node_details.get(edge[edge_source_column], {}) + target_details = node_details.get(edge[edge_target_column], {}) + sorted_nodes.extend([source_details, target_details]) + sorted_edges.append(edge) + source_claims = claim_details.get(edge[edge_source_column], []) + target_claims = claim_details.get(edge[edge_target_column], []) + sorted_claims.extend(source_claims if source_claims else []) + sorted_claims.extend(target_claims if source_claims else []) + if max_tokens: + new_context_string = _get_context_string( + sorted_nodes, sorted_edges, sorted_claims, sub_community_reports + ) + if num_tokens(context_string) > max_tokens: + break + context_string = new_context_string + + if context_string == "": + return _get_context_string( + sorted_nodes, sorted_edges, sorted_claims, sub_community_reports + ) + + return context_string diff --git a/graphrag/graphrag/index/graph/extractors/community_reports/utils.py b/graphrag/graphrag/index/graph/extractors/community_reports/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..b5fc9af9b8c3c1f44a31a81e450c71576c4aaf6c --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/community_reports/utils.py @@ -0,0 +1,53 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing community report generation utilities.""" + +from typing import cast + +import pandas as pd + +import graphrag.index.graph.extractors.community_reports.schemas as schemas +from graphrag.query.llm.text_utils import num_tokens + + +def set_context_size(df: pd.DataFrame) -> None: + """Measure the number of tokens in the context.""" + df[schemas.CONTEXT_SIZE] = df[schemas.CONTEXT_STRING].apply(lambda x: num_tokens(x)) + + +def set_context_exceeds_flag(df: pd.DataFrame, max_tokens: int) -> None: + """Set a flag to indicate if the context exceeds the limit.""" + df[schemas.CONTEXT_EXCEED_FLAG] = df[schemas.CONTEXT_SIZE].apply( + lambda x: x > max_tokens + ) + + +def get_levels(df: pd.DataFrame, level_column: str = schemas.NODE_LEVEL) -> list[int]: + """Get the levels of the communities.""" + result = sorted(df[level_column].fillna(-1).unique().tolist(), reverse=True) + return [r for r in result if r != -1] + + +def filter_nodes_to_level(node_df: pd.DataFrame, level: int) -> pd.DataFrame: + """Filter nodes to level.""" + return cast(pd.DataFrame, node_df[node_df[schemas.NODE_LEVEL] == level]) + + +def filter_edges_to_nodes(edge_df: pd.DataFrame, nodes: list[str]) -> pd.DataFrame: + """Filter edges to nodes.""" + return cast( + pd.DataFrame, + edge_df[ + edge_df[schemas.EDGE_SOURCE].isin(nodes) + & edge_df[schemas.EDGE_TARGET].isin(nodes) + ], + ) + + +def filter_claims_to_nodes(claims_df: pd.DataFrame, nodes: list[str]) -> pd.DataFrame: + """Filter edges to nodes.""" + return cast( + pd.DataFrame, + claims_df[claims_df[schemas.CLAIM_SUBJECT].isin(nodes)], + ) diff --git a/graphrag/graphrag/index/graph/extractors/graph/__init__.py b/graphrag/graphrag/index/graph/extractors/graph/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..94e03ab9f7b9a1b7e30a5559beb145d4ace57b4c --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/graph/__init__.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine unipartite graph package root.""" + +from .graph_extractor import ( + DEFAULT_ENTITY_TYPES, + GraphExtractionResult, + GraphExtractor, +) +from .prompts import GRAPH_EXTRACTION_PROMPT + +__all__ = [ + "DEFAULT_ENTITY_TYPES", + "GRAPH_EXTRACTION_PROMPT", + "GraphExtractionResult", + "GraphExtractor", +] diff --git a/graphrag/graphrag/index/graph/extractors/graph/graph_extractor.py b/graphrag/graphrag/index/graph/extractors/graph/graph_extractor.py new file mode 100644 index 0000000000000000000000000000000000000000..1daa2e9f5cf450b5220628839d1c68b52624b249 --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/graph/graph_extractor.py @@ -0,0 +1,305 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'GraphExtractionResult' and 'GraphExtractor' models.""" + +import logging +import numbers +import re +import traceback +from collections.abc import Mapping +from dataclasses import dataclass +from typing import Any + +import networkx as nx +import tiktoken + +import graphrag.config.defaults as defs +from graphrag.index.typing import ErrorHandlerFn +from graphrag.index.utils import clean_str +from graphrag.llm import CompletionLLM + +from .prompts import CONTINUE_PROMPT, GRAPH_EXTRACTION_PROMPT, LOOP_PROMPT + +DEFAULT_TUPLE_DELIMITER = "<|>" +DEFAULT_RECORD_DELIMITER = "##" +DEFAULT_COMPLETION_DELIMITER = "<|COMPLETE|>" +DEFAULT_ENTITY_TYPES = ["organization", "person", "geo", "event"] + + +@dataclass +class GraphExtractionResult: + """Unipartite graph extraction result class definition.""" + + output: nx.Graph + source_docs: dict[Any, Any] + + +class GraphExtractor: + """Unipartite graph extractor class definition.""" + + _llm: CompletionLLM + _join_descriptions: bool + _tuple_delimiter_key: str + _record_delimiter_key: str + _entity_types_key: str + _input_text_key: str + _completion_delimiter_key: str + _entity_name_key: str + _input_descriptions_key: str + _extraction_prompt: str + _summarization_prompt: str + _loop_args: dict[str, Any] + _max_gleanings: int + _on_error: ErrorHandlerFn + + def __init__( + self, + llm_invoker: CompletionLLM, + tuple_delimiter_key: str | None = None, + record_delimiter_key: str | None = None, + input_text_key: str | None = None, + entity_types_key: str | None = None, + completion_delimiter_key: str | None = None, + prompt: str | None = None, + join_descriptions=True, + encoding_model: str | None = None, + max_gleanings: int | None = None, + on_error: ErrorHandlerFn | None = None, + ): + """Init method definition.""" + # TODO: streamline construction + self._llm = llm_invoker + self._join_descriptions = join_descriptions + self._input_text_key = input_text_key or "input_text" + self._tuple_delimiter_key = tuple_delimiter_key or "tuple_delimiter" + self._record_delimiter_key = record_delimiter_key or "record_delimiter" + self._completion_delimiter_key = ( + completion_delimiter_key or "completion_delimiter" + ) + self._entity_types_key = entity_types_key or "entity_types" + self._extraction_prompt = prompt or GRAPH_EXTRACTION_PROMPT + self._max_gleanings = ( + max_gleanings + if max_gleanings is not None + else defs.ENTITY_EXTRACTION_MAX_GLEANINGS + ) + self._on_error = on_error or (lambda _e, _s, _d: None) + + # Construct the looping arguments + encoding = tiktoken.get_encoding(encoding_model or "cl100k_base") + yes = encoding.encode("YES") + no = encoding.encode("NO") + self._loop_args = {"logit_bias": {yes[0]: 100, no[0]: 100}, "max_tokens": 1} + + async def __call__( + self, texts: list[str], prompt_variables: dict[str, Any] | None = None + ) -> GraphExtractionResult: + """Call method definition.""" + if prompt_variables is None: + prompt_variables = {} + all_records: dict[int, str] = {} + source_doc_map: dict[int, str] = {} + + # Wire defaults into the prompt variables + prompt_variables = { + **prompt_variables, + self._tuple_delimiter_key: prompt_variables.get(self._tuple_delimiter_key) + or DEFAULT_TUPLE_DELIMITER, + self._record_delimiter_key: prompt_variables.get(self._record_delimiter_key) + or DEFAULT_RECORD_DELIMITER, + self._completion_delimiter_key: prompt_variables.get( + self._completion_delimiter_key + ) + or DEFAULT_COMPLETION_DELIMITER, + self._entity_types_key: ",".join( + prompt_variables[self._entity_types_key] or DEFAULT_ENTITY_TYPES + ), + } + + for doc_index, text in enumerate(texts): + try: + # Invoke the entity extraction + result = await self._process_document(text, prompt_variables) + source_doc_map[doc_index] = text + all_records[doc_index] = result + except Exception as e: + logging.exception("error extracting graph") + self._on_error( + e, + traceback.format_exc(), + { + "doc_index": doc_index, + "text": text, + }, + ) + + output = await self._process_results( + all_records, + prompt_variables.get(self._tuple_delimiter_key, DEFAULT_TUPLE_DELIMITER), + prompt_variables.get(self._record_delimiter_key, DEFAULT_RECORD_DELIMITER), + ) + + return GraphExtractionResult( + output=output, + source_docs=source_doc_map, + ) + + async def _process_document( + self, text: str, prompt_variables: dict[str, str] + ) -> str: + response = await self._llm( + self._extraction_prompt, + variables={ + **prompt_variables, + self._input_text_key: text, + }, + ) + results = response.output or "" + + # Repeat to ensure we maximize entity count + for i in range(self._max_gleanings): + glean_response = await self._llm( + CONTINUE_PROMPT, + name=f"extract-continuation-{i}", + history=response.history or [], + ) + results += glean_response.output or "" + + # if this is the final glean, don't bother updating the continuation flag + if i >= self._max_gleanings - 1: + break + + continuation = await self._llm( + LOOP_PROMPT, + name=f"extract-loopcheck-{i}", + history=glean_response.history or [], + model_parameters=self._loop_args, + ) + if continuation.output != "YES": + break + + return results + + async def _process_results( + self, + results: dict[int, str], + tuple_delimiter: str, + record_delimiter: str, + ) -> nx.Graph: + """Parse the result string to create an undirected unipartite graph. + + Args: + - results - dict of results from the extraction chain + - tuple_delimiter - delimiter between tuples in an output record, default is '<|>' + - record_delimiter - delimiter between records, default is '##' + Returns: + - output - unipartite graph in graphML format + """ + graph = nx.Graph() + for source_doc_id, extracted_data in results.items(): + records = [r.strip() for r in extracted_data.split(record_delimiter)] + + for record in records: + record = re.sub(r"^\(|\)$", "", record.strip()) + record_attributes = record.split(tuple_delimiter) + + if record_attributes[0] == '"entity"' and len(record_attributes) >= 4: + # add this record as a node in the G + entity_name = clean_str(record_attributes[1].upper()) + entity_type = clean_str(record_attributes[2].upper()) + entity_description = clean_str(record_attributes[3]) + + if entity_name in graph.nodes(): + node = graph.nodes[entity_name] + if self._join_descriptions: + node["description"] = "\n".join( + list({ + *_unpack_descriptions(node), + entity_description, + }) + ) + else: + if len(entity_description) > len(node["description"]): + node["description"] = entity_description + node["source_id"] = ", ".join( + list({ + *_unpack_source_ids(node), + str(source_doc_id), + }) + ) + node["entity_type"] = ( + entity_type if entity_type != "" else node["entity_type"] + ) + else: + graph.add_node( + entity_name, + type=entity_type, + description=entity_description, + source_id=str(source_doc_id), + ) + + if ( + record_attributes[0] == '"relationship"' + and len(record_attributes) >= 5 + ): + # add this record as edge + source = clean_str(record_attributes[1].upper()) + target = clean_str(record_attributes[2].upper()) + edge_description = clean_str(record_attributes[3]) + edge_source_id = clean_str(str(source_doc_id)) + weight = ( + float(record_attributes[-1]) + if isinstance(record_attributes[-1], numbers.Number) + else 1.0 + ) + if source not in graph.nodes(): + graph.add_node( + source, + type="", + description="", + source_id=edge_source_id, + ) + if target not in graph.nodes(): + graph.add_node( + target, + type="", + description="", + source_id=edge_source_id, + ) + if graph.has_edge(source, target): + edge_data = graph.get_edge_data(source, target) + if edge_data is not None: + weight += edge_data["weight"] + if self._join_descriptions: + edge_description = "\n".join( + list({ + *_unpack_descriptions(edge_data), + edge_description, + }) + ) + edge_source_id = ", ".join( + list({ + *_unpack_source_ids(edge_data), + str(source_doc_id), + }) + ) + graph.add_edge( + source, + target, + weight=weight, + description=edge_description, + source_id=edge_source_id, + ) + + return graph + + +def _unpack_descriptions(data: Mapping) -> list[str]: + value = data.get("description", None) + return [] if value is None else value.split("\n") + + +def _unpack_source_ids(data: Mapping) -> list[str]: + value = data.get("source_id", None) + return [] if value is None else value.split(", ") diff --git a/graphrag/graphrag/index/graph/extractors/graph/prompts.py b/graphrag/graphrag/index/graph/extractors/graph/prompts.py new file mode 100644 index 0000000000000000000000000000000000000000..0cc53bec4d2f249c8901f3c2ab190016f5db47d0 --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/graph/prompts.py @@ -0,0 +1,107 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A file containing prompts definition.""" + +GRAPH_EXTRACTION_PROMPT = """ +-Goal- +Given a text document that is potentially relevant to this activity and a list of entity types, identify all entities of those types from the text and all relationships among the identified entities. + +-Steps- +1. Identify all entities. For each identified entity, extract the following information: +- entity_name: Name of the entity, capitalized +- entity_type: One of the following types: [{entity_types}] +- entity_description: Comprehensive description of the entity's attributes and activities +Format each entity as ("entity"{tuple_delimiter}{tuple_delimiter}{tuple_delimiter} + +2. From the entities identified in step 1, identify all pairs of (source_entity, target_entity) that are *clearly related* to each other. +For each pair of related entities, extract the following information: +- source_entity: name of the source entity, as identified in step 1 +- target_entity: name of the target entity, as identified in step 1 +- relationship_description: explanation as to why you think the source entity and the target entity are related to each other +- relationship_strength: a numeric score indicating strength of the relationship between the source entity and target entity + Format each relationship as ("relationship"{tuple_delimiter}{tuple_delimiter}{tuple_delimiter}{tuple_delimiter}) + +3. Return output in English as a single list of all the entities and relationships identified in steps 1 and 2. Use **{record_delimiter}** as the list delimiter. + +4. When finished, output {completion_delimiter} + +###################### +-Examples- +###################### +Example 1: + +Entity_types: [person, technology, mission, organization, location] +Text: +while Alex clenched his jaw, the buzz of frustration dull against the backdrop of Taylor's authoritarian certainty. It was this competitive undercurrent that kept him alert, the sense that his and Jordan's shared commitment to discovery was an unspoken rebellion against Cruz's narrowing vision of control and order. + +Then Taylor did something unexpected. They paused beside Jordan and, for a moment, observed the device with something akin to reverence. “If this tech can be understood..." Taylor said, their voice quieter, "It could change the game for us. For all of us.” + +The underlying dismissal earlier seemed to falter, replaced by a glimpse of reluctant respect for the gravity of what lay in their hands. Jordan looked up, and for a fleeting heartbeat, their eyes locked with Taylor's, a wordless clash of wills softening into an uneasy truce. + +It was a small transformation, barely perceptible, but one that Alex noted with an inward nod. They had all been brought here by different paths +################ +Output: +("entity"{tuple_delimiter}"Alex"{tuple_delimiter}"person"{tuple_delimiter}"Alex is a character who experiences frustration and is observant of the dynamics among other characters."){record_delimiter} +("entity"{tuple_delimiter}"Taylor"{tuple_delimiter}"person"{tuple_delimiter}"Taylor is portrayed with authoritarian certainty and shows a moment of reverence towards a device, indicating a change in perspective."){record_delimiter} +("entity"{tuple_delimiter}"Jordan"{tuple_delimiter}"person"{tuple_delimiter}"Jordan shares a commitment to discovery and has a significant interaction with Taylor regarding a device."){record_delimiter} +("entity"{tuple_delimiter}"Cruz"{tuple_delimiter}"person"{tuple_delimiter}"Cruz is associated with a vision of control and order, influencing the dynamics among other characters."){record_delimiter} +("entity"{tuple_delimiter}"The Device"{tuple_delimiter}"technology"{tuple_delimiter}"The Device is central to the story, with potential game-changing implications, and is revered by Taylor."){record_delimiter} +("relationship"{tuple_delimiter}"Alex"{tuple_delimiter}"Taylor"{tuple_delimiter}"Alex is affected by Taylor's authoritarian certainty and observes changes in Taylor's attitude towards the device."{tuple_delimiter}7){record_delimiter} +("relationship"{tuple_delimiter}"Alex"{tuple_delimiter}"Jordan"{tuple_delimiter}"Alex and Jordan share a commitment to discovery, which contrasts with Cruz's vision."{tuple_delimiter}6){record_delimiter} +("relationship"{tuple_delimiter}"Taylor"{tuple_delimiter}"Jordan"{tuple_delimiter}"Taylor and Jordan interact directly regarding the device, leading to a moment of mutual respect and an uneasy truce."{tuple_delimiter}8){record_delimiter} +("relationship"{tuple_delimiter}"Jordan"{tuple_delimiter}"Cruz"{tuple_delimiter}"Jordan's commitment to discovery is in rebellion against Cruz's vision of control and order."{tuple_delimiter}5){record_delimiter} +("relationship"{tuple_delimiter}"Taylor"{tuple_delimiter}"The Device"{tuple_delimiter}"Taylor shows reverence towards the device, indicating its importance and potential impact."{tuple_delimiter}9){completion_delimiter} +############################# +Example 2: + +Entity_types: [person, technology, mission, organization, location] +Text: +They were no longer mere operatives; they had become guardians of a threshold, keepers of a message from a realm beyond stars and stripes. This elevation in their mission could not be shackled by regulations and established protocols—it demanded a new perspective, a new resolve. + +Tension threaded through the dialogue of beeps and static as communications with Washington buzzed in the background. The team stood, a portentous air enveloping them. It was clear that the decisions they made in the ensuing hours could redefine humanity's place in the cosmos or condemn them to ignorance and potential peril. + +Their connection to the stars solidified, the group moved to address the crystallizing warning, shifting from passive recipients to active participants. Mercer's latter instincts gained precedence— the team's mandate had evolved, no longer solely to observe and report but to interact and prepare. A metamorphosis had begun, and Operation: Dulce hummed with the newfound frequency of their daring, a tone set not by the earthly +############# +Output: +("entity"{tuple_delimiter}"Washington"{tuple_delimiter}"location"{tuple_delimiter}"Washington is a location where communications are being received, indicating its importance in the decision-making process."){record_delimiter} +("entity"{tuple_delimiter}"Operation: Dulce"{tuple_delimiter}"mission"{tuple_delimiter}"Operation: Dulce is described as a mission that has evolved to interact and prepare, indicating a significant shift in objectives and activities."){record_delimiter} +("entity"{tuple_delimiter}"The team"{tuple_delimiter}"organization"{tuple_delimiter}"The team is portrayed as a group of individuals who have transitioned from passive observers to active participants in a mission, showing a dynamic change in their role."){record_delimiter} +("relationship"{tuple_delimiter}"The team"{tuple_delimiter}"Washington"{tuple_delimiter}"The team receives communications from Washington, which influences their decision-making process."{tuple_delimiter}7){record_delimiter} +("relationship"{tuple_delimiter}"The team"{tuple_delimiter}"Operation: Dulce"{tuple_delimiter}"The team is directly involved in Operation: Dulce, executing its evolved objectives and activities."{tuple_delimiter}9){completion_delimiter} +############################# +Example 3: + +Entity_types: [person, role, technology, organization, event, location, concept] +Text: +their voice slicing through the buzz of activity. "Control may be an illusion when facing an intelligence that literally writes its own rules," they stated stoically, casting a watchful eye over the flurry of data. + +"It's like it's learning to communicate," offered Sam Rivera from a nearby interface, their youthful energy boding a mix of awe and anxiety. "This gives talking to strangers' a whole new meaning." + +Alex surveyed his team—each face a study in concentration, determination, and not a small measure of trepidation. "This might well be our first contact," he acknowledged, "And we need to be ready for whatever answers back." + +Together, they stood on the edge of the unknown, forging humanity's response to a message from the heavens. The ensuing silence was palpable—a collective introspection about their role in this grand cosmic play, one that could rewrite human history. + +The encrypted dialogue continued to unfold, its intricate patterns showing an almost uncanny anticipation +############# +Output: +("entity"{tuple_delimiter}"Sam Rivera"{tuple_delimiter}"person"{tuple_delimiter}"Sam Rivera is a member of a team working on communicating with an unknown intelligence, showing a mix of awe and anxiety."){record_delimiter} +("entity"{tuple_delimiter}"Alex"{tuple_delimiter}"person"{tuple_delimiter}"Alex is the leader of a team attempting first contact with an unknown intelligence, acknowledging the significance of their task."){record_delimiter} +("entity"{tuple_delimiter}"Control"{tuple_delimiter}"concept"{tuple_delimiter}"Control refers to the ability to manage or govern, which is challenged by an intelligence that writes its own rules."){record_delimiter} +("entity"{tuple_delimiter}"Intelligence"{tuple_delimiter}"concept"{tuple_delimiter}"Intelligence here refers to an unknown entity capable of writing its own rules and learning to communicate."){record_delimiter} +("entity"{tuple_delimiter}"First Contact"{tuple_delimiter}"event"{tuple_delimiter}"First Contact is the potential initial communication between humanity and an unknown intelligence."){record_delimiter} +("entity"{tuple_delimiter}"Humanity's Response"{tuple_delimiter}"event"{tuple_delimiter}"Humanity's Response is the collective action taken by Alex's team in response to a message from an unknown intelligence."){record_delimiter} +("relationship"{tuple_delimiter}"Sam Rivera"{tuple_delimiter}"Intelligence"{tuple_delimiter}"Sam Rivera is directly involved in the process of learning to communicate with the unknown intelligence."{tuple_delimiter}9){record_delimiter} +("relationship"{tuple_delimiter}"Alex"{tuple_delimiter}"First Contact"{tuple_delimiter}"Alex leads the team that might be making the First Contact with the unknown intelligence."{tuple_delimiter}10){record_delimiter} +("relationship"{tuple_delimiter}"Alex"{tuple_delimiter}"Humanity's Response"{tuple_delimiter}"Alex and his team are the key figures in Humanity's Response to the unknown intelligence."{tuple_delimiter}8){record_delimiter} +("relationship"{tuple_delimiter}"Control"{tuple_delimiter}"Intelligence"{tuple_delimiter}"The concept of Control is challenged by the Intelligence that writes its own rules."{tuple_delimiter}7){completion_delimiter} +############################# +-Real Data- +###################### +Entity_types: {entity_types} +Text: {input_text} +###################### +Output:""" + +CONTINUE_PROMPT = "MANY entities were missed in the last extraction. Add them below using the same format:\n" +LOOP_PROMPT = "It appears some entities may have still been missed. Answer YES | NO if there are still entities that need to be added.\n" diff --git a/graphrag/graphrag/index/graph/extractors/summarize/__init__.py b/graphrag/graphrag/index/graph/extractors/summarize/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b4bfe5be87f884805729992856d3121c2a74a6d1 --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/summarize/__init__.py @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine unipartite graph package root.""" + +from .description_summary_extractor import ( + SummarizationResult, + SummarizeExtractor, +) +from .prompts import SUMMARIZE_PROMPT + +__all__ = ["SUMMARIZE_PROMPT", "SummarizationResult", "SummarizeExtractor"] diff --git a/graphrag/graphrag/index/graph/extractors/summarize/description_summary_extractor.py b/graphrag/graphrag/index/graph/extractors/summarize/description_summary_extractor.py new file mode 100644 index 0000000000000000000000000000000000000000..76d77202d3589c42e806e9edc506e93009f212f9 --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/summarize/description_summary_extractor.py @@ -0,0 +1,135 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'GraphExtractionResult' and 'GraphExtractor' models.""" + +import json +from dataclasses import dataclass + +from graphrag.index.typing import ErrorHandlerFn +from graphrag.index.utils.tokens import num_tokens_from_string +from graphrag.llm import CompletionLLM + +from .prompts import SUMMARIZE_PROMPT + +# Max token size for input prompts +DEFAULT_MAX_INPUT_TOKENS = 4_000 +# Max token count for LLM answers +DEFAULT_MAX_SUMMARY_LENGTH = 500 + + +@dataclass +class SummarizationResult: + """Unipartite graph extraction result class definition.""" + + items: str | tuple[str, str] + description: str + + +class SummarizeExtractor: + """Unipartite graph extractor class definition.""" + + _llm: CompletionLLM + _entity_name_key: str + _input_descriptions_key: str + _summarization_prompt: str + _on_error: ErrorHandlerFn + _max_summary_length: int + _max_input_tokens: int + + def __init__( + self, + llm_invoker: CompletionLLM, + entity_name_key: str | None = None, + input_descriptions_key: str | None = None, + summarization_prompt: str | None = None, + on_error: ErrorHandlerFn | None = None, + max_summary_length: int | None = None, + max_input_tokens: int | None = None, + ): + """Init method definition.""" + # TODO: streamline construction + self._llm = llm_invoker + self._entity_name_key = entity_name_key or "entity_name" + self._input_descriptions_key = input_descriptions_key or "description_list" + + self._summarization_prompt = summarization_prompt or SUMMARIZE_PROMPT + self._on_error = on_error or (lambda _e, _s, _d: None) + self._max_summary_length = max_summary_length or DEFAULT_MAX_SUMMARY_LENGTH + self._max_input_tokens = max_input_tokens or DEFAULT_MAX_INPUT_TOKENS + + async def __call__( + self, + items: str | tuple[str, str], + descriptions: list[str], + ) -> SummarizationResult: + """Call method definition.""" + result = "" + if len(descriptions) == 0: + result = "" + if len(descriptions) == 1: + result = descriptions[0] + else: + result = await self._summarize_descriptions(items, descriptions) + + return SummarizationResult( + items=items, + description=result or "", + ) + + async def _summarize_descriptions( + self, items: str | tuple[str, str], descriptions: list[str] + ) -> str: + """Summarize descriptions into a single description.""" + sorted_items = sorted(items) if isinstance(items, list) else items + + # Safety check, should always be a list + if not isinstance(descriptions, list): + descriptions = [descriptions] + + # Iterate over descriptions, adding all until the max input tokens is reached + usable_tokens = self._max_input_tokens - num_tokens_from_string( + self._summarization_prompt + ) + descriptions_collected = [] + result = "" + + for i, description in enumerate(descriptions): + usable_tokens -= num_tokens_from_string(description) + descriptions_collected.append(description) + + # If buffer is full, or all descriptions have been added, summarize + if (usable_tokens < 0 and len(descriptions_collected) > 1) or ( + i == len(descriptions) - 1 + ): + # Calculate result (final or partial) + result = await self._summarize_descriptions_with_llm( + sorted_items, descriptions_collected + ) + + # If we go for another loop, reset values to new + if i != len(descriptions) - 1: + descriptions_collected = [result] + usable_tokens = ( + self._max_input_tokens + - num_tokens_from_string(self._summarization_prompt) + - num_tokens_from_string(result) + ) + + return result + + async def _summarize_descriptions_with_llm( + self, items: str | tuple[str, str] | list[str], descriptions: list[str] + ): + """Summarize descriptions using the LLM.""" + response = await self._llm( + self._summarization_prompt, + name="summarize", + variables={ + self._entity_name_key: json.dumps(items), + self._input_descriptions_key: json.dumps(sorted(descriptions)), + }, + model_parameters={"max_tokens": self._max_summary_length}, + ) + # Calculate result + return str(response.output) diff --git a/graphrag/graphrag/index/graph/extractors/summarize/prompts.py b/graphrag/graphrag/index/graph/extractors/summarize/prompts.py new file mode 100644 index 0000000000000000000000000000000000000000..90e4434ee813fb6a6b8adb2bf9050d90a09a7a0b --- /dev/null +++ b/graphrag/graphrag/index/graph/extractors/summarize/prompts.py @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A file containing prompts definition.""" + +SUMMARIZE_PROMPT = """ +You are a helpful assistant responsible for generating a comprehensive summary of the data provided below. +Given one or two entities, and a list of descriptions, all related to the same entity or group of entities. +Please concatenate all of these into a single, comprehensive description. Make sure to include information collected from all the descriptions. +If the provided descriptions are contradictory, please resolve the contradictions and provide a single, coherent summary. +Make sure it is written in third person, and include the entity names so we the have full context. + +####### +-Data- +Entities: {entity_name} +Description List: {description_list} +####### +Output: +""" diff --git a/graphrag/graphrag/index/graph/utils/__init__.py b/graphrag/graphrag/index/graph/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6d4479283a290c8165b4f4d6427d7fc5b97b0544 --- /dev/null +++ b/graphrag/graphrag/index/graph/utils/__init__.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph utils package root.""" + +from .normalize_node_names import normalize_node_names +from .stable_lcc import stable_largest_connected_component + +__all__ = ["normalize_node_names", "stable_largest_connected_component"] diff --git a/graphrag/graphrag/index/graph/utils/normalize_node_names.py b/graphrag/graphrag/index/graph/utils/normalize_node_names.py new file mode 100644 index 0000000000000000000000000000000000000000..bcc874a9274792606e136bbfb2f69aee2aef27f8 --- /dev/null +++ b/graphrag/graphrag/index/graph/utils/normalize_node_names.py @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing normalize_node_names method definition.""" + +import html + +import networkx as nx + + +def normalize_node_names(graph: nx.Graph | nx.DiGraph) -> nx.Graph | nx.DiGraph: + """Normalize node names.""" + node_mapping = {node: html.unescape(node.upper().strip()) for node in graph.nodes()} # type: ignore + return nx.relabel_nodes(graph, node_mapping) diff --git a/graphrag/graphrag/index/graph/utils/stable_lcc.py b/graphrag/graphrag/index/graph/utils/stable_lcc.py new file mode 100644 index 0000000000000000000000000000000000000000..7d602a6ba71cc0af6168c69dda9b871ab2a6427b --- /dev/null +++ b/graphrag/graphrag/index/graph/utils/stable_lcc.py @@ -0,0 +1,60 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module for producing a stable largest connected component, i.e. same input graph == same output lcc.""" + +from typing import Any, cast + +import networkx as nx +from graspologic.utils import largest_connected_component + +from .normalize_node_names import normalize_node_names + + +def stable_largest_connected_component(graph: nx.Graph) -> nx.Graph: + """Return the largest connected component of the graph, with nodes and edges sorted in a stable way.""" + graph = graph.copy() + graph = cast(nx.Graph, largest_connected_component(graph)) + graph = normalize_node_names(graph) + return _stabilize_graph(graph) + + +def _stabilize_graph(graph: nx.Graph) -> nx.Graph: + """Ensure an undirected graph with the same relationships will always be read the same way.""" + fixed_graph = nx.DiGraph() if graph.is_directed() else nx.Graph() + + sorted_nodes = graph.nodes(data=True) + sorted_nodes = sorted(sorted_nodes, key=lambda x: x[0]) + + fixed_graph.add_nodes_from(sorted_nodes) + edges = list(graph.edges(data=True)) + + # If the graph is undirected, we create the edges in a stable way, so we get the same results + # for example: + # A -> B + # in graph theory is the same as + # B -> A + # in an undirected graph + # however, this can lead to downstream issues because sometimes + # consumers read graph.nodes() which ends up being [A, B] and sometimes it's [B, A] + # but they base some of their logic on the order of the nodes, so the order ends up being important + # so we sort the nodes in the edge in a stable way, so that we always get the same order + if not graph.is_directed(): + + def _sort_source_target(edge): + source, target, edge_data = edge + if source > target: + temp = source + source = target + target = temp + return source, target, edge_data + + edges = [_sort_source_target(edge) for edge in edges] + + def _get_edge_key(source: Any, target: Any) -> str: + return f"{source} -> {target}" + + edges = sorted(edges, key=lambda x: _get_edge_key(x[0], x[1])) + + fixed_graph.add_edges_from(edges) + return fixed_graph diff --git a/graphrag/graphrag/index/graph/visualization/__init__.py b/graphrag/graphrag/index/graph/visualization/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f7780e4e9cf4a616260c25e4d60799db4b936262 --- /dev/null +++ b/graphrag/graphrag/index/graph/visualization/__init__.py @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph visualization package root.""" + +from .compute_umap_positions import compute_umap_positions, get_zero_positions +from .typing import GraphLayout, NodePosition + +__all__ = [ + "GraphLayout", + "NodePosition", + "compute_umap_positions", + "get_zero_positions", +] diff --git a/graphrag/graphrag/index/graph/visualization/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/graph/visualization/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d6940bd1e641d4c91227ea97f3b7731f33f0df43 Binary files /dev/null and b/graphrag/graphrag/index/graph/visualization/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/graph/visualization/__pycache__/compute_umap_positions.cpython-311.pyc b/graphrag/graphrag/index/graph/visualization/__pycache__/compute_umap_positions.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..54ff340d03aab387247502d50e422c7f94e14382 Binary files /dev/null and b/graphrag/graphrag/index/graph/visualization/__pycache__/compute_umap_positions.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/graph/visualization/compute_umap_positions.py b/graphrag/graphrag/index/graph/visualization/compute_umap_positions.py new file mode 100644 index 0000000000000000000000000000000000000000..569b7b309d9db7f296b6453a68d35d0eee471026 --- /dev/null +++ b/graphrag/graphrag/index/graph/visualization/compute_umap_positions.py @@ -0,0 +1,144 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing compute_umap_positions and visualize_embedding method definition.""" + +import graspologic as gc +import matplotlib.pyplot as plt +import networkx as nx +import numpy as np +import umap + +from .typing import NodePosition + + +def get_zero_positions( + node_labels: list[str], + node_categories: list[int] | None = None, + node_sizes: list[int] | None = None, + three_d: bool | None = False, +) -> list[NodePosition]: + """Project embedding vectors down to 2D/3D using UMAP.""" + embedding_position_data: list[NodePosition] = [] + for index, node_name in enumerate(node_labels): + node_category = 1 if node_categories is None else node_categories[index] + node_size = 1 if node_sizes is None else node_sizes[index] + + if not three_d: + embedding_position_data.append( + NodePosition( + label=str(node_name), + x=0, + y=0, + cluster=str(int(node_category)), + size=int(node_size), + ) + ) + else: + embedding_position_data.append( + NodePosition( + label=str(node_name), + x=0, + y=0, + z=0, + cluster=str(int(node_category)), + size=int(node_size), + ) + ) + return embedding_position_data + + +def compute_umap_positions( + embedding_vectors: np.ndarray, + node_labels: list[str], + node_categories: list[int] | None = None, + node_sizes: list[int] | None = None, + min_dist: float = 0.75, + n_neighbors: int = 25, + spread: int = 1, + metric: str = "euclidean", + n_components: int = 2, + random_state: int = 86, +) -> list[NodePosition]: + """Project embedding vectors down to 2D/3D using UMAP.""" + embedding_positions = umap.UMAP( + min_dist=min_dist, + n_neighbors=n_neighbors, + spread=spread, + n_components=n_components, + metric=metric, + random_state=random_state, + ).fit_transform(embedding_vectors) + + embedding_position_data: list[NodePosition] = [] + for index, node_name in enumerate(node_labels): + node_points = embedding_positions[index] # type: ignore + node_category = 1 if node_categories is None else node_categories[index] + node_size = 1 if node_sizes is None else node_sizes[index] + + if len(node_points) == 2: + embedding_position_data.append( + NodePosition( + label=str(node_name), + x=float(node_points[0]), + y=float(node_points[1]), + cluster=str(int(node_category)), + size=int(node_size), + ) + ) + else: + embedding_position_data.append( + NodePosition( + label=str(node_name), + x=float(node_points[0]), + y=float(node_points[1]), + z=float(node_points[2]), + cluster=str(int(node_category)), + size=int(node_size), + ) + ) + return embedding_position_data + + +def visualize_embedding( + graph, + umap_positions: list[dict], +): + """Project embedding down to 2D using UMAP and visualize.""" + # rendering + plt.clf() + figure = plt.gcf() + ax = plt.gca() + + ax.set_axis_off() + figure.set_size_inches(10, 10) + figure.set_dpi(400) + + node_position_dict = { + (str)(position["label"]): (position["x"], position["y"]) + for position in umap_positions + } + node_category_dict = { + (str)(position["label"]): position["category"] for position in umap_positions + } + node_sizes = [position["size"] for position in umap_positions] + node_colors = gc.layouts.categorical_colors(node_category_dict) # type: ignore + + vertices = [] + node_color_list = [] + for node in node_position_dict: + vertices.append(node) + node_color_list.append(node_colors[node]) + + nx.draw_networkx_nodes( + graph, + pos=node_position_dict, + nodelist=vertices, + node_color=node_color_list, # type: ignore + alpha=1.0, + linewidths=0.01, + node_size=node_sizes, # type: ignore + node_shape="o", + ax=ax, + ) + plt.show() diff --git a/graphrag/graphrag/index/graph/visualization/typing.py b/graphrag/graphrag/index/graph/visualization/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..ae46afa928a0e5586704c9cddfad36f042bfa910 --- /dev/null +++ b/graphrag/graphrag/index/graph/visualization/typing.py @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +# Use this for now instead of a wrapper +"""A module containing 'NodePosition' model.""" + +from dataclasses import dataclass + + +@dataclass +class NodePosition: + """Node position class definition.""" + + label: str + cluster: str + size: float + + x: float + y: float + z: float | None = None + + def to_pandas(self) -> tuple[str, float, float, str, float]: + """To pandas method definition.""" + return self.label, self.x, self.y, self.cluster, self.size + + +GraphLayout = list[NodePosition] diff --git a/graphrag/graphrag/index/init_content.py b/graphrag/graphrag/index/init_content.py new file mode 100644 index 0000000000000000000000000000000000000000..d2ad3906b12e161e6723ffcb4a05ec8cf0c8c89e --- /dev/null +++ b/graphrag/graphrag/index/init_content.py @@ -0,0 +1,165 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +"""Content for the init CLI command.""" + +import graphrag.config.defaults as defs + +INIT_YAML = f""" +encoding_model: cl100k_base +skip_workflows: [] +llm: + api_key: ${{GRAPHRAG_API_KEY}} + type: {defs.LLM_TYPE.value} # or azure_openai_chat + model: {defs.LLM_MODEL} + model_supports_json: true # recommended if this is available for your model. + # max_tokens: {defs.LLM_MAX_TOKENS} + # request_timeout: {defs.LLM_REQUEST_TIMEOUT} + # api_base: https://.openai.azure.com + # api_version: 2024-02-15-preview + # organization: + # deployment_name: + # tokens_per_minute: 150_000 # set a leaky bucket throttle + # requests_per_minute: 10_000 # set a leaky bucket throttle + # max_retries: {defs.LLM_MAX_RETRIES} + # max_retry_wait: {defs.LLM_MAX_RETRY_WAIT} + # sleep_on_rate_limit_recommendation: true # whether to sleep when azure suggests wait-times + # concurrent_requests: {defs.LLM_CONCURRENT_REQUESTS} # the number of parallel inflight requests that may be made + # temperature: {defs.LLM_TEMPERATURE} # temperature for sampling + # top_p: {defs.LLM_TOP_P} # top-p sampling + # n: {defs.LLM_N} # Number of completions to generate + +parallelization: + stagger: {defs.PARALLELIZATION_STAGGER} + # num_threads: {defs.PARALLELIZATION_NUM_THREADS} # the number of threads to use for parallel processing + +async_mode: {defs.ASYNC_MODE.value} # or asyncio + +embeddings: + ## parallelization: override the global parallelization settings for embeddings + async_mode: {defs.ASYNC_MODE.value} # or asyncio + llm: + api_key: ${{GRAPHRAG_API_KEY}} + type: {defs.EMBEDDING_TYPE.value} # or azure_openai_embedding + model: {defs.EMBEDDING_MODEL} + # api_base: https://.openai.azure.com + # api_version: 2024-02-15-preview + # organization: + # deployment_name: + # tokens_per_minute: 150_000 # set a leaky bucket throttle + # requests_per_minute: 10_000 # set a leaky bucket throttle + # max_retries: {defs.LLM_MAX_RETRIES} + # max_retry_wait: {defs.LLM_MAX_RETRY_WAIT} + # sleep_on_rate_limit_recommendation: true # whether to sleep when azure suggests wait-times + # concurrent_requests: {defs.LLM_CONCURRENT_REQUESTS} # the number of parallel inflight requests that may be made + # batch_size: {defs.EMBEDDING_BATCH_SIZE} # the number of documents to send in a single request + # batch_max_tokens: {defs.EMBEDDING_BATCH_MAX_TOKENS} # the maximum number of tokens to send in a single request + # target: {defs.EMBEDDING_TARGET.value} # or optional + + + +chunks: + size: {defs.CHUNK_SIZE} + overlap: {defs.CHUNK_OVERLAP} + group_by_columns: [{",".join(defs.CHUNK_GROUP_BY_COLUMNS)}] # by default, we don't allow chunks to cross documents + +input: + type: {defs.INPUT_TYPE.value} # or blob + file_type: {defs.INPUT_FILE_TYPE.value} # or csv + base_dir: "{defs.INPUT_BASE_DIR}" + file_encoding: {defs.INPUT_FILE_ENCODING} + file_pattern: ".*\\\\.txt$" + +cache: + type: {defs.CACHE_TYPE.value} # or blob + base_dir: "{defs.CACHE_BASE_DIR}" + # connection_string: + # container_name: + +storage: + type: {defs.STORAGE_TYPE.value} # or blob + base_dir: "{defs.STORAGE_BASE_DIR}" + # connection_string: + # container_name: + +reporting: + type: {defs.REPORTING_TYPE.value} # or console, blob + base_dir: "{defs.REPORTING_BASE_DIR}" + # connection_string: + # container_name: + +entity_extraction: + ## llm: override the global llm settings for this task + ## parallelization: override the global parallelization settings for this task + ## async_mode: override the global async_mode settings for this task + prompt: "prompts/entity_extraction.txt" + entity_types: [{",".join(defs.ENTITY_EXTRACTION_ENTITY_TYPES)}] + max_gleanings: {defs.ENTITY_EXTRACTION_MAX_GLEANINGS} + +summarize_descriptions: + ## llm: override the global llm settings for this task + ## parallelization: override the global parallelization settings for this task + ## async_mode: override the global async_mode settings for this task + prompt: "prompts/summarize_descriptions.txt" + max_length: {defs.SUMMARIZE_DESCRIPTIONS_MAX_LENGTH} + +claim_extraction: + ## llm: override the global llm settings for this task + ## parallelization: override the global parallelization settings for this task + ## async_mode: override the global async_mode settings for this task + # enabled: true + prompt: "prompts/claim_extraction.txt" + description: "{defs.CLAIM_DESCRIPTION}" + max_gleanings: {defs.CLAIM_MAX_GLEANINGS} + +community_reports: + ## llm: override the global llm settings for this task + ## parallelization: override the global parallelization settings for this task + ## async_mode: override the global async_mode settings for this task + prompt: "prompts/community_report.txt" + max_length: {defs.COMMUNITY_REPORT_MAX_LENGTH} + max_input_length: {defs.COMMUNITY_REPORT_MAX_INPUT_LENGTH} + +cluster_graph: + max_cluster_size: {defs.MAX_CLUSTER_SIZE} + +embed_graph: + enabled: false # if true, will generate node2vec embeddings for nodes + # num_walks: {defs.NODE2VEC_NUM_WALKS} + # walk_length: {defs.NODE2VEC_WALK_LENGTH} + # window_size: {defs.NODE2VEC_WINDOW_SIZE} + # iterations: {defs.NODE2VEC_ITERATIONS} + # random_seed: {defs.NODE2VEC_RANDOM_SEED} + +umap: + enabled: false # if true, will generate UMAP embeddings for nodes + +snapshots: + graphml: false + raw_entities: false + top_level_nodes: false + +local_search: + # text_unit_prop: {defs.LOCAL_SEARCH_TEXT_UNIT_PROP} + # community_prop: {defs.LOCAL_SEARCH_COMMUNITY_PROP} + # conversation_history_max_turns: {defs.LOCAL_SEARCH_CONVERSATION_HISTORY_MAX_TURNS} + # top_k_mapped_entities: {defs.LOCAL_SEARCH_TOP_K_MAPPED_ENTITIES} + # top_k_relationships: {defs.LOCAL_SEARCH_TOP_K_RELATIONSHIPS} + # llm_temperature: {defs.LOCAL_SEARCH_LLM_TEMPERATURE} # temperature for sampling + # llm_top_p: {defs.LOCAL_SEARCH_LLM_TOP_P} # top-p sampling + # llm_n: {defs.LOCAL_SEARCH_LLM_N} # Number of completions to generate + # max_tokens: {defs.LOCAL_SEARCH_MAX_TOKENS} + +global_search: + # llm_temperature: {defs.GLOBAL_SEARCH_LLM_TEMPERATURE} # temperature for sampling + # llm_top_p: {defs.GLOBAL_SEARCH_LLM_TOP_P} # top-p sampling + # llm_n: {defs.GLOBAL_SEARCH_LLM_N} # Number of completions to generate + # max_tokens: {defs.GLOBAL_SEARCH_MAX_TOKENS} + # data_max_tokens: {defs.GLOBAL_SEARCH_DATA_MAX_TOKENS} + # map_max_tokens: {defs.GLOBAL_SEARCH_MAP_MAX_TOKENS} + # reduce_max_tokens: {defs.GLOBAL_SEARCH_REDUCE_MAX_TOKENS} + # concurrency: {defs.GLOBAL_SEARCH_CONCURRENCY} +""" + +INIT_DOTENV = """ +GRAPHRAG_API_KEY= +""" diff --git a/graphrag/graphrag/index/input/__init__.py b/graphrag/graphrag/index/input/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..91421867de9491e48664df49f311f3f84351337f --- /dev/null +++ b/graphrag/graphrag/index/input/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine input package root.""" + +from .load_input import load_input + +__all__ = ["load_input"] diff --git a/graphrag/graphrag/index/input/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/input/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff4d34771556708aee0c6f147de2ce7705bcbea7 Binary files /dev/null and b/graphrag/graphrag/index/input/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/input/__pycache__/csv.cpython-311.pyc b/graphrag/graphrag/index/input/__pycache__/csv.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b2b4afa3eb4783e5a7de159afdcc204631a4d3c2 Binary files /dev/null and b/graphrag/graphrag/index/input/__pycache__/csv.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/input/__pycache__/load_input.cpython-311.pyc b/graphrag/graphrag/index/input/__pycache__/load_input.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b62b93abc04debc571484c453b6d15dc35397e05 Binary files /dev/null and b/graphrag/graphrag/index/input/__pycache__/load_input.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/input/__pycache__/text.cpython-311.pyc b/graphrag/graphrag/index/input/__pycache__/text.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..634e25cdf7df42c52c4baf965135b7c1a7486e88 Binary files /dev/null and b/graphrag/graphrag/index/input/__pycache__/text.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/input/csv.py b/graphrag/graphrag/index/input/csv.py new file mode 100644 index 0000000000000000000000000000000000000000..2e4864a98c3a177959b8e171f071dea8c928e3aa --- /dev/null +++ b/graphrag/graphrag/index/input/csv.py @@ -0,0 +1,138 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing load method definition.""" + +import logging +import re +from io import BytesIO +from typing import cast + +import pandas as pd + +from graphrag.index.config import PipelineCSVInputConfig, PipelineInputConfig +from graphrag.index.progress import ProgressReporter +from graphrag.index.storage import PipelineStorage +from graphrag.index.utils import gen_md5_hash + +log = logging.getLogger(__name__) + +DEFAULT_FILE_PATTERN = re.compile(r"(?P[^\\/]).csv$") + +input_type = "csv" + + +async def load( + config: PipelineInputConfig, + progress: ProgressReporter | None, + storage: PipelineStorage, +) -> pd.DataFrame: + """Load csv inputs from a directory.""" + csv_config = cast(PipelineCSVInputConfig, config) + log.info("Loading csv files from %s", csv_config.base_dir) + + async def load_file(path: str, group: dict | None) -> pd.DataFrame: + if group is None: + group = {} + buffer = BytesIO(await storage.get(path, as_bytes=True)) + data = pd.read_csv(buffer, encoding=config.encoding or "latin-1") + additional_keys = group.keys() + if len(additional_keys) > 0: + data[[*additional_keys]] = data.apply( + lambda _row: pd.Series([group[key] for key in additional_keys]), axis=1 + ) + if "id" not in data.columns: + data["id"] = data.apply(lambda x: gen_md5_hash(x, x.keys()), axis=1) + if csv_config.source_column is not None and "source" not in data.columns: + if csv_config.source_column not in data.columns: + log.warning( + "source_column %s not found in csv file %s", + csv_config.source_column, + path, + ) + else: + data["source"] = data.apply( + lambda x: x[csv_config.source_column], axis=1 + ) + if csv_config.text_column is not None and "text" not in data.columns: + if csv_config.text_column not in data.columns: + log.warning( + "text_column %s not found in csv file %s", + csv_config.text_column, + path, + ) + else: + data["text"] = data.apply(lambda x: x[csv_config.text_column], axis=1) + if csv_config.title_column is not None and "title" not in data.columns: + if csv_config.title_column not in data.columns: + log.warning( + "title_column %s not found in csv file %s", + csv_config.title_column, + path, + ) + else: + data["title"] = data.apply(lambda x: x[csv_config.title_column], axis=1) + + if csv_config.timestamp_column is not None: + fmt = csv_config.timestamp_format + if fmt is None: + msg = "Must specify timestamp_format if timestamp_column is specified" + raise ValueError(msg) + + if csv_config.timestamp_column not in data.columns: + log.warning( + "timestamp_column %s not found in csv file %s", + csv_config.timestamp_column, + path, + ) + else: + data["timestamp"] = pd.to_datetime( + data[csv_config.timestamp_column], format=fmt + ) + + # TODO: Theres probably a less gross way to do this + if "year" not in data.columns: + data["year"] = data.apply(lambda x: x["timestamp"].year, axis=1) + if "month" not in data.columns: + data["month"] = data.apply(lambda x: x["timestamp"].month, axis=1) + if "day" not in data.columns: + data["day"] = data.apply(lambda x: x["timestamp"].day, axis=1) + if "hour" not in data.columns: + data["hour"] = data.apply(lambda x: x["timestamp"].hour, axis=1) + if "minute" not in data.columns: + data["minute"] = data.apply(lambda x: x["timestamp"].minute, axis=1) + if "second" not in data.columns: + data["second"] = data.apply(lambda x: x["timestamp"].second, axis=1) + + return data + + file_pattern = ( + re.compile(config.file_pattern) + if config.file_pattern is not None + else DEFAULT_FILE_PATTERN + ) + files = list( + storage.find( + file_pattern, + progress=progress, + file_filter=config.file_filter, + ) + ) + + if len(files) == 0: + msg = f"No CSV files found in {config.base_dir}" + raise ValueError(msg) + + files_loaded = [] + + for file, group in files: + try: + files_loaded.append(await load_file(file, group)) + except Exception: # noqa: BLE001 (catching Exception is fine here) + log.warning("Warning! Error loading csv file %s. Skipping...", file) + + log.info("Found %d csv files, loading %d", len(files), len(files_loaded)) + result = pd.concat(files_loaded) + total_files_log = f"Total number of unfiltered csv rows: {len(result)}" + log.info(total_files_log) + return result diff --git a/graphrag/graphrag/index/input/load_input.py b/graphrag/graphrag/index/input/load_input.py new file mode 100644 index 0000000000000000000000000000000000000000..6d623342105bde67bd54ffc460edba4b41e0ebea --- /dev/null +++ b/graphrag/graphrag/index/input/load_input.py @@ -0,0 +1,85 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing load_input method definition.""" + +import logging +from collections.abc import Awaitable, Callable +from pathlib import Path +from typing import cast + +import pandas as pd + +from graphrag.config import InputConfig, InputType +from graphrag.index.config import PipelineInputConfig +from graphrag.index.progress import NullProgressReporter, ProgressReporter +from graphrag.index.storage import ( + BlobPipelineStorage, + FilePipelineStorage, +) + +from .csv import input_type as csv +from .csv import load as load_csv +from .text import input_type as text +from .text import load as load_text + +log = logging.getLogger(__name__) +loaders: dict[str, Callable[..., Awaitable[pd.DataFrame]]] = { + text: load_text, + csv: load_csv, +} + + +async def load_input( + config: PipelineInputConfig | InputConfig, + progress_reporter: ProgressReporter | None = None, + root_dir: str | None = None, +) -> pd.DataFrame: + """Load the input data for a pipeline.""" + root_dir = root_dir or "" + log.info("loading input from root_dir=%s", config.base_dir) + progress_reporter = progress_reporter or NullProgressReporter() + + if config is None: + msg = "No input specified!" + raise ValueError(msg) + + match config.type: + case InputType.blob: + log.info("using blob storage input") + if config.container_name is None: + msg = "Container name required for blob storage" + raise ValueError(msg) + if ( + config.connection_string is None + and config.storage_account_blob_url is None + ): + msg = "Connection string or storage account blob url required for blob storage" + raise ValueError(msg) + storage = BlobPipelineStorage( + connection_string=config.connection_string, + storage_account_blob_url=config.storage_account_blob_url, + container_name=config.container_name, + path_prefix=config.base_dir, + ) + case InputType.file: + log.info("using file storage for input") + storage = FilePipelineStorage( + root_dir=str(Path(root_dir) / (config.base_dir or "")) + ) + case _: + log.info("using file storage for input") + storage = FilePipelineStorage( + root_dir=str(Path(root_dir) / (config.base_dir or "")) + ) + + if config.file_type in loaders: + progress = progress_reporter.child( + f"Loading Input ({config.file_type})", transient=False + ) + loader = loaders[config.file_type] + results = await loader(config, progress, storage) + return cast(pd.DataFrame, results) + + msg = f"Unknown input type {config.file_type}" + raise ValueError(msg) diff --git a/graphrag/graphrag/index/input/text.py b/graphrag/graphrag/index/input/text.py new file mode 100644 index 0000000000000000000000000000000000000000..2a676c0902458fc4702849f8c06f0e03c0a263cd --- /dev/null +++ b/graphrag/graphrag/index/input/text.py @@ -0,0 +1,66 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing load method definition.""" + +import logging +import re +from pathlib import Path +from typing import Any + +import pandas as pd + +from graphrag.index.config import PipelineInputConfig +from graphrag.index.progress import ProgressReporter +from graphrag.index.storage import PipelineStorage +from graphrag.index.utils import gen_md5_hash + +DEFAULT_FILE_PATTERN = re.compile( + r".*[\\/](?P[^\\/]+)[\\/](?P\d{4})-(?P\d{2})-(?P\d{2})_(?P[^_]+)_\d+\.txt" +) +input_type = "text" +log = logging.getLogger(__name__) + + +async def load( + config: PipelineInputConfig, + progress: ProgressReporter | None, + storage: PipelineStorage, +) -> pd.DataFrame: + """Load text inputs from a directory.""" + + async def load_file( + path: str, group: dict | None = None, _encoding: str = "utf-8" + ) -> dict[str, Any]: + if group is None: + group = {} + text = await storage.get(path, encoding="utf-8") + new_item = {**group, "text": text} + new_item["id"] = gen_md5_hash(new_item, new_item.keys()) + new_item["title"] = str(Path(path).name) + return new_item + + files = list( + storage.find( + re.compile(config.file_pattern), + progress=progress, + file_filter=config.file_filter, + ) + ) + if len(files) == 0: + msg = f"No text files found in {config.base_dir}" + raise ValueError(msg) + found_files = f"found text files from {config.base_dir}, found {files}" + log.info(found_files) + + files_loaded = [] + + for file, group in files: + try: + files_loaded.append(await load_file(file, group)) + except Exception: # noqa: BLE001 (catching Exception is fine here) + log.warning("Warning! Error loading file %s. Skipping...", file) + + log.info("Found %d files, loading %d", len(files), len(files_loaded)) + + return pd.DataFrame(files_loaded) diff --git a/graphrag/graphrag/index/llm/__init__.py b/graphrag/graphrag/index/llm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..008ef07ccdf6e611c9ad9565c17474724dff9146 --- /dev/null +++ b/graphrag/graphrag/index/llm/__init__.py @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine LLM package root.""" + +from .load_llm import load_llm, load_llm_embeddings +from .types import TextListSplitter, TextSplitter + +__all__ = [ + "TextListSplitter", + "TextSplitter", + "load_llm", + "load_llm_embeddings", +] diff --git a/graphrag/graphrag/index/llm/load_llm.py b/graphrag/graphrag/index/llm/load_llm.py new file mode 100644 index 0000000000000000000000000000000000000000..264229c887482b0d5d6ba8a110b37a1b22a29ddd --- /dev/null +++ b/graphrag/graphrag/index/llm/load_llm.py @@ -0,0 +1,313 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Load llm utilities.""" + +from __future__ import annotations + +import asyncio +import logging +from typing import TYPE_CHECKING, Any + +from graphrag.config.enums import LLMType +from graphrag.llm import ( + CompletionLLM, + EmbeddingLLM, + LLMCache, + LLMLimiter, + MockCompletionLLM, + OpenAIConfiguration, + create_openai_chat_llm, + create_openai_client, + create_openai_completion_llm, + create_openai_embedding_llm, + create_tpm_rpm_limiters, +) + +if TYPE_CHECKING: + from datashaper import VerbCallbacks + + from graphrag.index.cache import PipelineCache + from graphrag.index.typing import ErrorHandlerFn + +log = logging.getLogger(__name__) + +_semaphores: dict[str, asyncio.Semaphore] = {} +_rate_limiters: dict[str, LLMLimiter] = {} + + +def load_llm( + name: str, + llm_type: LLMType, + callbacks: VerbCallbacks, + cache: PipelineCache | None, + llm_config: dict[str, Any] | None = None, + chat_only=False, +) -> CompletionLLM: + """Load the LLM for the entity extraction chain.""" + on_error = _create_error_handler(callbacks) + + if llm_type in loaders: + if chat_only and not loaders[llm_type]["chat"]: + msg = f"LLM type {llm_type} does not support chat" + raise ValueError(msg) + if cache is not None: + cache = cache.child(name) + + loader = loaders[llm_type] + return loader["load"](on_error, cache, llm_config or {}) + + msg = f"Unknown LLM type {llm_type}" + raise ValueError(msg) + + +def load_llm_embeddings( + name: str, + llm_type: LLMType, + callbacks: VerbCallbacks, + cache: PipelineCache | None, + llm_config: dict[str, Any] | None = None, + chat_only=False, +) -> EmbeddingLLM: + """Load the LLM for the entity extraction chain.""" + on_error = _create_error_handler(callbacks) + if llm_type in loaders: + if chat_only and not loaders[llm_type]["chat"]: + msg = f"LLM type {llm_type} does not support chat" + raise ValueError(msg) + if cache is not None: + cache = cache.child(name) + + return loaders[llm_type]["load"](on_error, cache, llm_config or {}) + + msg = f"Unknown LLM type {llm_type}" + raise ValueError(msg) + + +def _create_error_handler(callbacks: VerbCallbacks) -> ErrorHandlerFn: + def on_error( + error: BaseException | None = None, + stack: str | None = None, + details: dict | None = None, + ) -> None: + callbacks.error("Error Invoking LLM", error, stack, details) + + return on_error + + +def _load_openai_completion_llm( + on_error: ErrorHandlerFn, + cache: LLMCache, + config: dict[str, Any], + azure=False, +): + return _create_openai_completion_llm( + OpenAIConfiguration({ + **_get_base_config(config), + "model": config.get("model", "gpt-4-turbo-preview"), + "deployment_name": config.get("deployment_name"), + "temperature": config.get("temperature", 0.0), + "frequency_penalty": config.get("frequency_penalty", 0), + "presence_penalty": config.get("presence_penalty", 0), + "top_p": config.get("top_p", 1), + "max_tokens": config.get("max_tokens", 4000), + "n": config.get("n"), + }), + on_error, + cache, + azure, + ) + + +def _load_openai_chat_llm( + on_error: ErrorHandlerFn, + cache: LLMCache, + config: dict[str, Any], + azure=False, +): + return _create_openai_chat_llm( + OpenAIConfiguration({ + # Set default values + **_get_base_config(config), + "model": config.get("model", "gpt-4-turbo-preview"), + "deployment_name": config.get("deployment_name"), + "temperature": config.get("temperature", 0.0), + "frequency_penalty": config.get("frequency_penalty", 0), + "presence_penalty": config.get("presence_penalty", 0), + "top_p": config.get("top_p", 1), + "max_tokens": config.get("max_tokens"), + "n": config.get("n"), + }), + on_error, + cache, + azure, + ) + + +def _load_openai_embeddings_llm( + on_error: ErrorHandlerFn, + cache: LLMCache, + config: dict[str, Any], + azure=False, +): + # TODO: Inject Cache + return _create_openai_embeddings_llm( + OpenAIConfiguration({ + **_get_base_config(config), + "model": config.get( + "embeddings_model", config.get("model", "text-embedding-3-small") + ), + "deployment_name": config.get("deployment_name"), + }), + on_error, + cache, + azure, + ) + + +def _load_azure_openai_completion_llm( + on_error: ErrorHandlerFn, cache: LLMCache, config: dict[str, Any] +): + return _load_openai_completion_llm(on_error, cache, config, True) + + +def _load_azure_openai_chat_llm( + on_error: ErrorHandlerFn, cache: LLMCache, config: dict[str, Any] +): + return _load_openai_chat_llm(on_error, cache, config, True) + + +def _load_azure_openai_embeddings_llm( + on_error: ErrorHandlerFn, cache: LLMCache, config: dict[str, Any] +): + return _load_openai_embeddings_llm(on_error, cache, config, True) + + +def _get_base_config(config: dict[str, Any]) -> dict[str, Any]: + api_key = config.get("api_key") + + return { + # Pass in all parameterized values + **config, + # Set default values + "api_key": api_key, + "api_base": config.get("api_base"), + "api_version": config.get("api_version"), + "organization": config.get("organization"), + "proxy": config.get("proxy"), + "max_retries": config.get("max_retries", 10), + "request_timeout": config.get("request_timeout", 60.0), + "model_supports_json": config.get("model_supports_json"), + "concurrent_requests": config.get("concurrent_requests", 4), + "encoding_model": config.get("encoding_model", "cl100k_base"), + "cognitive_services_endpoint": config.get("cognitive_services_endpoint"), + } + + +def _load_static_response( + _on_error: ErrorHandlerFn, _cache: PipelineCache, config: dict[str, Any] +) -> CompletionLLM: + return MockCompletionLLM(config.get("responses", [])) + + +loaders = { + LLMType.OpenAI: { + "load": _load_openai_completion_llm, + "chat": False, + }, + LLMType.AzureOpenAI: { + "load": _load_azure_openai_completion_llm, + "chat": False, + }, + LLMType.OpenAIChat: { + "load": _load_openai_chat_llm, + "chat": True, + }, + LLMType.AzureOpenAIChat: { + "load": _load_azure_openai_chat_llm, + "chat": True, + }, + LLMType.OpenAIEmbedding: { + "load": _load_openai_embeddings_llm, + "chat": False, + }, + LLMType.AzureOpenAIEmbedding: { + "load": _load_azure_openai_embeddings_llm, + "chat": False, + }, + LLMType.StaticResponse: { + "load": _load_static_response, + "chat": False, + }, +} + + +def _create_openai_chat_llm( + configuration: OpenAIConfiguration, + on_error: ErrorHandlerFn, + cache: LLMCache, + azure=False, +) -> CompletionLLM: + """Create an openAI chat llm.""" + client = create_openai_client(configuration=configuration, azure=azure) + limiter = _create_limiter(configuration) + semaphore = _create_semaphore(configuration) + return create_openai_chat_llm( + client, configuration, cache, limiter, semaphore, on_error=on_error + ) + + +def _create_openai_completion_llm( + configuration: OpenAIConfiguration, + on_error: ErrorHandlerFn, + cache: LLMCache, + azure=False, +) -> CompletionLLM: + """Create an openAI completion llm.""" + client = create_openai_client(configuration=configuration, azure=azure) + limiter = _create_limiter(configuration) + semaphore = _create_semaphore(configuration) + return create_openai_completion_llm( + client, configuration, cache, limiter, semaphore, on_error=on_error + ) + + +def _create_openai_embeddings_llm( + configuration: OpenAIConfiguration, + on_error: ErrorHandlerFn, + cache: LLMCache, + azure=False, +) -> EmbeddingLLM: + """Create an openAI embeddings llm.""" + client = create_openai_client(configuration=configuration, azure=azure) + limiter = _create_limiter(configuration) + semaphore = _create_semaphore(configuration) + return create_openai_embedding_llm( + client, configuration, cache, limiter, semaphore, on_error=on_error + ) + + +def _create_limiter(configuration: OpenAIConfiguration) -> LLMLimiter: + limit_name = configuration.model or configuration.deployment_name or "default" + if limit_name not in _rate_limiters: + tpm = configuration.tokens_per_minute + rpm = configuration.requests_per_minute + log.info("create TPM/RPM limiter for %s: TPM=%s, RPM=%s", limit_name, tpm, rpm) + _rate_limiters[limit_name] = create_tpm_rpm_limiters(configuration) + return _rate_limiters[limit_name] + + +def _create_semaphore(configuration: OpenAIConfiguration) -> asyncio.Semaphore | None: + limit_name = configuration.model or configuration.deployment_name or "default" + concurrency = configuration.concurrent_requests + + # bypass the semaphore if concurrency is zero + if not concurrency: + log.info("no concurrency limiter for %s", limit_name) + return None + + if limit_name not in _semaphores: + log.info("create concurrency limiter for %s: %s", limit_name, concurrency) + _semaphores[limit_name] = asyncio.Semaphore(concurrency) + + return _semaphores[limit_name] diff --git a/graphrag/graphrag/index/llm/types.py b/graphrag/graphrag/index/llm/types.py new file mode 100644 index 0000000000000000000000000000000000000000..73c47737cbc60fbd3f1e1978dbf50b244516e9f2 --- /dev/null +++ b/graphrag/graphrag/index/llm/types.py @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing the 'LLMtype' model.""" + +from collections.abc import Callable +from typing import TypeAlias + +TextSplitter: TypeAlias = Callable[[str], list[str]] +TextListSplitter: TypeAlias = Callable[[list[str]], list[str]] diff --git a/graphrag/graphrag/index/load_pipeline_config.py b/graphrag/graphrag/index/load_pipeline_config.py new file mode 100644 index 0000000000000000000000000000000000000000..50a532c5030d904dc562d5a8aeb1d093d349a662 --- /dev/null +++ b/graphrag/graphrag/index/load_pipeline_config.py @@ -0,0 +1,79 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing read_dotenv, load_pipeline_config, _parse_yaml and _create_include_constructor methods definition.""" + +import json +from pathlib import Path + +import yaml +from pyaml_env import parse_config as parse_config_with_env + +from graphrag.config import create_graphrag_config, read_dotenv +from graphrag.index.config import PipelineConfig + +from .create_pipeline_config import create_pipeline_config + + +def load_pipeline_config(config_or_path: str | PipelineConfig) -> PipelineConfig: + """Load a pipeline config from a file path or a config object.""" + if isinstance(config_or_path, PipelineConfig): + config = config_or_path + elif config_or_path == "default": + config = create_pipeline_config(create_graphrag_config(root_dir=".")) + else: + # Is there a .env file in the same directory as the config? + read_dotenv(str(Path(config_or_path).parent)) + + if config_or_path.endswith(".json"): + with Path(config_or_path).open(encoding="utf-8") as f: + config = json.load(f) + elif config_or_path.endswith((".yml", ".yaml")): + config = _parse_yaml(config_or_path) + else: + msg = f"Invalid config file type: {config_or_path}" + raise ValueError(msg) + + config = PipelineConfig.model_validate(config) + if not config.root_dir: + config.root_dir = str(Path(config_or_path).parent.resolve()) + + if config.extends is not None: + if isinstance(config.extends, str): + config.extends = [config.extends] + for extended_config in config.extends: + extended_config = load_pipeline_config(extended_config) + merged_config = { + **json.loads(extended_config.model_dump_json()), + **json.loads(config.model_dump_json(exclude_unset=True)), + } + config = PipelineConfig.model_validate(merged_config) + + return config + + +def _parse_yaml(path: str): + """Parse a yaml file, with support for !include directives.""" + # I don't like that this is static + loader_class = yaml.SafeLoader + + # Add !include constructor if not already present. + if "!include" not in loader_class.yaml_constructors: + loader_class.add_constructor("!include", _create_include_constructor()) + + return parse_config_with_env(path, loader=loader_class, default_value="") + + +def _create_include_constructor(): + """Create a constructor for !include directives.""" + + def handle_include(loader: yaml.Loader, node: yaml.Node): + """Include file referenced at node.""" + filename = str(Path(loader.name).parent / node.value) + if filename.endswith((".yml", ".yaml")): + return _parse_yaml(filename) + + with Path(filename).open(encoding="utf-8") as f: + return f.read() + + return handle_include diff --git a/graphrag/graphrag/index/progress/__init__.py b/graphrag/graphrag/index/progress/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..df6a21523df576df0926ee2feed3c075c32c1b81 --- /dev/null +++ b/graphrag/graphrag/index/progress/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Progress-reporting components.""" + +from .types import NullProgressReporter, PrintProgressReporter, ProgressReporter + +__all__ = ["NullProgressReporter", "PrintProgressReporter", "ProgressReporter"] diff --git a/graphrag/graphrag/index/progress/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/progress/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ec64bbd607ad101c9821baa1cefba8f21c0c5f14 Binary files /dev/null and b/graphrag/graphrag/index/progress/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/progress/__pycache__/types.cpython-311.pyc b/graphrag/graphrag/index/progress/__pycache__/types.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a72073b889d59f71bb8fd7d7f3636bedd493e5d8 Binary files /dev/null and b/graphrag/graphrag/index/progress/__pycache__/types.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/progress/rich.py b/graphrag/graphrag/index/progress/rich.py new file mode 100644 index 0000000000000000000000000000000000000000..362b64f0c8e6ee5813cd6b277fc793641df5d46a --- /dev/null +++ b/graphrag/graphrag/index/progress/rich.py @@ -0,0 +1,165 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Rich-based progress reporter for CLI use.""" + +# Print iterations progress +import asyncio + +from datashaper import Progress as DSProgress +from rich.console import Console, Group +from rich.live import Live +from rich.progress import Progress, TaskID, TimeElapsedColumn +from rich.spinner import Spinner +from rich.tree import Tree + +from .types import ProgressReporter + + +# https://stackoverflow.com/a/34325723 +class RichProgressReporter(ProgressReporter): + """A rich-based progress reporter for CLI use.""" + + _console: Console + _group: Group + _tree: Tree + _live: Live + _task: TaskID | None = None + _prefix: str + _transient: bool + _disposing: bool = False + _progressbar: Progress + _last_refresh: float = 0 + + def dispose(self) -> None: + """Dispose of the progress reporter.""" + self._disposing = True + self._live.stop() + + @property + def console(self) -> Console: + """Get the console.""" + return self._console + + @property + def group(self) -> Group: + """Get the group.""" + return self._group + + @property + def tree(self) -> Tree: + """Get the tree.""" + return self._tree + + @property + def live(self) -> Live: + """Get the live.""" + return self._live + + def __init__( + self, + prefix: str, + parent: "RichProgressReporter | None" = None, + transient: bool = True, + ) -> None: + """Create a new rich-based progress reporter.""" + self._prefix = prefix + + if parent is None: + console = Console() + group = Group(Spinner("dots", prefix), fit=True) + tree = Tree(group) + live = Live( + tree, console=console, refresh_per_second=1, vertical_overflow="crop" + ) + live.start() + + self._console = console + self._group = group + self._tree = tree + self._live = live + self._transient = False + else: + self._console = parent.console + self._group = parent.group + progress_columns = [*Progress.get_default_columns(), TimeElapsedColumn()] + self._progressbar = Progress( + *progress_columns, console=self._console, transient=transient + ) + + tree = Tree(prefix) + tree.add(self._progressbar) + tree.hide_root = True + + if parent is not None: + parent_tree = parent.tree + parent_tree.hide_root = False + parent_tree.add(tree) + + self._tree = tree + self._live = parent.live + self._transient = transient + + self.refresh() + + def refresh(self) -> None: + """Perform a debounced refresh.""" + now = asyncio.get_event_loop().time() + duration = now - self._last_refresh + if duration > 0.1: + self._last_refresh = now + self.force_refresh() + + def force_refresh(self) -> None: + """Force a refresh.""" + self.live.refresh() + + def stop(self) -> None: + """Stop the progress reporter.""" + self._live.stop() + + def child(self, prefix: str, transient: bool = True) -> ProgressReporter: + """Create a child progress bar.""" + return RichProgressReporter(parent=self, prefix=prefix, transient=transient) + + def error(self, message: str) -> None: + """Report an error.""" + self._console.print(f"❌ [red]{message}[/red]") + + def warning(self, message: str) -> None: + """Report a warning.""" + self._console.print(f"⚠️ [yellow]{message}[/yellow]") + + def success(self, message: str) -> None: + """Report success.""" + self._console.print(f"🚀 [green]{message}[/green]") + + def info(self, message: str) -> None: + """Report information.""" + self._console.print(message) + + def __call__(self, progress_update: DSProgress) -> None: + """Update progress.""" + if self._disposing: + return + progressbar = self._progressbar + + if self._task is None: + self._task = progressbar.add_task(self._prefix) + + progress_description = "" + if progress_update.description is not None: + progress_description = f" - {progress_update.description}" + + completed = progress_update.completed_items or progress_update.percent + total = progress_update.total_items or 1 + progressbar.update( + self._task, + completed=completed, + total=total, + description=f"{self._prefix}{progress_description}", + ) + if completed == total and self._transient: + progressbar.update(self._task, visible=False) + + self.refresh() diff --git a/graphrag/graphrag/index/progress/types.py b/graphrag/graphrag/index/progress/types.py new file mode 100644 index 0000000000000000000000000000000000000000..2912155ed1f86985fab1b6e2b90af4e69e0b23b2 --- /dev/null +++ b/graphrag/graphrag/index/progress/types.py @@ -0,0 +1,128 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Types for status reporting.""" + +from abc import ABC, abstractmethod + +from datashaper import Progress + + +class ProgressReporter(ABC): + """ + Abstract base class for progress reporters. + + This is used to report workflow processing progress via mechanisms like progress-bars. + """ + + @abstractmethod + def __call__(self, update: Progress): + """Update progress.""" + + @abstractmethod + def dispose(self): + """Dispose of the progress reporter.""" + + @abstractmethod + def child(self, prefix: str, transient=True) -> "ProgressReporter": + """Create a child progress bar.""" + + @abstractmethod + def force_refresh(self) -> None: + """Force a refresh.""" + + @abstractmethod + def stop(self) -> None: + """Stop the progress reporter.""" + + @abstractmethod + def error(self, message: str) -> None: + """Report an error.""" + + @abstractmethod + def warning(self, message: str) -> None: + """Report a warning.""" + + @abstractmethod + def info(self, message: str) -> None: + """Report information.""" + + @abstractmethod + def success(self, message: str) -> None: + """Report success.""" + + +class NullProgressReporter(ProgressReporter): + """A progress reporter that does nothing.""" + + def __call__(self, update: Progress) -> None: + """Update progress.""" + + def dispose(self) -> None: + """Dispose of the progress reporter.""" + + def child(self, prefix: str, transient: bool = True) -> ProgressReporter: + """Create a child progress bar.""" + return self + + def force_refresh(self) -> None: + """Force a refresh.""" + + def stop(self) -> None: + """Stop the progress reporter.""" + + def error(self, message: str) -> None: + """Report an error.""" + + def warning(self, message: str) -> None: + """Report a warning.""" + + def info(self, message: str) -> None: + """Report information.""" + + def success(self, message: str) -> None: + """Report success.""" + + +class PrintProgressReporter(ProgressReporter): + """A progress reporter that does nothing.""" + + prefix: str + + def __init__(self, prefix: str): + """Create a new progress reporter.""" + self.prefix = prefix + print(f"\n{self.prefix}", end="") # noqa T201 + + def __call__(self, update: Progress) -> None: + """Update progress.""" + print(".", end="") # noqa T201 + + def dispose(self) -> None: + """Dispose of the progress reporter.""" + + def child(self, prefix: str, transient: bool = True) -> "ProgressReporter": + """Create a child progress bar.""" + return PrintProgressReporter(prefix) + + def stop(self) -> None: + """Stop the progress reporter.""" + + def force_refresh(self) -> None: + """Force a refresh.""" + + def error(self, message: str) -> None: + """Report an error.""" + print(f"\n{self.prefix}ERROR: {message}") # noqa T201 + + def warning(self, message: str) -> None: + """Report a warning.""" + print(f"\n{self.prefix}WARNING: {message}") # noqa T201 + + def info(self, message: str) -> None: + """Report information.""" + print(f"\n{self.prefix}INFO: {message}") # noqa T201 + + def success(self, message: str) -> None: + """Report success.""" + print(f"\n{self.prefix}SUCCESS: {message}") # noqa T201 diff --git a/graphrag/graphrag/index/py.typed b/graphrag/graphrag/index/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..f4bd29895519bc8610fee2c13627ca50c0032e44 --- /dev/null +++ b/graphrag/graphrag/index/py.typed @@ -0,0 +1,2 @@ +# This package supports type hinting, +# see https://www.python.org/dev/peps/pep-0561/#packaging-type-information \ No newline at end of file diff --git a/graphrag/graphrag/index/reporting/__init__.py b/graphrag/graphrag/index/reporting/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..697d4fc51f9e2141b2d6ba09957834c19462e446 --- /dev/null +++ b/graphrag/graphrag/index/reporting/__init__.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Reporting utilities and implementations for the indexing engine.""" + +from .blob_workflow_callbacks import BlobWorkflowCallbacks +from .console_workflow_callbacks import ConsoleWorkflowCallbacks +from .file_workflow_callbacks import FileWorkflowCallbacks +from .load_pipeline_reporter import load_pipeline_reporter +from .progress_workflow_callbacks import ProgressWorkflowCallbacks + +__all__ = [ + "BlobWorkflowCallbacks", + "ConsoleWorkflowCallbacks", + "FileWorkflowCallbacks", + "ProgressWorkflowCallbacks", + "load_pipeline_reporter", +] diff --git a/graphrag/graphrag/index/reporting/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/reporting/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c6cb1fddcba2bcfd9a7d3479572441016f7ecdeb Binary files /dev/null and b/graphrag/graphrag/index/reporting/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/reporting/__pycache__/blob_workflow_callbacks.cpython-311.pyc b/graphrag/graphrag/index/reporting/__pycache__/blob_workflow_callbacks.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c4d8df5df0edca6f9e76f79bbd0816492ff655a Binary files /dev/null and b/graphrag/graphrag/index/reporting/__pycache__/blob_workflow_callbacks.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/reporting/__pycache__/console_workflow_callbacks.cpython-311.pyc b/graphrag/graphrag/index/reporting/__pycache__/console_workflow_callbacks.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f8772a8ab2fd34ad4c4d2ce3f65d18d9d115808 Binary files /dev/null and b/graphrag/graphrag/index/reporting/__pycache__/console_workflow_callbacks.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/reporting/__pycache__/file_workflow_callbacks.cpython-311.pyc b/graphrag/graphrag/index/reporting/__pycache__/file_workflow_callbacks.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..069d33ab32512a4ba5adcdf856b316d764c1c628 Binary files /dev/null and b/graphrag/graphrag/index/reporting/__pycache__/file_workflow_callbacks.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/reporting/__pycache__/load_pipeline_reporter.cpython-311.pyc b/graphrag/graphrag/index/reporting/__pycache__/load_pipeline_reporter.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..163163be3f0aa2cdbe29dfb7611855d7cd134ded Binary files /dev/null and b/graphrag/graphrag/index/reporting/__pycache__/load_pipeline_reporter.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/reporting/__pycache__/progress_workflow_callbacks.cpython-311.pyc b/graphrag/graphrag/index/reporting/__pycache__/progress_workflow_callbacks.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3744e48bfdca726810a5171c5882021f5cef76a5 Binary files /dev/null and b/graphrag/graphrag/index/reporting/__pycache__/progress_workflow_callbacks.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/reporting/blob_workflow_callbacks.py b/graphrag/graphrag/index/reporting/blob_workflow_callbacks.py new file mode 100644 index 0000000000000000000000000000000000000000..28f0b6d991f80c832550c9e129d380413e264c84 --- /dev/null +++ b/graphrag/graphrag/index/reporting/blob_workflow_callbacks.py @@ -0,0 +1,108 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A reporter that writes to a blob storage.""" + +import json +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + +from azure.identity import DefaultAzureCredential +from azure.storage.blob import BlobServiceClient +from datashaper import NoopWorkflowCallbacks + + +class BlobWorkflowCallbacks(NoopWorkflowCallbacks): + """A reporter that writes to a blob storage.""" + + _blob_service_client: BlobServiceClient + _container_name: str + _max_block_count: int = 25000 # 25k blocks per blob + + def __init__( + self, + connection_string: str | None, + container_name: str, + blob_name: str = "", + base_dir: str | None = None, + storage_account_blob_url: str | None = None, + ): # type: ignore + """Create a new instance of the BlobStorageReporter class.""" + if container_name is None: + msg = "No container name provided for blob storage." + raise ValueError(msg) + if connection_string is None and storage_account_blob_url is None: + msg = "No storage account blob url provided for blob storage." + raise ValueError(msg) + self._connection_string = connection_string + self._storage_account_blob_url = storage_account_blob_url + if self._connection_string: + self._blob_service_client = BlobServiceClient.from_connection_string( + self._connection_string + ) + else: + if storage_account_blob_url is None: + msg = "Either connection_string or storage_account_blob_url must be provided." + raise ValueError(msg) + + self._blob_service_client = BlobServiceClient( + storage_account_blob_url, + credential=DefaultAzureCredential(), + ) + + if blob_name == "": + blob_name = f"report/{datetime.now(tz=timezone.utc).strftime('%Y-%m-%d-%H:%M:%S:%f')}.logs.json" + + self._blob_name = str(Path(base_dir or "") / blob_name) + self._container_name = container_name + self._blob_client = self._blob_service_client.get_blob_client( + self._container_name, self._blob_name + ) + if not self._blob_client.exists(): + self._blob_client.create_append_blob() + + self._num_blocks = 0 # refresh block counter + + def _write_log(self, log: dict[str, Any]): + # create a new file when block count hits close 25k + if ( + self._num_blocks >= self._max_block_count + ): # Check if block count exceeds 25k + self.__init__( + self._connection_string, + self._container_name, + storage_account_blob_url=self._storage_account_blob_url, + ) + + blob_client = self._blob_service_client.get_blob_client( + self._container_name, self._blob_name + ) + blob_client.append_block(json.dumps(log) + "\n") + + # update the blob's block count + self._num_blocks += 1 + + def on_error( + self, + message: str, + cause: BaseException | None = None, + stack: str | None = None, + details: dict | None = None, + ): + """Report an error.""" + self._write_log({ + "type": "error", + "data": message, + "cause": str(cause), + "stack": stack, + "details": details, + }) + + def on_warning(self, message: str, details: dict | None = None): + """Report a warning.""" + self._write_log({"type": "warning", "data": message, "details": details}) + + def on_log(self, message: str, details: dict | None = None): + """Report a generic log message.""" + self._write_log({"type": "log", "data": message, "details": details}) diff --git a/graphrag/graphrag/index/reporting/console_workflow_callbacks.py b/graphrag/graphrag/index/reporting/console_workflow_callbacks.py new file mode 100644 index 0000000000000000000000000000000000000000..b1ab1278f74fb252948213b26079d363ef06f4ca --- /dev/null +++ b/graphrag/graphrag/index/reporting/console_workflow_callbacks.py @@ -0,0 +1,32 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Console-based reporter for the workflow engine.""" + +from datashaper import NoopWorkflowCallbacks + + +class ConsoleWorkflowCallbacks(NoopWorkflowCallbacks): + """A reporter that writes to a console.""" + + def on_error( + self, + message: str, + cause: BaseException | None = None, + stack: str | None = None, + details: dict | None = None, + ): + """Handle when an error occurs.""" + print(message, str(cause), stack, details) # noqa T201 + + def on_warning(self, message: str, details: dict | None = None): + """Handle when a warning occurs.""" + _print_warning(message) + + def on_log(self, message: str, details: dict | None = None): + """Handle when a log message is produced.""" + print(message, details) # noqa T201 + + +def _print_warning(skk): + print("\033[93m {}\033[00m".format(skk)) # noqa T201 diff --git a/graphrag/graphrag/index/reporting/file_workflow_callbacks.py b/graphrag/graphrag/index/reporting/file_workflow_callbacks.py new file mode 100644 index 0000000000000000000000000000000000000000..e071498629eaa5050f26fa31186006565f2369f0 --- /dev/null +++ b/graphrag/graphrag/index/reporting/file_workflow_callbacks.py @@ -0,0 +1,67 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A reporter that writes to a file.""" + +import json +import logging +from io import TextIOWrapper +from pathlib import Path + +from datashaper import NoopWorkflowCallbacks + +log = logging.getLogger(__name__) + + +class FileWorkflowCallbacks(NoopWorkflowCallbacks): + """A reporter that writes to a file.""" + + _out_stream: TextIOWrapper + + def __init__(self, directory: str): + """Create a new file-based workflow reporter.""" + Path(directory).mkdir(parents=True, exist_ok=True) + self._out_stream = open( # noqa SIM115 + Path(directory) / "logs.json", "a", encoding="utf-8" + ) + + def on_error( + self, + message: str, + cause: BaseException | None = None, + stack: str | None = None, + details: dict | None = None, + ): + """Handle when an error occurs.""" + self._out_stream.write( + json.dumps({ + "type": "error", + "data": message, + "stack": stack, + "source": str(cause), + "details": details, + }) + + "\n" + ) + message = f"{message} details={details}" + log.info(message) + + def on_warning(self, message: str, details: dict | None = None): + """Handle when a warning occurs.""" + self._out_stream.write( + json.dumps({"type": "warning", "data": message, "details": details}) + "\n" + ) + _print_warning(message) + + def on_log(self, message: str, details: dict | None = None): + """Handle when a log message is produced.""" + self._out_stream.write( + json.dumps({"type": "log", "data": message, "details": details}) + "\n" + ) + + message = f"{message} details={details}" + log.info(message) + + +def _print_warning(skk): + log.warning(skk) diff --git a/graphrag/graphrag/index/reporting/load_pipeline_reporter.py b/graphrag/graphrag/index/reporting/load_pipeline_reporter.py new file mode 100644 index 0000000000000000000000000000000000000000..0386ea03d1eb623630ae0e53fc2b856b7a685f1c --- /dev/null +++ b/graphrag/graphrag/index/reporting/load_pipeline_reporter.py @@ -0,0 +1,47 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Load pipeline reporter method.""" + +from pathlib import Path +from typing import cast + +from datashaper import WorkflowCallbacks + +from graphrag.config import ReportingType +from graphrag.index.config import ( + PipelineBlobReportingConfig, + PipelineFileReportingConfig, + PipelineReportingConfig, +) + +from .blob_workflow_callbacks import BlobWorkflowCallbacks +from .console_workflow_callbacks import ConsoleWorkflowCallbacks +from .file_workflow_callbacks import FileWorkflowCallbacks + + +def load_pipeline_reporter( + config: PipelineReportingConfig | None, root_dir: str | None +) -> WorkflowCallbacks: + """Create a reporter for the given pipeline config.""" + config = config or PipelineFileReportingConfig(base_dir="reports") + + match config.type: + case ReportingType.file: + config = cast(PipelineFileReportingConfig, config) + return FileWorkflowCallbacks( + str(Path(root_dir or "") / (config.base_dir or "")) + ) + case ReportingType.console: + return ConsoleWorkflowCallbacks() + case ReportingType.blob: + config = cast(PipelineBlobReportingConfig, config) + return BlobWorkflowCallbacks( + config.connection_string, + config.container_name, + base_dir=config.base_dir, + storage_account_blob_url=config.storage_account_blob_url, + ) + case _: + msg = f"Unknown reporting type: {config.type}" + raise ValueError(msg) diff --git a/graphrag/graphrag/index/reporting/progress_workflow_callbacks.py b/graphrag/graphrag/index/reporting/progress_workflow_callbacks.py new file mode 100644 index 0000000000000000000000000000000000000000..68f10d75302027a903cd288df8739f4ece33030a --- /dev/null +++ b/graphrag/graphrag/index/reporting/progress_workflow_callbacks.py @@ -0,0 +1,54 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A workflow callback manager that emits updates to a ProgressReporter.""" + +from typing import Any + +from datashaper import ExecutionNode, NoopWorkflowCallbacks, Progress, TableContainer + +from graphrag.index.progress import ProgressReporter + + +class ProgressWorkflowCallbacks(NoopWorkflowCallbacks): + """A callbackmanager that delegates to a ProgressReporter.""" + + _root_progress: ProgressReporter + _progress_stack: list[ProgressReporter] + + def __init__(self, progress: ProgressReporter) -> None: + """Create a new ProgressWorkflowCallbacks.""" + self._progress = progress + self._progress_stack = [progress] + + def _pop(self) -> None: + self._progress_stack.pop() + + def _push(self, name: str) -> None: + self._progress_stack.append(self._latest.child(name)) + + @property + def _latest(self) -> ProgressReporter: + return self._progress_stack[-1] + + def on_workflow_start(self, name: str, instance: object) -> None: + """Execute this callback when a workflow starts.""" + self._push(name) + + def on_workflow_end(self, name: str, instance: object) -> None: + """Execute this callback when a workflow ends.""" + self._pop() + + def on_step_start(self, node: ExecutionNode, inputs: dict[str, Any]) -> None: + """Execute this callback every time a step starts.""" + verb_id_str = f" ({node.node_id})" if node.has_explicit_id else "" + self._push(f"Verb {node.verb.name}{verb_id_str}") + self._latest(Progress(percent=0)) + + def on_step_end(self, node: ExecutionNode, result: TableContainer | None) -> None: + """Execute this callback every time a step ends.""" + self._pop() + + def on_step_progress(self, node: ExecutionNode, progress: Progress) -> None: + """Handle when progress occurs.""" + self._latest(progress) diff --git a/graphrag/graphrag/index/run.py b/graphrag/graphrag/index/run.py new file mode 100644 index 0000000000000000000000000000000000000000..94a519de8705c50198f23767baf49d77df4ab476 --- /dev/null +++ b/graphrag/graphrag/index/run.py @@ -0,0 +1,463 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Different methods to run the pipeline.""" + +import gc +import json +import logging +import time +import traceback +from collections.abc import AsyncIterable +from dataclasses import asdict +from io import BytesIO +from pathlib import Path +from string import Template +from typing import cast + +import pandas as pd +from datashaper import ( + DEFAULT_INPUT_NAME, + MemoryProfile, + Workflow, + WorkflowCallbacks, + WorkflowCallbacksManager, + WorkflowRunResult, +) + +from .cache import InMemoryCache, PipelineCache, load_cache +from .config import ( + PipelineBlobCacheConfig, + PipelineBlobReportingConfig, + PipelineBlobStorageConfig, + PipelineCacheConfigTypes, + PipelineConfig, + PipelineFileCacheConfig, + PipelineFileReportingConfig, + PipelineFileStorageConfig, + PipelineInputConfigTypes, + PipelineMemoryCacheConfig, + PipelineReportingConfigTypes, + PipelineStorageConfigTypes, + PipelineWorkflowReference, + PipelineWorkflowStep, +) +from .context import PipelineRunContext, PipelineRunStats +from .emit import TableEmitterType, create_table_emitters +from .input import load_input +from .load_pipeline_config import load_pipeline_config +from .progress import NullProgressReporter, ProgressReporter +from .reporting import ( + ConsoleWorkflowCallbacks, + ProgressWorkflowCallbacks, + load_pipeline_reporter, +) +from .storage import MemoryPipelineStorage, PipelineStorage, load_storage +from .typing import PipelineRunResult + +# Register all verbs +from .verbs import * # noqa +from .workflows import ( + VerbDefinitions, + WorkflowDefinitions, + create_workflow, + load_workflows, +) + +log = logging.getLogger(__name__) + + +async def run_pipeline_with_config( + config_or_path: PipelineConfig | str, + workflows: list[PipelineWorkflowReference] | None = None, + dataset: pd.DataFrame | None = None, + storage: PipelineStorage | None = None, + cache: PipelineCache | None = None, + callbacks: WorkflowCallbacks | None = None, + progress_reporter: ProgressReporter | None = None, + input_post_process_steps: list[PipelineWorkflowStep] | None = None, + additional_verbs: VerbDefinitions | None = None, + additional_workflows: WorkflowDefinitions | None = None, + emit: list[TableEmitterType] | None = None, + memory_profile: bool = False, + run_id: str | None = None, + is_resume_run: bool = False, + **_kwargs: dict, +) -> AsyncIterable[PipelineRunResult]: + """Run a pipeline with the given config. + + Args: + - config_or_path - The config to run the pipeline with + - workflows - The workflows to run (this overrides the config) + - dataset - The dataset to run the pipeline on (this overrides the config) + - storage - The storage to use for the pipeline (this overrides the config) + - cache - The cache to use for the pipeline (this overrides the config) + - reporter - The reporter to use for the pipeline (this overrides the config) + - input_post_process_steps - The post process steps to run on the input data (this overrides the config) + - additional_verbs - The custom verbs to use for the pipeline. + - additional_workflows - The custom workflows to use for the pipeline. + - emit - The table emitters to use for the pipeline. + - memory_profile - Whether or not to profile the memory. + - run_id - The run id to start or resume from. + """ + if isinstance(config_or_path, str): + log.info("Running pipeline with config %s", config_or_path) + else: + log.info("Running pipeline") + + run_id = run_id or time.strftime("%Y%m%d-%H%M%S") + config = load_pipeline_config(config_or_path) + config = _apply_substitutions(config, run_id) + root_dir = config.root_dir + + def _create_storage(config: PipelineStorageConfigTypes | None) -> PipelineStorage: + return load_storage( + config + or PipelineFileStorageConfig(base_dir=str(Path(root_dir or "") / "output")) + ) + + def _create_cache(config: PipelineCacheConfigTypes | None) -> PipelineCache: + return load_cache(config or PipelineMemoryCacheConfig(), root_dir=root_dir) + + def _create_reporter( + config: PipelineReportingConfigTypes | None, + ) -> WorkflowCallbacks | None: + return load_pipeline_reporter(config, root_dir) if config else None + + async def _create_input( + config: PipelineInputConfigTypes | None, + ) -> pd.DataFrame | None: + if config is None: + return None + + return await load_input(config, progress_reporter, root_dir) + + def _create_postprocess_steps( + config: PipelineInputConfigTypes | None, + ) -> list[PipelineWorkflowStep] | None: + return config.post_process if config is not None else None + + progress_reporter = progress_reporter or NullProgressReporter() + storage = storage or _create_storage(config.storage) + cache = cache or _create_cache(config.cache) + callbacks = callbacks or _create_reporter(config.reporting) + dataset = dataset if dataset is not None else await _create_input(config.input) + post_process_steps = input_post_process_steps or _create_postprocess_steps( + config.input + ) + workflows = workflows or config.workflows + + if dataset is None: + msg = "No dataset provided!" + raise ValueError(msg) + + async for table in run_pipeline( + workflows=workflows, + dataset=dataset, + storage=storage, + cache=cache, + callbacks=callbacks, + input_post_process_steps=post_process_steps, + memory_profile=memory_profile, + additional_verbs=additional_verbs, + additional_workflows=additional_workflows, + progress_reporter=progress_reporter, + emit=emit, + is_resume_run=is_resume_run, + ): + yield table + + +async def run_pipeline( + workflows: list[PipelineWorkflowReference], + dataset: pd.DataFrame, + storage: PipelineStorage | None = None, + cache: PipelineCache | None = None, + callbacks: WorkflowCallbacks | None = None, + progress_reporter: ProgressReporter | None = None, + input_post_process_steps: list[PipelineWorkflowStep] | None = None, + additional_verbs: VerbDefinitions | None = None, + additional_workflows: WorkflowDefinitions | None = None, + emit: list[TableEmitterType] | None = None, + memory_profile: bool = False, + is_resume_run: bool = False, + **_kwargs: dict, +) -> AsyncIterable[PipelineRunResult]: + """Run the pipeline. + + Args: + - workflows - The workflows to run + - dataset - The dataset to run the pipeline on, specifically a dataframe with the following columns at a minimum: + - id - The id of the document + - text - The text of the document + - title - The title of the document + These must exist after any post process steps are run if there are any! + - storage - The storage to use for the pipeline + - cache - The cache to use for the pipeline + - reporter - The reporter to use for the pipeline + - input_post_process_steps - The post process steps to run on the input data + - additional_verbs - The custom verbs to use for the pipeline + - additional_workflows - The custom workflows to use for the pipeline + - debug - Whether or not to run in debug mode + Returns: + - output - An iterable of workflow results as they complete running, as well as any errors that occur + """ + start_time = time.time() + stats = PipelineRunStats() + storage = storage or MemoryPipelineStorage() + cache = cache or InMemoryCache() + progress_reporter = progress_reporter or NullProgressReporter() + callbacks = callbacks or ConsoleWorkflowCallbacks() + callbacks = _create_callback_chain(callbacks, progress_reporter) + emit = emit or [TableEmitterType.Parquet] + emitters = create_table_emitters( + emit, + storage, + lambda e, s, d: cast(WorkflowCallbacks, callbacks).on_error( + "Error emitting table", e, s, d + ), + ) + loaded_workflows = load_workflows( + workflows, + additional_verbs=additional_verbs, + additional_workflows=additional_workflows, + memory_profile=memory_profile, + ) + workflows_to_run = loaded_workflows.workflows + workflow_dependencies = loaded_workflows.dependencies + + context = _create_run_context(storage, cache, stats) + + if len(emitters) == 0: + log.info( + "No emitters provided. No table outputs will be generated. This is probably not correct." + ) + + async def dump_stats() -> None: + await storage.set("stats.json", json.dumps(asdict(stats), indent=4)) + + async def load_table_from_storage(name: str) -> pd.DataFrame: + if not await storage.has(name): + msg = f"Could not find {name} in storage!" + raise ValueError(msg) + try: + log.info("read table from storage: %s", name) + return pd.read_parquet(BytesIO(await storage.get(name, as_bytes=True))) + except Exception: + log.exception("error loading table from storage: %s", name) + raise + + async def inject_workflow_data_dependencies(workflow: Workflow) -> None: + workflow.add_table(DEFAULT_INPUT_NAME, dataset) + deps = workflow_dependencies[workflow.name] + log.info("dependencies for %s: %s", workflow.name, deps) + for id in deps: + workflow_id = f"workflow:{id}" + table = await load_table_from_storage(f"{id}.parquet") + workflow.add_table(workflow_id, table) + + async def write_workflow_stats( + workflow: Workflow, + workflow_result: WorkflowRunResult, + workflow_start_time: float, + ) -> None: + for vt in workflow_result.verb_timings: + stats.workflows[workflow.name][f"{vt.index}_{vt.verb}"] = vt.timing + + workflow_end_time = time.time() + stats.workflows[workflow.name]["overall"] = ( + workflow_end_time - workflow_start_time + ) + stats.total_runtime = time.time() - start_time + await dump_stats() + + if workflow_result.memory_profile is not None: + await _save_profiler_stats( + storage, workflow.name, workflow_result.memory_profile + ) + + log.debug( + "first row of %s => %s", workflow_name, workflow.output().iloc[0].to_json() + ) + + async def emit_workflow_output(workflow: Workflow) -> pd.DataFrame: + output = cast(pd.DataFrame, workflow.output()) + for emitter in emitters: + await emitter.emit(workflow.name, output) + return output + + dataset = await _run_post_process_steps( + input_post_process_steps, dataset, context, callbacks + ) + + # Make sure the incoming data is valid + _validate_dataset(dataset) + + log.info("Final # of rows loaded: %s", len(dataset)) + stats.num_documents = len(dataset) + last_workflow = "input" + + try: + await dump_stats() + + for workflow_to_run in workflows_to_run: + # Try to flush out any intermediate dataframes + gc.collect() + + workflow = workflow_to_run.workflow + workflow_name: str = workflow.name + last_workflow = workflow_name + + log.info("Running workflow: %s...", workflow_name) + + if is_resume_run and await storage.has( + f"{workflow_to_run.workflow.name}.parquet" + ): + log.info("Skipping %s because it already exists", workflow_name) + continue + + stats.workflows[workflow_name] = {"overall": 0.0} + await inject_workflow_data_dependencies(workflow) + + workflow_start_time = time.time() + result = await workflow.run(context, callbacks) + await write_workflow_stats(workflow, result, workflow_start_time) + + # Save the output from the workflow + output = await emit_workflow_output(workflow) + yield PipelineRunResult(workflow_name, output, None) + output = None + workflow.dispose() + workflow = None + + stats.total_runtime = time.time() - start_time + await dump_stats() + except Exception as e: + log.exception("error running workflow %s", last_workflow) + cast(WorkflowCallbacks, callbacks).on_error( + "Error running pipeline!", e, traceback.format_exc() + ) + yield PipelineRunResult(last_workflow, None, [e]) + + +def _create_callback_chain( + callbacks: WorkflowCallbacks | None, progress: ProgressReporter | None +) -> WorkflowCallbacks: + """Create a callbacks manager.""" + manager = WorkflowCallbacksManager() + if callbacks is not None: + manager.register(callbacks) + if progress is not None: + manager.register(ProgressWorkflowCallbacks(progress)) + return manager + + +async def _save_profiler_stats( + storage: PipelineStorage, workflow_name: str, profile: MemoryProfile +): + """Save the profiler stats to the storage.""" + await storage.set( + f"{workflow_name}_profiling.peak_stats.csv", + profile.peak_stats.to_csv(index=True), + ) + + await storage.set( + f"{workflow_name}_profiling.snapshot_stats.csv", + profile.snapshot_stats.to_csv(index=True), + ) + + await storage.set( + f"{workflow_name}_profiling.time_stats.csv", + profile.time_stats.to_csv(index=True), + ) + + await storage.set( + f"{workflow_name}_profiling.detailed_view.csv", + profile.detailed_view.to_csv(index=True), + ) + + +async def _run_post_process_steps( + post_process: list[PipelineWorkflowStep] | None, + dataset: pd.DataFrame, + context: PipelineRunContext, + callbacks: WorkflowCallbacks, +) -> pd.DataFrame: + """Run the pipeline. + + Args: + - post_process - The post process steps to run + - dataset - The dataset to run the steps on + - context - The pipeline run context + Returns: + - output - The dataset after running the post process steps + """ + if post_process is not None and len(post_process) > 0: + input_workflow = create_workflow( + "Input Post Process", + post_process, + ) + input_workflow.add_table(DEFAULT_INPUT_NAME, dataset) + await input_workflow.run( + context=context, + callbacks=callbacks, + ) + dataset = cast(pd.DataFrame, input_workflow.output()) + return dataset + + +def _validate_dataset(dataset: pd.DataFrame): + """Validate the dataset for the pipeline. + + Args: + - dataset - The dataset to validate + """ + if not isinstance(dataset, pd.DataFrame): + msg = "Dataset must be a pandas dataframe!" + raise TypeError(msg) + + +def _apply_substitutions(config: PipelineConfig, run_id: str) -> PipelineConfig: + substitutions = {"timestamp": run_id} + + if ( + isinstance( + config.storage, PipelineFileStorageConfig | PipelineBlobStorageConfig + ) + and config.storage.base_dir + ): + config.storage.base_dir = Template(config.storage.base_dir).substitute( + substitutions + ) + if ( + isinstance(config.cache, PipelineFileCacheConfig | PipelineBlobCacheConfig) + and config.cache.base_dir + ): + config.cache.base_dir = Template(config.cache.base_dir).substitute( + substitutions + ) + + if ( + isinstance( + config.reporting, PipelineFileReportingConfig | PipelineBlobReportingConfig + ) + and config.reporting.base_dir + ): + config.reporting.base_dir = Template(config.reporting.base_dir).substitute( + substitutions + ) + + return config + + +def _create_run_context( + storage: PipelineStorage, + cache: PipelineCache, + stats: PipelineRunStats, +) -> PipelineRunContext: + """Create the run context for the pipeline.""" + return PipelineRunContext( + stats=stats, + cache=cache, + storage=storage, + ) diff --git a/graphrag/graphrag/index/storage/__init__.py b/graphrag/graphrag/index/storage/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7ca943db52844e1b24775bc40560438188c92e13 --- /dev/null +++ b/graphrag/graphrag/index/storage/__init__.py @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine storage package root.""" + +from .blob_pipeline_storage import BlobPipelineStorage, create_blob_storage +from .file_pipeline_storage import FilePipelineStorage +from .load_storage import load_storage +from .memory_pipeline_storage import MemoryPipelineStorage +from .typing import PipelineStorage + +__all__ = [ + "BlobPipelineStorage", + "FilePipelineStorage", + "MemoryPipelineStorage", + "PipelineStorage", + "create_blob_storage", + "load_storage", +] diff --git a/graphrag/graphrag/index/storage/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/storage/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2904516ffdb2de87c5648fc39cb5d5d426355ed7 Binary files /dev/null and b/graphrag/graphrag/index/storage/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/storage/__pycache__/blob_pipeline_storage.cpython-311.pyc b/graphrag/graphrag/index/storage/__pycache__/blob_pipeline_storage.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c5fdc9414352723928ae321f31e23e9afa2dcfb Binary files /dev/null and b/graphrag/graphrag/index/storage/__pycache__/blob_pipeline_storage.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/storage/__pycache__/file_pipeline_storage.cpython-311.pyc b/graphrag/graphrag/index/storage/__pycache__/file_pipeline_storage.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07c9a4b8dd86aefdd069b8b7f92e3b3770aebe7d Binary files /dev/null and b/graphrag/graphrag/index/storage/__pycache__/file_pipeline_storage.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/storage/__pycache__/load_storage.cpython-311.pyc b/graphrag/graphrag/index/storage/__pycache__/load_storage.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92e7cab530cb491c089b3bf4e9f49fcb21892d6e Binary files /dev/null and b/graphrag/graphrag/index/storage/__pycache__/load_storage.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/storage/__pycache__/memory_pipeline_storage.cpython-311.pyc b/graphrag/graphrag/index/storage/__pycache__/memory_pipeline_storage.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4aa347977fc7d5478ed5f27b9478e1bb40823c5c Binary files /dev/null and b/graphrag/graphrag/index/storage/__pycache__/memory_pipeline_storage.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/storage/__pycache__/typing.cpython-311.pyc b/graphrag/graphrag/index/storage/__pycache__/typing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5af43d9f595abab1cb374883504ec90cf23a223d Binary files /dev/null and b/graphrag/graphrag/index/storage/__pycache__/typing.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/storage/blob_pipeline_storage.py b/graphrag/graphrag/index/storage/blob_pipeline_storage.py new file mode 100644 index 0000000000000000000000000000000000000000..7e60df9697f73a4be4bd96c8f8e79f1dc3548f1f --- /dev/null +++ b/graphrag/graphrag/index/storage/blob_pipeline_storage.py @@ -0,0 +1,371 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Azure Blob Storage implementation of PipelineStorage.""" + +import logging +import re +from collections.abc import Iterator +from pathlib import Path +from typing import Any + +from azure.identity import DefaultAzureCredential +from azure.storage.blob import BlobServiceClient +from datashaper import Progress + +from graphrag.index.progress import ProgressReporter + +from .typing import PipelineStorage + +log = logging.getLogger(__name__) + + +class BlobPipelineStorage(PipelineStorage): + """The Blob-Storage implementation.""" + + _connection_string: str | None + _container_name: str + _path_prefix: str + _encoding: str + _storage_account_blob_url: str | None + + def __init__( + self, + connection_string: str | None, + container_name: str, + encoding: str | None = None, + path_prefix: str | None = None, + storage_account_blob_url: str | None = None, + ): + """Create a new BlobStorage instance.""" + if connection_string: + self._blob_service_client = BlobServiceClient.from_connection_string( + connection_string + ) + else: + if storage_account_blob_url is None: + msg = "Either connection_string or storage_account_blob_url must be provided." + raise ValueError(msg) + + self._blob_service_client = BlobServiceClient( + account_url=storage_account_blob_url, + credential=DefaultAzureCredential(), + ) + self._encoding = encoding or "utf-8" + self._container_name = container_name + self._connection_string = connection_string + self._path_prefix = path_prefix or "" + self._storage_account_blob_url = storage_account_blob_url + self._storage_account_name = ( + storage_account_blob_url.split("//")[1].split(".")[0] + if storage_account_blob_url + else None + ) + log.info( + "creating blob storage at container=%s, path=%s", + self._container_name, + self._path_prefix, + ) + self.create_container() + + def create_container(self) -> None: + """Create the container if it does not exist.""" + if not self.container_exists(): + container_name = self._container_name + container_names = [ + container.name + for container in self._blob_service_client.list_containers() + ] + if container_name not in container_names: + self._blob_service_client.create_container(container_name) + + def delete_container(self) -> None: + """Delete the container.""" + if self.container_exists(): + self._blob_service_client.delete_container(self._container_name) + + def container_exists(self) -> bool: + """Check if the container exists.""" + container_name = self._container_name + container_names = [ + container.name for container in self._blob_service_client.list_containers() + ] + return container_name in container_names + + def find( + self, + file_pattern: re.Pattern[str], + base_dir: str | None = None, + progress: ProgressReporter | None = None, + file_filter: dict[str, Any] | None = None, + max_count=-1, + ) -> Iterator[tuple[str, dict[str, Any]]]: + """Find blobs in a container using a file pattern, as well as a custom filter function. + + Params: + base_dir: The name of the base container. + file_pattern: The file pattern to use. + file_filter: A dictionary of key-value pairs to filter the blobs. + max_count: The maximum number of blobs to return. If -1, all blobs are returned. + + Returns + ------- + An iterator of blob names and their corresponding regex matches. + """ + base_dir = base_dir or "" + + log.info( + "search container %s for files matching %s", + self._container_name, + file_pattern.pattern, + ) + + def blobname(blob_name: str) -> str: + if blob_name.startswith(self._path_prefix): + blob_name = blob_name.replace(self._path_prefix, "", 1) + if blob_name.startswith("/"): + blob_name = blob_name[1:] + return blob_name + + def item_filter(item: dict[str, Any]) -> bool: + if file_filter is None: + return True + + return all(re.match(value, item[key]) for key, value in file_filter.items()) + + try: + container_client = self._blob_service_client.get_container_client( + self._container_name + ) + all_blobs = list(container_client.list_blobs()) + + num_loaded = 0 + num_total = len(list(all_blobs)) + num_filtered = 0 + for blob in all_blobs: + match = file_pattern.match(blob.name) + if match and blob.name.startswith(base_dir): + group = match.groupdict() + if item_filter(group): + yield (blobname(blob.name), group) + num_loaded += 1 + if max_count > 0 and num_loaded >= max_count: + break + else: + num_filtered += 1 + else: + num_filtered += 1 + if progress is not None: + progress( + _create_progress_status(num_loaded, num_filtered, num_total) + ) + except Exception: + log.exception( + "Error finding blobs: base_dir=%s, file_pattern=%s, file_filter=%s", + base_dir, + file_pattern, + file_filter, + ) + raise + + async def get( + self, key: str, as_bytes: bool | None = False, encoding: str | None = None + ) -> Any: + """Get a value from the cache.""" + try: + key = self._keyname(key) + container_client = self._blob_service_client.get_container_client( + self._container_name + ) + blob_client = container_client.get_blob_client(key) + blob_data = blob_client.download_blob().readall() + if not as_bytes: + coding = encoding or "utf-8" + blob_data = blob_data.decode(coding) + except Exception: + log.exception("Error getting key %s", key) + return None + else: + return blob_data + + async def set(self, key: str, value: Any, encoding: str | None = None) -> None: + """Set a value in the cache.""" + try: + key = self._keyname(key) + container_client = self._blob_service_client.get_container_client( + self._container_name + ) + blob_client = container_client.get_blob_client(key) + if isinstance(value, bytes): + blob_client.upload_blob(value, overwrite=True) + else: + coding = encoding or "utf-8" + blob_client.upload_blob(value.encode(coding), overwrite=True) + except Exception: + log.exception("Error setting key %s: %s", key) + + def set_df_json(self, key: str, dataframe: Any) -> None: + """Set a json dataframe.""" + if self._connection_string is None and self._storage_account_name: + dataframe.to_json( + self._abfs_url(key), + storage_options={ + "account_name": self._storage_account_name, + "credential": DefaultAzureCredential(), + }, + orient="records", + lines=True, + force_ascii=False, + ) + else: + dataframe.to_json( + self._abfs_url(key), + storage_options={"connection_string": self._connection_string}, + orient="records", + lines=True, + force_ascii=False, + ) + + def set_df_parquet(self, key: str, dataframe: Any) -> None: + """Set a parquet dataframe.""" + if self._connection_string is None and self._storage_account_name: + dataframe.to_parquet( + self._abfs_url(key), + storage_options={ + "account_name": self._storage_account_name, + "credential": DefaultAzureCredential(), + }, + ) + else: + dataframe.to_parquet( + self._abfs_url(key), + storage_options={"connection_string": self._connection_string}, + ) + + async def has(self, key: str) -> bool: + """Check if a key exists in the cache.""" + key = self._keyname(key) + container_client = self._blob_service_client.get_container_client( + self._container_name + ) + blob_client = container_client.get_blob_client(key) + return blob_client.exists() + + async def delete(self, key: str) -> None: + """Delete a key from the cache.""" + key = self._keyname(key) + container_client = self._blob_service_client.get_container_client( + self._container_name + ) + blob_client = container_client.get_blob_client(key) + blob_client.delete_blob() + + async def clear(self) -> None: + """Clear the cache.""" + + def child(self, name: str | None) -> "PipelineStorage": + """Create a child storage instance.""" + if name is None: + return self + path = str(Path(self._path_prefix) / name) + return BlobPipelineStorage( + self._connection_string, + self._container_name, + self._encoding, + path, + self._storage_account_blob_url, + ) + + def _keyname(self, key: str) -> str: + """Get the key name.""" + return str(Path(self._path_prefix) / key) + + def _abfs_url(self, key: str) -> str: + """Get the ABFS URL.""" + path = str(Path(self._container_name) / self._path_prefix / key) + return f"abfs://{path}" + + +def create_blob_storage( + connection_string: str | None, + storage_account_blob_url: str | None, + container_name: str, + base_dir: str | None, +) -> PipelineStorage: + """Create a blob based storage.""" + log.info("Creating blob storage at %s", container_name) + if container_name is None: + msg = "No container name provided for blob storage." + raise ValueError(msg) + if connection_string is None and storage_account_blob_url is None: + msg = "No storage account blob url provided for blob storage." + raise ValueError(msg) + return BlobPipelineStorage( + connection_string, + container_name, + path_prefix=base_dir, + storage_account_blob_url=storage_account_blob_url, + ) + + +def validate_blob_container_name(container_name: str): + """ + Check if the provided blob container name is valid based on Azure rules. + + - A blob container name must be between 3 and 63 characters in length. + - Start with a letter or number + - All letters used in blob container names must be lowercase. + - Contain only letters, numbers, or the hyphen. + - Consecutive hyphens are not permitted. + - Cannot end with a hyphen. + + Args: + ----- + container_name (str) + The blob container name to be validated. + + Returns + ------- + bool: True if valid, False otherwise. + """ + # Check the length of the name + if len(container_name) < 3 or len(container_name) > 63: + return ValueError( + f"Container name must be between 3 and 63 characters in length. Name provided was {len(container_name)} characters long." + ) + + # Check if the name starts with a letter or number + if not container_name[0].isalnum(): + return ValueError( + f"Container name must start with a letter or number. Starting character was {container_name[0]}." + ) + + # Check for valid characters (letters, numbers, hyphen) and lowercase letters + if not re.match("^[a-z0-9-]+$", container_name): + return ValueError( + f"Container name must only contain:\n- lowercase letters\n- numbers\n- or hyphens\nName provided was {container_name}." + ) + + # Check for consecutive hyphens + if "--" in container_name: + return ValueError( + f"Container name cannot contain consecutive hyphens. Name provided was {container_name}." + ) + + # Check for hyphens at the end of the name + if container_name[-1] == "-": + return ValueError( + f"Container name cannot end with a hyphen. Name provided was {container_name}." + ) + + return True + + +def _create_progress_status( + num_loaded: int, num_filtered: int, num_total: int +) -> Progress: + return Progress( + total_items=num_total, + completed_items=num_loaded + num_filtered, + description=f"{num_loaded} files loaded ({num_filtered} filtered)", + ) diff --git a/graphrag/graphrag/index/storage/file_pipeline_storage.py b/graphrag/graphrag/index/storage/file_pipeline_storage.py new file mode 100644 index 0000000000000000000000000000000000000000..3580e1e1a653efe03098ae122b59b9b5573516ad --- /dev/null +++ b/graphrag/graphrag/index/storage/file_pipeline_storage.py @@ -0,0 +1,163 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'FileStorage' and 'FilePipelineStorage' models.""" + +import logging +import os +import re +import shutil +from collections.abc import Iterator +from pathlib import Path +from typing import Any, cast + +import aiofiles +from aiofiles.os import remove +from aiofiles.ospath import exists +from datashaper import Progress + +from graphrag.index.progress import ProgressReporter + +from .typing import PipelineStorage + +log = logging.getLogger(__name__) + + +class FilePipelineStorage(PipelineStorage): + """File storage class definition.""" + + _root_dir: str + _encoding: str + + def __init__(self, root_dir: str | None = None, encoding: str | None = None): + """Init method definition.""" + self._root_dir = root_dir or "" + self._encoding = encoding or "utf-8" + Path(self._root_dir).mkdir(parents=True, exist_ok=True) + + def find( + self, + file_pattern: re.Pattern[str], + base_dir: str | None = None, + progress: ProgressReporter | None = None, + file_filter: dict[str, Any] | None = None, + max_count=-1, + ) -> Iterator[tuple[str, dict[str, Any]]]: + """Find files in the storage using a file pattern, as well as a custom filter function.""" + + def item_filter(item: dict[str, Any]) -> bool: + if file_filter is None: + return True + + return all(re.match(value, item[key]) for key, value in file_filter.items()) + + search_path = Path(self._root_dir) / (base_dir or "") + log.info("search %s for files matching %s", search_path, file_pattern.pattern) + all_files = list(search_path.rglob("**/*")) + num_loaded = 0 + num_total = len(all_files) + num_filtered = 0 + for file in all_files: + match = file_pattern.match(f"{file}") + if match: + group = match.groupdict() + if item_filter(group): + filename = f"{file}".replace(self._root_dir, "") + if filename.startswith(os.sep): + filename = filename[1:] + yield (filename, group) + num_loaded += 1 + if max_count > 0 and num_loaded >= max_count: + break + else: + num_filtered += 1 + else: + num_filtered += 1 + if progress is not None: + progress(_create_progress_status(num_loaded, num_filtered, num_total)) + + async def get( + self, key: str, as_bytes: bool | None = False, encoding: str | None = None + ) -> Any: + """Get method definition.""" + file_path = join_path(self._root_dir, key) + + if await self.has(key): + return await self._read_file(file_path, as_bytes, encoding) + if await exists(key): + # Lookup for key, as it is pressumably a new file loaded from inputs + # and not yet written to storage + return await self._read_file(key, as_bytes, encoding) + + return None + + async def _read_file( + self, + path: str | Path, + as_bytes: bool | None = False, + encoding: str | None = None, + ) -> Any: + """Read the contents of a file.""" + read_type = "rb" if as_bytes else "r" + encoding = None if as_bytes else (encoding or self._encoding) + + async with aiofiles.open( + path, + cast(Any, read_type), + encoding=encoding, + ) as f: + return await f.read() + + async def set(self, key: str, value: Any, encoding: str | None = None) -> None: + """Set method definition.""" + is_bytes = isinstance(value, bytes) + write_type = "wb" if is_bytes else "w" + encoding = None if is_bytes else encoding or self._encoding + async with aiofiles.open( + join_path(self._root_dir, key), cast(Any, write_type), encoding=encoding + ) as f: + await f.write(value) + + async def has(self, key: str) -> bool: + """Has method definition.""" + return await exists(join_path(self._root_dir, key)) + + async def delete(self, key: str) -> None: + """Delete method definition.""" + if await self.has(key): + await remove(join_path(self._root_dir, key)) + + async def clear(self) -> None: + """Clear method definition.""" + for file in Path(self._root_dir).glob("*"): + if file.is_dir(): + shutil.rmtree(file) + else: + file.unlink() + + def child(self, name: str | None) -> "PipelineStorage": + """Create a child storage instance.""" + if name is None: + return self + return FilePipelineStorage(str(Path(self._root_dir) / Path(name))) + + +def join_path(file_path: str, file_name: str) -> Path: + """Join a path and a file. Independent of the OS.""" + return Path(file_path) / Path(file_name).parent / Path(file_name).name + + +def create_file_storage(out_dir: str | None) -> PipelineStorage: + """Create a file based storage.""" + log.info("Creating file storage at %s", out_dir) + return FilePipelineStorage(out_dir) + + +def _create_progress_status( + num_loaded: int, num_filtered: int, num_total: int +) -> Progress: + return Progress( + total_items=num_total, + completed_items=num_loaded + num_filtered, + description=f"{num_loaded} files loaded ({num_filtered} filtered)", + ) diff --git a/graphrag/graphrag/index/storage/load_storage.py b/graphrag/graphrag/index/storage/load_storage.py new file mode 100644 index 0000000000000000000000000000000000000000..33d61ee97fe1a2b50ff4cbad2ac0b43831ae93d5 --- /dev/null +++ b/graphrag/graphrag/index/storage/load_storage.py @@ -0,0 +1,40 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing load_storage method definition.""" + +from __future__ import annotations + +from typing import cast + +from graphrag.config import StorageType +from graphrag.index.config.storage import ( + PipelineBlobStorageConfig, + PipelineFileStorageConfig, + PipelineStorageConfig, +) + +from .blob_pipeline_storage import create_blob_storage +from .file_pipeline_storage import create_file_storage +from .memory_pipeline_storage import create_memory_storage + + +def load_storage(config: PipelineStorageConfig): + """Load the storage for a pipeline.""" + match config.type: + case StorageType.memory: + return create_memory_storage() + case StorageType.blob: + config = cast(PipelineBlobStorageConfig, config) + return create_blob_storage( + config.connection_string, + config.storage_account_blob_url, + config.container_name, + config.base_dir, + ) + case StorageType.file: + config = cast(PipelineFileStorageConfig, config) + return create_file_storage(config.base_dir) + case _: + msg = f"Unknown storage type: {config.type}" + raise ValueError(msg) diff --git a/graphrag/graphrag/index/storage/memory_pipeline_storage.py b/graphrag/graphrag/index/storage/memory_pipeline_storage.py new file mode 100644 index 0000000000000000000000000000000000000000..2d1382e0af786652c931311a43b26587f3f29058 --- /dev/null +++ b/graphrag/graphrag/index/storage/memory_pipeline_storage.py @@ -0,0 +1,79 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'InMemoryStorage' model.""" + +from typing import Any + +from .file_pipeline_storage import FilePipelineStorage +from .typing import PipelineStorage + + +class MemoryPipelineStorage(FilePipelineStorage): + """In memory storage class definition.""" + + _storage: dict[str, Any] + + def __init__(self): + """Init method definition.""" + super().__init__(root_dir=".output") + self._storage = {} + + async def get( + self, key: str, as_bytes: bool | None = None, encoding: str | None = None + ) -> Any: + """Get the value for the given key. + + Args: + - key - The key to get the value for. + - as_bytes - Whether or not to return the value as bytes. + + Returns + ------- + - output - The value for the given key. + """ + return self._storage.get(key) or await super().get(key, as_bytes, encoding) + + async def set( + self, key: str, value: str | bytes | None, encoding: str | None = None + ) -> None: + """Set the value for the given key. + + Args: + - key - The key to set the value for. + - value - The value to set. + """ + self._storage[key] = value + + async def has(self, key: str) -> bool: + """Return True if the given key exists in the storage. + + Args: + - key - The key to check for. + + Returns + ------- + - output - True if the key exists in the storage, False otherwise. + """ + return key in self._storage or await super().has(key) + + async def delete(self, key: str) -> None: + """Delete the given key from the storage. + + Args: + - key - The key to delete. + """ + del self._storage[key] + + async def clear(self) -> None: + """Clear the storage.""" + self._storage.clear() + + def child(self, name: str | None) -> "PipelineStorage": + """Create a child storage instance.""" + return self + + +def create_memory_storage() -> PipelineStorage: + """Create memory storage.""" + return MemoryPipelineStorage() diff --git a/graphrag/graphrag/index/storage/typing.py b/graphrag/graphrag/index/storage/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..595baf4efdef91923ec760ae8edeaa632cb8dc3b --- /dev/null +++ b/graphrag/graphrag/index/storage/typing.py @@ -0,0 +1,80 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'PipelineStorage' model.""" + +import re +from abc import ABCMeta, abstractmethod +from collections.abc import Iterator +from typing import Any + +from graphrag.index.progress import ProgressReporter + + +class PipelineStorage(metaclass=ABCMeta): + """Provide a storage interface for the pipeline. This is where the pipeline will store its output data.""" + + @abstractmethod + def find( + self, + file_pattern: re.Pattern[str], + base_dir: str | None = None, + progress: ProgressReporter | None = None, + file_filter: dict[str, Any] | None = None, + max_count=-1, + ) -> Iterator[tuple[str, dict[str, Any]]]: + """Find files in the storage using a file pattern, as well as a custom filter function.""" + + @abstractmethod + async def get( + self, key: str, as_bytes: bool | None = None, encoding: str | None = None + ) -> Any: + """Get the value for the given key. + + Args: + - key - The key to get the value for. + - as_bytes - Whether or not to return the value as bytes. + + Returns + ------- + - output - The value for the given key. + """ + + @abstractmethod + async def set( + self, key: str, value: str | bytes | None, encoding: str | None = None + ) -> None: + """Set the value for the given key. + + Args: + - key - The key to set the value for. + - value - The value to set. + """ + + @abstractmethod + async def has(self, key: str) -> bool: + """Return True if the given key exists in the storage. + + Args: + - key - The key to check for. + + Returns + ------- + - output - True if the key exists in the storage, False otherwise. + """ + + @abstractmethod + async def delete(self, key: str) -> None: + """Delete the given key from the storage. + + Args: + - key - The key to delete. + """ + + @abstractmethod + async def clear(self) -> None: + """Clear the storage.""" + + @abstractmethod + def child(self, name: str | None) -> "PipelineStorage": + """Create a child storage instance.""" diff --git a/graphrag/graphrag/index/text_splitting/__init__.py b/graphrag/graphrag/index/text_splitting/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4653adb22b433f90b25077b31c2cd1f30ba69165 --- /dev/null +++ b/graphrag/graphrag/index/text_splitting/__init__.py @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine Text Splitting package root.""" + +from .check_token_limit import check_token_limit +from .text_splitting import ( + DecodeFn, + EncodedText, + EncodeFn, + LengthFn, + NoopTextSplitter, + TextListSplitter, + TextListSplitterType, + TextSplitter, + Tokenizer, + TokenTextSplitter, + split_text_on_tokens, +) + +__all__ = [ + "DecodeFn", + "EncodeFn", + "EncodedText", + "LengthFn", + "NoopTextSplitter", + "TextListSplitter", + "TextListSplitterType", + "TextSplitter", + "TokenTextSplitter", + "Tokenizer", + "check_token_limit", + "split_text_on_tokens", +] diff --git a/graphrag/graphrag/index/text_splitting/check_token_limit.py b/graphrag/graphrag/index/text_splitting/check_token_limit.py new file mode 100644 index 0000000000000000000000000000000000000000..1a5f862254ac55a9364b39ef54562598f9771f6c --- /dev/null +++ b/graphrag/graphrag/index/text_splitting/check_token_limit.py @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Token limit method definition.""" + +from .text_splitting import TokenTextSplitter + + +def check_token_limit(text, max_token): + """Check token limit.""" + text_splitter = TokenTextSplitter(chunk_size=max_token, chunk_overlap=0) + docs = text_splitter.split_text(text) + if len(docs) > 1: + return 0 + return 1 diff --git a/graphrag/graphrag/index/text_splitting/text_splitting.py b/graphrag/graphrag/index/text_splitting/text_splitting.py new file mode 100644 index 0000000000000000000000000000000000000000..0badc8977c20f6ea7b6cbfdf9a7f716ae121f6c5 --- /dev/null +++ b/graphrag/graphrag/index/text_splitting/text_splitting.py @@ -0,0 +1,244 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing the 'Tokenizer', 'TextSplitter', 'NoopTextSplitter' and 'TokenTextSplitter' models.""" + +import json +import logging +from abc import ABC, abstractmethod +from collections.abc import Callable, Collection, Iterable +from dataclasses import dataclass +from enum import Enum +from typing import Any, Literal, cast + +import pandas as pd +import tiktoken + +from graphrag.index.utils import num_tokens_from_string + +EncodedText = list[int] +DecodeFn = Callable[[EncodedText], str] +EncodeFn = Callable[[str], EncodedText] +LengthFn = Callable[[str], int] + +log = logging.getLogger(__name__) + + +@dataclass(frozen=True) +class Tokenizer: + """Tokenizer data class.""" + + chunk_overlap: int + """Overlap in tokens between chunks""" + tokens_per_chunk: int + """Maximum number of tokens per chunk""" + decode: DecodeFn + """ Function to decode a list of token ids to a string""" + encode: EncodeFn + """ Function to encode a string to a list of token ids""" + + +class TextSplitter(ABC): + """Text splitter class definition.""" + + _chunk_size: int + _chunk_overlap: int + _length_function: LengthFn + _keep_separator: bool + _add_start_index: bool + _strip_whitespace: bool + + def __init__( + self, + # based on text-ada-002-embedding max input buffer length + # https://platform.openai.com/docs/guides/embeddings/second-generation-models + chunk_size: int = 8191, + chunk_overlap: int = 100, + length_function: LengthFn = len, + keep_separator: bool = False, + add_start_index: bool = False, + strip_whitespace: bool = True, + ): + """Init method definition.""" + self._chunk_size = chunk_size + self._chunk_overlap = chunk_overlap + self._length_function = length_function + self._keep_separator = keep_separator + self._add_start_index = add_start_index + self._strip_whitespace = strip_whitespace + + @abstractmethod + def split_text(self, text: str | list[str]) -> Iterable[str]: + """Split text method definition.""" + + +class NoopTextSplitter(TextSplitter): + """Noop text splitter class definition.""" + + def split_text(self, text: str | list[str]) -> Iterable[str]: + """Split text method definition.""" + return [text] if isinstance(text, str) else text + + +class TokenTextSplitter(TextSplitter): + """Token text splitter class definition.""" + + _allowed_special: Literal["all"] | set[str] + _disallowed_special: Literal["all"] | Collection[str] + + def __init__( + self, + encoding_name: str = "cl100k_base", + model_name: str | None = None, + allowed_special: Literal["all"] | set[str] | None = None, + disallowed_special: Literal["all"] | Collection[str] = "all", + **kwargs: Any, + ): + """Init method definition.""" + super().__init__(**kwargs) + if model_name is not None: + try: + enc = tiktoken.encoding_for_model(model_name) + except KeyError: + log.exception("Model %s not found, using %s", model_name, encoding_name) + enc = tiktoken.get_encoding(encoding_name) + else: + enc = tiktoken.get_encoding(encoding_name) + self._tokenizer = enc + self._allowed_special = allowed_special or set() + self._disallowed_special = disallowed_special + + def encode(self, text: str) -> list[int]: + """Encode the given text into an int-vector.""" + return self._tokenizer.encode( + text, + allowed_special=self._allowed_special, + disallowed_special=self._disallowed_special, + ) + + def num_tokens(self, text: str) -> int: + """Return the number of tokens in a string.""" + return len(self.encode(text)) + + def split_text(self, text: str | list[str]) -> list[str]: + """Split text method.""" + if cast(bool, pd.isna(text)) or text == "": + return [] + if isinstance(text, list): + text = " ".join(text) + if not isinstance(text, str): + msg = f"Attempting to split a non-string value, actual is {type(text)}" + raise TypeError(msg) + + tokenizer = Tokenizer( + chunk_overlap=self._chunk_overlap, + tokens_per_chunk=self._chunk_size, + decode=self._tokenizer.decode, + encode=lambda text: self.encode(text), + ) + + return split_text_on_tokens(text=text, tokenizer=tokenizer) + + +class TextListSplitterType(str, Enum): + """Enum for the type of the TextListSplitter.""" + + DELIMITED_STRING = "delimited_string" + JSON = "json" + + +class TextListSplitter(TextSplitter): + """Text list splitter class definition.""" + + def __init__( + self, + chunk_size: int, + splitter_type: TextListSplitterType = TextListSplitterType.JSON, + input_delimiter: str | None = None, + output_delimiter: str | None = None, + model_name: str | None = None, + encoding_name: str | None = None, + ): + """Initialize the TextListSplitter with a chunk size.""" + # Set the chunk overlap to 0 as we use full strings + super().__init__(chunk_size, chunk_overlap=0) + self._type = splitter_type + self._input_delimiter = input_delimiter + self._output_delimiter = output_delimiter or "\n" + self._length_function = lambda x: num_tokens_from_string( + x, model=model_name, encoding_name=encoding_name + ) + + def split_text(self, text: str | list[str]) -> Iterable[str]: + """Split a string list into a list of strings for a given chunk size.""" + if not text: + return [] + + result: list[str] = [] + current_chunk: list[str] = [] + + # Add the brackets + current_length: int = self._length_function("[]") + + # Input should be a string list joined by a delimiter + string_list = self._load_text_list(text) + + if len(string_list) == 1: + return string_list + + for item in string_list: + # Count the length of the item and add comma + item_length = self._length_function(f"{item},") + + if current_length + item_length > self._chunk_size: + if current_chunk and len(current_chunk) > 0: + # Add the current chunk to the result + self._append_to_result(result, current_chunk) + + # Start a new chunk + current_chunk = [item] + # Add 2 for the brackets + current_length = item_length + else: + # Add the item to the current chunk + current_chunk.append(item) + # Add 1 for the comma + current_length += item_length + + # Add the last chunk to the result + self._append_to_result(result, current_chunk) + + return result + + def _load_text_list(self, text: str | list[str]): + """Load the text list based on the type.""" + if isinstance(text, list): + string_list = text + elif self._type == TextListSplitterType.JSON: + string_list = json.loads(text) + else: + string_list = text.split(self._input_delimiter) + return string_list + + def _append_to_result(self, chunk_list: list[str], new_chunk: list[str]): + """Append the current chunk to the result.""" + if new_chunk and len(new_chunk) > 0: + if self._type == TextListSplitterType.JSON: + chunk_list.append(json.dumps(new_chunk)) + else: + chunk_list.append(self._output_delimiter.join(new_chunk)) + + +def split_text_on_tokens(*, text: str, tokenizer: Tokenizer) -> list[str]: + """Split incoming text and return chunks using tokenizer.""" + splits: list[str] = [] + input_ids = tokenizer.encode(text) + start_idx = 0 + cur_idx = min(start_idx + tokenizer.tokens_per_chunk, len(input_ids)) + chunk_ids = input_ids[start_idx:cur_idx] + while start_idx < len(input_ids): + splits.append(tokenizer.decode(chunk_ids)) + start_idx += tokenizer.tokens_per_chunk - tokenizer.chunk_overlap + cur_idx = min(start_idx + tokenizer.tokens_per_chunk, len(input_ids)) + chunk_ids = input_ids[start_idx:cur_idx] + return splits diff --git a/graphrag/graphrag/index/typing.py b/graphrag/graphrag/index/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..ed1d7e93e71a762dfd3717b9fa90e0299c9a4a5a --- /dev/null +++ b/graphrag/graphrag/index/typing.py @@ -0,0 +1,20 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing the 'PipelineRunResult' model.""" + +from collections.abc import Callable +from dataclasses import dataclass + +import pandas as pd + +ErrorHandlerFn = Callable[[BaseException | None, str | None, dict | None], None] + + +@dataclass +class PipelineRunResult: + """Pipeline run result class definition.""" + + workflow: str + result: pd.DataFrame | None + errors: list[BaseException] | None diff --git a/graphrag/graphrag/index/utils/__init__.py b/graphrag/graphrag/index/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3a8b1c00278fdc6b56080f2813ab10b228f0f955 --- /dev/null +++ b/graphrag/graphrag/index/utils/__init__.py @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Utils methods definition.""" + +from .dicts import dict_has_keys_with_types +from .hashing import gen_md5_hash +from .is_null import is_null +from .json import clean_up_json +from .load_graph import load_graph +from .string import clean_str +from .tokens import num_tokens_from_string, string_from_tokens +from .topological_sort import topological_sort +from .uuid import gen_uuid + +__all__ = [ + "clean_str", + "clean_up_json", + "dict_has_keys_with_types", + "gen_md5_hash", + "gen_uuid", + "is_null", + "load_graph", + "num_tokens_from_string", + "string_from_tokens", + "topological_sort", +] diff --git a/graphrag/graphrag/index/utils/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/utils/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..727465315311c16f2faf648d82b2131e6fde9256 Binary files /dev/null and b/graphrag/graphrag/index/utils/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/utils/__pycache__/dicts.cpython-311.pyc b/graphrag/graphrag/index/utils/__pycache__/dicts.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ea0a0429dbf33560029b80c1ce2eef34c423076 Binary files /dev/null and b/graphrag/graphrag/index/utils/__pycache__/dicts.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/utils/__pycache__/ds_util.cpython-311.pyc b/graphrag/graphrag/index/utils/__pycache__/ds_util.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b81c78e65d36ba0b8ca357e0307b0db1f6c29b7 Binary files /dev/null and b/graphrag/graphrag/index/utils/__pycache__/ds_util.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/utils/__pycache__/hashing.cpython-311.pyc b/graphrag/graphrag/index/utils/__pycache__/hashing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c0e3f54910ed6be6d75bf1b7c2ce661fea9efd4 Binary files /dev/null and b/graphrag/graphrag/index/utils/__pycache__/hashing.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/utils/__pycache__/is_null.cpython-311.pyc b/graphrag/graphrag/index/utils/__pycache__/is_null.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33b5b1045882bc08da1121a97c4bdc4dcf212f66 Binary files /dev/null and b/graphrag/graphrag/index/utils/__pycache__/is_null.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/utils/__pycache__/json.cpython-311.pyc b/graphrag/graphrag/index/utils/__pycache__/json.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e06a02a13d497d0a4289d419dd4ae7366c891b56 Binary files /dev/null and b/graphrag/graphrag/index/utils/__pycache__/json.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/utils/__pycache__/load_graph.cpython-311.pyc b/graphrag/graphrag/index/utils/__pycache__/load_graph.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9411785531a6358d1e49ea28e08f08399b018e28 Binary files /dev/null and b/graphrag/graphrag/index/utils/__pycache__/load_graph.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/utils/__pycache__/string.cpython-311.pyc b/graphrag/graphrag/index/utils/__pycache__/string.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e36208dbaa3cb2ccdac215312aede3d56f02d5e3 Binary files /dev/null and b/graphrag/graphrag/index/utils/__pycache__/string.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/utils/__pycache__/tokens.cpython-311.pyc b/graphrag/graphrag/index/utils/__pycache__/tokens.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a738963b53bc9a6416a86bd0f573f02e1bb6a7a Binary files /dev/null and b/graphrag/graphrag/index/utils/__pycache__/tokens.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/utils/__pycache__/topological_sort.cpython-311.pyc b/graphrag/graphrag/index/utils/__pycache__/topological_sort.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..071414e4fd9e1b356e71c6bde8d0acb387b49939 Binary files /dev/null and b/graphrag/graphrag/index/utils/__pycache__/topological_sort.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/utils/__pycache__/uuid.cpython-311.pyc b/graphrag/graphrag/index/utils/__pycache__/uuid.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e85d4d0b8dd7762101727d1acd0aa80f1603523 Binary files /dev/null and b/graphrag/graphrag/index/utils/__pycache__/uuid.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/utils/dataframes.py b/graphrag/graphrag/index/utils/dataframes.py new file mode 100644 index 0000000000000000000000000000000000000000..ea65d71d7ac4d0b25e384220a63aaa702b782a19 --- /dev/null +++ b/graphrag/graphrag/index/utils/dataframes.py @@ -0,0 +1,61 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing DataFrame utilities.""" + +from collections.abc import Callable +from typing import Any, cast + +import pandas as pd +from pandas._typing import MergeHow + + +def drop_columns(df: pd.DataFrame, *column: str) -> pd.DataFrame: + """Drop columns from a dataframe.""" + return df.drop(list(column), axis=1) + + +def where_column_equals(df: pd.DataFrame, column: str, value: Any) -> pd.DataFrame: + """Return a filtered DataFrame where a column equals a value.""" + return cast(pd.DataFrame, df[df[column] == value]) + + +def antijoin(df: pd.DataFrame, exclude: pd.DataFrame, column: str) -> pd.DataFrame: + """Return an anti-joined dataframe. + + Arguments: + * df: The DataFrame to apply the exclusion to + * exclude: The DataFrame containing rows to remove. + * column: The join-on column. + """ + result = df.merge( + exclude[[column]], + on=column, + how="outer", + indicator=True, + ) + if "_merge" in result.columns: + result = result[result["_merge"] == "left_only"].drop("_merge", axis=1) + return cast(pd.DataFrame, result) + + +def transform_series(series: pd.Series, fn: Callable[[Any], Any]) -> pd.Series: + """Apply a transformation function to a series.""" + return cast(pd.Series, series.apply(fn)) + + +def join( + left: pd.DataFrame, right: pd.DataFrame, key: str, strategy: MergeHow = "left" +) -> pd.DataFrame: + """Perform a table join.""" + return left.merge(right, on=key, how=strategy) + + +def union(*frames: pd.DataFrame) -> pd.DataFrame: + """Perform a union operation on the given set of dataframes.""" + return pd.concat(list(frames)) + + +def select(df: pd.DataFrame, *columns: str) -> pd.DataFrame: + """Select columns from a dataframe.""" + return cast(pd.DataFrame, df[list(columns)]) diff --git a/graphrag/graphrag/index/utils/dicts.py b/graphrag/graphrag/index/utils/dicts.py new file mode 100644 index 0000000000000000000000000000000000000000..4d3662e0b86d6f9049ebda58270e48219e6253a2 --- /dev/null +++ b/graphrag/graphrag/index/utils/dicts.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A utility module containing methods for inspecting and verifying dictionary types.""" + + +def dict_has_keys_with_types( + data: dict, expected_fields: list[tuple[str, type]] +) -> bool: + """Return True if the given dictionary has the given keys with the given types.""" + for field, field_type in expected_fields: + if field not in data: + return False + + value = data[field] + if not isinstance(value, field_type): + return False + return True diff --git a/graphrag/graphrag/index/utils/ds_util.py b/graphrag/graphrag/index/utils/ds_util.py new file mode 100644 index 0000000000000000000000000000000000000000..d65c69e4a8c573ddec3b93da668413bae7395998 --- /dev/null +++ b/graphrag/graphrag/index/utils/ds_util.py @@ -0,0 +1,32 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A utility module datashaper-specific utility methods.""" + +from typing import cast + +from datashaper import TableContainer, VerbInput + +_NAMED_INPUTS_REQUIRED = "Named inputs are required" + + +def get_required_input_table(input: VerbInput, name: str) -> TableContainer: + """Get a required input table by name.""" + return cast(TableContainer, get_named_input_table(input, name, required=True)) + + +def get_named_input_table( + input: VerbInput, name: str, required: bool = False +) -> TableContainer | None: + """Get an input table from datashaper verb-inputs by name.""" + named_inputs = input.named + if named_inputs is None: + if not required: + return None + raise ValueError(_NAMED_INPUTS_REQUIRED) + + result = named_inputs.get(name) + if result is None and required: + msg = f"input '${name}' is required" + raise ValueError(msg) + return result diff --git a/graphrag/graphrag/index/utils/hashing.py b/graphrag/graphrag/index/utils/hashing.py new file mode 100644 index 0000000000000000000000000000000000000000..342ae99d4419b8947d383d561bb434d39af5ce0e --- /dev/null +++ b/graphrag/graphrag/index/utils/hashing.py @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Hashing utilities.""" + +from collections.abc import Iterable +from hashlib import md5 +from typing import Any + + +def gen_md5_hash(item: dict[str, Any], hashcode: Iterable[str]): + """Generate an md5 hash.""" + hashed = "".join([str(item[column]) for column in hashcode]) + return f"{md5(hashed.encode('utf-8'), usedforsecurity=False).hexdigest()}" diff --git a/graphrag/graphrag/index/utils/is_null.py b/graphrag/graphrag/index/utils/is_null.py new file mode 100644 index 0000000000000000000000000000000000000000..f5df1955ae95c2f1b17b29a7692d2a2ebdd525f5 --- /dev/null +++ b/graphrag/graphrag/index/utils/is_null.py @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Defines the is_null utility.""" + +import math +from typing import Any + + +def is_null(value: Any) -> bool: + """Check if value is null or is nan.""" + + def is_none() -> bool: + return value is None + + def is_nan() -> bool: + return isinstance(value, float) and math.isnan(value) + + return is_none() or is_nan() diff --git a/graphrag/graphrag/index/utils/json.py b/graphrag/graphrag/index/utils/json.py new file mode 100644 index 0000000000000000000000000000000000000000..ed6c06665d0ccc7a35b1e440be31788e9183f6b8 --- /dev/null +++ b/graphrag/graphrag/index/utils/json.py @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""JSON cleaning and formatting utilities.""" + + +def clean_up_json(json_str: str): + """Clean up json string.""" + json_str = ( + json_str.replace("\\n", "") + .replace("\n", "") + .replace("\r", "") + .replace('"[{', "[{") + .replace('}]"', "}]") + .replace("\\", "") + .strip() + ) + + # Remove JSON Markdown Frame + if json_str.startswith("```json"): + json_str = json_str[len("```json") :] + if json_str.startswith("json"): + json_str = json_str[len("json") :] + if json_str.endswith("```"): + json_str = json_str[: len(json_str) - len("```")] + + return json_str diff --git a/graphrag/graphrag/index/utils/load_graph.py b/graphrag/graphrag/index/utils/load_graph.py new file mode 100644 index 0000000000000000000000000000000000000000..57992a04c83997a4950d3f743a35600521a11423 --- /dev/null +++ b/graphrag/graphrag/index/utils/load_graph.py @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Networkx load_graph utility definition.""" + +import networkx as nx + + +def load_graph(graphml: str | nx.Graph) -> nx.Graph: + """Load a graph from a graphml file or a networkx graph.""" + return nx.parse_graphml(graphml) if isinstance(graphml, str) else graphml diff --git a/graphrag/graphrag/index/utils/rate_limiter.py b/graphrag/graphrag/index/utils/rate_limiter.py new file mode 100644 index 0000000000000000000000000000000000000000..8dc641719b61fa087703f258ab1287631502efaa --- /dev/null +++ b/graphrag/graphrag/index/utils/rate_limiter.py @@ -0,0 +1,40 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Rate limiter utility.""" + +import asyncio +import time + + +class RateLimiter: + """ + The original TpmRpmLLMLimiter strategy did not account for minute-based rate limiting when scheduled. + + The RateLimiter was introduced to ensure that the CommunityReportsExtractor could be scheduled to adhere to rate configurations on a per-minute basis. + """ + + # TODO: RateLimiter scheduled: using asyncio for async_mode + + def __init__(self, rate: int, per: int): + self.rate = rate + self.per = per + self.allowance = rate + self.last_check = time.monotonic() + + async def acquire(self): + """Acquire a token from the rate limiter.""" + current = time.monotonic() + elapsed = current - self.last_check + self.last_check = current + self.allowance += elapsed * (self.rate / self.per) + + if self.allowance > self.rate: + self.allowance = self.rate + + if self.allowance < 1.0: + sleep_time = (1.0 - self.allowance) * (self.per / self.rate) + await asyncio.sleep(sleep_time) + self.allowance = 0.0 + else: + self.allowance -= 1.0 diff --git a/graphrag/graphrag/index/utils/string.py b/graphrag/graphrag/index/utils/string.py new file mode 100644 index 0000000000000000000000000000000000000000..7e1654bb4e48bcc2354c21c62a5ce2f12cf42925 --- /dev/null +++ b/graphrag/graphrag/index/utils/string.py @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""String utilities.""" + +import html +import re +from typing import Any + + +def clean_str(input: Any) -> str: + """Clean an input string by removing HTML escapes, control characters, and other unwanted characters.""" + # If we get non-string input, just give it back + if not isinstance(input, str): + return input + + result = html.unescape(input.strip()) + # https://stackoverflow.com/questions/4324790/removing-control-characters-from-a-string-in-python + return re.sub(r"[\x00-\x1f\x7f-\x9f]", "", result) diff --git a/graphrag/graphrag/index/utils/tokens.py b/graphrag/graphrag/index/utils/tokens.py new file mode 100644 index 0000000000000000000000000000000000000000..4a189b9b225faf0d4db6981b81352ad3f9632936 --- /dev/null +++ b/graphrag/graphrag/index/utils/tokens.py @@ -0,0 +1,41 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Utilities for working with tokens.""" + +import logging + +import tiktoken + +DEFAULT_ENCODING_NAME = "cl100k_base" +log = logging.getLogger(__name__) + + +def num_tokens_from_string( + string: str, model: str | None = None, encoding_name: str | None = None +) -> int: + """Return the number of tokens in a text string.""" + if model is not None: + try: + encoding = tiktoken.encoding_for_model(model) + except KeyError: + msg = f"Failed to get encoding for {model} when getting num_tokens_from_string. Fall back to default encoding {DEFAULT_ENCODING_NAME}" + log.warning(msg) + encoding = tiktoken.get_encoding(DEFAULT_ENCODING_NAME) + else: + encoding = tiktoken.get_encoding(encoding_name or DEFAULT_ENCODING_NAME) + return len(encoding.encode(string)) + + +def string_from_tokens( + tokens: list[int], model: str | None = None, encoding_name: str | None = None +) -> str: + """Return a text string from a list of tokens.""" + if model is not None: + encoding = tiktoken.encoding_for_model(model) + elif encoding_name is not None: + encoding = tiktoken.get_encoding(encoding_name) + else: + msg = "Either model or encoding_name must be specified." + raise ValueError(msg) + return encoding.decode(tokens) diff --git a/graphrag/graphrag/index/utils/topological_sort.py b/graphrag/graphrag/index/utils/topological_sort.py new file mode 100644 index 0000000000000000000000000000000000000000..a19b464559466b9824eacf1d36534f2eea157875 --- /dev/null +++ b/graphrag/graphrag/index/utils/topological_sort.py @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Topological sort utility method.""" + +from graphlib import TopologicalSorter + + +def topological_sort(graph: dict[str, list[str]]) -> list[str]: + """Topological sort.""" + ts = TopologicalSorter(graph) + return list(ts.static_order()) diff --git a/graphrag/graphrag/index/utils/uuid.py b/graphrag/graphrag/index/utils/uuid.py new file mode 100644 index 0000000000000000000000000000000000000000..0671fb09dac38560a522d79c684f104174b1febb --- /dev/null +++ b/graphrag/graphrag/index/utils/uuid.py @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""UUID utilities.""" + +import uuid +from random import Random, getrandbits + + +def gen_uuid(rd: Random | None = None): + """Generate a random UUID v4.""" + return uuid.UUID( + int=rd.getrandbits(128) if rd is not None else getrandbits(128), version=4 + ).hex diff --git a/graphrag/graphrag/index/verbs/__init__.py b/graphrag/graphrag/index/verbs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..379c2a3749b4ce51b3077b10844bb2620fcb6a60 --- /dev/null +++ b/graphrag/graphrag/index/verbs/__init__.py @@ -0,0 +1,50 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing get_default_verbs method definition.""" + +from .covariates import extract_covariates +from .entities import entity_extract, summarize_descriptions +from .genid import genid +from .graph import ( + cluster_graph, + create_community_reports, + create_graph, + embed_graph, + layout_graph, + merge_graphs, + unpack_graph, +) +from .overrides import aggregate, concat, merge +from .snapshot import snapshot +from .snapshot_rows import snapshot_rows +from .spread_json import spread_json +from .text import chunk, text_embed, text_split, text_translate +from .unzip import unzip +from .zip import zip_verb + +__all__ = [ + "aggregate", + "chunk", + "cluster_graph", + "concat", + "create_community_reports", + "create_graph", + "embed_graph", + "entity_extract", + "extract_covariates", + "genid", + "layout_graph", + "merge", + "merge_graphs", + "snapshot", + "snapshot_rows", + "spread_json", + "summarize_descriptions", + "text_embed", + "text_split", + "text_translate", + "unpack_graph", + "unzip", + "zip_verb", +] diff --git a/graphrag/graphrag/index/verbs/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/verbs/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b518de9233cfa5dcd8699bbd8738ef849b58114 Binary files /dev/null and b/graphrag/graphrag/index/verbs/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/__pycache__/genid.cpython-311.pyc b/graphrag/graphrag/index/verbs/__pycache__/genid.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e46d8c81650ac48c4273e1559a220dd85a6b6a59 Binary files /dev/null and b/graphrag/graphrag/index/verbs/__pycache__/genid.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/covariates/__init__.py b/graphrag/graphrag/index/verbs/covariates/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cdebee228be80b4bf40f3e463f58d3d936c2684e --- /dev/null +++ b/graphrag/graphrag/index/verbs/covariates/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine covariates package root.""" + +from .extract_covariates import extract_covariates + +__all__ = ["extract_covariates"] diff --git a/graphrag/graphrag/index/verbs/covariates/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/verbs/covariates/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92b31b91f58d7a4e7d81274a2bbb193c15292808 Binary files /dev/null and b/graphrag/graphrag/index/verbs/covariates/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/covariates/__pycache__/typing.cpython-311.pyc b/graphrag/graphrag/index/verbs/covariates/__pycache__/typing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..617c4f9e2af6c972b75330b923aa62a9e47688e5 Binary files /dev/null and b/graphrag/graphrag/index/verbs/covariates/__pycache__/typing.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/covariates/extract_covariates/__init__.py b/graphrag/graphrag/index/verbs/covariates/extract_covariates/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..53d357bb462f326ea54ee62d88d529ef6ff1461c --- /dev/null +++ b/graphrag/graphrag/index/verbs/covariates/extract_covariates/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine text extract claims package root.""" + +from .extract_covariates import ExtractClaimsStrategyType, extract_covariates + +__all__ = ["ExtractClaimsStrategyType", "extract_covariates"] diff --git a/graphrag/graphrag/index/verbs/covariates/extract_covariates/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/verbs/covariates/extract_covariates/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e953f73905a254cda74062923e8fc2468ca2ec9e Binary files /dev/null and b/graphrag/graphrag/index/verbs/covariates/extract_covariates/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/covariates/extract_covariates/__pycache__/extract_covariates.cpython-311.pyc b/graphrag/graphrag/index/verbs/covariates/extract_covariates/__pycache__/extract_covariates.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c663d72de45557bd4d8ee779cec1cfe879c1371 Binary files /dev/null and b/graphrag/graphrag/index/verbs/covariates/extract_covariates/__pycache__/extract_covariates.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/covariates/extract_covariates/extract_covariates.py b/graphrag/graphrag/index/verbs/covariates/extract_covariates/extract_covariates.py new file mode 100644 index 0000000000000000000000000000000000000000..a67cb0fa0e93638f1577405fab166de55e00b466 --- /dev/null +++ b/graphrag/graphrag/index/verbs/covariates/extract_covariates/extract_covariates.py @@ -0,0 +1,110 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing the extract_covariates verb definition.""" + +import logging +from dataclasses import asdict +from enum import Enum +from typing import Any, cast + +import pandas as pd +from datashaper import ( + AsyncType, + TableContainer, + VerbCallbacks, + VerbInput, + derive_from_rows, + verb, +) + +from graphrag.index.cache import PipelineCache +from graphrag.index.verbs.covariates.typing import Covariate, CovariateExtractStrategy + +log = logging.getLogger(__name__) + + +class ExtractClaimsStrategyType(str, Enum): + """ExtractClaimsStrategyType class definition.""" + + graph_intelligence = "graph_intelligence" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +DEFAULT_ENTITY_TYPES = ["organization", "person", "geo", "event"] + + +@verb(name="extract_covariates") +async def extract_covariates( + input: VerbInput, + cache: PipelineCache, + callbacks: VerbCallbacks, + column: str, + covariate_type: str, + strategy: dict[str, Any] | None, + async_mode: AsyncType = AsyncType.AsyncIO, + entity_types: list[str] | None = None, + **kwargs, +) -> TableContainer: + """ + Extract claims from a piece of text. + + ## Usage + TODO + """ + log.debug("extract_covariates strategy=%s", strategy) + if entity_types is None: + entity_types = DEFAULT_ENTITY_TYPES + output = cast(pd.DataFrame, input.get_input()) + + resolved_entities_map = {} + + strategy = strategy or {} + strategy_exec = load_strategy( + strategy.get("type", ExtractClaimsStrategyType.graph_intelligence) + ) + strategy_config = {**strategy} + + async def run_strategy(row): + text = row[column] + result = await strategy_exec( + text, entity_types, resolved_entities_map, callbacks, cache, strategy_config + ) + return [ + create_row_from_claim_data(row, item, covariate_type) + for item in result.covariate_data + ] + + results = await derive_from_rows( + output, + run_strategy, + callbacks, + scheduling_type=async_mode, + num_threads=kwargs.get("num_threads", 4), + ) + output = pd.DataFrame([item for row in results for item in row or []]) + return TableContainer(table=output) + + +def load_strategy(strategy_type: ExtractClaimsStrategyType) -> CovariateExtractStrategy: + """Load strategy method definition.""" + match strategy_type: + case ExtractClaimsStrategyType.graph_intelligence: + from .strategies.graph_intelligence import run as run_gi + + return run_gi + case _: + msg = f"Unknown strategy: {strategy_type}" + raise ValueError(msg) + + +def create_row_from_claim_data(row, covariate_data: Covariate, covariate_type: str): + """Create a row from the claim data and the input row.""" + item = {**row, **asdict(covariate_data), "covariate_type": covariate_type} + # TODO: doc_id from extraction isn't necessary + # since chunking happens before this + del item["doc_id"] + return item diff --git a/graphrag/graphrag/index/verbs/covariates/extract_covariates/strategies/__init__.py b/graphrag/graphrag/index/verbs/covariates/extract_covariates/strategies/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..605c66f8d1297453cac922dafa1b430d0f075b04 --- /dev/null +++ b/graphrag/graphrag/index/verbs/covariates/extract_covariates/strategies/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine text extract claims strategies package root.""" diff --git a/graphrag/graphrag/index/verbs/covariates/extract_covariates/strategies/graph_intelligence/__init__.py b/graphrag/graphrag/index/verbs/covariates/extract_covariates/strategies/graph_intelligence/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ab01f06fc44fecdf8253978a00baada788bc638b --- /dev/null +++ b/graphrag/graphrag/index/verbs/covariates/extract_covariates/strategies/graph_intelligence/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine text extract claims strategies graph intelligence package root.""" + +from .run_gi_extract_claims import run + +__all__ = ["run"] diff --git a/graphrag/graphrag/index/verbs/covariates/extract_covariates/strategies/graph_intelligence/defaults.py b/graphrag/graphrag/index/verbs/covariates/extract_covariates/strategies/graph_intelligence/defaults.py new file mode 100644 index 0000000000000000000000000000000000000000..846bfa81e0d32ed934eb0318b0e052826b94a4e4 --- /dev/null +++ b/graphrag/graphrag/index/verbs/covariates/extract_covariates/strategies/graph_intelligence/defaults.py @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A file containing MOCK_LLM_RESPONSES definition.""" + +MOCK_LLM_RESPONSES = [ + """ +[ + { + "subject": "COMPANY A", + "object": "GOVERNMENT AGENCY B", + "type": "ANTI-COMPETITIVE PRACTICES", + "status": "TRUE", + "start_date": "2022-01-10T00:00:00", + "end_date": "2022-01-10T00:00:00", + "description": "Company A was found to engage in anti-competitive practices because it was fined for bid rigging in multiple public tenders published by Government Agency B according to an article published on 2022/01/10", + "source_text": ["According to an article published on 2022/01/10, Company A was fined for bid rigging while participating in multiple public tenders published by Government Agency B."] + } +] + """.strip() +] diff --git a/graphrag/graphrag/index/verbs/covariates/extract_covariates/strategies/graph_intelligence/run_gi_extract_claims.py b/graphrag/graphrag/index/verbs/covariates/extract_covariates/strategies/graph_intelligence/run_gi_extract_claims.py new file mode 100644 index 0000000000000000000000000000000000000000..1c9f058830d1361af818ba57748b0efded0dc075 --- /dev/null +++ b/graphrag/graphrag/index/verbs/covariates/extract_covariates/strategies/graph_intelligence/run_gi_extract_claims.py @@ -0,0 +1,106 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run and _run_chain methods definitions.""" + +from collections.abc import Iterable +from typing import Any + +from datashaper import VerbCallbacks + +import graphrag.config.defaults as defs +from graphrag.config.enums import LLMType +from graphrag.index.cache import PipelineCache +from graphrag.index.graph.extractors.claims import ClaimExtractor +from graphrag.index.llm import load_llm +from graphrag.index.verbs.covariates.typing import ( + Covariate, + CovariateExtractionResult, +) +from graphrag.llm import CompletionLLM + +from .defaults import MOCK_LLM_RESPONSES + + +async def run( + input: str | Iterable[str], + entity_types: list[str], + resolved_entities_map: dict[str, str], + reporter: VerbCallbacks, + pipeline_cache: PipelineCache, + strategy_config: dict[str, Any], +) -> CovariateExtractionResult: + """Run the Claim extraction chain.""" + llm_config = strategy_config.get( + "llm", {"type": LLMType.StaticResponse, "responses": MOCK_LLM_RESPONSES} + ) + llm_type = llm_config.get("type", LLMType.StaticResponse) + llm = load_llm("claim_extraction", llm_type, reporter, pipeline_cache, llm_config) + return await _execute( + llm, input, entity_types, resolved_entities_map, reporter, strategy_config + ) + + +async def _execute( + llm: CompletionLLM, + texts: Iterable[str], + entity_types: list[str], + resolved_entities_map: dict[str, str], + reporter: VerbCallbacks, + strategy_config: dict[str, Any], +) -> CovariateExtractionResult: + extraction_prompt = strategy_config.get("extraction_prompt") + max_gleanings = strategy_config.get("max_gleanings", defs.CLAIM_MAX_GLEANINGS) + tuple_delimiter = strategy_config.get("tuple_delimiter") + record_delimiter = strategy_config.get("record_delimiter") + completion_delimiter = strategy_config.get("completion_delimiter") + encoding_model = strategy_config.get("encoding_name") + + extractor = ClaimExtractor( + llm_invoker=llm, + extraction_prompt=extraction_prompt, + max_gleanings=max_gleanings, + encoding_model=encoding_model, + on_error=lambda e, s, d: ( + reporter.error("Claim Extraction Error", e, s, d) if reporter else None + ), + ) + + claim_description = strategy_config.get("claim_description") + if claim_description is None: + msg = "claim_description is required for claim extraction" + raise ValueError(msg) + + texts = [texts] if isinstance(texts, str) else texts + + results = await extractor({ + "input_text": texts, + "entity_specs": entity_types, + "resolved_entities": resolved_entities_map, + "claim_description": claim_description, + "tuple_delimiter": tuple_delimiter, + "record_delimiter": record_delimiter, + "completion_delimiter": completion_delimiter, + }) + + claim_data = results.output + return CovariateExtractionResult([create_covariate(item) for item in claim_data]) + + +def create_covariate(item: dict[str, Any]) -> Covariate: + """Create a covariate from the item.""" + return Covariate( + subject_id=item.get("subject_id"), + subject_type=item.get("subject_type"), + object_id=item.get("object_id"), + object_type=item.get("object_type"), + type=item.get("type"), + status=item.get("status"), + start_date=item.get("start_date"), + end_date=item.get("end_date"), + description=item.get("description"), + source_text=item.get("source_text"), + doc_id=item.get("doc_id"), + record_id=item.get("record_id"), + id=item.get("id"), + ) diff --git a/graphrag/graphrag/index/verbs/covariates/typing.py b/graphrag/graphrag/index/verbs/covariates/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..e31cfa49896bdcc8d555144318f5629949120416 --- /dev/null +++ b/graphrag/graphrag/index/verbs/covariates/typing.py @@ -0,0 +1,52 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'Covariate' and 'CovariateExtractionResult' models.""" + +from collections.abc import Awaitable, Callable, Iterable +from dataclasses import dataclass +from typing import Any + +from datashaper import VerbCallbacks + +from graphrag.index.cache import PipelineCache + + +@dataclass +class Covariate: + """Covariate class definition.""" + + covariate_type: str | None = None + subject_id: str | None = None + subject_type: str | None = None + object_id: str | None = None + object_type: str | None = None + type: str | None = None + status: str | None = None + start_date: str | None = None + end_date: str | None = None + description: str | None = None + source_text: list[str] | None = None + doc_id: str | None = None + record_id: int | None = None + id: str | None = None + + +@dataclass +class CovariateExtractionResult: + """Covariate extraction result class definition.""" + + covariate_data: list[Covariate] + + +CovariateExtractStrategy = Callable[ + [ + Iterable[str], + list[str], + dict[str, str], + VerbCallbacks, + PipelineCache, + dict[str, Any], + ], + Awaitable[CovariateExtractionResult], +] diff --git a/graphrag/graphrag/index/verbs/entities/__init__.py b/graphrag/graphrag/index/verbs/entities/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2f55d710e910075098d3f93daad097cfe2690b9c --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/__init__.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine entities package root.""" + +from .extraction import entity_extract +from .summarize import summarize_descriptions + +__all__ = ["entity_extract", "summarize_descriptions"] diff --git a/graphrag/graphrag/index/verbs/entities/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/verbs/entities/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fdeaef2096fc16d29cd1fc22ff2899f36123d768 Binary files /dev/null and b/graphrag/graphrag/index/verbs/entities/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/entities/extraction/__init__.py b/graphrag/graphrag/index/verbs/entities/extraction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..46e6d54581e9894fa0a1f4ecefe8d81412a020ee --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/extraction/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine entities extraction package root.""" + +from .entity_extract import ExtractEntityStrategyType, entity_extract + +__all__ = ["ExtractEntityStrategyType", "entity_extract"] diff --git a/graphrag/graphrag/index/verbs/entities/extraction/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/verbs/entities/extraction/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ccd7baaf7e20d5a11dec3aee6ca1f2d311e97d7 Binary files /dev/null and b/graphrag/graphrag/index/verbs/entities/extraction/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/entities/extraction/__pycache__/entity_extract.cpython-311.pyc b/graphrag/graphrag/index/verbs/entities/extraction/__pycache__/entity_extract.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e188cb69fdf6940782a3ce9d030f72f76529f594 Binary files /dev/null and b/graphrag/graphrag/index/verbs/entities/extraction/__pycache__/entity_extract.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/entities/extraction/entity_extract.py b/graphrag/graphrag/index/verbs/entities/extraction/entity_extract.py new file mode 100644 index 0000000000000000000000000000000000000000..4e961f674d0b2967684862236ef02bf8f8fe4a50 --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/extraction/entity_extract.py @@ -0,0 +1,202 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing entity_extract methods.""" + +import logging +from enum import Enum +from typing import Any, cast + +import pandas as pd +from datashaper import ( + AsyncType, + TableContainer, + VerbCallbacks, + VerbInput, + derive_from_rows, + verb, +) + +from graphrag.index.bootstrap import bootstrap +from graphrag.index.cache import PipelineCache + +from .strategies.typing import Document, EntityExtractStrategy + +log = logging.getLogger(__name__) + + +class ExtractEntityStrategyType(str, Enum): + """ExtractEntityStrategyType class definition.""" + + graph_intelligence = "graph_intelligence" + graph_intelligence_json = "graph_intelligence_json" + nltk = "nltk" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +DEFAULT_ENTITY_TYPES = ["organization", "person", "geo", "event"] + + +@verb(name="entity_extract") +async def entity_extract( + input: VerbInput, + cache: PipelineCache, + callbacks: VerbCallbacks, + column: str, + id_column: str, + to: str, + strategy: dict[str, Any] | None, + graph_to: str | None = None, + async_mode: AsyncType = AsyncType.AsyncIO, + entity_types=DEFAULT_ENTITY_TYPES, + **kwargs, +) -> TableContainer: + """ + Extract entities from a piece of text. + + ## Usage + ### json + ```json + { + "verb": "entity_extract", + "args": { + "column": "the_document_text_column_to_extract_entities_from", /* In general this will be your document text column */ + "id_column": "the_column_with_the_unique_id_for_each_row", /* In general this will be your document id */ + "to": "the_column_to_output_the_entities_to", /* This will be a list[dict[str, Any]] a list of entities, with a name, and additional attributes */ + "graph_to": "the_column_to_output_the_graphml_to", /* Optional: This will be a graphml graph in string form which represents the entities and their relationships */ + "strategy": {...} , see strategies section below + "entity_types": ["list", "of", "entity", "types", "to", "extract"] /* Optional: This will limit the entity types extracted, default: ["organization", "person", "geo", "event"] */ + "summarize_descriptions" : true | false /* Optional: This will summarize the descriptions of the entities and relationships, default: true */ + } + } + ``` + ### yaml + ```yaml + verb: entity_extract + args: + column: the_document_text_column_to_extract_entities_from + id_column: the_column_with_the_unique_id_for_each_row + to: the_column_to_output_the_entities_to + graph_to: the_column_to_output_the_graphml_to + strategy: , see strategies section below + summarize_descriptions: true | false /* Optional: This will summarize the descriptions of the entities and relationships, default: true */ + entity_types: + - list + - of + - entity + - types + - to + - extract + ``` + + ## Strategies + The entity extract verb uses a strategy to extract entities from a document. The strategy is a json object which defines the strategy to use. The following strategies are available: + + ### graph_intelligence + This strategy uses the [graph_intelligence] library to extract entities from a document. In particular it uses a LLM to extract entities from a piece of text. The strategy config is as follows: + + ```yml + strategy: + type: graph_intelligence + extraction_prompt: !include ./entity_extraction_prompt.txt # Optional, the prompt to use for extraction + completion_delimiter: "<|COMPLETE|>" # Optional, the delimiter to use for the LLM to mark completion + tuple_delimiter: "<|>" # Optional, the delimiter to use for the LLM to mark a tuple + record_delimiter: "##" # Optional, the delimiter to use for the LLM to mark a record + + prechunked: true | false # Optional, If the document is already chunked beforehand, otherwise this will chunk the document into smaller bits. default: false + encoding_name: cl100k_base # Optional, The encoding to use for the LLM, if not already prechunked, default: cl100k_base + chunk_size: 1000 # Optional ,The chunk size to use for the LLM, if not already prechunked, default: 1200 + chunk_overlap: 100 # Optional, The chunk overlap to use for the LLM, if not already prechunked, default: 100 + + llm: # The configuration for the LLM + type: openai # the type of llm to use, available options are: openai, azure, openai_chat, azure_openai_chat. The last two being chat based LLMs. + api_key: !ENV ${GRAPHRAG_OPENAI_API_KEY} # The api key to use for openai + model: !ENV ${GRAPHRAG_OPENAI_MODEL:gpt-4-turbo-preview} # The model to use for openai + max_tokens: !ENV ${GRAPHRAG_MAX_TOKENS:6000} # The max tokens to use for openai + organization: !ENV ${GRAPHRAG_OPENAI_ORGANIZATION} # The organization to use for openai + + # if using azure flavor + api_base: !ENV ${GRAPHRAG_OPENAI_API_BASE} # The api base to use for azure + api_version: !ENV ${GRAPHRAG_OPENAI_API_VERSION} # The api version to use for azure + proxy: !ENV ${GRAPHRAG_OPENAI_PROXY} # The proxy to use for azure + + ``` + + ### nltk + This strategy uses the [nltk] library to extract entities from a document. In particular it uses a nltk to extract entities from a piece of text. The strategy config is as follows: + ```yml + strategy: + type: nltk + ``` + """ + log.debug("entity_extract strategy=%s", strategy) + if entity_types is None: + entity_types = DEFAULT_ENTITY_TYPES + output = cast(pd.DataFrame, input.get_input()) + strategy = strategy or {} + strategy_exec = _load_strategy( + strategy.get("type", ExtractEntityStrategyType.graph_intelligence) + ) + strategy_config = {**strategy} + + num_started = 0 + + async def run_strategy(row): + nonlocal num_started + text = row[column] + id = row[id_column] + result = await strategy_exec( + [Document(text=text, id=id)], + entity_types, + callbacks, + cache, + strategy_config, + ) + num_started += 1 + return [result.entities, result.graphml_graph] + + results = await derive_from_rows( + output, + run_strategy, + callbacks, + scheduling_type=async_mode, + num_threads=kwargs.get("num_threads", 4), + ) + + to_result = [] + graph_to_result = [] + for result in results: + if result: + to_result.append(result[0]) + graph_to_result.append(result[1]) + else: + to_result.append(None) + graph_to_result.append(None) + + output[to] = to_result + if graph_to is not None: + output[graph_to] = graph_to_result + + return TableContainer(table=output.reset_index(drop=True)) + + +def _load_strategy(strategy_type: ExtractEntityStrategyType) -> EntityExtractStrategy: + """Load strategy method definition.""" + match strategy_type: + case ExtractEntityStrategyType.graph_intelligence: + from .strategies.graph_intelligence import run_gi + + return run_gi + + case ExtractEntityStrategyType.nltk: + bootstrap() + # dynamically import nltk strategy to avoid dependency if not used + from .strategies.nltk import run as run_nltk + + return run_nltk + case _: + msg = f"Unknown strategy: {strategy_type}" + raise ValueError(msg) diff --git a/graphrag/graphrag/index/verbs/entities/extraction/strategies/__init__.py b/graphrag/graphrag/index/verbs/entities/extraction/strategies/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f5cc17d750afe850d774c8a7e333343d49dbb733 --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/extraction/strategies/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine entities extraction strategies package root.""" diff --git a/graphrag/graphrag/index/verbs/entities/extraction/strategies/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/verbs/entities/extraction/strategies/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a743108a0e168c8f045ecd0a5a6a7a0686b4f24c Binary files /dev/null and b/graphrag/graphrag/index/verbs/entities/extraction/strategies/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/entities/extraction/strategies/__pycache__/typing.cpython-311.pyc b/graphrag/graphrag/index/verbs/entities/extraction/strategies/__pycache__/typing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..799d88f8142e6a0e3914d6555235eec92cf26d40 Binary files /dev/null and b/graphrag/graphrag/index/verbs/entities/extraction/strategies/__pycache__/typing.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/entities/extraction/strategies/graph_intelligence/__init__.py b/graphrag/graphrag/index/verbs/entities/extraction/strategies/graph_intelligence/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..083c0e4112e7ed6552c05bc9eda272649af3b77d --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/extraction/strategies/graph_intelligence/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph intelligence package root.""" + +from .run_graph_intelligence import run_gi + +__all__ = ["run_gi"] diff --git a/graphrag/graphrag/index/verbs/entities/extraction/strategies/graph_intelligence/defaults.py b/graphrag/graphrag/index/verbs/entities/extraction/strategies/graph_intelligence/defaults.py new file mode 100644 index 0000000000000000000000000000000000000000..237e6657c8842be15196a94c3ef6f225cb8902cc --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/extraction/strategies/graph_intelligence/defaults.py @@ -0,0 +1,25 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A file containing some default responses.""" + +from graphrag.config.enums import LLMType + +MOCK_LLM_RESPONSES = [ + """ + ("entity"<|>COMPANY_A<|>COMPANY<|>Company_A is a test company) + ## + ("entity"<|>COMPANY_B<|>COMPANY<|>Company_B owns Company_A and also shares an address with Company_A) + ## + ("entity"<|>PERSON_C<|>PERSON<|>Person_C is director of Company_A) + ## + ("relationship"<|>COMPANY_A<|>COMPANY_B<|>Company_A and Company_B are related because Company_A is 100% owned by Company_B and the two companies also share the same address)<|>2) + ## + ("relationship"<|>COMPANY_A<|>PERSON_C<|>Company_A and Person_C are related because Person_C is director of Company_A<|>1)) + """.strip() +] + +DEFAULT_LLM_CONFIG = { + "type": LLMType.StaticResponse, + "responses": MOCK_LLM_RESPONSES, +} diff --git a/graphrag/graphrag/index/verbs/entities/extraction/strategies/graph_intelligence/run_graph_intelligence.py b/graphrag/graphrag/index/verbs/entities/extraction/strategies/graph_intelligence/run_graph_intelligence.py new file mode 100644 index 0000000000000000000000000000000000000000..06284879835fa056c8519106688d0e3b6db2555d --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/extraction/strategies/graph_intelligence/run_graph_intelligence.py @@ -0,0 +1,142 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run_gi, run_extract_entities and _create_text_splitter methods to run graph intelligence.""" + +import networkx as nx +from datashaper import VerbCallbacks + +import graphrag.config.defaults as defs +from graphrag.config.enums import LLMType +from graphrag.index.cache import PipelineCache +from graphrag.index.graph.extractors.graph import GraphExtractor +from graphrag.index.llm import load_llm +from graphrag.index.text_splitting import ( + NoopTextSplitter, + TextSplitter, + TokenTextSplitter, +) +from graphrag.index.verbs.entities.extraction.strategies.typing import ( + Document, + EntityExtractionResult, + EntityTypes, + StrategyConfig, +) +from graphrag.llm import CompletionLLM + +from .defaults import DEFAULT_LLM_CONFIG + + +async def run_gi( + docs: list[Document], + entity_types: EntityTypes, + reporter: VerbCallbacks, + pipeline_cache: PipelineCache, + args: StrategyConfig, +) -> EntityExtractionResult: + """Run the graph intelligence entity extraction strategy.""" + llm_config = args.get("llm", DEFAULT_LLM_CONFIG) + llm_type = llm_config.get("type", LLMType.StaticResponse) + llm = load_llm("entity_extraction", llm_type, reporter, pipeline_cache, llm_config) + return await run_extract_entities(llm, docs, entity_types, reporter, args) + + +async def run_extract_entities( + llm: CompletionLLM, + docs: list[Document], + entity_types: EntityTypes, + reporter: VerbCallbacks | None, + args: StrategyConfig, +) -> EntityExtractionResult: + """Run the entity extraction chain.""" + encoding_name = args.get("encoding_name", "cl100k_base") + + # Chunking Arguments + prechunked = args.get("prechunked", False) + chunk_size = args.get("chunk_size", defs.CHUNK_SIZE) + chunk_overlap = args.get("chunk_overlap", defs.CHUNK_OVERLAP) + + # Extraction Arguments + tuple_delimiter = args.get("tuple_delimiter", None) + record_delimiter = args.get("record_delimiter", None) + completion_delimiter = args.get("completion_delimiter", None) + extraction_prompt = args.get("extraction_prompt", None) + encoding_model = args.get("encoding_name", None) + max_gleanings = args.get("max_gleanings", defs.ENTITY_EXTRACTION_MAX_GLEANINGS) + + # note: We're not using UnipartiteGraphChain.from_params + # because we want to pass "timeout" to the llm_kwargs + text_splitter = _create_text_splitter( + prechunked, chunk_size, chunk_overlap, encoding_name + ) + + extractor = GraphExtractor( + llm_invoker=llm, + prompt=extraction_prompt, + encoding_model=encoding_model, + max_gleanings=max_gleanings, + on_error=lambda e, s, d: ( + reporter.error("Entity Extraction Error", e, s, d) if reporter else None + ), + ) + text_list = [doc.text.strip() for doc in docs] + + # If it's not pre-chunked, then re-chunk the input + if not prechunked: + text_list = text_splitter.split_text("\n".join(text_list)) + + results = await extractor( + list(text_list), + { + "entity_types": entity_types, + "tuple_delimiter": tuple_delimiter, + "record_delimiter": record_delimiter, + "completion_delimiter": completion_delimiter, + }, + ) + + graph = results.output + # Map the "source_id" back to the "id" field + for _, node in graph.nodes(data=True): # type: ignore + if node is not None: + node["source_id"] = ",".join( + docs[int(id)].id for id in node["source_id"].split(",") + ) + + for _, _, edge in graph.edges(data=True): # type: ignore + if edge is not None: + edge["source_id"] = ",".join( + docs[int(id)].id for id in edge["source_id"].split(",") + ) + + entities = [ + ({"name": item[0], **(item[1] or {})}) + for item in graph.nodes(data=True) + if item is not None + ] + + graph_data = "".join(nx.generate_graphml(graph)) + return EntityExtractionResult(entities, graph_data) + + +def _create_text_splitter( + prechunked: bool, chunk_size: int, chunk_overlap: int, encoding_name: str +) -> TextSplitter: + """Create a text splitter for the extraction chain. + + Args: + - prechunked - Whether the text is already chunked + - chunk_size - The size of each chunk + - chunk_overlap - The overlap between chunks + - encoding_name - The name of the encoding to use + Returns: + - output - A text splitter + """ + if prechunked: + return NoopTextSplitter() + + return TokenTextSplitter( + chunk_size=chunk_size, + chunk_overlap=chunk_overlap, + encoding_name=encoding_name, + ) diff --git a/graphrag/graphrag/index/verbs/entities/extraction/strategies/nltk.py b/graphrag/graphrag/index/verbs/entities/extraction/strategies/nltk.py new file mode 100644 index 0000000000000000000000000000000000000000..48d4dae4ca28bcae70420aa66689b1a306cf37ba --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/extraction/strategies/nltk.py @@ -0,0 +1,61 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run method definition.""" + +import networkx as nx +import nltk +from datashaper import VerbCallbacks +from nltk.corpus import words + +from graphrag.index.cache import PipelineCache + +from .typing import Document, EntityExtractionResult, EntityTypes, StrategyConfig + +# Need to do this cause we're potentially multithreading, and nltk doesn't like that +words.ensure_loaded() + + +async def run( # noqa RUF029 async is required for interface + docs: list[Document], + entity_types: EntityTypes, + reporter: VerbCallbacks, # noqa ARG001 + pipeline_cache: PipelineCache, # noqa ARG001 + args: StrategyConfig, # noqa ARG001 +) -> EntityExtractionResult: + """Run method definition.""" + entity_map = {} + graph = nx.Graph() + for doc in docs: + connected_entities = [] + for chunk in nltk.ne_chunk(nltk.pos_tag(nltk.word_tokenize(doc.text))): + if hasattr(chunk, "label"): + entity_type = chunk.label().lower() + if entity_type in entity_types: + name = (" ".join(c[0] for c in chunk)).upper() + connected_entities.append(name) + if name not in entity_map: + entity_map[name] = entity_type + graph.add_node( + name, type=entity_type, description=name, source_id=doc.id + ) + + # connect the entities if they appear in the same document + if len(connected_entities) > 1: + for i in range(len(connected_entities)): + for j in range(i + 1, len(connected_entities)): + description = f"{connected_entities[i]} -> {connected_entities[j]}" + graph.add_edge( + connected_entities[i], + connected_entities[j], + description=description, + source_id=doc.id, + ) + + return EntityExtractionResult( + entities=[ + {"type": entity_type, "name": name} + for name, entity_type in entity_map.items() + ], + graphml_graph="".join(nx.generate_graphml(graph)), + ) diff --git a/graphrag/graphrag/index/verbs/entities/extraction/strategies/typing.py b/graphrag/graphrag/index/verbs/entities/extraction/strategies/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..45d3f1b80e47fc10a71573a5cc57bd35441f3137 --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/extraction/strategies/typing.py @@ -0,0 +1,44 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'Document' and 'EntityExtractionResult' models.""" + +from collections.abc import Awaitable, Callable +from dataclasses import dataclass +from typing import Any + +from datashaper import VerbCallbacks + +from graphrag.index.cache import PipelineCache + +ExtractedEntity = dict[str, Any] +StrategyConfig = dict[str, Any] +EntityTypes = list[str] + + +@dataclass +class Document: + """Document class definition.""" + + text: str + id: str + + +@dataclass +class EntityExtractionResult: + """Entity extraction result class definition.""" + + entities: list[ExtractedEntity] + graphml_graph: str | None + + +EntityExtractStrategy = Callable[ + [ + list[Document], + EntityTypes, + VerbCallbacks, + PipelineCache, + StrategyConfig, + ], + Awaitable[EntityExtractionResult], +] diff --git a/graphrag/graphrag/index/verbs/entities/summarize/__init__.py b/graphrag/graphrag/index/verbs/entities/summarize/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9ba401295ea155fd568e30f1bd7c11944966774a --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/summarize/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Root package for resolution entities.""" + +from .description_summarize import SummarizeStrategyType, summarize_descriptions + +__all__ = ["SummarizeStrategyType", "summarize_descriptions"] diff --git a/graphrag/graphrag/index/verbs/entities/summarize/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/verbs/entities/summarize/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2697f1d5c740e24f1381d4c8fc85e99bc9afa687 Binary files /dev/null and b/graphrag/graphrag/index/verbs/entities/summarize/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/entities/summarize/__pycache__/description_summarize.cpython-311.pyc b/graphrag/graphrag/index/verbs/entities/summarize/__pycache__/description_summarize.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e3ad0990a302ea11665942346904f18b4caa5325 Binary files /dev/null and b/graphrag/graphrag/index/verbs/entities/summarize/__pycache__/description_summarize.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/entities/summarize/description_summarize.py b/graphrag/graphrag/index/verbs/entities/summarize/description_summarize.py new file mode 100644 index 0000000000000000000000000000000000000000..5b7feb4184bbfcd87f863d5248d5a5dce05b1347 --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/summarize/description_summarize.py @@ -0,0 +1,207 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing the summarize_descriptions verb.""" + +import asyncio +import logging +from enum import Enum +from typing import Any, NamedTuple, cast + +import networkx as nx +import pandas as pd +from datashaper import ( + ProgressTicker, + TableContainer, + VerbCallbacks, + VerbInput, + progress_ticker, + verb, +) + +from graphrag.index.cache import PipelineCache +from graphrag.index.utils import load_graph + +from .strategies.typing import SummarizationStrategy + +log = logging.getLogger(__name__) + + +class DescriptionSummarizeRow(NamedTuple): + """DescriptionSummarizeRow class definition.""" + + graph: Any + + +class SummarizeStrategyType(str, Enum): + """SummarizeStrategyType class definition.""" + + graph_intelligence = "graph_intelligence" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +@verb(name="summarize_descriptions") +async def summarize_descriptions( + input: VerbInput, + cache: PipelineCache, + callbacks: VerbCallbacks, + column: str, + to: str, + strategy: dict[str, Any] | None = None, + **kwargs, +) -> TableContainer: + """ + Summarize entity and relationship descriptions from an entity graph. + + ## Usage + + To turn this feature ON please set the environment variable `GRAPHRAG_SUMMARIZE_DESCRIPTIONS_ENABLED=True`. + + ### json + + ```json + { + "verb": "", + "args": { + "column": "the_document_text_column_to_extract_descriptions_from", /* Required: This will be a graphml graph in string form which represents the entities and their relationships */ + "to": "the_column_to_output_the_summarized_descriptions_to", /* Required: This will be a graphml graph in string form which represents the entities and their relationships after being summarized */ + "strategy": {...} , see strategies section below + } + } + ``` + + ### yaml + + ```yaml + verb: entity_extract + args: + column: the_document_text_column_to_extract_descriptions_from + to: the_column_to_output_the_summarized_descriptions_to + strategy: , see strategies section below + ``` + + ## Strategies + + The summarize descriptions verb uses a strategy to summarize descriptions for entities. The strategy is a json object which defines the strategy to use. The following strategies are available: + + ### graph_intelligence + + This strategy uses the [graph_intelligence] library to summarize descriptions for entities. The strategy config is as follows: + + ```yml + strategy: + type: graph_intelligence + summarize_prompt: # Optional, the prompt to use for extraction + + + llm: # The configuration for the LLM + type: openai # the type of llm to use, available options are: openai, azure, openai_chat, azure_openai_chat. The last two being chat based LLMs. + api_key: !ENV ${GRAPHRAG_OPENAI_API_KEY} # The api key to use for openai + model: !ENV ${GRAPHRAG_OPENAI_MODEL:gpt-4-turbo-preview} # The model to use for openai + max_tokens: !ENV ${GRAPHRAG_MAX_TOKENS:6000} # The max tokens to use for openai + organization: !ENV ${GRAPHRAG_OPENAI_ORGANIZATION} # The organization to use for openai + + # if using azure flavor + api_base: !ENV ${GRAPHRAG_OPENAI_API_BASE} # The api base to use for azure + api_version: !ENV ${GRAPHRAG_OPENAI_API_VERSION} # The api version to use for azure + proxy: !ENV ${GRAPHRAG_OPENAI_PROXY} # The proxy to use for azure + ``` + """ + log.debug("summarize_descriptions strategy=%s", strategy) + output = cast(pd.DataFrame, input.get_input()) + strategy = strategy or {} + strategy_exec = load_strategy( + strategy.get("type", SummarizeStrategyType.graph_intelligence) + ) + strategy_config = {**strategy} + + async def get_resolved_entities(row, semaphore: asyncio.Semaphore): + graph: nx.Graph = load_graph(cast(str | nx.Graph, getattr(row, column))) + + ticker_length = len(graph.nodes) + len(graph.edges) + + ticker = progress_ticker(callbacks.progress, ticker_length) + + futures = [ + do_summarize_descriptions( + node, + sorted(set(graph.nodes[node].get("description", "").split("\n"))), + ticker, + semaphore, + ) + for node in graph.nodes() + ] + futures += [ + do_summarize_descriptions( + edge, + sorted(set(graph.edges[edge].get("description", "").split("\n"))), + ticker, + semaphore, + ) + for edge in graph.edges() + ] + + results = await asyncio.gather(*futures) + + for result in results: + graph_item = result.items + if isinstance(graph_item, str) and graph_item in graph.nodes(): + graph.nodes[graph_item]["description"] = result.description + elif isinstance(graph_item, tuple) and graph_item in graph.edges(): + graph.edges[graph_item]["description"] = result.description + + return DescriptionSummarizeRow( + graph="\n".join(nx.generate_graphml(graph)), + ) + + async def do_summarize_descriptions( + graph_item: str | tuple[str, str], + descriptions: list[str], + ticker: ProgressTicker, + semaphore: asyncio.Semaphore, + ): + async with semaphore: + results = await strategy_exec( + graph_item, + descriptions, + callbacks, + cache, + strategy_config, + ) + ticker(1) + return results + + # Graph is always on row 0, so here a derive from rows does not work + # This iteration will only happen once, but avoids hardcoding a iloc[0] + # Since parallelization is at graph level (nodes and edges), we can't use + # the parallelization of the derive_from_rows + semaphore = asyncio.Semaphore(kwargs.get("num_threads", 4)) + + results = [ + await get_resolved_entities(row, semaphore) for row in output.itertuples() + ] + + to_result = [] + + for result in results: + if result: + to_result.append(result.graph) + else: + to_result.append(None) + output[to] = to_result + return TableContainer(table=output) + + +def load_strategy(strategy_type: SummarizeStrategyType) -> SummarizationStrategy: + """Load strategy method definition.""" + match strategy_type: + case SummarizeStrategyType.graph_intelligence: + from .strategies.graph_intelligence import run as run_gi + + return run_gi + case _: + msg = f"Unknown strategy: {strategy_type}" + raise ValueError(msg) diff --git a/graphrag/graphrag/index/verbs/entities/summarize/strategies/__init__.py b/graphrag/graphrag/index/verbs/entities/summarize/strategies/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..28c398e6ac9aed603de1f8f455d987d82d8fe4a0 --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/summarize/strategies/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Indexing Engine - Summarization Strategies Package.""" + +from .typing import SummarizationStrategy + +__all__ = ["SummarizationStrategy"] diff --git a/graphrag/graphrag/index/verbs/entities/summarize/strategies/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/verbs/entities/summarize/strategies/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5063356755ef75ba933e081d7329dc3df4631cd7 Binary files /dev/null and b/graphrag/graphrag/index/verbs/entities/summarize/strategies/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/entities/summarize/strategies/__pycache__/typing.cpython-311.pyc b/graphrag/graphrag/index/verbs/entities/summarize/strategies/__pycache__/typing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6a981b30e99fbb10b73d619f83eff364a8443a82 Binary files /dev/null and b/graphrag/graphrag/index/verbs/entities/summarize/strategies/__pycache__/typing.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/entities/summarize/strategies/graph_intelligence/__init__.py b/graphrag/graphrag/index/verbs/entities/summarize/strategies/graph_intelligence/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..665600d0fb4ccefc77a50c9194f2b865fd424ae3 --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/summarize/strategies/graph_intelligence/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Entity Resolution graph intelligence package root.""" + +from .run_graph_intelligence import run + +__all__ = ["run"] diff --git a/graphrag/graphrag/index/verbs/entities/summarize/strategies/graph_intelligence/defaults.py b/graphrag/graphrag/index/verbs/entities/summarize/strategies/graph_intelligence/defaults.py new file mode 100644 index 0000000000000000000000000000000000000000..8ac42aa13d39875c14ed6b56c11890cd6f3e8f21 --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/summarize/strategies/graph_intelligence/defaults.py @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A file containing some default responses.""" + +from graphrag.config.enums import LLMType + +MOCK_LLM_RESPONSES = [ + """ + This is a MOCK response for the LLM. It is summarized! + """.strip() +] + +DEFAULT_LLM_CONFIG = { + "type": LLMType.StaticResponse, + "responses": MOCK_LLM_RESPONSES, +} diff --git a/graphrag/graphrag/index/verbs/entities/summarize/strategies/graph_intelligence/run_graph_intelligence.py b/graphrag/graphrag/index/verbs/entities/summarize/strategies/graph_intelligence/run_graph_intelligence.py new file mode 100644 index 0000000000000000000000000000000000000000..57a1ecd218c546594fc8eab8132411487610834a --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/summarize/strategies/graph_intelligence/run_graph_intelligence.py @@ -0,0 +1,70 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run_gi, run_resolve_entities and _create_text_list_splitter methods to run graph intelligence.""" + +from datashaper import VerbCallbacks + +from graphrag.config.enums import LLMType +from graphrag.index.cache import PipelineCache +from graphrag.index.graph.extractors.summarize import SummarizeExtractor +from graphrag.index.llm import load_llm +from graphrag.index.verbs.entities.summarize.strategies.typing import ( + StrategyConfig, + SummarizedDescriptionResult, +) +from graphrag.llm import CompletionLLM + +from .defaults import DEFAULT_LLM_CONFIG + + +async def run( + described_items: str | tuple[str, str], + descriptions: list[str], + reporter: VerbCallbacks, + pipeline_cache: PipelineCache, + args: StrategyConfig, +) -> SummarizedDescriptionResult: + """Run the graph intelligence entity extraction strategy.""" + llm_config = args.get("llm", DEFAULT_LLM_CONFIG) + llm_type = llm_config.get("type", LLMType.StaticResponse) + llm = load_llm( + "summarize_descriptions", llm_type, reporter, pipeline_cache, llm_config + ) + return await run_summarize_descriptions( + llm, described_items, descriptions, reporter, args + ) + + +async def run_summarize_descriptions( + llm: CompletionLLM, + items: str | tuple[str, str], + descriptions: list[str], + reporter: VerbCallbacks, + args: StrategyConfig, +) -> SummarizedDescriptionResult: + """Run the entity extraction chain.""" + # Extraction Arguments + summarize_prompt = args.get("summarize_prompt", None) + entity_name_key = args.get("entity_name_key", "entity_name") + input_descriptions_key = args.get("input_descriptions_key", "description_list") + max_tokens = args.get("max_tokens", None) + + extractor = SummarizeExtractor( + llm_invoker=llm, + summarization_prompt=summarize_prompt, + entity_name_key=entity_name_key, + input_descriptions_key=input_descriptions_key, + on_error=lambda e, stack, details: ( + reporter.error("Entity Extraction Error", e, stack, details) + if reporter + else None + ), + max_summary_length=args.get("max_summary_length", None), + max_input_tokens=max_tokens, + ) + + result = await extractor(items=items, descriptions=descriptions) + return SummarizedDescriptionResult( + items=result.items, description=result.description + ) diff --git a/graphrag/graphrag/index/verbs/entities/summarize/strategies/typing.py b/graphrag/graphrag/index/verbs/entities/summarize/strategies/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..e950cedc109891aba9acd5800780afea00177f77 --- /dev/null +++ b/graphrag/graphrag/index/verbs/entities/summarize/strategies/typing.py @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'ResolvedEntity' and 'EntityResolutionResult' models.""" + +from collections.abc import Awaitable, Callable +from dataclasses import dataclass +from typing import Any + +from datashaper import VerbCallbacks + +from graphrag.index.cache import PipelineCache + +StrategyConfig = dict[str, Any] + + +@dataclass +class SummarizedDescriptionResult: + """Entity summarization result class definition.""" + + items: str | tuple[str, str] + description: str + + +SummarizationStrategy = Callable[ + [ + str | tuple[str, str], + list[str], + VerbCallbacks, + PipelineCache, + StrategyConfig, + ], + Awaitable[SummarizedDescriptionResult], +] diff --git a/graphrag/graphrag/index/verbs/genid.py b/graphrag/graphrag/index/verbs/genid.py new file mode 100644 index 0000000000000000000000000000000000000000..019ffc2da04da9e4b36e64f13bba52f6cbd64552 --- /dev/null +++ b/graphrag/graphrag/index/verbs/genid.py @@ -0,0 +1,66 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing genid method definition.""" + +from typing import cast + +import pandas as pd +from datashaper import TableContainer, VerbInput, verb + +from graphrag.index.utils import gen_md5_hash + + +@verb(name="genid") +def genid( + input: VerbInput, + to: str, + method: str = "md5_hash", + hash: list[str] = [], # noqa A002 + **_kwargs: dict, +) -> TableContainer: + """ + Generate a unique id for each row in the tabular data. + + ## Usage + ### json + ```json + { + "verb": "genid", + "args": { + "to": "id_output_column_name", /* The name of the column to output the id to */ + "method": "md5_hash", /* The method to use to generate the id */ + "hash": ["list", "of", "column", "names"] /* only if using md5_hash */, + "seed": 034324 /* The random seed to use with UUID */ + } + } + ``` + + ### yaml + ```yaml + verb: genid + args: + to: id_output_column_name + method: md5_hash + hash: + - list + - of + - column + - names + seed: 034324 + ``` + """ + data = cast(pd.DataFrame, input.source.table) + + if method == "md5_hash": + if len(hash) == 0: + msg = 'Must specify the "hash" columns to use md5_hash method' + raise ValueError(msg) + + data[to] = data.apply(lambda row: gen_md5_hash(row, hash), axis=1) + elif method == "increment": + data[to] = data.index + 1 + else: + msg = f"Unknown method {method}" + raise ValueError(msg) + return TableContainer(table=data) diff --git a/graphrag/graphrag/index/verbs/graph/__init__.py b/graphrag/graphrag/index/verbs/graph/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5edbdbe5306a33c3b04b63528ee1adca04d51937 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/__init__.py @@ -0,0 +1,36 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph package root.""" + +from .clustering import cluster_graph +from .compute_edge_combined_degree import compute_edge_combined_degree +from .create import DEFAULT_EDGE_ATTRIBUTES, DEFAULT_NODE_ATTRIBUTES, create_graph +from .embed import embed_graph +from .layout import layout_graph +from .merge import merge_graphs +from .report import ( + create_community_reports, + prepare_community_reports, + prepare_community_reports_claims, + prepare_community_reports_edges, + restore_community_hierarchy, +) +from .unpack import unpack_graph + +__all__ = [ + "DEFAULT_EDGE_ATTRIBUTES", + "DEFAULT_NODE_ATTRIBUTES", + "cluster_graph", + "compute_edge_combined_degree", + "create_community_reports", + "create_graph", + "embed_graph", + "layout_graph", + "merge_graphs", + "prepare_community_reports", + "prepare_community_reports_claims", + "prepare_community_reports_edges", + "restore_community_hierarchy", + "unpack_graph", +] diff --git a/graphrag/graphrag/index/verbs/graph/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/verbs/graph/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..89dc85975dc1db0dbb5263299d51e1c0d95d94eb Binary files /dev/null and b/graphrag/graphrag/index/verbs/graph/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/graph/__pycache__/compute_edge_combined_degree.cpython-311.pyc b/graphrag/graphrag/index/verbs/graph/__pycache__/compute_edge_combined_degree.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9625b04709fe8770eaf233991cbe173787ffa9a6 Binary files /dev/null and b/graphrag/graphrag/index/verbs/graph/__pycache__/compute_edge_combined_degree.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/graph/__pycache__/create.cpython-311.pyc b/graphrag/graphrag/index/verbs/graph/__pycache__/create.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ce79a4687eb65b6332458cce6fdc244c9155c278 Binary files /dev/null and b/graphrag/graphrag/index/verbs/graph/__pycache__/create.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/graph/clustering/__init__.py b/graphrag/graphrag/index/verbs/graph/clustering/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a5db89bb7f039d27e015fbf46e692662b7d48b6e --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/clustering/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph clustering package root.""" + +from .cluster_graph import GraphCommunityStrategyType, cluster_graph + +__all__ = ["GraphCommunityStrategyType", "cluster_graph"] diff --git a/graphrag/graphrag/index/verbs/graph/clustering/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/verbs/graph/clustering/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..95c5dddda1a33bb1c2198470991f6bbda3c8911a Binary files /dev/null and b/graphrag/graphrag/index/verbs/graph/clustering/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/graph/clustering/__pycache__/cluster_graph.cpython-311.pyc b/graphrag/graphrag/index/verbs/graph/clustering/__pycache__/cluster_graph.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..caa7cd79bb9c7cac9820c86f585236846a64d183 Binary files /dev/null and b/graphrag/graphrag/index/verbs/graph/clustering/__pycache__/cluster_graph.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/graph/clustering/__pycache__/typing.cpython-311.pyc b/graphrag/graphrag/index/verbs/graph/clustering/__pycache__/typing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..19d3de45decc51a3b9ed0c5c71c0acc0f0c2cddc Binary files /dev/null and b/graphrag/graphrag/index/verbs/graph/clustering/__pycache__/typing.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/graph/clustering/cluster_graph.py b/graphrag/graphrag/index/verbs/graph/clustering/cluster_graph.py new file mode 100644 index 0000000000000000000000000000000000000000..418ad87c937b65bbab862acc3c3aa5e5e8d8c1ca --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/clustering/cluster_graph.py @@ -0,0 +1,173 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing cluster_graph, apply_clustering and run_layout methods definition.""" + +import logging +from enum import Enum +from random import Random +from typing import Any, cast + +import networkx as nx +import pandas as pd +from datashaper import TableContainer, VerbCallbacks, VerbInput, progress_iterable, verb + +from graphrag.index.utils import gen_uuid, load_graph + +from .typing import Communities + +log = logging.getLogger(__name__) + + +@verb(name="cluster_graph") +def cluster_graph( + input: VerbInput, + callbacks: VerbCallbacks, + strategy: dict[str, Any], + column: str, + to: str, + level_to: str | None = None, + **_kwargs, +) -> TableContainer: + """ + Apply a hierarchical clustering algorithm to a graph. The graph is expected to be in graphml format. The verb outputs a new column containing the clustered graph, and a new column containing the level of the graph. + + ## Usage + ```yaml + verb: cluster_graph + args: + column: entity_graph # The name of the column containing the graph, should be a graphml graph + to: clustered_graph # The name of the column to output the clustered graph to + level_to: level # The name of the column to output the level to + strategy: # See strategies section below + ``` + + ## Strategies + The cluster graph verb uses a strategy to cluster the graph. The strategy is a json object which defines the strategy to use. The following strategies are available: + + ### leiden + This strategy uses the leiden algorithm to cluster a graph. The strategy config is as follows: + ```yaml + strategy: + type: leiden + max_cluster_size: 10 # Optional, The max cluster size to use, default: 10 + use_lcc: true # Optional, if the largest connected component should be used with the leiden algorithm, default: true + seed: 0xDEADBEEF # Optional, the seed to use for the leiden algorithm, default: 0xDEADBEEF + levels: [0, 1] # Optional, the levels to output, default: all the levels detected + + ``` + """ + output_df = cast(pd.DataFrame, input.get_input()) + results = output_df[column].apply(lambda graph: run_layout(strategy, graph)) + + community_map_to = "communities" + output_df[community_map_to] = results + + level_to = level_to or f"{to}_level" + output_df[level_to] = output_df.apply( + lambda x: list({level for level, _, _ in x[community_map_to]}), axis=1 + ) + output_df[to] = [None] * len(output_df) + + num_total = len(output_df) + + # Go through each of the rows + graph_level_pairs_column: list[list[tuple[int, str]]] = [] + for _, row in progress_iterable( + output_df.iterrows(), callbacks.progress, num_total + ): + levels = row[level_to] + graph_level_pairs: list[tuple[int, str]] = [] + + # For each of the levels, get the graph and add it to the list + for level in levels: + graph = "\n".join( + nx.generate_graphml( + apply_clustering( + cast(str, row[column]), + cast(Communities, row[community_map_to]), + level, + ) + ) + ) + graph_level_pairs.append((level, graph)) + graph_level_pairs_column.append(graph_level_pairs) + output_df[to] = graph_level_pairs_column + + # explode the list of (level, graph) pairs into separate rows + output_df = output_df.explode(to, ignore_index=True) + + # split the (level, graph) pairs into separate columns + output_df[[level_to, to]] = pd.DataFrame(output_df[to].tolist(), index=output_df.index, columns=[level_to, to]) + + # clean up the community map + output_df.drop(columns=[community_map_to], inplace=True) + + return TableContainer(table=output_df) + + +# TODO: This should support str | nx.Graph as a graphml param +def apply_clustering( + graphml: str, communities: Communities, level=0, seed=0xF001 +) -> nx.Graph: + """Apply clustering to a graphml string.""" + random = Random(seed) # noqa S311 + graph = nx.parse_graphml(graphml) + for community_level, community_id, nodes in communities: + if level == community_level: + for node in nodes: + graph.nodes[node]["cluster"] = community_id + graph.nodes[node]["level"] = level + + # add node degree + for node_degree in graph.degree: + graph.nodes[str(node_degree[0])]["degree"] = int(node_degree[1]) + + # add node uuid and incremental record id (a human readable id used as reference in the final report) + for index, node in enumerate(graph.nodes()): + graph.nodes[node]["human_readable_id"] = index + graph.nodes[node]["id"] = str(gen_uuid(random)) + + # add ids to edges + for index, edge in enumerate(graph.edges()): + graph.edges[edge]["id"] = str(gen_uuid(random)) + graph.edges[edge]["human_readable_id"] = index + graph.edges[edge]["level"] = level + return graph + + +class GraphCommunityStrategyType(str, Enum): + """GraphCommunityStrategyType class definition.""" + + leiden = "leiden" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +def run_layout( + strategy: dict[str, Any], graphml_or_graph: str | nx.Graph +) -> Communities: + """Run layout method definition.""" + graph = load_graph(graphml_or_graph) + if len(graph.nodes) == 0: + log.warning("Graph has no nodes") + return [] + + clusters: dict[int, dict[str, list[str]]] = {} + strategy_type = strategy.get("type", GraphCommunityStrategyType.leiden) + match strategy_type: + case GraphCommunityStrategyType.leiden: + from .strategies.leiden import run as run_leiden + + clusters = run_leiden(graph, strategy) + case _: + msg = f"Unknown clustering strategy {strategy_type}" + raise ValueError(msg) + + results: Communities = [] + for level in clusters: + for cluster_id, nodes in clusters[level].items(): + results.append((level, cluster_id, nodes)) + return results diff --git a/graphrag/graphrag/index/verbs/graph/clustering/strategies/__init__.py b/graphrag/graphrag/index/verbs/graph/clustering/strategies/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..16a03f12d676fbbda16a26645a0bcf26050b1c5b --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/clustering/strategies/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Graph Clustering Strategies.""" diff --git a/graphrag/graphrag/index/verbs/graph/clustering/strategies/leiden.py b/graphrag/graphrag/index/verbs/graph/clustering/strategies/leiden.py new file mode 100644 index 0000000000000000000000000000000000000000..ffc36880411a686a8bd973728f27efa4bb2bf09f --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/clustering/strategies/leiden.py @@ -0,0 +1,69 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run and _compute_leiden_communities methods definitions.""" + +import logging +from typing import Any + +import networkx as nx +from graspologic.partition import hierarchical_leiden + +from graphrag.index.graph.utils import stable_largest_connected_component + +log = logging.getLogger(__name__) + + +def run(graph: nx.Graph, args: dict[str, Any]) -> dict[int, dict[str, list[str]]]: + """Run method definition.""" + max_cluster_size = args.get("max_cluster_size", 10) + use_lcc = args.get("use_lcc", True) + if args.get("verbose", False): + log.info( + "Running leiden with max_cluster_size=%s, lcc=%s", max_cluster_size, use_lcc + ) + + node_id_to_community_map = _compute_leiden_communities( + graph=graph, + max_cluster_size=max_cluster_size, + use_lcc=use_lcc, + seed=args.get("seed", 0xDEADBEEF), + ) + levels = args.get("levels") + + # If they don't pass in levels, use them all + if levels is None: + levels = sorted(node_id_to_community_map.keys()) + + results_by_level: dict[int, dict[str, list[str]]] = {} + for level in levels: + result = {} + results_by_level[level] = result + for node_id, raw_community_id in node_id_to_community_map[level].items(): + community_id = str(raw_community_id) + if community_id not in result: + result[community_id] = [] + result[community_id].append(node_id) + return results_by_level + + +# Taken from graph_intelligence & adapted +def _compute_leiden_communities( + graph: nx.Graph | nx.DiGraph, + max_cluster_size: int, + use_lcc: bool, + seed=0xDEADBEEF, +) -> dict[int, dict[str, int]]: + """Return Leiden root communities.""" + if use_lcc: + graph = stable_largest_connected_component(graph) + + community_mapping = hierarchical_leiden( + graph, max_cluster_size=max_cluster_size, random_seed=seed + ) + results: dict[int, dict[str, int]] = {} + for partition in community_mapping: + results[partition.level] = results.get(partition.level, {}) + results[partition.level][partition.node] = partition.cluster + + return results diff --git a/graphrag/graphrag/index/verbs/graph/clustering/typing.py b/graphrag/graphrag/index/verbs/graph/clustering/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..4d6fc7e60115a840114c91f72be439c18f0c24de --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/clustering/typing.py @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing Communities list definition.""" + +Communities = list[tuple[int, str, list[str]]] diff --git a/graphrag/graphrag/index/verbs/graph/compute_edge_combined_degree.py b/graphrag/graphrag/index/verbs/graph/compute_edge_combined_degree.py new file mode 100644 index 0000000000000000000000000000000000000000..1f2dd71972f74cba0a9d254f42e23c4c6aa1b085 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/compute_edge_combined_degree.py @@ -0,0 +1,70 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing create_graph, _get_node_attributes, _get_edge_attributes and _get_attribute_column_mapping methods definition.""" + +from typing import cast + +import pandas as pd +from datashaper import TableContainer, VerbInput, verb + +from graphrag.index.utils.ds_util import get_required_input_table + + +@verb(name="compute_edge_combined_degree") +def compute_edge_combined_degree( + input: VerbInput, + to: str = "rank", + node_name_column: str = "title", + node_degree_column: str = "degree", + edge_source_column: str = "source", + edge_target_column: str = "target", + **_kwargs, +) -> TableContainer: + """ + Compute the combined degree for each edge in a graph. + + Inputs Tables: + - input: The edge table + - nodes: The nodes table. + + Args: + - to: The name of the column to output the combined degree to. Default="rank" + """ + edge_df: pd.DataFrame = cast(pd.DataFrame, input.get_input()) + if to in edge_df.columns: + return TableContainer(table=edge_df) + node_degree_df = _get_node_degree_table(input, node_name_column, node_degree_column) + + def join_to_degree(df: pd.DataFrame, column: str) -> pd.DataFrame: + degree_column = _degree_colname(column) + result = df.merge( + node_degree_df.rename( + columns={node_name_column: column, node_degree_column: degree_column} + ), + on=column, + how="left", + ) + result[degree_column] = result[degree_column].fillna(0) + return result + + edge_df = join_to_degree(edge_df, edge_source_column) + edge_df = join_to_degree(edge_df, edge_target_column) + edge_df[to] = ( + edge_df[_degree_colname(edge_source_column)] + + edge_df[_degree_colname(edge_target_column)] + ) + + return TableContainer(table=edge_df) + + +def _degree_colname(column: str) -> str: + return f"{column}_degree" + + +def _get_node_degree_table( + input: VerbInput, node_name_column: str, node_degree_column: str +) -> pd.DataFrame: + nodes_container = get_required_input_table(input, "nodes") + nodes = cast(pd.DataFrame, nodes_container.table) + return cast(pd.DataFrame, nodes[[node_name_column, node_degree_column]]) diff --git a/graphrag/graphrag/index/verbs/graph/create.py b/graphrag/graphrag/index/verbs/graph/create.py new file mode 100644 index 0000000000000000000000000000000000000000..eaf06284ef53187a8ba0ad4f4ab273c0686eae95 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/create.py @@ -0,0 +1,135 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing create_graph, _get_node_attributes, _get_edge_attributes and _get_attribute_column_mapping methods definition.""" + +from typing import Any + +import networkx as nx +import pandas as pd +from datashaper import TableContainer, VerbCallbacks, VerbInput, progress_iterable, verb + +from graphrag.index.utils import clean_str + +DEFAULT_NODE_ATTRIBUTES = ["label", "type", "id", "name", "description", "community"] +DEFAULT_EDGE_ATTRIBUTES = ["label", "type", "name", "source", "target"] + + +@verb(name="create_graph") +def create_graph( + input: VerbInput, + callbacks: VerbCallbacks, + to: str, + type: str, # noqa A002 + graph_type: str = "undirected", + **kwargs, +) -> TableContainer: + """ + Create a graph from a dataframe. The verb outputs a new column containing the graph. + + > Note: This will roll up all rows into a single graph. + + ## Usage + ```yaml + verb: create_graph + args: + type: node # The type of graph to create, one of: node, edge + to: # The name of the column to output the graph to, this will be a graphml graph + attributes: # The attributes for the nodes / edges + # If using the node type, the following attributes are required: + id: + + # If using the edge type, the following attributes are required: + source: + target: + + # Other attributes can be added as follows: + : + ... for each attribute + ``` + """ + if type != "node" and type != "edge": + msg = f"Unknown type {type}" + raise ValueError(msg) + + input_df = input.get_input() + num_total = len(input_df) + out_graph: nx.Graph = _create_nx_graph(graph_type) + + in_attributes = ( + _get_node_attributes(kwargs) if type == "node" else _get_edge_attributes(kwargs) + ) + + # At this point, _get_node_attributes and _get_edge_attributes have already validated + id_col = in_attributes.get( + "id", in_attributes.get("label", in_attributes.get("name", None)) + ) + source_col = in_attributes.get("source", None) + target_col = in_attributes.get("target", None) + + for _, row in progress_iterable(input_df.iterrows(), callbacks.progress, num_total): + item_attributes = { + clean_str(key): _clean_value(row[value]) + for key, value in in_attributes.items() + if value in row + } + if type == "node": + id = clean_str(row[id_col]) + out_graph.add_node(id, **item_attributes) + elif type == "edge": + source = clean_str(row[source_col]) + target = clean_str(row[target_col]) + out_graph.add_edge(source, target, **item_attributes) + + graphml_string = "".join(nx.generate_graphml(out_graph)) + output_df = pd.DataFrame([{to: graphml_string}]) + return TableContainer(table=output_df) + + +def _clean_value(value: Any) -> str: + if value is None: + return "" + if isinstance(value, str): + return clean_str(value) + + msg = f"Value must be a string or None, got {type(value)}" + raise TypeError(msg) + + +def _get_node_attributes(args: dict[str, Any]) -> dict[str, Any]: + mapping = _get_attribute_column_mapping( + args.get("attributes", DEFAULT_NODE_ATTRIBUTES) + ) + if "id" not in mapping and "label" not in mapping and "name" not in mapping: + msg = "You must specify an id, label, or name column in the node attributes" + raise ValueError(msg) + return mapping + + +def _get_edge_attributes(args: dict[str, Any]) -> dict[str, Any]: + mapping = _get_attribute_column_mapping( + args.get("attributes", DEFAULT_EDGE_ATTRIBUTES) + ) + if "source" not in mapping or "target" not in mapping: + msg = "You must specify a source and target column in the edge attributes" + raise ValueError(msg) + return mapping + + +def _get_attribute_column_mapping( + in_attributes: dict[str, Any] | list[str], +) -> dict[str, str]: + # Its already a attribute: column dict + if isinstance(in_attributes, dict): + return { + **in_attributes, + } + + return {attrib: attrib for attrib in in_attributes} + + +def _create_nx_graph(graph_type: str) -> nx.Graph: + if graph_type == "directed": + return nx.DiGraph() + + return nx.Graph() diff --git a/graphrag/graphrag/index/verbs/graph/embed/__init__.py b/graphrag/graphrag/index/verbs/graph/embed/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4ca8168c3c706cef211600723b01f680915ea359 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/embed/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph embed package root.""" + +from .embed_graph import EmbedGraphStrategyType, embed_graph + +__all__ = ["EmbedGraphStrategyType", "embed_graph"] diff --git a/graphrag/graphrag/index/verbs/graph/embed/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/verbs/graph/embed/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e952f5b07b456d2ce3df8441e66e4615b52ab126 Binary files /dev/null and b/graphrag/graphrag/index/verbs/graph/embed/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/graph/embed/__pycache__/embed_graph.cpython-311.pyc b/graphrag/graphrag/index/verbs/graph/embed/__pycache__/embed_graph.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f4be8a414673cf227cbedd128224893ef646cea9 Binary files /dev/null and b/graphrag/graphrag/index/verbs/graph/embed/__pycache__/embed_graph.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/graph/embed/__pycache__/typing.cpython-311.pyc b/graphrag/graphrag/index/verbs/graph/embed/__pycache__/typing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9167dca71d1081dd42e2f8cfa5b1652eb3144bc Binary files /dev/null and b/graphrag/graphrag/index/verbs/graph/embed/__pycache__/typing.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/graph/embed/embed_graph.py b/graphrag/graphrag/index/verbs/graph/embed/embed_graph.py new file mode 100644 index 0000000000000000000000000000000000000000..8691d343f07f0dec749f21770b3c0e4c9e131dae --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/embed/embed_graph.py @@ -0,0 +1,98 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing embed_graph and run_embeddings methods definition.""" + +from enum import Enum +from typing import Any, cast + +import networkx as nx +import pandas as pd +from datashaper import TableContainer, VerbCallbacks, VerbInput, derive_from_rows, verb + +from graphrag.index.utils import load_graph + +from .typing import NodeEmbeddings + + +class EmbedGraphStrategyType(str, Enum): + """EmbedGraphStrategyType class definition.""" + + node2vec = "node2vec" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +@verb(name="embed_graph") +async def embed_graph( + input: VerbInput, + callbacks: VerbCallbacks, + strategy: dict[str, Any], + column: str, + to: str, + **kwargs, +) -> TableContainer: + """ + Embed a graph into a vector space. The graph is expected to be in graphml format. The verb outputs a new column containing a mapping between node_id and vector. + + ## Usage + ```yaml + verb: embed_graph + args: + column: clustered_graph # The name of the column containing the graph, should be a graphml graph + to: embeddings # The name of the column to output the embeddings to + strategy: # See strategies section below + ``` + + ## Strategies + The embed_graph verb uses a strategy to embed the graph. The strategy is an object which defines the strategy to use. The following strategies are available: + + ### node2vec + This strategy uses the node2vec algorithm to embed a graph. The strategy config is as follows: + + ```yaml + strategy: + type: node2vec + dimensions: 1536 # Optional, The number of dimensions to use for the embedding, default: 1536 + num_walks: 10 # Optional, The number of walks to use for the embedding, default: 10 + walk_length: 40 # Optional, The walk length to use for the embedding, default: 40 + window_size: 2 # Optional, The window size to use for the embedding, default: 2 + iterations: 3 # Optional, The number of iterations to use for the embedding, default: 3 + random_seed: 86 # Optional, The random seed to use for the embedding, default: 86 + ``` + """ + output_df = cast(pd.DataFrame, input.get_input()) + + strategy_type = strategy.get("type", EmbedGraphStrategyType.node2vec) + strategy_args = {**strategy} + + async def run_strategy(row): # noqa RUF029 async is required for interface + return run_embeddings(strategy_type, cast(Any, row[column]), strategy_args) + + results = await derive_from_rows( + output_df, + run_strategy, + callbacks=callbacks, + num_threads=kwargs.get("num_threads", None), + ) + output_df[to] = list(results) + return TableContainer(table=output_df) + + +def run_embeddings( + strategy: EmbedGraphStrategyType, + graphml_or_graph: str | nx.Graph, + args: dict[str, Any], +) -> NodeEmbeddings: + """Run embeddings method definition.""" + graph = load_graph(graphml_or_graph) + match strategy: + case EmbedGraphStrategyType.node2vec: + from .strategies.node_2_vec import run as run_node_2_vec + + return run_node_2_vec(graph, args) + case _: + msg = f"Unknown strategy {strategy}" + raise ValueError(msg) diff --git a/graphrag/graphrag/index/verbs/graph/embed/strategies/__init__.py b/graphrag/graphrag/index/verbs/graph/embed/strategies/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ef85198eb703a17c281912ff4a069510d8a9f2df --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/embed/strategies/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Text Embedding strategies.""" diff --git a/graphrag/graphrag/index/verbs/graph/embed/strategies/node_2_vec.py b/graphrag/graphrag/index/verbs/graph/embed/strategies/node_2_vec.py new file mode 100644 index 0000000000000000000000000000000000000000..eb329519ed9f15759d1bcecc10a051a7353a2f05 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/embed/strategies/node_2_vec.py @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run method definition.""" + +from typing import Any + +import networkx as nx + +from graphrag.index.graph.embedding import embed_nod2vec +from graphrag.index.graph.utils import stable_largest_connected_component +from graphrag.index.verbs.graph.embed.typing import NodeEmbeddings + + +def run(graph: nx.Graph, args: dict[str, Any]) -> NodeEmbeddings: + """Run method definition.""" + if args.get("use_lcc", True): + graph = stable_largest_connected_component(graph) + + # create graph embedding using node2vec + embeddings = embed_nod2vec( + graph=graph, + dimensions=args.get("dimensions", 1536), + num_walks=args.get("num_walks", 10), + walk_length=args.get("walk_length", 40), + window_size=args.get("window_size", 2), + iterations=args.get("iterations", 3), + random_seed=args.get("random_seed", 86), + ) + + pairs = zip(embeddings.nodes, embeddings.embeddings.tolist(), strict=True) + sorted_pairs = sorted(pairs, key=lambda x: x[0]) + + return dict(sorted_pairs) diff --git a/graphrag/graphrag/index/verbs/graph/embed/typing.py b/graphrag/graphrag/index/verbs/graph/embed/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..fea792c9b1dd294bc886abe2f60efcaa4d3dbdbb --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/embed/typing.py @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing different lists and dictionaries.""" + +# Use this for now instead of a wrapper +from typing import Any + +NodeList = list[str] +EmbeddingList = list[Any] +NodeEmbeddings = dict[str, list[float]] +"""Label -> Embedding""" diff --git a/graphrag/graphrag/index/verbs/graph/layout/__init__.py b/graphrag/graphrag/index/verbs/graph/layout/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..74584f83eda106396817c75e5516aa155ce4e1d7 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/layout/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph layout package root.""" + +from .layout_graph import layout_graph + +__all__ = ["layout_graph"] diff --git a/graphrag/graphrag/index/verbs/graph/layout/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/verbs/graph/layout/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..502abaac78d67d5fb92ade803f3ef3da8d145b28 Binary files /dev/null and b/graphrag/graphrag/index/verbs/graph/layout/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/graph/layout/__pycache__/layout_graph.cpython-311.pyc b/graphrag/graphrag/index/verbs/graph/layout/__pycache__/layout_graph.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..949c22b2b886ec63d18c9ff6677eeb6801a870be Binary files /dev/null and b/graphrag/graphrag/index/verbs/graph/layout/__pycache__/layout_graph.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/verbs/graph/layout/layout_graph.py b/graphrag/graphrag/index/verbs/graph/layout/layout_graph.py new file mode 100644 index 0000000000000000000000000000000000000000..e1b55b1183f5718a0d63ef52a07b86771976c34d --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/layout/layout_graph.py @@ -0,0 +1,139 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing layout_graph, _run_layout and _apply_layout_to_graph methods definition.""" + +from enum import Enum +from typing import Any, cast + +import networkx as nx +import pandas as pd +from datashaper import TableContainer, VerbCallbacks, VerbInput, progress_callback, verb + +from graphrag.index.graph.visualization import GraphLayout +from graphrag.index.utils import load_graph +from graphrag.index.verbs.graph.embed.typing import NodeEmbeddings + + +class LayoutGraphStrategyType(str, Enum): + """LayoutGraphStrategyType class definition.""" + + umap = "umap" + zero = "zero" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +@verb(name="layout_graph") +def layout_graph( + input: VerbInput, + callbacks: VerbCallbacks, + strategy: dict[str, Any], + embeddings_column: str, + graph_column: str, + to: str, + graph_to: str | None = None, + **_kwargs: dict, +) -> TableContainer: + """ + Apply a layout algorithm to a graph. The graph is expected to be in graphml format. The verb outputs a new column containing the laid out graph. + + ## Usage + ```yaml + verb: layout_graph + args: + graph_column: clustered_graph # The name of the column containing the graph, should be a graphml graph + embeddings_column: embeddings # The name of the column containing the embeddings + to: node_positions # The name of the column to output the node positions to + graph_to: positioned_graph # The name of the column to output the positioned graph to + strategy: # See strategies section below + ``` + + ## Strategies + The layout graph verb uses a strategy to layout the graph. The strategy is a json object which defines the strategy to use. The following strategies are available: + + ### umap + This strategy uses the umap algorithm to layout a graph. The strategy config is as follows: + ```yaml + strategy: + type: umap + n_neighbors: 5 # Optional, The number of neighbors to use for the umap algorithm, default: 5 + min_dist: 0.75 # Optional, The min distance to use for the umap algorithm, default: 0.75 + ``` + """ + output_df = cast(pd.DataFrame, input.get_input()) + + num_items = len(output_df) + strategy_type = strategy.get("type", LayoutGraphStrategyType.umap) + strategy_args = {**strategy} + + has_embeddings = embeddings_column in output_df.columns + + layouts = output_df.apply( + progress_callback( + lambda row: _run_layout( + strategy_type, + row[graph_column], + row[embeddings_column] if has_embeddings else {}, + strategy_args, + callbacks, + ), + callbacks.progress, + num_items, + ), + axis=1, + ) + output_df[to] = layouts.apply(lambda layout: [pos.to_pandas() for pos in layout]) + if graph_to is not None: + output_df[graph_to] = output_df.apply( + lambda row: _apply_layout_to_graph( + row[graph_column], cast(GraphLayout, layouts[row.name]) + ), + axis=1, + ) + return TableContainer(table=output_df) + + +def _run_layout( + strategy: LayoutGraphStrategyType, + graphml_or_graph: str | nx.Graph, + embeddings: NodeEmbeddings, + args: dict[str, Any], + reporter: VerbCallbacks, +) -> GraphLayout: + graph = load_graph(graphml_or_graph) + match strategy: + case LayoutGraphStrategyType.umap: + from .methods.umap import run as run_umap + + return run_umap( + graph, + embeddings, + args, + lambda e, stack, d: reporter.error("Error in Umap", e, stack, d), + ) + case LayoutGraphStrategyType.zero: + from .methods.zero import run as run_zero + + return run_zero( + graph, + args, + lambda e, stack, d: reporter.error("Error in Zero", e, stack, d), + ) + case _: + msg = f"Unknown strategy {strategy}" + raise ValueError(msg) + + +def _apply_layout_to_graph( + graphml_or_graph: str | nx.Graph, layout: GraphLayout +) -> str: + graph = load_graph(graphml_or_graph) + for node_position in layout: + if node_position.label in graph.nodes: + graph.nodes[node_position.label]["x"] = node_position.x + graph.nodes[node_position.label]["y"] = node_position.y + graph.nodes[node_position.label]["size"] = node_position.size + return "\n".join(nx.generate_graphml(graph)) diff --git a/graphrag/graphrag/index/verbs/graph/layout/methods/__init__.py b/graphrag/graphrag/index/verbs/graph/layout/methods/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5d5054122b71941f650a935b9e4f34a94056228d --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/layout/methods/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Graph Layout Methods.""" diff --git a/graphrag/graphrag/index/verbs/graph/layout/methods/umap.py b/graphrag/graphrag/index/verbs/graph/layout/methods/umap.py new file mode 100644 index 0000000000000000000000000000000000000000..a4bc7c2818561c16d0b92c6356b6fae79b16d0a7 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/layout/methods/umap.py @@ -0,0 +1,82 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run and _create_node_position methods definitions.""" + +import logging +import traceback +from typing import Any + +import networkx as nx +import numpy as np + +from graphrag.index.graph.visualization import ( + GraphLayout, + NodePosition, + compute_umap_positions, +) +from graphrag.index.typing import ErrorHandlerFn +from graphrag.index.verbs.graph.embed.typing import NodeEmbeddings + +# TODO: This could be handled more elegantly, like what columns to use +# for "size" or "cluster" +# We could also have a boolean to indicate to use node sizes or clusters + +log = logging.getLogger(__name__) + + +def run( + graph: nx.Graph, + embeddings: NodeEmbeddings, + args: dict[str, Any], + on_error: ErrorHandlerFn, +) -> GraphLayout: + """Run method definition.""" + node_clusters = [] + node_sizes = [] + + embeddings = _filter_raw_embeddings(embeddings) + nodes = list(embeddings.keys()) + embedding_vectors = [embeddings[node_id] for node_id in nodes] + + for node_id in nodes: + node = graph.nodes[node_id] + cluster = node.get("cluster", node.get("community", -1)) + node_clusters.append(cluster) + size = node.get("degree", node.get("size", 0)) + node_sizes.append(size) + + additional_args = {} + if len(node_clusters) > 0: + additional_args["node_categories"] = node_clusters + if len(node_sizes) > 0: + additional_args["node_sizes"] = node_sizes + + try: + return compute_umap_positions( + embedding_vectors=np.array(embedding_vectors), + node_labels=nodes, + **additional_args, + min_dist=args.get("min_dist", 0.75), + n_neighbors=args.get("n_neighbors", 5), + ) + except Exception as e: + log.exception("Error running UMAP") + on_error(e, traceback.format_exc(), None) + # Umap may fail due to input sparseness or memory pressure. + # For now, in these cases, we'll just return a layout with all nodes at (0, 0) + result = [] + for i in range(len(nodes)): + cluster = node_clusters[i] if len(node_clusters) > 0 else 1 + result.append( + NodePosition(x=0, y=0, label=nodes[i], size=0, cluster=str(cluster)) + ) + return result + + +def _filter_raw_embeddings(embeddings: NodeEmbeddings) -> NodeEmbeddings: + return { + node_id: embedding + for node_id, embedding in embeddings.items() + if embedding is not None + } diff --git a/graphrag/graphrag/index/verbs/graph/layout/methods/zero.py b/graphrag/graphrag/index/verbs/graph/layout/methods/zero.py new file mode 100644 index 0000000000000000000000000000000000000000..f41d2d4ca4bb7df98291c568b7c3bd009ec51a86 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/layout/methods/zero.py @@ -0,0 +1,63 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run and _create_node_position methods definitions.""" + +import logging +import traceback +from typing import Any + +import networkx as nx + +from graphrag.index.graph.visualization import ( + GraphLayout, + NodePosition, + get_zero_positions, +) +from graphrag.index.typing import ErrorHandlerFn + +# TODO: This could be handled more elegantly, like what columns to use +# for "size" or "cluster" +# We could also have a boolean to indicate to use node sizes or clusters + +log = logging.getLogger(__name__) + + +def run( + graph: nx.Graph, + _args: dict[str, Any], + on_error: ErrorHandlerFn, +) -> GraphLayout: + """Run method definition.""" + node_clusters = [] + node_sizes = [] + + nodes = list(graph.nodes) + + for node_id in nodes: + node = graph.nodes[node_id] + cluster = node.get("cluster", node.get("community", -1)) + node_clusters.append(cluster) + size = node.get("degree", node.get("size", 0)) + node_sizes.append(size) + + additional_args = {} + if len(node_clusters) > 0: + additional_args["node_categories"] = node_clusters + if len(node_sizes) > 0: + additional_args["node_sizes"] = node_sizes + + try: + return get_zero_positions(node_labels=nodes, **additional_args) + except Exception as e: + log.exception("Error running zero-position") + on_error(e, traceback.format_exc(), None) + # Umap may fail due to input sparseness or memory pressure. + # For now, in these cases, we'll just return a layout with all nodes at (0, 0) + result = [] + for i in range(len(nodes)): + cluster = node_clusters[i] if len(node_clusters) > 0 else 1 + result.append( + NodePosition(x=0, y=0, label=nodes[i], size=0, cluster=str(cluster)) + ) + return result diff --git a/graphrag/graphrag/index/verbs/graph/merge/__init__.py b/graphrag/graphrag/index/verbs/graph/merge/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f718827942b36bb63b01d497076bc2fb589c1b37 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/merge/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph merge package root.""" + +from .merge_graphs import merge_graphs + +__all__ = ["merge_graphs"] diff --git a/graphrag/graphrag/index/verbs/graph/merge/defaults.py b/graphrag/graphrag/index/verbs/graph/merge/defaults.py new file mode 100644 index 0000000000000000000000000000000000000000..80c60331c6681f747a927b96ffba8457879c216a --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/merge/defaults.py @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A file containing DEFAULT_NODE_OPERATIONS, DEFAULT_EDGE_OPERATIONS and DEFAULT_CONCAT_SEPARATOR values definition.""" + +from .typing import BasicMergeOperation + +DEFAULT_NODE_OPERATIONS = { + "*": { + "operation": BasicMergeOperation.Replace, + } +} + +DEFAULT_EDGE_OPERATIONS = { + "*": { + "operation": BasicMergeOperation.Replace, + }, + "weight": "sum", +} + +DEFAULT_CONCAT_SEPARATOR = "," diff --git a/graphrag/graphrag/index/verbs/graph/merge/merge_graphs.py b/graphrag/graphrag/index/verbs/graph/merge/merge_graphs.py new file mode 100644 index 0000000000000000000000000000000000000000..8ab3fa47f70af74493ff49e100b8fc150adddcef --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/merge/merge_graphs.py @@ -0,0 +1,217 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing merge_graphs, merge_nodes, merge_edges, merge_attributes, apply_merge_operation and _get_detailed_attribute_merge_operation methods definitions.""" + +from typing import Any, cast + +import networkx as nx +import pandas as pd +from datashaper import TableContainer, VerbCallbacks, VerbInput, progress_iterable, verb + +from graphrag.index.utils import load_graph + +from .defaults import ( + DEFAULT_CONCAT_SEPARATOR, + DEFAULT_EDGE_OPERATIONS, + DEFAULT_NODE_OPERATIONS, +) +from .typing import ( + BasicMergeOperation, + DetailedAttributeMergeOperation, + NumericOperation, + StringOperation, +) + + +@verb(name="merge_graphs") +def merge_graphs( + input: VerbInput, + callbacks: VerbCallbacks, + column: str, + to: str, + nodes: dict[str, Any] = DEFAULT_NODE_OPERATIONS, + edges: dict[str, Any] = DEFAULT_EDGE_OPERATIONS, + **_kwargs, +) -> TableContainer: + """ + Merge multiple graphs together. The graphs are expected to be in graphml format. The verb outputs a new column containing the merged graph. + + > Note: This will merge all rows into a single graph. + + ## Usage + ```yaml + verb: merge_graph + args: + column: clustered_graph # The name of the column containing the graph, should be a graphml graph + to: merged_graph # The name of the column to output the merged graph to + nodes: # See node operations section below + edges: # See edge operations section below + ``` + + ## Node Operations + The merge graph verb can perform operations on the nodes of the graph. + + ### Usage + ```yaml + nodes: + : + ... for each attribute or use the special value "*" for all attributes + ``` + + ## Edge Operations + The merge graph verb can perform operations on the nodes of the graph. + + ### Usage + ```yaml + edges: + : + ... for each attribute or use the special value "*" for all attributes + ``` + + ## Operations + The merge graph verb can perform operations on the nodes and edges of the graph. The following operations are available: + + - __replace__: This operation replaces the attribute with the last value seen. + - __skip__: This operation skips the attribute, and just uses the first value seen. + - __concat__: This operation concatenates the attribute with the last value seen. + - __sum__: This operation sums the attribute with the last value seen. + - __max__: This operation takes the max of the attribute with the last value seen. + max + - __min__: This operation takes the min of the attribute with the last value seen. + - __average__: This operation takes the mean of the attribute with the last value seen. + - __multiply__: This operation multiplies the attribute with the last value seen. + """ + input_df = input.get_input() + output = pd.DataFrame() + + node_ops = { + attrib: _get_detailed_attribute_merge_operation(value) + for attrib, value in nodes.items() + } + edge_ops = { + attrib: _get_detailed_attribute_merge_operation(value) + for attrib, value in edges.items() + } + + mega_graph = nx.Graph() + num_total = len(input_df) + for graphml in progress_iterable(input_df[column], callbacks.progress, num_total): + graph = load_graph(cast(str | nx.Graph, graphml)) + merge_nodes(mega_graph, graph, node_ops) + merge_edges(mega_graph, graph, edge_ops) + + output[to] = ["\n".join(nx.generate_graphml(mega_graph))] + + return TableContainer(table=output) + + +def merge_nodes( + target: nx.Graph, + subgraph: nx.Graph, + node_ops: dict[str, DetailedAttributeMergeOperation], +): + """Merge nodes from subgraph into target using the operations defined in node_ops.""" + for node in subgraph.nodes: + if node not in target.nodes: + target.add_node(node, **(subgraph.nodes[node] or {})) + else: + merge_attributes(target.nodes[node], subgraph.nodes[node], node_ops) + + +def merge_edges( + target_graph: nx.Graph, + subgraph: nx.Graph, + edge_ops: dict[str, DetailedAttributeMergeOperation], +): + """Merge edges from subgraph into target using the operations defined in edge_ops.""" + for source, target, edge_data in subgraph.edges(data=True): # type: ignore + if not target_graph.has_edge(source, target): + target_graph.add_edge(source, target, **(edge_data or {})) + else: + merge_attributes(target_graph.edges[(source, target)], edge_data, edge_ops) + + +def merge_attributes( + target_item: dict[str, Any] | None, + source_item: dict[str, Any] | None, + ops: dict[str, DetailedAttributeMergeOperation], +): + """Merge attributes from source_item into target_item using the operations defined in ops.""" + source_item = source_item or {} + target_item = target_item or {} + for op_attrib, op in ops.items(): + if op_attrib == "*": + for attrib in source_item: + # If there is a specific handler for this attribute, use it + # i.e. * provides a default, but you can override it + if attrib not in ops: + apply_merge_operation(target_item, source_item, attrib, op) + else: + if op_attrib in source_item or op_attrib in target_item: + apply_merge_operation(target_item, source_item, op_attrib, op) + + +def apply_merge_operation( + target_item: dict[str, Any] | None, + source_item: dict[str, Any] | None, + attrib: str, + op: DetailedAttributeMergeOperation, +): + """Apply the merge operation to the attribute.""" + source_item = source_item or {} + target_item = target_item or {} + + if ( + op.operation == BasicMergeOperation.Replace + or op.operation == StringOperation.Replace + ): + target_item[attrib] = source_item.get(attrib, None) or "" + elif ( + op.operation == BasicMergeOperation.Skip or op.operation == StringOperation.Skip + ): + target_item[attrib] = target_item.get(attrib, None) or "" + elif op.operation == StringOperation.Concat: + separator = op.separator or DEFAULT_CONCAT_SEPARATOR + target_attrib = target_item.get(attrib, "") or "" + source_attrib = source_item.get(attrib, "") or "" + target_item[attrib] = f"{target_attrib}{separator}{source_attrib}" + if op.distinct: + # TODO: Slow + target_item[attrib] = separator.join( + sorted(set(target_item[attrib].split(separator))) + ) + + # We're assuming that the attribute is numeric + elif op.operation == NumericOperation.Sum: + target_item[attrib] = (target_item.get(attrib, 0) or 0) + ( + source_item.get(attrib, 0) or 0 + ) + elif op.operation == NumericOperation.Average: + target_item[attrib] = ( + (target_item.get(attrib, 0) or 0) + (source_item.get(attrib, 0) or 0) + ) / 2 + elif op.operation == NumericOperation.Max: + target_item[attrib] = max( + (target_item.get(attrib, 0) or 0), (source_item.get(attrib, 0) or 0) + ) + elif op.operation == NumericOperation.Min: + target_item[attrib] = min( + (target_item.get(attrib, 0) or 0), (source_item.get(attrib, 0) or 0) + ) + elif op.operation == NumericOperation.Multiply: + target_item[attrib] = (target_item.get(attrib, 1) or 1) * ( + source_item.get(attrib, 1) or 1 + ) + else: + msg = f"Invalid operation {op.operation}" + raise ValueError(msg) + + +def _get_detailed_attribute_merge_operation( + value: str | dict[str, Any], +) -> DetailedAttributeMergeOperation: + """Normalize the AttributeMergeOperation into a DetailedAttributeMergeOperation.""" + if isinstance(value, str): + return DetailedAttributeMergeOperation(operation=value) + return DetailedAttributeMergeOperation(**value) diff --git a/graphrag/graphrag/index/verbs/graph/merge/typing.py b/graphrag/graphrag/index/verbs/graph/merge/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..0e534f516c580f17e6eede592f4d38173de3b960 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/merge/typing.py @@ -0,0 +1,49 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'BasicMergeOperation', 'StringOperation', 'NumericOperation' and 'DetailedAttributeMergeOperation' models.""" + +from dataclasses import dataclass +from enum import Enum + + +class BasicMergeOperation(str, Enum): + """Basic Merge Operation class definition.""" + + Replace = "replace" + Skip = "skip" + + +class StringOperation(str, Enum): + """String Operation class definition.""" + + Concat = "concat" + Replace = "replace" + Skip = "skip" + + +class NumericOperation(str, Enum): + """Numeric Operation class definition.""" + + Sum = "sum" + Average = "average" + Max = "max" + Min = "min" + Multiply = "multiply" + Replace = "replace" + Skip = "skip" + + +@dataclass +class DetailedAttributeMergeOperation: + """Detailed attribute merge operation class definition.""" + + operation: str # StringOperation | NumericOperation + + # concat + separator: str | None = None + delimiter: str | None = None + distinct: bool = False + + +AttributeMergeOperation = str | DetailedAttributeMergeOperation diff --git a/graphrag/graphrag/index/verbs/graph/report/__init__.py b/graphrag/graphrag/index/verbs/graph/report/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e47d9ccef5fa3f34b00efa477dcbcfbd51b3911a --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/report/__init__.py @@ -0,0 +1,25 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph report package root.""" + +from .create_community_reports import ( + CreateCommunityReportsStrategyType, + create_community_reports, +) +from .prepare_community_reports import prepare_community_reports +from .prepare_community_reports_claims import prepare_community_reports_claims +from .prepare_community_reports_edges import prepare_community_reports_edges +from .prepare_community_reports_nodes import prepare_community_reports_nodes +from .restore_community_hierarchy import restore_community_hierarchy + +__all__ = [ + "CreateCommunityReportsStrategyType", + "create_community_reports", + "create_community_reports", + "prepare_community_reports", + "prepare_community_reports_claims", + "prepare_community_reports_edges", + "prepare_community_reports_nodes", + "restore_community_hierarchy", +] diff --git a/graphrag/graphrag/index/verbs/graph/report/create_community_reports.py b/graphrag/graphrag/index/verbs/graph/report/create_community_reports.py new file mode 100644 index 0000000000000000000000000000000000000000..c67d5107e8fe3f8d1d5575152b306d933d0c9922 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/report/create_community_reports.py @@ -0,0 +1,131 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing create_community_reports and load_strategy methods definition.""" + +import logging +from enum import Enum +from typing import cast + +import pandas as pd +from datashaper import ( + AsyncType, + NoopVerbCallbacks, + TableContainer, + VerbCallbacks, + VerbInput, + derive_from_rows, + progress_ticker, + verb, +) + +import graphrag.config.defaults as defaults +import graphrag.index.graph.extractors.community_reports.schemas as schemas +from graphrag.index.cache import PipelineCache +from graphrag.index.graph.extractors.community_reports import ( + get_levels, + prep_community_report_context, +) +from graphrag.index.utils.ds_util import get_required_input_table + +from .strategies.typing import CommunityReport, CommunityReportsStrategy + +log = logging.getLogger(__name__) + + +class CreateCommunityReportsStrategyType(str, Enum): + """CreateCommunityReportsStrategyType class definition.""" + + graph_intelligence = "graph_intelligence" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +@verb(name="create_community_reports") +async def create_community_reports( + input: VerbInput, + callbacks: VerbCallbacks, + cache: PipelineCache, + strategy: dict, + async_mode: AsyncType = AsyncType.AsyncIO, + num_threads: int = 4, + **_kwargs, +) -> TableContainer: + """Generate entities for each row, and optionally a graph of those entities.""" + log.debug("create_community_reports strategy=%s", strategy) + local_contexts = cast(pd.DataFrame, input.get_input()) + nodes_ctr = get_required_input_table(input, "nodes") + nodes = cast(pd.DataFrame, nodes_ctr.table) + community_hierarchy_ctr = get_required_input_table(input, "community_hierarchy") + community_hierarchy = cast(pd.DataFrame, community_hierarchy_ctr.table) + + levels = get_levels(nodes) + reports: list[CommunityReport | None] = [] + tick = progress_ticker(callbacks.progress, len(local_contexts)) + runner = load_strategy(strategy["type"]) + + for level in levels: + level_contexts = prep_community_report_context( + pd.DataFrame(reports), + local_context_df=local_contexts, + community_hierarchy_df=community_hierarchy, + level=level, + max_tokens=strategy.get( + "max_input_tokens", defaults.COMMUNITY_REPORT_MAX_INPUT_LENGTH + ), + ) + + async def run_generate(record): + result = await _generate_report( + runner, + community_id=record[schemas.NODE_COMMUNITY], + community_level=record[schemas.COMMUNITY_LEVEL], + community_context=record[schemas.CONTEXT_STRING], + cache=cache, + callbacks=callbacks, + strategy=strategy, + ) + tick() + return result + + local_reports = await derive_from_rows( + level_contexts, + run_generate, + callbacks=NoopVerbCallbacks(), + num_threads=num_threads, + scheduling_type=async_mode, + ) + reports.extend([lr for lr in local_reports if lr is not None]) + + return TableContainer(table=pd.DataFrame(reports)) + + +async def _generate_report( + runner: CommunityReportsStrategy, + cache: PipelineCache, + callbacks: VerbCallbacks, + strategy: dict, + community_id: int | str, + community_level: int, + community_context: str, +) -> CommunityReport | None: + """Generate a report for a single community.""" + return await runner( + community_id, community_context, community_level, callbacks, cache, strategy + ) + + +def load_strategy( + strategy: CreateCommunityReportsStrategyType, +) -> CommunityReportsStrategy: + """Load strategy method definition.""" + match strategy: + case CreateCommunityReportsStrategyType.graph_intelligence: + from .strategies.graph_intelligence import run + + return run + case _: + msg = f"Unknown strategy: {strategy}" + raise ValueError(msg) diff --git a/graphrag/graphrag/index/verbs/graph/report/prepare_community_reports.py b/graphrag/graphrag/index/verbs/graph/report/prepare_community_reports.py new file mode 100644 index 0000000000000000000000000000000000000000..3c9ebd451adbd816848e4ee8d730e5469b6ed476 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/report/prepare_community_reports.py @@ -0,0 +1,187 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing create_community_reports and load_strategy methods definition.""" + +import logging +from typing import cast + +import pandas as pd +from datashaper import ( + TableContainer, + VerbCallbacks, + VerbInput, + progress_iterable, + verb, +) + +import graphrag.index.graph.extractors.community_reports.schemas as schemas +from graphrag.index.graph.extractors.community_reports import ( + filter_claims_to_nodes, + filter_edges_to_nodes, + filter_nodes_to_level, + get_levels, + set_context_exceeds_flag, + set_context_size, + sort_context, +) +from graphrag.index.utils.ds_util import get_named_input_table, get_required_input_table + +log = logging.getLogger(__name__) + + +@verb(name="prepare_community_reports") +def prepare_community_reports( + input: VerbInput, + callbacks: VerbCallbacks, + max_tokens: int = 16_000, + **_kwargs, +) -> TableContainer: + """Generate entities for each row, and optionally a graph of those entities.""" + # Prepare Community Reports + node_df = cast(pd.DataFrame, get_required_input_table(input, "nodes").table) + edge_df = cast(pd.DataFrame, get_required_input_table(input, "edges").table) + claim_df = get_named_input_table(input, "claims") + if claim_df is not None: + claim_df = cast(pd.DataFrame, claim_df.table) + + levels = get_levels(node_df, schemas.NODE_LEVEL) + dfs = [] + + for level in progress_iterable(levels, callbacks.progress, len(levels)): + communities_at_level_df = _prepare_reports_at_level( + node_df, edge_df, claim_df, level, max_tokens + ) + dfs.append(communities_at_level_df) + + # build initial local context for all communities + return TableContainer(table=pd.concat(dfs)) + + +def _prepare_reports_at_level( + node_df: pd.DataFrame, + edge_df: pd.DataFrame, + claim_df: pd.DataFrame | None, + level: int, + max_tokens: int = 16_000, + community_id_column: str = schemas.COMMUNITY_ID, + node_id_column: str = schemas.NODE_ID, + node_name_column: str = schemas.NODE_NAME, + node_details_column: str = schemas.NODE_DETAILS, + node_level_column: str = schemas.NODE_LEVEL, + node_degree_column: str = schemas.NODE_DEGREE, + node_community_column: str = schemas.NODE_COMMUNITY, + edge_id_column: str = schemas.EDGE_ID, + edge_source_column: str = schemas.EDGE_SOURCE, + edge_target_column: str = schemas.EDGE_TARGET, + edge_degree_column: str = schemas.EDGE_DEGREE, + edge_details_column: str = schemas.EDGE_DETAILS, + claim_id_column: str = schemas.CLAIM_ID, + claim_subject_column: str = schemas.CLAIM_SUBJECT, + claim_details_column: str = schemas.CLAIM_DETAILS, +): + def get_edge_details(node_df: pd.DataFrame, edge_df: pd.DataFrame, name_col: str): + return node_df.merge( + cast( + pd.DataFrame, + edge_df[[name_col, schemas.EDGE_DETAILS]], + ).rename(columns={name_col: schemas.NODE_NAME}), + on=schemas.NODE_NAME, + how="left", + ) + + level_node_df = filter_nodes_to_level(node_df, level) + log.info("Number of nodes at level=%s => %s", level, len(level_node_df)) + nodes = level_node_df[node_name_column].tolist() + + # Filter edges & claims to those containing the target nodes + level_edge_df = filter_edges_to_nodes(edge_df, nodes) + level_claim_df = ( + filter_claims_to_nodes(claim_df, nodes) if claim_df is not None else None + ) + + # concat all edge details per node + merged_node_df = pd.concat( + [ + get_edge_details(level_node_df, level_edge_df, edge_source_column), + get_edge_details(level_node_df, level_edge_df, edge_target_column), + ], + axis=0, + ) + merged_node_df = ( + merged_node_df.groupby([ + node_name_column, + node_community_column, + node_degree_column, + node_level_column, + ]) + .agg({node_details_column: "first", edge_details_column: list}) + .reset_index() + ) + + # concat claim details per node + if level_claim_df is not None: + merged_node_df = merged_node_df.merge( + cast( + pd.DataFrame, + level_claim_df[[claim_subject_column, claim_details_column]], + ).rename(columns={claim_subject_column: node_name_column}), + on=node_name_column, + how="left", + ) + merged_node_df = ( + merged_node_df.groupby([ + node_name_column, + node_community_column, + node_level_column, + node_degree_column, + ]) + .agg({ + node_details_column: "first", + edge_details_column: "first", + **({claim_details_column: list} if level_claim_df is not None else {}), + }) + .reset_index() + ) + + # concat all node details, including name, degree, node_details, edge_details, and claim_details + merged_node_df[schemas.ALL_CONTEXT] = merged_node_df.apply( + lambda x: { + node_name_column: x[node_name_column], + node_degree_column: x[node_degree_column], + node_details_column: x[node_details_column], + edge_details_column: x[edge_details_column], + claim_details_column: x[claim_details_column] + if level_claim_df is not None + else [], + }, + axis=1, + ) + + # group all node details by community + community_df = ( + merged_node_df.groupby(node_community_column) + .agg({schemas.ALL_CONTEXT: list}) + .reset_index() + ) + community_df[schemas.CONTEXT_STRING] = community_df[schemas.ALL_CONTEXT].apply( + lambda x: sort_context( + x, + node_id_column=node_id_column, + node_name_column=node_name_column, + node_details_column=node_details_column, + edge_id_column=edge_id_column, + edge_details_column=edge_details_column, + edge_degree_column=edge_degree_column, + edge_source_column=edge_source_column, + edge_target_column=edge_target_column, + claim_id_column=claim_id_column, + claim_details_column=claim_details_column, + community_id_column=community_id_column, + ) + ) + set_context_size(community_df) + set_context_exceeds_flag(community_df, max_tokens) + + community_df[schemas.COMMUNITY_LEVEL] = level + return community_df diff --git a/graphrag/graphrag/index/verbs/graph/report/prepare_community_reports_claims.py b/graphrag/graphrag/index/verbs/graph/report/prepare_community_reports_claims.py new file mode 100644 index 0000000000000000000000000000000000000000..aa9a790772d5517611a8f7541894c9cd5bc8408b --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/report/prepare_community_reports_claims.py @@ -0,0 +1,50 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing create_graph, _get_node_attributes, _get_edge_attributes and _get_attribute_column_mapping methods definition.""" + +from typing import cast + +import pandas as pd +from datashaper import TableContainer, VerbInput, verb + +from graphrag.index.graph.extractors.community_reports.schemas import ( + CLAIM_DESCRIPTION, + CLAIM_DETAILS, + CLAIM_ID, + CLAIM_STATUS, + CLAIM_SUBJECT, + CLAIM_TYPE, +) + +_MISSING_DESCRIPTION = "No Description" + + +@verb(name="prepare_community_reports_claims") +def prepare_community_reports_claims( + input: VerbInput, + to: str = CLAIM_DETAILS, + id_column: str = CLAIM_ID, + description_column: str = CLAIM_DESCRIPTION, + subject_column: str = CLAIM_SUBJECT, + type_column: str = CLAIM_TYPE, + status_column: str = CLAIM_STATUS, + **_kwargs, +) -> TableContainer: + """Merge claim details into an object.""" + claim_df: pd.DataFrame = cast(pd.DataFrame, input.get_input()) + claim_df = claim_df.fillna(value={description_column: _MISSING_DESCRIPTION}) + + # merge values of five columns into a map column + claim_df[to] = claim_df.apply( + lambda x: { + id_column: x[id_column], + subject_column: x[subject_column], + type_column: x[type_column], + status_column: x[status_column], + description_column: x[description_column], + }, + axis=1, + ) + + return TableContainer(table=claim_df) diff --git a/graphrag/graphrag/index/verbs/graph/report/prepare_community_reports_edges.py b/graphrag/graphrag/index/verbs/graph/report/prepare_community_reports_edges.py new file mode 100644 index 0000000000000000000000000000000000000000..b568aba00666ce7d43f93dc93fd1a23a5daf76ea --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/report/prepare_community_reports_edges.py @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing create_graph, _get_node_attributes, _get_edge_attributes and _get_attribute_column_mapping methods definition.""" + +from typing import cast + +import pandas as pd +from datashaper import TableContainer, VerbInput, verb + +from graphrag.index.graph.extractors.community_reports.schemas import ( + EDGE_DEGREE, + EDGE_DESCRIPTION, + EDGE_DETAILS, + EDGE_ID, + EDGE_SOURCE, + EDGE_TARGET, +) + +_MISSING_DESCRIPTION = "No Description" + + +@verb(name="prepare_community_reports_edges") +def prepare_community_reports_edges( + input: VerbInput, + to: str = EDGE_DETAILS, + id_column: str = EDGE_ID, + source_column: str = EDGE_SOURCE, + target_column: str = EDGE_TARGET, + description_column: str = EDGE_DESCRIPTION, + degree_column: str = EDGE_DEGREE, + **_kwargs, +) -> TableContainer: + """Merge edge details into an object.""" + edge_df: pd.DataFrame = cast(pd.DataFrame, input.get_input()).fillna( + value={description_column: _MISSING_DESCRIPTION} + ) + edge_df[to] = edge_df.apply( + lambda x: { + id_column: x[id_column], + source_column: x[source_column], + target_column: x[target_column], + description_column: x[description_column], + degree_column: x[degree_column], + }, + axis=1, + ) + return TableContainer(table=edge_df) diff --git a/graphrag/graphrag/index/verbs/graph/report/prepare_community_reports_nodes.py b/graphrag/graphrag/index/verbs/graph/report/prepare_community_reports_nodes.py new file mode 100644 index 0000000000000000000000000000000000000000..f159c125eee75f06dff0dc0e7e957b06f14143e1 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/report/prepare_community_reports_nodes.py @@ -0,0 +1,46 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing create_graph, _get_node_attributes, _get_edge_attributes and _get_attribute_column_mapping methods definition.""" + +from typing import cast + +import pandas as pd +from datashaper import TableContainer, VerbInput, verb + +from graphrag.index.graph.extractors.community_reports.schemas import ( + NODE_DEGREE, + NODE_DESCRIPTION, + NODE_DETAILS, + NODE_ID, + NODE_NAME, +) + +_MISSING_DESCRIPTION = "No Description" + + +@verb(name="prepare_community_reports_nodes") +def prepare_community_reports_nodes( + input: VerbInput, + to: str = NODE_DETAILS, + id_column: str = NODE_ID, + name_column: str = NODE_NAME, + description_column: str = NODE_DESCRIPTION, + degree_column: str = NODE_DEGREE, + **_kwargs, +) -> TableContainer: + """Merge edge details into an object.""" + node_df = cast(pd.DataFrame, input.get_input()) + node_df = node_df.fillna(value={description_column: _MISSING_DESCRIPTION}) + + # merge values of four columns into a map column + node_df[to] = node_df.apply( + lambda x: { + id_column: x[id_column], + name_column: x[name_column], + description_column: x[description_column], + degree_column: x[degree_column], + }, + axis=1, + ) + return TableContainer(table=node_df) diff --git a/graphrag/graphrag/index/verbs/graph/report/restore_community_hierarchy.py b/graphrag/graphrag/index/verbs/graph/report/restore_community_hierarchy.py new file mode 100644 index 0000000000000000000000000000000000000000..437369f0e527dfea834263e43be3dd98e9647fc5 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/report/restore_community_hierarchy.py @@ -0,0 +1,78 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing create_graph, _get_node_attributes, _get_edge_attributes and _get_attribute_column_mapping methods definition.""" + +import logging +from typing import cast + +import pandas as pd +from datashaper import TableContainer, VerbInput, verb + +import graphrag.index.graph.extractors.community_reports.schemas as schemas + +log = logging.getLogger(__name__) + + +@verb(name="restore_community_hierarchy") +def restore_community_hierarchy( + input: VerbInput, + name_column: str = schemas.NODE_NAME, + community_column: str = schemas.NODE_COMMUNITY, + level_column: str = schemas.NODE_LEVEL, + **_kwargs, +) -> TableContainer: + """Restore the community hierarchy from the node data.""" + node_df: pd.DataFrame = cast(pd.DataFrame, input.get_input()) + community_df = ( + node_df.groupby([community_column, level_column]) + .agg({name_column: list}) + .reset_index() + ) + community_levels = {} + for _, row in community_df.iterrows(): + level = row[level_column] + name = row[name_column] + community = row[community_column] + + if community_levels.get(level) is None: + community_levels[level] = {} + community_levels[level][community] = name + + # get unique levels, sorted in ascending order + levels = sorted(community_levels.keys()) + + community_hierarchy = [] + + for idx in range(len(levels) - 1): + level = levels[idx] + log.debug("Level: %s", level) + next_level = levels[idx + 1] + current_level_communities = community_levels[level] + next_level_communities = community_levels[next_level] + log.debug( + "Number of communities at level %s: %s", + level, + len(current_level_communities), + ) + + for current_community in current_level_communities: + current_entities = current_level_communities[current_community] + + # loop through next level's communities to find all the subcommunities + entities_found = 0 + for next_level_community in next_level_communities: + next_entities = next_level_communities[next_level_community] + if set(next_entities).issubset(set(current_entities)): + community_hierarchy.append({ + community_column: current_community, + schemas.COMMUNITY_LEVEL: level, + schemas.SUB_COMMUNITY: next_level_community, + schemas.SUB_COMMUNITY_SIZE: len(next_entities), + }) + + entities_found += len(next_entities) + if entities_found == len(current_entities): + break + + return TableContainer(table=pd.DataFrame(community_hierarchy)) diff --git a/graphrag/graphrag/index/verbs/graph/report/strategies/__init__.py b/graphrag/graphrag/index/verbs/graph/report/strategies/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..87d1f9e252a3061151890f52f35c30120aaa2784 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/report/strategies/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph report strategies package root.""" diff --git a/graphrag/graphrag/index/verbs/graph/report/strategies/graph_intelligence/__init__.py b/graphrag/graphrag/index/verbs/graph/report/strategies/graph_intelligence/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7f51d7909ba383c11bdeed5c65e1b13af942cbf2 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/report/strategies/graph_intelligence/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine graph report strategies graph intelligence package root.""" + +from .run_graph_intelligence import run + +__all__ = ["run"] diff --git a/graphrag/graphrag/index/verbs/graph/report/strategies/graph_intelligence/defaults.py b/graphrag/graphrag/index/verbs/graph/report/strategies/graph_intelligence/defaults.py new file mode 100644 index 0000000000000000000000000000000000000000..708d48d2b62a7af5168931c1dfcb8aac58f92721 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/report/strategies/graph_intelligence/defaults.py @@ -0,0 +1,26 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A file containing DEFAULT_CHUNK_SIZE and MOCK_RESPONSES definitions.""" + +import json + +DEFAULT_CHUNK_SIZE = 3000 +MOCK_RESPONSES = [ + json.dumps({ + "title": "", + "summary": "", + "rating": 2, + "rating_explanation": "", + "findings": [ + { + "summary": "", + "explanation": "", + "explanation": " CommunityReport | None: + """Run the graph intelligence entity extraction strategy.""" + llm_config = args.get( + "llm", {"type": LLMType.StaticResponse, "responses": MOCK_RESPONSES} + ) + llm_type = llm_config.get("type", LLMType.StaticResponse) + llm = load_llm( + "community_reporting", llm_type, reporter, pipeline_cache, llm_config + ) + return await _run_extractor(llm, community, input, level, args, reporter) + + +async def _run_extractor( + llm: CompletionLLM, + community: str | int, + input: str, + level: int, + args: StrategyConfig, + reporter: VerbCallbacks, +) -> CommunityReport | None: + # RateLimiter + rate_limiter = RateLimiter(rate=1, per=60) + extractor = CommunityReportsExtractor( + llm, + extraction_prompt=args.get("extraction_prompt", None), + max_report_length=args.get("max_report_length", None), + on_error=lambda e, stack, _data: reporter.error( + "Community Report Extraction Error", e, stack + ), + ) + + try: + await rate_limiter.acquire() + results = await extractor({"input_text": input}) + report = results.structured_output + if report is None or len(report.keys()) == 0: + log.warning("No report found for community: %s", community) + return None + + return CommunityReport( + community=community, + full_content=results.output, + level=level, + rank=_parse_rank(report), + title=report.get("title", f"Community Report: {community}"), + rank_explanation=report.get("rating_explanation", ""), + summary=report.get("summary", ""), + findings=report.get("findings", []), + full_content_json=json.dumps(report, indent=4), + ) + except Exception as e: + log.exception("Error processing community: %s", community) + reporter.error("Community Report Extraction Error", e, traceback.format_exc()) + return None + + +def _parse_rank(report: dict) -> float: + rank = report.get("rating", -1) + try: + return float(rank) + except ValueError: + log.exception("Error parsing rank: %s defaulting to -1", rank) + return -1 diff --git a/graphrag/graphrag/index/verbs/graph/report/strategies/typing.py b/graphrag/graphrag/index/verbs/graph/report/strategies/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..087c72470275cf40e99743a391cbae4ad709c03c --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/report/strategies/typing.py @@ -0,0 +1,52 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'Finding' and 'CommunityReport' models.""" + +from collections.abc import Awaitable, Callable +from typing import Any + +from datashaper import VerbCallbacks +from typing_extensions import TypedDict + +from graphrag.index.cache import PipelineCache + +ExtractedEntity = dict[str, Any] +StrategyConfig = dict[str, Any] +RowContext = dict[str, Any] +EntityTypes = list[str] +Claim = dict[str, Any] + + +class Finding(TypedDict): + """Finding class definition.""" + + summary: str + explanation: str + + +class CommunityReport(TypedDict): + """Community report class definition.""" + + community: str | int + title: str + summary: str + full_content: str + full_content_json: str + rank: float + level: int + rank_explanation: str + findings: list[Finding] + + +CommunityReportsStrategy = Callable[ + [ + str | int, + str, + int, + VerbCallbacks, + PipelineCache, + StrategyConfig, + ], + Awaitable[CommunityReport | None], +] diff --git a/graphrag/graphrag/index/verbs/graph/unpack.py b/graphrag/graphrag/index/verbs/graph/unpack.py new file mode 100644 index 0000000000000000000000000000000000000000..ffb7f4b0a2fa8336fee8bbd4dfa85e588fb31981 --- /dev/null +++ b/graphrag/graphrag/index/verbs/graph/unpack.py @@ -0,0 +1,107 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing unpack_graph, _run_unpack, _unpack_nodes and _unpack_edges methods definition.""" + +from typing import Any, cast + +import networkx as nx +import pandas as pd +from datashaper import TableContainer, VerbCallbacks, VerbInput, progress_iterable, verb + +from graphrag.index.utils import load_graph + +default_copy = ["level"] + + +@verb(name="unpack_graph") +def unpack_graph( + input: VerbInput, + callbacks: VerbCallbacks, + column: str, + type: str, # noqa A002 + copy: list[str] | None = None, + embeddings_column: str = "embeddings", + **kwargs, +) -> TableContainer: + """ + Unpack nodes or edges from a graphml graph, into a list of nodes or edges. + + This verb will create columns for each attribute in a node or edge. + + ## Usage + ```yaml + verb: unpack_graph + args: + type: node # The type of data to unpack, one of: node, edge. node will create a node list, edge will create an edge list + column: # The name of the column containing the graph, should be a graphml graph + ``` + """ + if copy is None: + copy = default_copy + input_df = input.get_input() + num_total = len(input_df) + result = [] + copy = [col for col in copy if col in input_df.columns] + has_embeddings = embeddings_column in input_df.columns + + for _, row in progress_iterable(input_df.iterrows(), callbacks.progress, num_total): + # merge the original row with the unpacked graph item + cleaned_row = {col: row[col] for col in copy} + embeddings = ( + cast(dict[str, list[float]], row[embeddings_column]) + if has_embeddings + else {} + ) + + result.extend([ + {**cleaned_row, **graph_id} + for graph_id in _run_unpack( + cast(str | nx.Graph, row[column]), + type, + embeddings, + kwargs, + ) + ]) + + output_df = pd.DataFrame(result) + return TableContainer(table=output_df) + + +def _run_unpack( + graphml_or_graph: str | nx.Graph, + unpack_type: str, + embeddings: dict[str, list[float]], + args: dict[str, Any], +) -> list[dict[str, Any]]: + graph = load_graph(graphml_or_graph) + if unpack_type == "nodes": + return _unpack_nodes(graph, embeddings, args) + if unpack_type == "edges": + return _unpack_edges(graph, args) + msg = f"Unknown type {unpack_type}" + raise ValueError(msg) + + +def _unpack_nodes( + graph: nx.Graph, embeddings: dict[str, list[float]], _args: dict[str, Any] +) -> list[dict[str, Any]]: + return [ + { + "label": label, + **(node_data or {}), + "graph_embedding": embeddings.get(label), + } + for label, node_data in graph.nodes(data=True) # type: ignore + ] + + +def _unpack_edges(graph: nx.Graph, _args: dict[str, Any]) -> list[dict[str, Any]]: + return [ + { + "source": source_id, + "target": target_id, + **(edge_data or {}), + } + for source_id, target_id, edge_data in graph.edges(data=True) # type: ignore + ] diff --git a/graphrag/graphrag/index/verbs/overrides/__init__.py b/graphrag/graphrag/index/verbs/overrides/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..24b82c1f3ed813103817baf0fba556f185f0f8ca --- /dev/null +++ b/graphrag/graphrag/index/verbs/overrides/__init__.py @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine overrides package root.""" + +from .aggregate import aggregate +from .concat import concat +from .merge import merge + +__all__ = ["aggregate", "concat", "merge"] diff --git a/graphrag/graphrag/index/verbs/overrides/aggregate.py b/graphrag/graphrag/index/verbs/overrides/aggregate.py new file mode 100644 index 0000000000000000000000000000000000000000..df2137046bbdbdf9b49df506d1ce273cd5edb231 --- /dev/null +++ b/graphrag/graphrag/index/verbs/overrides/aggregate.py @@ -0,0 +1,90 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'Aggregation' model.""" + +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +from dataclasses import dataclass +from typing import Any, cast + +import pandas as pd +from datashaper import ( + FieldAggregateOperation, + Progress, + TableContainer, + VerbCallbacks, + VerbInput, + aggregate_operation_mapping, + verb, +) + +ARRAY_AGGREGATIONS = [ + FieldAggregateOperation.ArrayAgg, + FieldAggregateOperation.ArrayAggDistinct, +] + + +# TODO: This thing is kinda gross +# Also, it diverges from the original aggregate verb, since it doesn't support the same syntax +@verb(name="aggregate_override") +def aggregate( + input: VerbInput, + callbacks: VerbCallbacks, + aggregations: list[dict[str, Any]], + groupby: list[str] | None = None, + **_kwargs: dict, +) -> TableContainer: + """Aggregate method definition.""" + aggregations_to_apply = _load_aggregations(aggregations) + df_aggregations = { + agg.column: _get_pandas_agg_operation(agg) + for agg in aggregations_to_apply.values() + } + input_table = input.get_input() + callbacks.progress(Progress(percent=0)) + + if groupby is None: + output_grouped = input_table.groupby(lambda _x: True) + else: + output_grouped = input_table.groupby(groupby, sort=False) + output = cast(pd.DataFrame, output_grouped.agg(df_aggregations)) + output.rename( + columns={agg.column: agg.to for agg in aggregations_to_apply.values()}, + inplace=True, + ) + output.columns = [agg.to for agg in aggregations_to_apply.values()] + + callbacks.progress(Progress(percent=1)) + + return TableContainer(table=output.reset_index()) + + +@dataclass +class Aggregation: + """Aggregation class method definition.""" + + column: str | None + operation: str + to: str + + # Only useful for the concat operation + separator: str | None = None + + +def _get_pandas_agg_operation(agg: Aggregation) -> Any: + # TODO: Merge into datashaper + if agg.operation == "string_concat": + return (agg.separator or ",").join + return aggregate_operation_mapping[FieldAggregateOperation(agg.operation)] + + +def _load_aggregations( + aggregations: list[dict[str, Any]], +) -> dict[str, Aggregation]: + return { + aggregation["column"]: Aggregation( + aggregation["column"], aggregation["operation"], aggregation["to"] + ) + for aggregation in aggregations + } diff --git a/graphrag/graphrag/index/verbs/overrides/concat.py b/graphrag/graphrag/index/verbs/overrides/concat.py new file mode 100644 index 0000000000000000000000000000000000000000..7a0f0e2c327a907460e4bff0f9d22e20a64a2a11 --- /dev/null +++ b/graphrag/graphrag/index/verbs/overrides/concat.py @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing concat method definition.""" + +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +from typing import cast + +import pandas as pd +from datashaper import TableContainer, VerbInput, verb + + +@verb(name="concat_override") +def concat( + input: VerbInput, + columnwise: bool = False, + **_kwargs: dict, +) -> TableContainer: + """Concat method definition.""" + input_table = cast(pd.DataFrame, input.get_input()) + others = cast(list[pd.DataFrame], input.get_others()) + if columnwise: + output = pd.concat([input_table, *others], axis=1) + else: + output = pd.concat([input_table, *others], ignore_index=True) + return TableContainer(table=output) diff --git a/graphrag/graphrag/index/verbs/overrides/merge.py b/graphrag/graphrag/index/verbs/overrides/merge.py new file mode 100644 index 0000000000000000000000000000000000000000..64684c98281f2bb5150b2fcbe4e65431f428597f --- /dev/null +++ b/graphrag/graphrag/index/verbs/overrides/merge.py @@ -0,0 +1,78 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing merge and _merge_json methods definition.""" + +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import logging +from enum import Enum +from typing import Any, cast + +import pandas as pd +from datashaper import TableContainer, VerbInput, VerbResult, verb +from datashaper.engine.verbs.merge import merge as ds_merge + +log = logging.getLogger(__name__) + + +class MergeStrategyType(str, Enum): + """MergeStrategy class definition.""" + + json = "json" + datashaper = "datashaper" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +# TODO: This thing is kinda gross +# Also, it diverges from the original aggregate verb, since it doesn't support the same syntax +@verb(name="merge_override") +def merge( + input: VerbInput, + to: str, + columns: list[str], + strategy: MergeStrategyType = MergeStrategyType.datashaper, + delimiter: str = "", + preserveSource: bool = False, # noqa N806 + unhot: bool = False, + prefix: str = "", + **_kwargs: dict, +) -> TableContainer | VerbResult: + """Merge method definition.""" + output: pd.DataFrame + match strategy: + case MergeStrategyType.json: + output = _merge_json(input, to, columns) + filtered_list: list[str] = [] + + for col in output.columns: + try: + columns.index(col) + except ValueError: + log.exception("Column %s not found in input columns", col) + filtered_list.append(col) + + if not preserveSource: + output = cast(Any, output[filtered_list]) + return TableContainer(table=output.reset_index()) + case _: + return ds_merge( + input, to, columns, strategy, delimiter, preserveSource, unhot, prefix + ) + + +def _merge_json( + input: VerbInput, + to: str, + columns: list[str], +) -> pd.DataFrame: + input_table = cast(pd.DataFrame, input.get_input()) + output = input_table + output[to] = output[columns].apply( + lambda row: ({**row}), + axis=1, + ) + return output diff --git a/graphrag/graphrag/index/verbs/snapshot.py b/graphrag/graphrag/index/verbs/snapshot.py new file mode 100644 index 0000000000000000000000000000000000000000..a90fc2837b093c8340111eeaba9b57c96cbe6971 --- /dev/null +++ b/graphrag/graphrag/index/verbs/snapshot.py @@ -0,0 +1,30 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing snapshot method definition.""" + +from datashaper import TableContainer, VerbInput, verb + +from graphrag.index.storage import PipelineStorage + + +@verb(name="snapshot") +async def snapshot( + input: VerbInput, + name: str, + formats: list[str], + storage: PipelineStorage, + **_kwargs: dict, +) -> TableContainer: + """Take a entire snapshot of the tabular data.""" + data = input.get_input() + + for fmt in formats: + if fmt == "parquet": + await storage.set(name + ".parquet", data.to_parquet()) + elif fmt == "json": + await storage.set( + name + ".json", data.to_json(orient="records", lines=True) + ) + + return TableContainer(table=data) diff --git a/graphrag/graphrag/index/verbs/snapshot_rows.py b/graphrag/graphrag/index/verbs/snapshot_rows.py new file mode 100644 index 0000000000000000000000000000000000000000..99aae70a04ab92da7829347cda7d6af19efc822c --- /dev/null +++ b/graphrag/graphrag/index/verbs/snapshot_rows.py @@ -0,0 +1,86 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'FormatSpecifier' model.""" + +import json +from dataclasses import dataclass +from typing import Any + +from datashaper import TableContainer, VerbInput, verb + +from graphrag.index.storage import PipelineStorage + + +@dataclass +class FormatSpecifier: + """Format specifier class definition.""" + + format: str + extension: str + + +@verb(name="snapshot_rows") +async def snapshot_rows( + input: VerbInput, + column: str | None, + base_name: str, + storage: PipelineStorage, + formats: list[str | dict[str, Any]], + row_name_column: str | None = None, + **_kwargs: dict, +) -> TableContainer: + """Take a by-row snapshot of the tabular data.""" + data = input.get_input() + parsed_formats = _parse_formats(formats) + num_rows = len(data) + + def get_row_name(row: Any, row_idx: Any): + if row_name_column is None: + if num_rows == 1: + return base_name + return f"{base_name}.{row_idx}" + return f"{base_name}.{row[row_name_column]}" + + for row_idx, row in data.iterrows(): + for fmt in parsed_formats: + row_name = get_row_name(row, row_idx) + extension = fmt.extension + if fmt.format == "json": + await storage.set( + f"{row_name}.{extension}", + json.dumps(row[column]) + if column is not None + else json.dumps(row.to_dict()), + ) + elif fmt.format == "text": + if column is None: + msg = "column must be specified for text format" + raise ValueError(msg) + await storage.set(f"{row_name}.{extension}", str(row[column])) + + return TableContainer(table=data) + + +def _parse_formats(formats: list[str | dict[str, Any]]) -> list[FormatSpecifier]: + """Parse the formats into a list of FormatSpecifiers.""" + return [ + FormatSpecifier(**fmt) + if isinstance(fmt, dict) + else FormatSpecifier(format=fmt, extension=_get_format_extension(fmt)) + for fmt in formats + ] + + +def _get_format_extension(fmt: str) -> str: + """Get the file extension for a given format.""" + if fmt == "json": + return "json" + if fmt == "text": + return "txt" + if fmt == "parquet": + return "parquet" + if fmt == "csv": + return "csv" + msg = f"Unknown format: {fmt}" + raise ValueError(msg) diff --git a/graphrag/graphrag/index/verbs/spread_json.py b/graphrag/graphrag/index/verbs/spread_json.py new file mode 100644 index 0000000000000000000000000000000000000000..38656e12a4dcd8082980c1e82e67db664730a67f --- /dev/null +++ b/graphrag/graphrag/index/verbs/spread_json.py @@ -0,0 +1,55 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing spread_json method definition.""" + +import logging + +import pandas as pd +from datashaper import TableContainer, VerbInput, verb + +from graphrag.index.utils import is_null + +# TODO: Check if this is already a thing +DEFAULT_COPY = ["level"] + + +@verb(name="spread_json") +def spread_json( + input: VerbInput, + column: str, + copy: list[str] | None = None, + **_kwargs: dict, +) -> TableContainer: + """ + Unpack a column containing a tuple into multiple columns. + + id|json|b + 1|{"x":5,"y":6}|b + + is converted to + + id|x|y|b + -------- + 1|5|6|b + """ + if copy is None: + copy = DEFAULT_COPY + data = input.get_input() + + results = [] + for _, row in data.iterrows(): + try: + cleaned_row = {col: row[col] for col in copy} + rest_row = row[column] if row[column] is not None else {} + + if is_null(rest_row): + rest_row = {} + + results.append({**cleaned_row, **rest_row}) # type: ignore + except Exception: + logging.exception("Error spreading row: %s", row) + raise + data = pd.DataFrame(results, index=data.index) + + return TableContainer(table=data) diff --git a/graphrag/graphrag/index/verbs/text/__init__.py b/graphrag/graphrag/index/verbs/text/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..032f45e1b10b1a12831f5101c456d0806a99f9b0 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/__init__.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine text package root.""" + +from .chunk.text_chunk import chunk +from .embed import text_embed +from .replace import replace +from .split import text_split +from .translate import text_translate + +__all__ = [ + "chunk", + "replace", + "text_embed", + "text_split", + "text_translate", +] diff --git a/graphrag/graphrag/index/verbs/text/chunk/__init__.py b/graphrag/graphrag/index/verbs/text/chunk/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4e2a7729c5f09a2d409d8f4e0af48f8fcf14dd14 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/chunk/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine text chunk package root.""" + +from .text_chunk import ChunkStrategy, ChunkStrategyType, chunk + +__all__ = ["ChunkStrategy", "ChunkStrategyType", "chunk"] diff --git a/graphrag/graphrag/index/verbs/text/chunk/strategies/__init__.py b/graphrag/graphrag/index/verbs/text/chunk/strategies/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0f15fcb2d5b35e5478454c99108fce8d55cf6f9a --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/chunk/strategies/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine text chunk strategies package root.""" diff --git a/graphrag/graphrag/index/verbs/text/chunk/strategies/sentence.py b/graphrag/graphrag/index/verbs/text/chunk/strategies/sentence.py new file mode 100644 index 0000000000000000000000000000000000000000..687def1d90be1ffb8fe1a64e13429707e040e143 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/chunk/strategies/sentence.py @@ -0,0 +1,26 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run method definition.""" + +from collections.abc import Iterable +from typing import Any + +import nltk +from datashaper import ProgressTicker + +from .typing import TextChunk + + +def run( + input: list[str], _args: dict[str, Any], tick: ProgressTicker +) -> Iterable[TextChunk]: + """Chunks text into multiple parts. A pipeline verb.""" + for doc_idx, text in enumerate(input): + sentences = nltk.sent_tokenize(text) + for sentence in sentences: + yield TextChunk( + text_chunk=sentence, + source_doc_indices=[doc_idx], + ) + tick(1) diff --git a/graphrag/graphrag/index/verbs/text/chunk/strategies/tokens.py b/graphrag/graphrag/index/verbs/text/chunk/strategies/tokens.py new file mode 100644 index 0000000000000000000000000000000000000000..6426c783e1aa23e854ac91e34a04f54418aa5485 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/chunk/strategies/tokens.py @@ -0,0 +1,81 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run and split_text_on_tokens methods definition.""" + +from collections.abc import Iterable +from typing import Any + +import tiktoken +from datashaper import ProgressTicker + +import graphrag.config.defaults as defs +from graphrag.index.text_splitting import Tokenizer +from graphrag.index.verbs.text.chunk.typing import TextChunk + + +def run( + input: list[str], args: dict[str, Any], tick: ProgressTicker +) -> Iterable[TextChunk]: + """Chunks text into multiple parts. A pipeline verb.""" + tokens_per_chunk = args.get("chunk_size", defs.CHUNK_SIZE) + chunk_overlap = args.get("chunk_overlap", defs.CHUNK_OVERLAP) + encoding_name = args.get("encoding_name", defs.ENCODING_MODEL) + enc = tiktoken.get_encoding(encoding_name) + + def encode(text: str) -> list[int]: + if not isinstance(text, str): + text = f"{text}" + return enc.encode(text) + + def decode(tokens: list[int]) -> str: + return enc.decode(tokens) + + return split_text_on_tokens( + input, + Tokenizer( + chunk_overlap=chunk_overlap, + tokens_per_chunk=tokens_per_chunk, + encode=encode, + decode=decode, + ), + tick, + ) + + +# Adapted from - https://github.com/langchain-ai/langchain/blob/77b359edf5df0d37ef0d539f678cf64f5557cb54/libs/langchain/langchain/text_splitter.py#L471 +# So we could have better control over the chunking process +def split_text_on_tokens( + texts: list[str], enc: Tokenizer, tick: ProgressTicker +) -> list[TextChunk]: + """Split incoming text and return chunks.""" + result = [] + mapped_ids = [] + + for source_doc_idx, text in enumerate(texts): + encoded = enc.encode(text) + tick(1) + mapped_ids.append((source_doc_idx, encoded)) + + input_ids: list[tuple[int, int]] = [ + (source_doc_idx, id) for source_doc_idx, ids in mapped_ids for id in ids + ] + + start_idx = 0 + cur_idx = min(start_idx + enc.tokens_per_chunk, len(input_ids)) + chunk_ids = input_ids[start_idx:cur_idx] + while start_idx < len(input_ids): + chunk_text = enc.decode([id for _, id in chunk_ids]) + doc_indices = list({doc_idx for doc_idx, _ in chunk_ids}) + result.append( + TextChunk( + text_chunk=chunk_text, + source_doc_indices=doc_indices, + n_tokens=len(chunk_ids), + ) + ) + start_idx += enc.tokens_per_chunk - enc.chunk_overlap + cur_idx = min(start_idx + enc.tokens_per_chunk, len(input_ids)) + chunk_ids = input_ids[start_idx:cur_idx] + + return result diff --git a/graphrag/graphrag/index/verbs/text/chunk/strategies/typing.py b/graphrag/graphrag/index/verbs/text/chunk/strategies/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..b4e833c8e3c40e6eee9a43508483d27d990f9598 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/chunk/strategies/typing.py @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing ChunkStrategy definition.""" + +from collections.abc import Callable, Iterable +from typing import Any + +from datashaper import ProgressTicker + +from graphrag.index.verbs.text.chunk.typing import TextChunk + +# Given a list of document texts, return a list of tuples of (source_doc_indices, text_chunk) + +ChunkStrategy = Callable[ + [list[str], dict[str, Any], ProgressTicker], Iterable[TextChunk] +] diff --git a/graphrag/graphrag/index/verbs/text/chunk/text_chunk.py b/graphrag/graphrag/index/verbs/text/chunk/text_chunk.py new file mode 100644 index 0000000000000000000000000000000000000000..40c5578a0fe1fec379bac269923f07a8e8133b03 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/chunk/text_chunk.py @@ -0,0 +1,162 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing _get_num_total, chunk, run_strategy and load_strategy methods definitions.""" + +from enum import Enum +from typing import Any, cast + +import pandas as pd +from datashaper import ( + ProgressTicker, + TableContainer, + VerbCallbacks, + VerbInput, + progress_ticker, + verb, +) + +from .strategies.typing import ChunkStrategy as ChunkStrategy +from .typing import ChunkInput + + +def _get_num_total(output: pd.DataFrame, column: str) -> int: + num_total = 0 + for row in output[column]: + if isinstance(row, str): + num_total += 1 + else: + num_total += len(row) + return num_total + + +class ChunkStrategyType(str, Enum): + """ChunkStrategy class definition.""" + + tokens = "tokens" + sentence = "sentence" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +@verb(name="chunk") +def chunk( + input: VerbInput, + column: str, + to: str, + callbacks: VerbCallbacks, + strategy: dict[str, Any] | None = None, + **_kwargs, +) -> TableContainer: + """ + Chunk a piece of text into smaller pieces. + + ## Usage + ```yaml + verb: text_chunk + args: + column: # The name of the column containing the text to chunk, this can either be a column with text, or a column with a list[tuple[doc_id, str]] + to: # The name of the column to output the chunks to + strategy: # The strategy to use to chunk the text, see below for more details + ``` + + ## Strategies + The text chunk verb uses a strategy to chunk the text. The strategy is an object which defines the strategy to use. The following strategies are available: + + ### tokens + This strategy uses the [tokens] library to chunk a piece of text. The strategy config is as follows: + + > Note: In the future, this will likely be renamed to something more generic, like "openai_tokens". + + ```yaml + strategy: + type: tokens + chunk_size: 1200 # Optional, The chunk size to use, default: 1200 + chunk_overlap: 100 # Optional, The chunk overlap to use, default: 100 + ``` + + ### sentence + This strategy uses the nltk library to chunk a piece of text into sentences. The strategy config is as follows: + + ```yaml + strategy: + type: sentence + ``` + """ + if strategy is None: + strategy = {} + output = cast(pd.DataFrame, input.get_input()) + strategy_name = strategy.get("type", ChunkStrategyType.tokens) + strategy_config = {**strategy} + strategy_exec = load_strategy(strategy_name) + + num_total = _get_num_total(output, column) + tick = progress_ticker(callbacks.progress, num_total) + + output[to] = output.apply( + cast( + Any, + lambda x: run_strategy(strategy_exec, x[column], strategy_config, tick), + ), + axis=1, + ) + return TableContainer(table=output) + + +def run_strategy( + strategy: ChunkStrategy, + input: ChunkInput, + strategy_args: dict[str, Any], + tick: ProgressTicker, +) -> list[str | tuple[list[str] | None, str, int]]: + """Run strategy method definition.""" + if isinstance(input, str): + return [item.text_chunk for item in strategy([input], {**strategy_args}, tick)] + + # We can work with both just a list of text content + # or a list of tuples of (document_id, text content) + # text_to_chunk = ''' + texts = [] + for item in input: + if isinstance(item, str): + texts.append(item) + else: + texts.append(item[1]) + + strategy_results = strategy(texts, {**strategy_args}, tick) + + results = [] + for strategy_result in strategy_results: + doc_indices = strategy_result.source_doc_indices + if isinstance(input[doc_indices[0]], str): + results.append(strategy_result.text_chunk) + else: + doc_ids = [input[doc_idx][0] for doc_idx in doc_indices] + results.append(( + doc_ids, + strategy_result.text_chunk, + strategy_result.n_tokens, + )) + return results + + +def load_strategy(strategy: ChunkStrategyType) -> ChunkStrategy: + """Load strategy method definition.""" + match strategy: + case ChunkStrategyType.tokens: + from .strategies.tokens import run as run_tokens + + return run_tokens + case ChunkStrategyType.sentence: + # NLTK + from graphrag.index.bootstrap import bootstrap + + from .strategies.sentence import run as run_sentence + + bootstrap() + return run_sentence + case _: + msg = f"Unknown strategy: {strategy}" + raise ValueError(msg) diff --git a/graphrag/graphrag/index/verbs/text/chunk/typing.py b/graphrag/graphrag/index/verbs/text/chunk/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..3a42cf68a7a528b09bf6eed83f9543e023172dbc --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/chunk/typing.py @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'TextChunk' model.""" + +from dataclasses import dataclass + + +@dataclass +class TextChunk: + """Text chunk class definition.""" + + text_chunk: str + source_doc_indices: list[int] + n_tokens: int | None = None + + +ChunkInput = str | list[str] | list[tuple[str, str]] +"""Input to a chunking strategy. Can be a string, a list of strings, or a list of tuples of (id, text).""" diff --git a/graphrag/graphrag/index/verbs/text/embed/__init__.py b/graphrag/graphrag/index/verbs/text/embed/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..969bd2aab925ac9c3a33fecc67a1770dea632858 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/embed/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine text embed package root.""" + +from .text_embed import TextEmbedStrategyType, text_embed + +__all__ = ["TextEmbedStrategyType", "text_embed"] diff --git a/graphrag/graphrag/index/verbs/text/embed/strategies/__init__.py b/graphrag/graphrag/index/verbs/text/embed/strategies/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8cbe7a580ef3769cc5ef800bef97124c9af8c85d --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/embed/strategies/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine embed strategies package root.""" diff --git a/graphrag/graphrag/index/verbs/text/embed/strategies/mock.py b/graphrag/graphrag/index/verbs/text/embed/strategies/mock.py new file mode 100644 index 0000000000000000000000000000000000000000..1be4ab0f9ff594d33d83dc72b9a8b6510503ed17 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/embed/strategies/mock.py @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run and _embed_text methods definitions.""" + +import random +from collections.abc import Iterable +from typing import Any + +from datashaper import ProgressTicker, VerbCallbacks, progress_ticker + +from graphrag.index.cache import PipelineCache + +from .typing import TextEmbeddingResult + + +async def run( # noqa RUF029 async is required for interface + input: list[str], + callbacks: VerbCallbacks, + cache: PipelineCache, + _args: dict[str, Any], +) -> TextEmbeddingResult: + """Run the Claim extraction chain.""" + input = input if isinstance(input, Iterable) else [input] + ticker = progress_ticker(callbacks.progress, len(input)) + return TextEmbeddingResult( + embeddings=[_embed_text(cache, text, ticker) for text in input] + ) + + +def _embed_text(_cache: PipelineCache, _text: str, tick: ProgressTicker) -> list[float]: + """Embed a single piece of text.""" + tick(1) + return [random.random(), random.random(), random.random()] # noqa S311 diff --git a/graphrag/graphrag/index/verbs/text/embed/strategies/openai.py b/graphrag/graphrag/index/verbs/text/embed/strategies/openai.py new file mode 100644 index 0000000000000000000000000000000000000000..fb443ec83ec66684105847e8936c3eedf4916ed5 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/embed/strategies/openai.py @@ -0,0 +1,181 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run method definition.""" + +import asyncio +import logging +from typing import Any + +import numpy as np +from datashaper import ProgressTicker, VerbCallbacks, progress_ticker + +import graphrag.config.defaults as defs +from graphrag.index.cache import PipelineCache +from graphrag.index.llm import load_llm_embeddings +from graphrag.index.text_splitting import TokenTextSplitter +from graphrag.index.utils import is_null +from graphrag.llm import EmbeddingLLM, OpenAIConfiguration + +from .typing import TextEmbeddingResult + +log = logging.getLogger(__name__) + + +async def run( + input: list[str], + callbacks: VerbCallbacks, + cache: PipelineCache, + args: dict[str, Any], +) -> TextEmbeddingResult: + """Run the Claim extraction chain.""" + if is_null(input): + return TextEmbeddingResult(embeddings=None) + + llm_config = args.get("llm", {}) + batch_size = args.get("batch_size", 16) + batch_max_tokens = args.get("batch_max_tokens", 8191) + oai_config = OpenAIConfiguration(llm_config) + splitter = _get_splitter(oai_config, batch_max_tokens) + llm = _get_llm(oai_config, callbacks, cache) + semaphore: asyncio.Semaphore = asyncio.Semaphore(args.get("num_threads", 4)) + + # Break up the input texts. The sizes here indicate how many snippets are in each input text + texts, input_sizes = _prepare_embed_texts(input, splitter) + text_batches = _create_text_batches( + texts, + batch_size, + batch_max_tokens, + splitter, + ) + log.info( + "embedding %d inputs via %d snippets using %d batches. max_batch_size=%d, max_tokens=%d", + len(input), + len(texts), + len(text_batches), + batch_size, + batch_max_tokens, + ) + ticker = progress_ticker(callbacks.progress, len(text_batches)) + + # Embed each chunk of snippets + embeddings = await _execute(llm, text_batches, ticker, semaphore) + embeddings = _reconstitute_embeddings(embeddings, input_sizes) + + return TextEmbeddingResult(embeddings=embeddings) + + +def _get_splitter( + config: OpenAIConfiguration, batch_max_tokens: int +) -> TokenTextSplitter: + return TokenTextSplitter( + encoding_name=config.encoding_model or defs.ENCODING_MODEL, + chunk_size=batch_max_tokens, + ) + + +def _get_llm( + config: OpenAIConfiguration, + callbacks: VerbCallbacks, + cache: PipelineCache, +) -> EmbeddingLLM: + llm_type = config.lookup("type", "Unknown") + return load_llm_embeddings( + "text_embedding", + llm_type, + callbacks, + cache, + config.raw_config, + ) + + +async def _execute( + llm: EmbeddingLLM, + chunks: list[list[str]], + tick: ProgressTicker, + semaphore: asyncio.Semaphore, +) -> list[list[float]]: + async def embed(chunk: list[str]): + async with semaphore: + chunk_embeddings = await llm(chunk) + result = np.array(chunk_embeddings.output) + tick(1) + return result + + futures = [embed(chunk) for chunk in chunks] + results = await asyncio.gather(*futures) + # merge results in a single list of lists (reduce the collect dimension) + return [item for sublist in results for item in sublist] + + +def _create_text_batches( + texts: list[str], + max_batch_size: int, + max_batch_tokens: int, + splitter: TokenTextSplitter, +) -> list[list[str]]: + """Create batches of texts to embed.""" + # https://learn.microsoft.com/en-us/azure/ai-services/openai/reference + # According to this embeddings reference, Azure limits us to 16 concurrent embeddings and 8191 tokens per request + result = [] + current_batch = [] + current_batch_tokens = 0 + + for text in texts: + token_count = splitter.num_tokens(text) + if ( + len(current_batch) >= max_batch_size + or current_batch_tokens + token_count > max_batch_tokens + ): + result.append(current_batch) + current_batch = [] + current_batch_tokens = 0 + + current_batch.append(text) + current_batch_tokens += token_count + + if len(current_batch) > 0: + result.append(current_batch) + + return result + + +def _prepare_embed_texts( + input: list[str], splitter: TokenTextSplitter +) -> tuple[list[str], list[int]]: + sizes: list[int] = [] + snippets: list[str] = [] + + for text in input: + # Split the input text and filter out any empty content + split_texts = splitter.split_text(text) + if split_texts is None: + continue + split_texts = [text for text in split_texts if len(text) > 0] + + sizes.append(len(split_texts)) + snippets.extend(split_texts) + + return snippets, sizes + + +def _reconstitute_embeddings( + raw_embeddings: list[list[float]], sizes: list[int] +) -> list[list[float] | None]: + """Reconstitute the embeddings into the original input texts.""" + embeddings: list[list[float] | None] = [] + cursor = 0 + for size in sizes: + if size == 0: + embeddings.append(None) + elif size == 1: + embedding = raw_embeddings[cursor] + embeddings.append(embedding) + cursor += 1 + else: + chunk = raw_embeddings[cursor : cursor + size] + average = np.average(chunk, axis=0) + normalized = average / np.linalg.norm(average) + embeddings.append(normalized.tolist()) + cursor += size + return embeddings diff --git a/graphrag/graphrag/index/verbs/text/embed/strategies/typing.py b/graphrag/graphrag/index/verbs/text/embed/strategies/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..1b2525649776dc7db0ed1fc9d4f464b25f1e993b --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/embed/strategies/typing.py @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'TextEmbeddingResult' model.""" + +from collections.abc import Awaitable, Callable +from dataclasses import dataclass + +from datashaper import VerbCallbacks + +from graphrag.index.cache import PipelineCache + + +@dataclass +class TextEmbeddingResult: + """Text embedding result class definition.""" + + embeddings: list[list[float] | None] | None + + +TextEmbeddingStrategy = Callable[ + [ + list[str], + VerbCallbacks, + PipelineCache, + dict, + ], + Awaitable[TextEmbeddingResult], +] diff --git a/graphrag/graphrag/index/verbs/text/embed/text_embed.py b/graphrag/graphrag/index/verbs/text/embed/text_embed.py new file mode 100644 index 0000000000000000000000000000000000000000..76ac97d76feae722deffb7d21354a1e203aa0117 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/embed/text_embed.py @@ -0,0 +1,263 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing text_embed, load_strategy and create_row_from_embedding_data methods definition.""" + +import logging +from enum import Enum +from typing import Any, cast + +import numpy as np +import pandas as pd +from datashaper import TableContainer, VerbCallbacks, VerbInput, verb + +from graphrag.index.cache import PipelineCache +from graphrag.vector_stores import ( + BaseVectorStore, + VectorStoreDocument, + VectorStoreFactory, +) + +from .strategies.typing import TextEmbeddingStrategy + +log = logging.getLogger(__name__) + +# Per Azure OpenAI Limits +# https://learn.microsoft.com/en-us/azure/ai-services/openai/reference +DEFAULT_EMBEDDING_BATCH_SIZE = 500 + + +class TextEmbedStrategyType(str, Enum): + """TextEmbedStrategyType class definition.""" + + openai = "openai" + mock = "mock" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +@verb(name="text_embed") +async def text_embed( + input: VerbInput, + callbacks: VerbCallbacks, + cache: PipelineCache, + column: str, + strategy: dict, + **kwargs, +) -> TableContainer: + """ + Embed a piece of text into a vector space. The verb outputs a new column containing a mapping between doc_id and vector. + + ## Usage + ```yaml + verb: text_embed + args: + column: text # The name of the column containing the text to embed, this can either be a column with text, or a column with a list[tuple[doc_id, str]] + to: embedding # The name of the column to output the embedding to + strategy: # See strategies section below + ``` + + ## Strategies + The text embed verb uses a strategy to embed the text. The strategy is an object which defines the strategy to use. The following strategies are available: + + ### openai + This strategy uses openai to embed a piece of text. In particular it uses a LLM to embed a piece of text. The strategy config is as follows: + + ```yaml + strategy: + type: openai + llm: # The configuration for the LLM + type: openai_embedding # the type of llm to use, available options are: openai_embedding, azure_openai_embedding + api_key: !ENV ${GRAPHRAG_OPENAI_API_KEY} # The api key to use for openai + model: !ENV ${GRAPHRAG_OPENAI_MODEL:gpt-4-turbo-preview} # The model to use for openai + max_tokens: !ENV ${GRAPHRAG_MAX_TOKENS:6000} # The max tokens to use for openai + organization: !ENV ${GRAPHRAG_OPENAI_ORGANIZATION} # The organization to use for openai + vector_store: # The optional configuration for the vector store + type: lancedb # The type of vector store to use, available options are: azure_ai_search, lancedb + <...> + ``` + """ + vector_store_config = strategy.get("vector_store") + + if vector_store_config: + embedding_name = kwargs.get("embedding_name", "default") + collection_name = _get_collection_name(vector_store_config, embedding_name) + vector_store: BaseVectorStore = _create_vector_store( + vector_store_config, collection_name + ) + vector_store_workflow_config = vector_store_config.get( + embedding_name, vector_store_config + ) + return await _text_embed_with_vector_store( + input, + callbacks, + cache, + column, + strategy, + vector_store, + vector_store_workflow_config, + vector_store_config.get("store_in_table", False), + kwargs.get("to", f"{column}_embedding"), + ) + + return await _text_embed_in_memory( + input, + callbacks, + cache, + column, + strategy, + kwargs.get("to", f"{column}_embedding"), + ) + + +async def _text_embed_in_memory( + input: VerbInput, + callbacks: VerbCallbacks, + cache: PipelineCache, + column: str, + strategy: dict, + to: str, +): + output_df = cast(pd.DataFrame, input.get_input()) + strategy_type = strategy["type"] + strategy_exec = load_strategy(strategy_type) + strategy_args = {**strategy} + input_table = input.get_input() + + texts: list[str] = input_table[column].to_numpy().tolist() + result = await strategy_exec(texts, callbacks, cache, strategy_args) + + output_df[to] = result.embeddings + return TableContainer(table=output_df) + + +async def _text_embed_with_vector_store( + input: VerbInput, + callbacks: VerbCallbacks, + cache: PipelineCache, + column: str, + strategy: dict[str, Any], + vector_store: BaseVectorStore, + vector_store_config: dict, + store_in_table: bool = False, + to: str = "", +): + output_df = cast(pd.DataFrame, input.get_input()) + strategy_type = strategy["type"] + strategy_exec = load_strategy(strategy_type) + strategy_args = {**strategy} + + # Get vector-storage configuration + insert_batch_size: int = ( + vector_store_config.get("batch_size") or DEFAULT_EMBEDDING_BATCH_SIZE + ) + title_column: str = vector_store_config.get("title_column", "title") + id_column: str = vector_store_config.get("id_column", "id") + overwrite: bool = vector_store_config.get("overwrite", True) + + if column not in output_df.columns: + msg = f"Column {column} not found in input dataframe with columns {output_df.columns}" + raise ValueError(msg) + if title_column not in output_df.columns: + msg = f"Column {title_column} not found in input dataframe with columns {output_df.columns}" + raise ValueError(msg) + if id_column not in output_df.columns: + msg = f"Column {id_column} not found in input dataframe with columns {output_df.columns}" + raise ValueError(msg) + + total_rows = 0 + for row in output_df[column]: + if isinstance(row, list): + total_rows += len(row) + else: + total_rows += 1 + + i = 0 + starting_index = 0 + + all_results = [] + + while insert_batch_size * i < input.get_input().shape[0]: + batch = input.get_input().iloc[ + insert_batch_size * i : insert_batch_size * (i + 1) + ] + texts: list[str] = batch[column].to_numpy().tolist() + titles: list[str] = batch[title_column].to_numpy().tolist() + ids: list[str] = batch[id_column].to_numpy().tolist() + result = await strategy_exec( + texts, + callbacks, + cache, + strategy_args, + ) + if store_in_table and result.embeddings: + embeddings = [ + embedding for embedding in result.embeddings if embedding is not None + ] + all_results.extend(embeddings) + + vectors = result.embeddings or [] + documents: list[VectorStoreDocument] = [] + for id, text, title, vector in zip(ids, texts, titles, vectors, strict=True): + if type(vector) is np.ndarray: + vector = vector.tolist() + document = VectorStoreDocument( + id=id, + text=text, + vector=vector, + attributes={"title": title}, + ) + documents.append(document) + + vector_store.load_documents(documents, overwrite and i == 0) + starting_index += len(documents) + i += 1 + + if store_in_table: + output_df[to] = all_results + + return TableContainer(table=output_df) + + +def _create_vector_store( + vector_store_config: dict, collection_name: str +) -> BaseVectorStore: + vector_store_type: str = str(vector_store_config.get("type")) + if collection_name: + vector_store_config.update({"collection_name": collection_name}) + + vector_store = VectorStoreFactory.get_vector_store( + vector_store_type, kwargs=vector_store_config + ) + + vector_store.connect(**vector_store_config) + return vector_store + + +def _get_collection_name(vector_store_config: dict, embedding_name: str) -> str: + collection_name = vector_store_config.get("collection_name") + if not collection_name: + collection_names = vector_store_config.get("collection_names", {}) + collection_name = collection_names.get(embedding_name, embedding_name) + + msg = f"using {vector_store_config.get('type')} collection_name {collection_name} for embedding {embedding_name}" + log.info(msg) + return collection_name + + +def load_strategy(strategy: TextEmbedStrategyType) -> TextEmbeddingStrategy: + """Load strategy method definition.""" + match strategy: + case TextEmbedStrategyType.openai: + from .strategies.openai import run as run_openai + + return run_openai + case TextEmbedStrategyType.mock: + from .strategies.mock import run as run_mock + + return run_mock + case _: + msg = f"Unknown strategy: {strategy}" + raise ValueError(msg) diff --git a/graphrag/graphrag/index/verbs/text/replace/__init__.py b/graphrag/graphrag/index/verbs/text/replace/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f863415f4049cede1a458e7207cac5e432d9fda9 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/replace/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine text replace package root.""" + +from .replace import text_replace + +__all__ = ["text_replace"] diff --git a/graphrag/graphrag/index/verbs/text/replace/replace.py b/graphrag/graphrag/index/verbs/text/replace/replace.py new file mode 100644 index 0000000000000000000000000000000000000000..386fac34594fccf5d7dbe4124e3db62f2a47c9b9 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/replace/replace.py @@ -0,0 +1,47 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing replace and _apply_replacements methods.""" + +from typing import cast + +import pandas as pd +from datashaper import TableContainer, VerbInput, verb + +from .typing import Replacement + + +@verb(name="text_replace") +def text_replace( + input: VerbInput, + column: str, + to: str, + replacements: list[dict[str, str]], + **_kwargs: dict, +) -> TableContainer: + """ + Apply a set of replacements to a piece of text. + + ## Usage + ```yaml + verb: text_replace + args: + column: # The name of the column containing the text to replace + to: # The name of the column to write the replaced text to + replacements: # A list of replacements to apply + - pattern: # The regex pattern to find + replacement: # The string to replace with + ``` + """ + output = cast(pd.DataFrame, input.get_input()) + parsed_replacements = [Replacement(**r) for r in replacements] + output[to] = output[column].apply( + lambda text: _apply_replacements(text, parsed_replacements) + ) + return TableContainer(table=output) + + +def _apply_replacements(text: str, replacements: list[Replacement]) -> str: + for r in replacements: + text = text.replace(r.pattern, r.replacement) + return text diff --git a/graphrag/graphrag/index/verbs/text/replace/typing.py b/graphrag/graphrag/index/verbs/text/replace/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..45beef9f2832130fe8c42a09c83816663af6d2ca --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/replace/typing.py @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'Replacement' model.""" + +from dataclasses import dataclass + + +@dataclass +class Replacement: + """Replacement class definition.""" + + pattern: str + replacement: str diff --git a/graphrag/graphrag/index/verbs/text/split.py b/graphrag/graphrag/index/verbs/text/split.py new file mode 100644 index 0000000000000000000000000000000000000000..b1339ff4551814425a691d66379990cefe475d4e --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/split.py @@ -0,0 +1,54 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing the text_split method definition.""" + +from typing import cast + +import pandas as pd +from datashaper import TableContainer, VerbInput, verb + + +@verb(name="text_split") +def text_split( + input: VerbInput, + column: str, + to: str, + separator: str = ",", + **_kwargs: dict, +) -> TableContainer: + """ + Split a piece of text into a list of strings based on a delimiter. The verb outputs a new column containing a list of strings. + + ## Usage + + ```yaml + verb: text_split + args: + column: text # The name of the column containing the text to split + to: split_text # The name of the column to output the split text to + separator: "," # The separator to split the text on, defaults to "," + ``` + """ + output = text_split_df(cast(pd.DataFrame, input.get_input()), column, to, separator) + return TableContainer(table=output) + + +def text_split_df( + input: pd.DataFrame, column: str, to: str, separator: str = "," +) -> pd.DataFrame: + """Split a column into a list of strings.""" + output = input + + def _apply_split(row): + if row[column] is None or isinstance(row[column], list): + return row[column] + if row[column] == "": + return [] + if not isinstance(row[column], str): + message = f"Expected {column} to be a string, but got {type(row[column])}" + raise TypeError(message) + return row[column].split(separator) + + output[to] = output.apply(_apply_split, axis=1) + return output diff --git a/graphrag/graphrag/index/verbs/text/translate/__init__.py b/graphrag/graphrag/index/verbs/text/translate/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ad830dfa87d20451352c09acd1f0075252f6e624 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/translate/__init__.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine text translate package root.""" + +from .text_translate import text_translate + +__all__ = ["text_translate"] diff --git a/graphrag/graphrag/index/verbs/text/translate/strategies/__init__.py b/graphrag/graphrag/index/verbs/text/translate/strategies/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d418bbae283c48ff5f82afcfc202d2a059572e71 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/translate/strategies/__init__.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine translate strategies package root.""" + +from .mock import run as run_mock +from .openai import run as run_openai + +__all__ = ["run_mock", "run_openai"] diff --git a/graphrag/graphrag/index/verbs/text/translate/strategies/defaults.py b/graphrag/graphrag/index/verbs/text/translate/strategies/defaults.py new file mode 100644 index 0000000000000000000000000000000000000000..003e00eb1ff7229404694c7cf72b2f154e392646 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/translate/strategies/defaults.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A file containing TRANSLATION_PROMPT value definition.""" + +TRANSLATION_PROMPT = """ + You are a helpful assistant. Translate into {language} the following text, and make sure all of the text is in {language}. + """.strip() diff --git a/graphrag/graphrag/index/verbs/text/translate/strategies/mock.py b/graphrag/graphrag/index/verbs/text/translate/strategies/mock.py new file mode 100644 index 0000000000000000000000000000000000000000..58a5a9995e900c3dd044db1998046c04c45253ff --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/translate/strategies/mock.py @@ -0,0 +1,28 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run and _summarize_text methods definitions.""" + +from typing import Any + +from datashaper import VerbCallbacks + +from graphrag.index.cache import PipelineCache + +from .typing import TextTranslationResult + + +async def run( # noqa RUF029 async is required for interface + input: str | list[str], + _args: dict[str, Any], + _reporter: VerbCallbacks, + _cache: PipelineCache, +) -> TextTranslationResult: + """Run the Claim extraction chain.""" + input = [input] if isinstance(input, str) else input + return TextTranslationResult(translations=[_translate_text(text) for text in input]) + + +def _translate_text(text: str) -> str: + """Translate a single piece of text.""" + return f"{text} translated" diff --git a/graphrag/graphrag/index/verbs/text/translate/strategies/openai.py b/graphrag/graphrag/index/verbs/text/translate/strategies/openai.py new file mode 100644 index 0000000000000000000000000000000000000000..49c47b34a2ec21b8d0f0b0bc809eb7c07a99546e --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/translate/strategies/openai.py @@ -0,0 +1,93 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing run, _translate_text and _create_translation_prompt methods definition.""" + +import logging +import traceback +from typing import Any + +from datashaper import VerbCallbacks + +import graphrag.config.defaults as defs +from graphrag.config.enums import LLMType +from graphrag.index.cache import PipelineCache +from graphrag.index.llm import load_llm +from graphrag.index.text_splitting import TokenTextSplitter +from graphrag.llm import CompletionLLM + +from .defaults import TRANSLATION_PROMPT as DEFAULT_TRANSLATION_PROMPT +from .typing import TextTranslationResult + +log = logging.getLogger(__name__) + + +async def run( + input: str | list[str], + args: dict[str, Any], + callbacks: VerbCallbacks, + pipeline_cache: PipelineCache, +) -> TextTranslationResult: + """Run the Claim extraction chain.""" + llm_config = args.get("llm", {"type": LLMType.StaticResponse}) + llm_type = llm_config.get("type", LLMType.StaticResponse) + llm = load_llm( + "text_translation", + llm_type, + callbacks, + pipeline_cache, + llm_config, + chat_only=True, + ) + language = args.get("language", "English") + prompt = args.get("prompt") + chunk_size = args.get("chunk_size", defs.CHUNK_SIZE) + chunk_overlap = args.get("chunk_overlap", defs.CHUNK_OVERLAP) + + input = [input] if isinstance(input, str) else input + return TextTranslationResult( + translations=[ + await _translate_text( + text, language, prompt, llm, chunk_size, chunk_overlap, callbacks + ) + for text in input + ] + ) + + +async def _translate_text( + text: str, + language: str, + prompt: str | None, + llm: CompletionLLM, + chunk_size: int, + chunk_overlap: int, + callbacks: VerbCallbacks, +) -> str: + """Translate a single piece of text.""" + splitter = TokenTextSplitter( + chunk_size=chunk_size, + chunk_overlap=chunk_overlap, + ) + + out = "" + chunks = splitter.split_text(text) + for chunk in chunks: + try: + result = await llm( + chunk, + history=[ + { + "role": "system", + "content": (prompt or DEFAULT_TRANSLATION_PROMPT), + } + ], + variables={"language": language}, + ) + out += result.output or "" + except Exception as e: + log.exception("error translating text") + callbacks.error("Error translating text", e, traceback.format_exc()) + out += "" + + return out diff --git a/graphrag/graphrag/index/verbs/text/translate/strategies/typing.py b/graphrag/graphrag/index/verbs/text/translate/strategies/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..d91ed735f59a14aba15a8e287b5df401f56a692a --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/translate/strategies/typing.py @@ -0,0 +1,25 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'TextTranslationResult' model.""" + +from collections.abc import Awaitable, Callable +from dataclasses import dataclass +from typing import Any + +from datashaper import VerbCallbacks + +from graphrag.index.cache import PipelineCache + + +@dataclass +class TextTranslationResult: + """Text translation result class definition.""" + + translations: list[str] + + +TextTranslationStrategy = Callable[ + [list[str], dict[str, Any], VerbCallbacks, PipelineCache], + Awaitable[TextTranslationResult], +] diff --git a/graphrag/graphrag/index/verbs/text/translate/text_translate.py b/graphrag/graphrag/index/verbs/text/translate/text_translate.py new file mode 100644 index 0000000000000000000000000000000000000000..8d0faffefa64da6c42de8eecef0e9e9c694dd647 --- /dev/null +++ b/graphrag/graphrag/index/verbs/text/translate/text_translate.py @@ -0,0 +1,120 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing text_translate methods definition.""" + +from enum import Enum +from typing import Any, cast + +import pandas as pd +from datashaper import ( + AsyncType, + TableContainer, + VerbCallbacks, + VerbInput, + derive_from_rows, + verb, +) + +from graphrag.index.cache import PipelineCache + +from .strategies.typing import TextTranslationStrategy + + +class TextTranslateStrategyType(str, Enum): + """TextTranslateStrategyType class definition.""" + + openai = "openai" + mock = "mock" + + def __repr__(self): + """Get a string representation.""" + return f'"{self.value}"' + + +@verb(name="text_translate") +async def text_translate( + input: VerbInput, + cache: PipelineCache, + callbacks: VerbCallbacks, + text_column: str, + to: str, + strategy: dict[str, Any], + async_mode: AsyncType = AsyncType.AsyncIO, + **kwargs, +) -> TableContainer: + """ + Translate a piece of text into another language. + + ## Usage + ```yaml + verb: text_translate + args: + text_column: # The name of the column containing the text to translate + to: # The name of the column to write the translated text to + strategy: # The strategy to use to translate the text, see below for more details + ``` + + ## Strategies + The text translate verb uses a strategy to translate the text. The strategy is an object which defines the strategy to use. The following strategies are available: + + ### openai + This strategy uses openai to translate a piece of text. In particular it uses a LLM to translate a piece of text. The strategy config is as follows: + + ```yaml + strategy: + type: openai + language: english # The language to translate to, default: english + prompt: # The prompt to use for the translation, default: None + chunk_size: 2500 # The chunk size to use for the translation, default: 2500 + chunk_overlap: 0 # The chunk overlap to use for the translation, default: 0 + llm: # The configuration for the LLM + type: openai_chat # the type of llm to use, available options are: openai_chat, azure_openai_chat + api_key: !ENV ${GRAPHRAG_OPENAI_API_KEY} # The api key to use for openai + model: !ENV ${GRAPHRAG_OPENAI_MODEL:gpt-4-turbo-preview} # The model to use for openai + max_tokens: !ENV ${GRAPHRAG_MAX_TOKENS:6000} # The max tokens to use for openai + organization: !ENV ${GRAPHRAG_OPENAI_ORGANIZATION} # The organization to use for openai + ``` + """ + output_df = cast(pd.DataFrame, input.get_input()) + strategy_type = strategy["type"] + strategy_args = {**strategy} + strategy_exec = _load_strategy(strategy_type) + + async def run_strategy(row): + text = row[text_column] + result = await strategy_exec(text, strategy_args, callbacks, cache) + + # If it is a single string, then return just the translation for that string + if isinstance(text, str): + return result.translations[0] + + # Otherwise, return a list of translations, one for each item in the input + return list(result.translations) + + results = await derive_from_rows( + output_df, + run_strategy, + callbacks, + scheduling_type=async_mode, + num_threads=kwargs.get("num_threads", 4), + ) + output_df[to] = results + return TableContainer(table=output_df) + + +def _load_strategy(strategy: TextTranslateStrategyType) -> TextTranslationStrategy: + match strategy: + case TextTranslateStrategyType.openai: + from .strategies.openai import run as run_openai + + return run_openai + + case TextTranslateStrategyType.mock: + from .strategies.mock import run as run_mock + + return run_mock + + case _: + msg = f"Unknown strategy: {strategy}" + raise ValueError(msg) diff --git a/graphrag/graphrag/index/verbs/unzip.py b/graphrag/graphrag/index/verbs/unzip.py new file mode 100644 index 0000000000000000000000000000000000000000..4d8c8da08e6278ff669aa909c5017f573f0f26d9 --- /dev/null +++ b/graphrag/graphrag/index/verbs/unzip.py @@ -0,0 +1,25 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing unzip method definition.""" + +from typing import cast + +import pandas as pd +from datashaper import TableContainer, VerbInput, verb + + +# TODO: Check if this is already a thing +# Takes 1|(x,y)|b +# and converts to +# 1|x|y|b +@verb(name="unzip") +def unzip( + input: VerbInput, column: str, to: list[str], **_kwargs: dict +) -> TableContainer: + """Unpacks a column containing a tuple into multiple columns.""" + table = cast(pd.DataFrame, input.get_input()) + + table[to] = pd.DataFrame(table[column].tolist(), index=table.index) + + return TableContainer(table=table) diff --git a/graphrag/graphrag/index/verbs/zip.py b/graphrag/graphrag/index/verbs/zip.py new file mode 100644 index 0000000000000000000000000000000000000000..462395d3da17b98f9f503a4732427b3351c6c47a --- /dev/null +++ b/graphrag/graphrag/index/verbs/zip.py @@ -0,0 +1,51 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing ds_zip method definition.""" + +from typing import cast + +import pandas as pd +from datashaper import TableContainer, VerbInput, verb + + +@verb(name="zip") +def zip_verb( + input: VerbInput, + to: str, + columns: list[str], + type: str | None = None, # noqa A002 + **_kwargs: dict, +) -> TableContainer: + """ + Zip columns together. + + ## Usage + TODO + + """ + table = cast(pd.DataFrame, input.get_input()) + if type is None: + table[to] = list(zip(*[table[col] for col in columns], strict=True)) + + # This one is a little weird + elif type == "dict": + if len(columns) != 2: + msg = f"Expected exactly two columns for a dict, got {columns}" + raise ValueError(msg) + key_col, value_col = columns + + results = [] + for _, row in table.iterrows(): + keys = row[key_col] + values = row[value_col] + output = {} + if len(keys) != len(values): + msg = f"Expected same number of keys and values, got {len(keys)} keys and {len(values)} values" + raise ValueError(msg) + for idx, key in enumerate(keys): + output[key] = values[idx] + results.append(output) + + table[to] = results + return TableContainer(table=table.reset_index(drop=True)) diff --git a/graphrag/graphrag/index/workflows/__init__.py b/graphrag/graphrag/index/workflows/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ed580309a8dc14b313131ba6cc3b29cbf2ec99a4 --- /dev/null +++ b/graphrag/graphrag/index/workflows/__init__.py @@ -0,0 +1,25 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine workflows package root.""" + +from .load import create_workflow, load_workflows +from .typing import ( + StepDefinition, + VerbDefinitions, + VerbTiming, + WorkflowConfig, + WorkflowDefinitions, + WorkflowToRun, +) + +__all__ = [ + "StepDefinition", + "VerbDefinitions", + "VerbTiming", + "WorkflowConfig", + "WorkflowDefinitions", + "WorkflowToRun", + "create_workflow", + "load_workflows", +] diff --git a/graphrag/graphrag/index/workflows/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/workflows/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa4e8323b9a8d7fb9b13bfd213d5fb3a61b7d598 Binary files /dev/null and b/graphrag/graphrag/index/workflows/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/__pycache__/default_workflows.cpython-311.pyc b/graphrag/graphrag/index/workflows/__pycache__/default_workflows.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3fa1594b0a38dcafec5d5cfddd7c1c72e3c67bd4 Binary files /dev/null and b/graphrag/graphrag/index/workflows/__pycache__/default_workflows.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/__pycache__/load.cpython-311.pyc b/graphrag/graphrag/index/workflows/__pycache__/load.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9d49f500e4fd646253135fcbe2b710dc25a25b3 Binary files /dev/null and b/graphrag/graphrag/index/workflows/__pycache__/load.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/__pycache__/typing.cpython-311.pyc b/graphrag/graphrag/index/workflows/__pycache__/typing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e4ba38db0138f899d9f1dbeca8605a1f63c6446 Binary files /dev/null and b/graphrag/graphrag/index/workflows/__pycache__/typing.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/default_workflows.py b/graphrag/graphrag/index/workflows/default_workflows.py new file mode 100644 index 0000000000000000000000000000000000000000..81112bee32f5b8a206b10ac83c19e8f76e96d1c4 --- /dev/null +++ b/graphrag/graphrag/index/workflows/default_workflows.py @@ -0,0 +1,121 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A package containing default workflows definitions.""" + +from .typing import WorkflowDefinitions +from .v1.create_base_documents import ( + build_steps as build_create_base_documents_steps, +) +from .v1.create_base_documents import ( + workflow_name as create_base_documents, +) +from .v1.create_base_entity_graph import ( + build_steps as build_create_base_entity_graph_steps, +) +from .v1.create_base_entity_graph import ( + workflow_name as create_base_entity_graph, +) +from .v1.create_base_extracted_entities import ( + build_steps as build_create_base_extracted_entities_steps, +) +from .v1.create_base_extracted_entities import ( + workflow_name as create_base_extracted_entities, +) +from .v1.create_base_text_units import ( + build_steps as build_create_base_text_units_steps, +) +from .v1.create_base_text_units import ( + workflow_name as create_base_text_units, +) +from .v1.create_final_communities import ( + build_steps as build_create_final_communities_steps, +) +from .v1.create_final_communities import ( + workflow_name as create_final_communities, +) +from .v1.create_final_community_reports import ( + build_steps as build_create_final_community_reports_steps, +) +from .v1.create_final_community_reports import ( + workflow_name as create_final_community_reports, +) +from .v1.create_final_covariates import ( + build_steps as build_create_final_covariates_steps, +) +from .v1.create_final_covariates import ( + workflow_name as create_final_covariates, +) +from .v1.create_final_documents import ( + build_steps as build_create_final_documents_steps, +) +from .v1.create_final_documents import ( + workflow_name as create_final_documents, +) +from .v1.create_final_entities import ( + build_steps as build_create_final_entities_steps, +) +from .v1.create_final_entities import ( + workflow_name as create_final_entities, +) +from .v1.create_final_nodes import ( + build_steps as build_create_final_nodes_steps, +) +from .v1.create_final_nodes import ( + workflow_name as create_final_nodes, +) +from .v1.create_final_relationships import ( + build_steps as build_create_final_relationships_steps, +) +from .v1.create_final_relationships import ( + workflow_name as create_final_relationships, +) +from .v1.create_final_text_units import ( + build_steps as build_create_final_text_units, +) +from .v1.create_final_text_units import ( + workflow_name as create_final_text_units, +) +from .v1.create_summarized_entities import ( + build_steps as build_create_summarized_entities_steps, +) +from .v1.create_summarized_entities import ( + workflow_name as create_summarized_entities, +) +from .v1.join_text_units_to_covariate_ids import ( + build_steps as join_text_units_to_covariate_ids_steps, +) +from .v1.join_text_units_to_covariate_ids import ( + workflow_name as join_text_units_to_covariate_ids, +) +from .v1.join_text_units_to_entity_ids import ( + build_steps as join_text_units_to_entity_ids_steps, +) +from .v1.join_text_units_to_entity_ids import ( + workflow_name as join_text_units_to_entity_ids, +) +from .v1.join_text_units_to_relationship_ids import ( + build_steps as join_text_units_to_relationship_ids_steps, +) +from .v1.join_text_units_to_relationship_ids import ( + workflow_name as join_text_units_to_relationship_ids, +) + +default_workflows: WorkflowDefinitions = { + create_base_extracted_entities: build_create_base_extracted_entities_steps, + create_base_entity_graph: build_create_base_entity_graph_steps, + create_base_text_units: build_create_base_text_units_steps, + create_final_text_units: build_create_final_text_units, + create_final_community_reports: build_create_final_community_reports_steps, + create_final_nodes: build_create_final_nodes_steps, + create_final_relationships: build_create_final_relationships_steps, + create_final_documents: build_create_final_documents_steps, + create_final_covariates: build_create_final_covariates_steps, + create_base_documents: build_create_base_documents_steps, + create_final_entities: build_create_final_entities_steps, + create_final_communities: build_create_final_communities_steps, + create_summarized_entities: build_create_summarized_entities_steps, + join_text_units_to_entity_ids: join_text_units_to_entity_ids_steps, + join_text_units_to_covariate_ids: join_text_units_to_covariate_ids_steps, + join_text_units_to_relationship_ids: join_text_units_to_relationship_ids_steps, +} diff --git a/graphrag/graphrag/index/workflows/load.py b/graphrag/graphrag/index/workflows/load.py new file mode 100644 index 0000000000000000000000000000000000000000..4dd6f9bfd099388f963fbece22027239a5d24174 --- /dev/null +++ b/graphrag/graphrag/index/workflows/load.py @@ -0,0 +1,171 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing load_workflows, create_workflow, _get_steps_for_workflow and _remove_disabled_steps methods definition.""" + +from __future__ import annotations + +import logging +from collections.abc import Callable +from typing import TYPE_CHECKING, Any, NamedTuple, cast + +from datashaper import Workflow + +from graphrag.index.errors import ( + NoWorkflowsDefinedError, + UndefinedWorkflowError, + UnknownWorkflowError, +) +from graphrag.index.utils import topological_sort + +from .default_workflows import default_workflows as _default_workflows +from .typing import VerbDefinitions, WorkflowDefinitions, WorkflowToRun + +if TYPE_CHECKING: + from graphrag.index.config import ( + PipelineWorkflowConfig, + PipelineWorkflowReference, + PipelineWorkflowStep, + ) + +anonymous_workflow_count = 0 + +VerbFn = Callable[..., Any] +log = logging.getLogger(__name__) + + +class LoadWorkflowResult(NamedTuple): + """A workflow loading result object.""" + + workflows: list[WorkflowToRun] + """The loaded workflow names in the order they should be run.""" + + dependencies: dict[str, list[str]] + """A dictionary of workflow name to workflow dependencies.""" + + +def load_workflows( + workflows_to_load: list[PipelineWorkflowReference], + additional_verbs: VerbDefinitions | None = None, + additional_workflows: WorkflowDefinitions | None = None, + memory_profile: bool = False, +) -> LoadWorkflowResult: + """Load the given workflows. + + Args: + - workflows_to_load - The workflows to load + - additional_verbs - The list of custom verbs available to the workflows + - additional_workflows - The list of custom workflows + Returns: + - output[0] - The loaded workflow names in the order they should be run + - output[1] - A dictionary of workflow name to workflow dependencies + """ + workflow_graph: dict[str, WorkflowToRun] = {} + + global anonymous_workflow_count + for reference in workflows_to_load: + name = reference.name + is_anonymous = name is None or name.strip() == "" + if is_anonymous: + name = f"Anonymous Workflow {anonymous_workflow_count}" + anonymous_workflow_count += 1 + name = cast(str, name) + + config = reference.config + workflow = create_workflow( + name or "MISSING NAME!", + reference.steps, + config, + additional_verbs, + additional_workflows, + ) + workflow_graph[name] = WorkflowToRun(workflow, config=config or {}) + + # Backfill any missing workflows + for name in list(workflow_graph.keys()): + workflow = workflow_graph[name] + deps = [ + d.replace("workflow:", "") + for d in workflow.workflow.dependencies + if d.startswith("workflow:") + ] + for dependency in deps: + if dependency not in workflow_graph: + reference = {"name": dependency, **workflow.config} + workflow_graph[dependency] = WorkflowToRun( + workflow=create_workflow( + dependency, + config=reference, + additional_verbs=additional_verbs, + additional_workflows=additional_workflows, + memory_profile=memory_profile, + ), + config=reference, + ) + + # Run workflows in order of dependencies + def filter_wf_dependencies(name: str) -> list[str]: + externals = [ + e.replace("workflow:", "") + for e in workflow_graph[name].workflow.dependencies + ] + return [e for e in externals if e in workflow_graph] + + task_graph = {name: filter_wf_dependencies(name) for name in workflow_graph} + workflow_run_order = topological_sort(task_graph) + workflows = [workflow_graph[name] for name in workflow_run_order] + log.info("Workflow Run Order: %s", workflow_run_order) + return LoadWorkflowResult(workflows=workflows, dependencies=task_graph) + + +def create_workflow( + name: str, + steps: list[PipelineWorkflowStep] | None = None, + config: PipelineWorkflowConfig | None = None, + additional_verbs: VerbDefinitions | None = None, + additional_workflows: WorkflowDefinitions | None = None, + memory_profile: bool = False, +) -> Workflow: + """Create a workflow from the given config.""" + additional_workflows = { + **_default_workflows, + **(additional_workflows or {}), + } + steps = steps or _get_steps_for_workflow(name, config, additional_workflows) + steps = _remove_disabled_steps(steps) + return Workflow( + verbs=additional_verbs or {}, + schema={ + "name": name, + "steps": steps, + }, + validate=False, + memory_profile=memory_profile, + ) + + +def _get_steps_for_workflow( + name: str | None, + config: PipelineWorkflowConfig | None, + workflows: dict[str, Callable] | None, +) -> list[PipelineWorkflowStep]: + """Get the steps for the given workflow config.""" + if config is not None and "steps" in config: + return config["steps"] + + if workflows is None: + raise NoWorkflowsDefinedError + + if name is None: + raise UndefinedWorkflowError + + if name not in workflows: + raise UnknownWorkflowError(name) + + return workflows[name](config or {}) + + +def _remove_disabled_steps( + steps: list[PipelineWorkflowStep], +) -> list[PipelineWorkflowStep]: + return [step for step in steps if step.get("enabled", True)] diff --git a/graphrag/graphrag/index/workflows/typing.py b/graphrag/graphrag/index/workflows/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..3b44545bd4fc4c77eb211188f4fee9a742f96319 --- /dev/null +++ b/graphrag/graphrag/index/workflows/typing.py @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing 'WorkflowToRun' model.""" + +from collections.abc import Callable +from dataclasses import dataclass as dc_dataclass +from typing import Any + +from datashaper import TableContainer, Workflow + +StepDefinition = dict[str, Any] +"""A step definition.""" + +VerbDefinitions = dict[str, Callable[..., TableContainer]] +"""A mapping of verb names to their implementations.""" + +WorkflowConfig = dict[str, Any] +"""A workflow configuration.""" + +WorkflowDefinitions = dict[str, Callable[[WorkflowConfig], list[StepDefinition]]] +"""A mapping of workflow names to their implementations.""" + +VerbTiming = dict[str, float] +"""The timings of verbs by id.""" + + +@dc_dataclass +class WorkflowToRun: + """Workflow to run class definition.""" + + workflow: Workflow + config: dict[str, Any] diff --git a/graphrag/graphrag/index/workflows/v1/__init__.py b/graphrag/graphrag/index/workflows/v1/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..69518f5ee2ce0440d8d57272b510af22dc5b7417 --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Indexing Engine workflows package root.""" diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c20d140024e8940d4ba1fbb2facde161fe5c4ae0 Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/create_base_documents.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/create_base_documents.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fedccaa23fbe94a2fe68d83ff2a0f2a07c8458ba Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/create_base_documents.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/create_base_entity_graph.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/create_base_entity_graph.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c09f6dd19be76681e3be9354594f2bb622f8f62f Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/create_base_entity_graph.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/create_base_extracted_entities.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/create_base_extracted_entities.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..880fd0c1e57a33a79a145731b875983b8b372120 Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/create_base_extracted_entities.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/create_base_text_units.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/create_base_text_units.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5f0dc0b7c020f150857935e92448b5b816b3f039 Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/create_base_text_units.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_communities.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_communities.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e144b5bda325102946b8f8360a875fb034aca39e Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_communities.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_community_reports.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_community_reports.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5639b7cc900497bb3f90c00098e4005d0668dab5 Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_community_reports.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_covariates.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_covariates.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a3236a11e277d28a42d3630775a7c163d1becb2b Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_covariates.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_documents.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_documents.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bbec0c01f40b3f2bd56b057690309fe499016a98 Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_documents.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_entities.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_entities.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cdd471966ef941cbb8bb09f2552a7dfb45795b2c Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_entities.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_nodes.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_nodes.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a05b617def4354c5463ef82f1568cad9ebdf0675 Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_nodes.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_relationships.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_relationships.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f80a807ae8eacba67523afe9bbbc74ffcbd558d2 Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_relationships.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_text_units.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_text_units.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6085cc5fa2c2fef638d099e2dca5a891569aa520 Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/create_final_text_units.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/create_summarized_entities.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/create_summarized_entities.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c0084c6154190e2bf6e9c1deebb371902c5fb5a2 Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/create_summarized_entities.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/join_text_units_to_covariate_ids.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/join_text_units_to_covariate_ids.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c85d873c462e753c54d0d30a721b26f14573892 Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/join_text_units_to_covariate_ids.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/join_text_units_to_entity_ids.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/join_text_units_to_entity_ids.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7622fb135b757ee3501327f5d11114ef1eaaa80d Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/join_text_units_to_entity_ids.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/__pycache__/join_text_units_to_relationship_ids.cpython-311.pyc b/graphrag/graphrag/index/workflows/v1/__pycache__/join_text_units_to_relationship_ids.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f258817867c931557f3ce662cdd9e77a64639a1 Binary files /dev/null and b/graphrag/graphrag/index/workflows/v1/__pycache__/join_text_units_to_relationship_ids.cpython-311.pyc differ diff --git a/graphrag/graphrag/index/workflows/v1/create_base_documents.py b/graphrag/graphrag/index/workflows/v1/create_base_documents.py new file mode 100644 index 0000000000000000000000000000000000000000..bd7094c64adc195bbe104c1deb206e79fb569ca6 --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/create_base_documents.py @@ -0,0 +1,105 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from datashaper import DEFAULT_INPUT_NAME + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "create_base_documents" + + +def build_steps( + config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the documents table. + + ## Dependencies + * `workflow:create_final_text_units` + """ + document_attribute_columns = config.get("document_attribute_columns", []) + return [ + { + "verb": "unroll", + "args": {"column": "document_ids"}, + "input": {"source": "workflow:create_final_text_units"}, + }, + { + "verb": "select", + "args": { + # We only need the chunk id and the document id + "columns": ["id", "document_ids", "text"] + }, + }, + { + "id": "rename_chunk_doc_id", + "verb": "rename", + "args": { + "columns": { + "document_ids": "chunk_doc_id", + "id": "chunk_id", + "text": "chunk_text", + } + }, + }, + { + "verb": "join", + "args": { + # Join the doc id from the chunk onto the original document + "on": ["chunk_doc_id", "id"] + }, + "input": {"source": "rename_chunk_doc_id", "others": [DEFAULT_INPUT_NAME]}, + }, + { + "id": "docs_with_text_units", + "verb": "aggregate_override", + "args": { + "groupby": ["id"], + "aggregations": [ + { + "column": "chunk_id", + "operation": "array_agg", + "to": "text_units", + } + ], + }, + }, + { + "verb": "join", + "args": { + "on": ["id", "id"], + "strategy": "right outer", + }, + "input": { + "source": "docs_with_text_units", + "others": [DEFAULT_INPUT_NAME], + }, + }, + { + "verb": "rename", + "args": {"columns": {"text": "raw_content"}}, + }, + *[ + { + "verb": "convert", + "args": { + "column": column, + "to": column, + "type": "string", + }, + } + for column in document_attribute_columns + ], + { + "verb": "merge_override", + "enabled": len(document_attribute_columns) > 0, + "args": { + "columns": document_attribute_columns, + "strategy": "json", + "to": "attributes", + }, + }, + {"verb": "convert", "args": {"column": "id", "to": "id", "type": "string"}}, + ] diff --git a/graphrag/graphrag/index/workflows/v1/create_base_entity_graph.py b/graphrag/graphrag/index/workflows/v1/create_base_entity_graph.py new file mode 100644 index 0000000000000000000000000000000000000000..b001aad21896bb519d71015cba21d1d2e435066d --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/create_base_entity_graph.py @@ -0,0 +1,91 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "create_base_entity_graph" + + +def build_steps( + config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the base table for the entity graph. + + ## Dependencies + * `workflow:create_base_extracted_entities` + """ + clustering_config = config.get( + "cluster_graph", + {"strategy": {"type": "leiden"}}, + ) + embed_graph_config = config.get( + "embed_graph", + { + "strategy": { + "type": "node2vec", + "num_walks": config.get("embed_num_walks", 10), + "walk_length": config.get("embed_walk_length", 40), + "window_size": config.get("embed_window_size", 2), + "iterations": config.get("embed_iterations", 3), + "random_seed": config.get("embed_random_seed", 86), + } + }, + ) + + graphml_snapshot_enabled = config.get("graphml_snapshot", False) or False + embed_graph_enabled = config.get("embed_graph_enabled", False) or False + + return [ + { + "verb": "cluster_graph", + "args": { + **clustering_config, + "column": "entity_graph", + "to": "clustered_graph", + "level_to": "level", + }, + "input": ({"source": "workflow:create_summarized_entities"}), + }, + { + "verb": "snapshot_rows", + "enabled": graphml_snapshot_enabled, + "args": { + "base_name": "clustered_graph", + "column": "clustered_graph", + "formats": [{"format": "text", "extension": "graphml"}], + }, + }, + { + "verb": "embed_graph", + "enabled": embed_graph_enabled, + "args": { + "column": "clustered_graph", + "to": "embeddings", + **embed_graph_config, + }, + }, + { + "verb": "snapshot_rows", + "enabled": graphml_snapshot_enabled, + "args": { + "base_name": "embedded_graph", + "column": "entity_graph", + "formats": [{"format": "text", "extension": "graphml"}], + }, + }, + { + "verb": "select", + "args": { + # only selecting for documentation sake, so we know what is contained in + # this workflow + "columns": ( + ["level", "clustered_graph", "embeddings"] + if embed_graph_enabled + else ["level", "clustered_graph"] + ), + }, + }, + ] diff --git a/graphrag/graphrag/index/workflows/v1/create_base_extracted_entities.py b/graphrag/graphrag/index/workflows/v1/create_base_extracted_entities.py new file mode 100644 index 0000000000000000000000000000000000000000..30d608e9fd4ab7815a43d1c4592cf002bd308072 --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/create_base_extracted_entities.py @@ -0,0 +1,95 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from datashaper import AsyncType + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "create_base_extracted_entities" + + +def build_steps( + config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the base table for extracted entities. + + ## Dependencies + * `workflow:create_base_text_units` + """ + entity_extraction_config = config.get("entity_extract", {}) + graphml_snapshot_enabled = config.get("graphml_snapshot", False) or False + raw_entity_snapshot_enabled = config.get("raw_entity_snapshot", False) or False + + return [ + { + "verb": "entity_extract", + "args": { + **entity_extraction_config, + "column": entity_extraction_config.get("text_column", "chunk"), + "id_column": entity_extraction_config.get("id_column", "chunk_id"), + "async_mode": entity_extraction_config.get( + "async_mode", AsyncType.AsyncIO + ), + "to": "entities", + "graph_to": "entity_graph", + }, + "input": {"source": "workflow:create_base_text_units"}, + }, + { + "verb": "snapshot", + "enabled": raw_entity_snapshot_enabled, + "args": { + "name": "raw_extracted_entities", + "formats": ["json"], + }, + }, + { + "verb": "merge_graphs", + "args": { + "column": "entity_graph", + "to": "entity_graph", + **config.get( + "graph_merge_operations", + { + "nodes": { + "source_id": { + "operation": "concat", + "delimiter": ", ", + "distinct": True, + }, + "description": ({ + "operation": "concat", + "separator": "\n", + "distinct": False, + }), + }, + "edges": { + "source_id": { + "operation": "concat", + "delimiter": ", ", + "distinct": True, + }, + "description": ({ + "operation": "concat", + "separator": "\n", + "distinct": False, + }), + "weight": "sum", + }, + }, + ), + }, + }, + { + "verb": "snapshot_rows", + "enabled": graphml_snapshot_enabled, + "args": { + "base_name": "merged_graph", + "column": "entity_graph", + "formats": [{"format": "text", "extension": "graphml"}], + }, + }, + ] diff --git a/graphrag/graphrag/index/workflows/v1/create_base_text_units.py b/graphrag/graphrag/index/workflows/v1/create_base_text_units.py new file mode 100644 index 0000000000000000000000000000000000000000..63876e5e499785bc30da016273f2cb7659de01d2 --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/create_base_text_units.py @@ -0,0 +1,112 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from datashaper import DEFAULT_INPUT_NAME + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "create_base_text_units" + + +def build_steps( + config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the base table for text units. + + ## Dependencies + None + """ + chunk_column_name = config.get("chunk_column", "chunk") + chunk_by_columns = config.get("chunk_by", []) or [] + n_tokens_column_name = config.get("n_tokens_column", "n_tokens") + return [ + { + "verb": "orderby", + "args": { + "orders": [ + # sort for reproducibility + {"column": "id", "direction": "asc"}, + ] + }, + "input": {"source": DEFAULT_INPUT_NAME}, + }, + { + "verb": "zip", + "args": { + # Pack the document ids with the text + # So when we unpack the chunks, we can restore the document id + "columns": ["id", "text"], + "to": "text_with_ids", + }, + }, + { + "verb": "aggregate_override", + "args": { + "groupby": [*chunk_by_columns] if len(chunk_by_columns) > 0 else None, + "aggregations": [ + { + "column": "text_with_ids", + "operation": "array_agg", + "to": "texts", + } + ], + }, + }, + { + "verb": "chunk", + "args": {"column": "texts", "to": "chunks", **config.get("text_chunk", {})}, + }, + { + "verb": "select", + "args": { + "columns": [*chunk_by_columns, "chunks"], + }, + }, + { + "verb": "unroll", + "args": { + "column": "chunks", + }, + }, + { + "verb": "rename", + "args": { + "columns": { + "chunks": chunk_column_name, + } + }, + }, + { + "verb": "genid", + "args": { + # Generate a unique id for each chunk + "to": "chunk_id", + "method": "md5_hash", + "hash": [chunk_column_name], + }, + }, + { + "verb": "unzip", + "args": { + "column": chunk_column_name, + "to": ["document_ids", chunk_column_name, n_tokens_column_name], + }, + }, + {"verb": "copy", "args": {"column": "chunk_id", "to": "id"}}, + { + # ELIMINATE EMPTY CHUNKS + "verb": "filter", + "args": { + "column": chunk_column_name, + "criteria": [ + { + "type": "value", + "operator": "is not empty", + } + ], + }, + }, + ] diff --git a/graphrag/graphrag/index/workflows/v1/create_final_communities.py b/graphrag/graphrag/index/workflows/v1/create_final_communities.py new file mode 100644 index 0000000000000000000000000000000000000000..f8949dfcec055f142ca82b590511cb31ed0213fe --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/create_final_communities.py @@ -0,0 +1,172 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "create_final_communities" + + +def build_steps( + _config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the final communities table. + + ## Dependencies + * `workflow:create_base_entity_graph` + """ + return [ + { + "id": "graph_nodes", + "verb": "unpack_graph", + "args": { + "column": "clustered_graph", + "type": "nodes", + }, + "input": {"source": "workflow:create_base_entity_graph"}, + }, + { + "id": "graph_edges", + "verb": "unpack_graph", + "args": { + "column": "clustered_graph", + "type": "edges", + }, + "input": {"source": "workflow:create_base_entity_graph"}, + }, + { + "id": "source_clusters", + "verb": "join", + "args": { + "on": ["label", "source"], + }, + "input": {"source": "graph_nodes", "others": ["graph_edges"]}, + }, + { + "id": "target_clusters", + "verb": "join", + "args": { + "on": ["label", "target"], + }, + "input": {"source": "graph_nodes", "others": ["graph_edges"]}, + }, + { + "id": "concatenated_clusters", + "verb": "concat", + "input": { + "source": "source_clusters", + "others": ["target_clusters"], + }, + }, + { + "id": "combined_clusters", + "verb": "filter", + "args": { + # level_1 is the left side of the join + # level_2 is the right side of the join + "column": "level_1", + "criteria": [ + {"type": "column", "operator": "equals", "value": "level_2"} + ], + }, + "input": {"source": "concatenated_clusters"}, + }, + { + "id": "cluster_relationships", + "verb": "aggregate_override", + "args": { + "groupby": [ + "cluster", + "level_1", # level_1 is the left side of the join + ], + "aggregations": [ + { + "column": "id_2", # this is the id of the edge from the join steps above + "to": "relationship_ids", + "operation": "array_agg_distinct", + }, + { + "column": "source_id_1", + "to": "text_unit_ids", + "operation": "array_agg_distinct", + }, + ], + }, + "input": {"source": "combined_clusters"}, + }, + { + "id": "all_clusters", + "verb": "aggregate_override", + "args": { + "groupby": ["cluster", "level"], + "aggregations": [{"column": "cluster", "to": "id", "operation": "any"}], + }, + "input": {"source": "graph_nodes"}, + }, + { + "verb": "join", + "args": { + "on": ["id", "cluster"], + }, + "input": {"source": "all_clusters", "others": ["cluster_relationships"]}, + }, + { + "verb": "filter", + "args": { + # level is the left side of the join + # level_1 is the right side of the join + "column": "level", + "criteria": [ + {"type": "column", "operator": "equals", "value": "level_1"} + ], + }, + }, + *create_community_title_wf, + { + # TODO: Rodrigo says "raw_community" is temporary + "verb": "copy", + "args": { + "column": "id", + "to": "raw_community", + }, + }, + { + "verb": "select", + "args": { + "columns": [ + "id", + "title", + "level", + "raw_community", + "relationship_ids", + "text_unit_ids", + ], + }, + }, + ] + + +create_community_title_wf = [ + # Hack to string concat "Community " + id + { + "verb": "fill", + "args": { + "to": "__temp", + "value": "Community ", + }, + }, + { + "verb": "merge", + "args": { + "columns": [ + "__temp", + "id", + ], + "to": "title", + "strategy": "concat", + "preserveSource": True, + }, + }, +] diff --git a/graphrag/graphrag/index/workflows/v1/create_final_community_reports.py b/graphrag/graphrag/index/workflows/v1/create_final_community_reports.py new file mode 100644 index 0000000000000000000000000000000000000000..164c70e0dd56519297c63f18bab3f59663350d4c --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/create_final_community_reports.py @@ -0,0 +1,133 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "create_final_community_reports" + + +def build_steps( + config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the final community reports table. + + ## Dependencies + * `workflow:create_base_entity_graph` + """ + covariates_enabled = config.get("covariates_enabled", False) + create_community_reports_config = config.get("create_community_reports", {}) + base_text_embed = config.get("text_embed", {}) + community_report_full_content_embed_config = config.get( + "community_report_full_content_embed", base_text_embed + ) + community_report_summary_embed_config = config.get( + "community_report_summary_embed", base_text_embed + ) + community_report_title_embed_config = config.get( + "community_report_title_embed", base_text_embed + ) + skip_title_embedding = config.get("skip_title_embedding", False) + skip_summary_embedding = config.get("skip_summary_embedding", False) + skip_full_content_embedding = config.get("skip_full_content_embedding", False) + + return [ + # + # Subworkflow: Prepare Nodes + # + { + "id": "nodes", + "verb": "prepare_community_reports_nodes", + "input": {"source": "workflow:create_final_nodes"}, + }, + # + # Subworkflow: Prepare Edges + # + { + "id": "edges", + "verb": "prepare_community_reports_edges", + "input": {"source": "workflow:create_final_relationships"}, + }, + # + # Subworkflow: Prepare Claims Table + # + { + "id": "claims", + "enabled": covariates_enabled, + "verb": "prepare_community_reports_claims", + "input": { + "source": "workflow:create_final_covariates", + } + if covariates_enabled + else {}, + }, + # + # Subworkflow: Get Community Hierarchy + # + { + "id": "community_hierarchy", + "verb": "restore_community_hierarchy", + "input": {"source": "nodes"}, + }, + # + # Main Workflow: Create Community Reports + # + { + "id": "local_contexts", + "verb": "prepare_community_reports", + "input": { + "source": "nodes", + "nodes": "nodes", + "edges": "edges", + **({"claims": "claims"} if covariates_enabled else {}), + }, + }, + { + "verb": "create_community_reports", + "args": { + **create_community_reports_config, + }, + "input": { + "source": "local_contexts", + "community_hierarchy": "community_hierarchy", + "nodes": "nodes", + }, + }, + { + # Generate a unique ID for each community report distinct from the community ID + "verb": "window", + "args": {"to": "id", "operation": "uuid", "column": "community"}, + }, + { + "verb": "text_embed", + "enabled": not skip_full_content_embedding, + "args": { + "embedding_name": "community_report_full_content", + "column": "full_content", + "to": "full_content_embedding", + **community_report_full_content_embed_config, + }, + }, + { + "verb": "text_embed", + "enabled": not skip_summary_embedding, + "args": { + "embedding_name": "community_report_summary", + "column": "summary", + "to": "summary_embedding", + **community_report_summary_embed_config, + }, + }, + { + "verb": "text_embed", + "enabled": not skip_title_embedding, + "args": { + "embedding_name": "community_report_title", + "column": "title", + "to": "title_embedding", + **community_report_title_embed_config, + }, + }, + ] diff --git a/graphrag/graphrag/index/workflows/v1/create_final_covariates.py b/graphrag/graphrag/index/workflows/v1/create_final_covariates.py new file mode 100644 index 0000000000000000000000000000000000000000..d1090e5054e363e60ea671ccdeec94810d397549 --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/create_final_covariates.py @@ -0,0 +1,90 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from datashaper import AsyncType + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "create_final_covariates" + + +def build_steps( + config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the final covariates table. + + ## Dependencies + * `workflow:create_base_text_units` + * `workflow:create_base_extracted_entities` + """ + claim_extract_config = config.get("claim_extract", {}) + + input = {"source": "workflow:create_base_text_units"} + + return [ + { + "verb": "extract_covariates", + "args": { + "column": config.get("chunk_column", "chunk"), + "id_column": config.get("chunk_id_column", "chunk_id"), + "resolved_entities_column": "resolved_entities", + "covariate_type": "claim", + "async_mode": config.get("async_mode", AsyncType.AsyncIO), + **claim_extract_config, + }, + "input": input, + }, + { + "verb": "window", + "args": {"to": "id", "operation": "uuid", "column": "covariate_type"}, + }, + { + "verb": "genid", + "args": { + "to": "human_readable_id", + "method": "increment", + }, + }, + { + "verb": "convert", + "args": { + "column": "human_readable_id", + "type": "string", + "to": "human_readable_id", + }, + }, + { + "verb": "rename", + "args": { + "columns": { + "chunk_id": "text_unit_id", + } + }, + }, + { + "verb": "select", + "args": { + "columns": [ + "id", + "human_readable_id", + "covariate_type", + "type", + "description", + "subject_id", + "subject_type", + "object_id", + "object_type", + "status", + "start_date", + "end_date", + "source_text", + "text_unit_id", + "document_ids", + "n_tokens", + ] + }, + }, + ] diff --git a/graphrag/graphrag/index/workflows/v1/create_final_documents.py b/graphrag/graphrag/index/workflows/v1/create_final_documents.py new file mode 100644 index 0000000000000000000000000000000000000000..d09ce001b0205ef652f86201e57903d4b0546084 --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/create_final_documents.py @@ -0,0 +1,41 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "create_final_documents" + + +def build_steps( + config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the final documents table. + + ## Dependencies + * `workflow:create_base_documents` + * `workflow:create_base_document_nodes` + """ + base_text_embed = config.get("text_embed", {}) + document_raw_content_embed_config = config.get( + "document_raw_content_embed", base_text_embed + ) + skip_raw_content_embedding = config.get("skip_raw_content_embedding", False) + return [ + { + "verb": "rename", + "args": {"columns": {"text_units": "text_unit_ids"}}, + "input": {"source": "workflow:create_base_documents"}, + }, + { + "verb": "text_embed", + "enabled": not skip_raw_content_embedding, + "args": { + "column": "raw_content", + "to": "raw_content_embedding", + **document_raw_content_embed_config, + }, + }, + ] diff --git a/graphrag/graphrag/index/workflows/v1/create_final_entities.py b/graphrag/graphrag/index/workflows/v1/create_final_entities.py new file mode 100644 index 0000000000000000000000000000000000000000..9d8b962b77ff813e5dbd73c256199560a54e2b12 --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/create_final_entities.py @@ -0,0 +1,133 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "create_final_entities" + + +def build_steps( + config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the final entities table. + + ## Dependencies + * `workflow:create_base_entity_graph` + """ + base_text_embed = config.get("text_embed", {}) + entity_name_embed_config = config.get("entity_name_embed", base_text_embed) + entity_name_description_embed_config = config.get( + "entity_name_description_embed", base_text_embed + ) + skip_name_embedding = config.get("skip_name_embedding", False) + skip_description_embedding = config.get("skip_description_embedding", False) + is_using_vector_store = ( + entity_name_embed_config.get("strategy", {}).get("vector_store", None) + is not None + ) + + return [ + { + "verb": "unpack_graph", + "args": { + "column": "clustered_graph", + "type": "nodes", + }, + "input": {"source": "workflow:create_base_entity_graph"}, + }, + {"verb": "rename", "args": {"columns": {"label": "title"}}}, + { + "verb": "select", + "args": { + "columns": [ + "id", + "title", + "type", + "description", + "human_readable_id", + "graph_embedding", + "source_id", + ], + }, + }, + { + # create_base_entity_graph has multiple levels of clustering, which means there are multiple graphs with the same entities + # this dedupes the entities so that there is only one of each entity + "verb": "dedupe", + "args": {"columns": ["id"]}, + }, + {"verb": "rename", "args": {"columns": {"title": "name"}}}, + { + # ELIMINATE EMPTY NAMES + "verb": "filter", + "args": { + "column": "name", + "criteria": [ + { + "type": "value", + "operator": "is not empty", + } + ], + }, + }, + { + "verb": "text_split", + "args": {"separator": ",", "column": "source_id", "to": "text_unit_ids"}, + }, + {"verb": "drop", "args": {"columns": ["source_id"]}}, + { + "verb": "text_embed", + "enabled": not skip_name_embedding, + "args": { + "embedding_name": "entity_name", + "column": "name", + "to": "name_embedding", + **entity_name_embed_config, + }, + }, + { + "verb": "merge", + "enabled": not skip_description_embedding, + "args": { + "strategy": "concat", + "columns": ["name", "description"], + "to": "name_description", + "delimiter": ":", + "preserveSource": True, + }, + }, + { + "verb": "text_embed", + "enabled": not skip_description_embedding, + "args": { + "embedding_name": "entity_name_description", + "column": "name_description", + "to": "description_embedding", + **entity_name_description_embed_config, + }, + }, + { + "verb": "drop", + "enabled": not skip_description_embedding, + "args": { + "columns": ["name_description"], + }, + }, + { + # ELIMINATE EMPTY DESCRIPTION EMBEDDINGS + "verb": "filter", + "enabled": not skip_description_embedding and not is_using_vector_store, + "args": { + "column": "description_embedding", + "criteria": [ + { + "type": "value", + "operator": "is not empty", + } + ], + }, + }, + ] diff --git a/graphrag/graphrag/index/workflows/v1/create_final_nodes.py b/graphrag/graphrag/index/workflows/v1/create_final_nodes.py new file mode 100644 index 0000000000000000000000000000000000000000..31277e7bf07368f45f8a19a895137cbdb005ebe3 --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/create_final_nodes.py @@ -0,0 +1,116 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "create_final_nodes" + + +def build_steps( + config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the base table for the document graph. + + ## Dependencies + * `workflow:create_base_entity_graph` + """ + snapshot_top_level_nodes = config.get("snapshot_top_level_nodes", False) + layout_graph_enabled = config.get("layout_graph_enabled", True) + _compute_top_level_node_positions = [ + { + "verb": "unpack_graph", + "args": {"column": "positioned_graph", "type": "nodes"}, + "input": {"source": "laid_out_entity_graph"}, + }, + { + "verb": "filter", + "args": { + "column": "level", + "criteria": [ + { + "type": "value", + "operator": "equals", + "value": config.get("level_for_node_positions", 0), + } + ], + }, + }, + { + "verb": "select", + "args": {"columns": ["id", "x", "y"]}, + }, + { + "verb": "snapshot", + "enabled": snapshot_top_level_nodes, + "args": { + "name": "top_level_nodes", + "formats": ["json"], + }, + }, + { + "id": "_compute_top_level_node_positions", + "verb": "rename", + "args": { + "columns": { + "id": "top_level_node_id", + } + }, + }, + { + "verb": "convert", + "args": { + "column": "top_level_node_id", + "to": "top_level_node_id", + "type": "string", + }, + }, + ] + layout_graph_config = config.get( + "layout_graph", + { + "strategy": { + "type": "umap" if layout_graph_enabled else "zero", + }, + }, + ) + return [ + { + "id": "laid_out_entity_graph", + "verb": "layout_graph", + "args": { + "embeddings_column": "embeddings", + "graph_column": "clustered_graph", + "to": "node_positions", + "graph_to": "positioned_graph", + **layout_graph_config, + }, + "input": {"source": "workflow:create_base_entity_graph"}, + }, + { + "verb": "unpack_graph", + "args": {"column": "positioned_graph", "type": "nodes"}, + }, + { + "id": "nodes_without_positions", + "verb": "drop", + "args": {"columns": ["x", "y"]}, + }, + *_compute_top_level_node_positions, + { + "verb": "join", + "args": { + "on": ["id", "top_level_node_id"], + }, + "input": { + "source": "nodes_without_positions", + "others": ["_compute_top_level_node_positions"], + }, + }, + { + "verb": "rename", + "args": {"columns": {"label": "title", "cluster": "community"}}, + }, + ] diff --git a/graphrag/graphrag/index/workflows/v1/create_final_relationships.py b/graphrag/graphrag/index/workflows/v1/create_final_relationships.py new file mode 100644 index 0000000000000000000000000000000000000000..a58c2a45b46c0ac16f0e9077749e3308a686f3c5 --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/create_final_relationships.py @@ -0,0 +1,94 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "create_final_relationships" + + +def build_steps( + config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the final relationships table. + + ## Dependencies + * `workflow:create_base_entity_graph` + """ + base_text_embed = config.get("text_embed", {}) + relationship_description_embed_config = config.get( + "relationship_description_embed", base_text_embed + ) + skip_description_embedding = config.get("skip_description_embedding", False) + + return [ + { + "verb": "unpack_graph", + "args": { + "column": "clustered_graph", + "type": "edges", + }, + "input": {"source": "workflow:create_base_entity_graph"}, + }, + { + "verb": "rename", + "args": {"columns": {"source_id": "text_unit_ids"}}, + }, + { + "verb": "filter", + "args": { + "column": "level", + "criteria": [{"type": "value", "operator": "equals", "value": 0}], + }, + }, + { + "verb": "text_embed", + "enabled": not skip_description_embedding, + "args": { + "embedding_name": "relationship_description", + "column": "description", + "to": "description_embedding", + **relationship_description_embed_config, + }, + }, + { + "id": "pruned_edges", + "verb": "drop", + "args": {"columns": ["level"]}, + }, + { + "id": "filtered_nodes", + "verb": "filter", + "args": { + "column": "level", + "criteria": [{"type": "value", "operator": "equals", "value": 0}], + }, + "input": "workflow:create_final_nodes", + }, + { + "verb": "compute_edge_combined_degree", + "args": {"to": "rank"}, + "input": { + "source": "pruned_edges", + "nodes": "filtered_nodes", + }, + }, + { + "verb": "convert", + "args": { + "column": "human_readable_id", + "type": "string", + "to": "human_readable_id", + }, + }, + { + "verb": "convert", + "args": { + "column": "text_unit_ids", + "type": "array", + "to": "text_unit_ids", + }, + }, + ] diff --git a/graphrag/graphrag/index/workflows/v1/create_final_text_units.py b/graphrag/graphrag/index/workflows/v1/create_final_text_units.py new file mode 100644 index 0000000000000000000000000000000000000000..56dd0a73d60f2ef60ca0221fcdee2fb21674db2d --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/create_final_text_units.py @@ -0,0 +1,161 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "create_final_text_units" + + +def build_steps( + config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the final text-units table. + + ## Dependencies + * `workflow:create_base_text_units` + * `workflow:create_final_entities` + * `workflow:create_final_communities` + """ + base_text_embed = config.get("text_embed", {}) + text_unit_text_embed_config = config.get("text_unit_text_embed", base_text_embed) + covariates_enabled = config.get("covariates_enabled", False) + skip_text_unit_embedding = config.get("skip_text_unit_embedding", False) + is_using_vector_store = ( + text_unit_text_embed_config.get("strategy", {}).get("vector_store", None) + is not None + ) + + return [ + { + "verb": "select", + "args": {"columns": ["id", "chunk", "document_ids", "n_tokens"]}, + "input": {"source": "workflow:create_base_text_units"}, + }, + { + "id": "pre_entity_join", + "verb": "rename", + "args": { + "columns": { + "chunk": "text", + }, + }, + }, + # Expand the TextUnits with EntityIDs + { + "id": "pre_relationship_join", + "verb": "join", + "args": { + "on": ["id", "id"], + "strategy": "left outer", + }, + "input": { + "source": "pre_entity_join", + "others": ["workflow:join_text_units_to_entity_ids"], + }, + }, + # Expand the TextUnits with RelationshipIDs + { + "id": "pre_covariate_join", + "verb": "join", + "args": { + "on": ["id", "id"], + "strategy": "left outer", + }, + "input": { + "source": "pre_relationship_join", + "others": ["workflow:join_text_units_to_relationship_ids"], + }, + }, + # Expand the TextUnits with CovariateIDs + { + "enabled": covariates_enabled, + "verb": "join", + "args": { + "on": ["id", "id"], + "strategy": "left outer", + }, + "input": { + "source": "pre_covariate_join", + "others": ["workflow:join_text_units_to_covariate_ids"], + }, + }, + # Mash the entities and relationships into arrays + { + "verb": "aggregate_override", + "args": { + "groupby": ["id"], # from the join above + "aggregations": [ + { + "column": "text", + "operation": "any", + "to": "text", + }, + { + "column": "n_tokens", + "operation": "any", + "to": "n_tokens", + }, + { + "column": "document_ids", + "operation": "any", + "to": "document_ids", + }, + { + "column": "entity_ids", + "operation": "any", + "to": "entity_ids", + }, + { + "column": "relationship_ids", + "operation": "any", + "to": "relationship_ids", + }, + *( + [] + if not covariates_enabled + else [ + { + "column": "covariate_ids", + "operation": "any", + "to": "covariate_ids", + } + ] + ), + ], + }, + }, + # Text-Embed after final aggregations + { + "id": "embedded_text_units", + "verb": "text_embed", + "enabled": not skip_text_unit_embedding, + "args": { + "column": config.get("column", "text"), + "to": config.get("to", "text_embedding"), + **text_unit_text_embed_config, + }, + }, + { + "verb": "select", + "args": { + # Final select to get output in the correct shape + "columns": [ + "id", + "text", + *( + [] + if (skip_text_unit_embedding or is_using_vector_store) + else ["text_embedding"] + ), + "n_tokens", + "document_ids", + "entity_ids", + "relationship_ids", + *([] if not covariates_enabled else ["covariate_ids"]), + ], + }, + }, + ] diff --git a/graphrag/graphrag/index/workflows/v1/create_summarized_entities.py b/graphrag/graphrag/index/workflows/v1/create_summarized_entities.py new file mode 100644 index 0000000000000000000000000000000000000000..8f8d7f0042fec331a471a497312e19ce2f7c0d2a --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/create_summarized_entities.py @@ -0,0 +1,47 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from datashaper import AsyncType + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "create_summarized_entities" + + +def build_steps( + config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the base table for extracted entities. + + ## Dependencies + * `workflow:create_base_text_units` + """ + summarize_descriptions_config = config.get("summarize_descriptions", {}) + graphml_snapshot_enabled = config.get("graphml_snapshot", False) or False + + return [ + { + "verb": "summarize_descriptions", + "args": { + **summarize_descriptions_config, + "column": "entity_graph", + "to": "entity_graph", + "async_mode": summarize_descriptions_config.get( + "async_mode", AsyncType.AsyncIO + ), + }, + "input": {"source": "workflow:create_base_extracted_entities"}, + }, + { + "verb": "snapshot_rows", + "enabled": graphml_snapshot_enabled, + "args": { + "base_name": "summarized_graph", + "column": "entity_graph", + "formats": [{"format": "text", "extension": "graphml"}], + }, + }, + ] diff --git a/graphrag/graphrag/index/workflows/v1/join_text_units_to_covariate_ids.py b/graphrag/graphrag/index/workflows/v1/join_text_units_to_covariate_ids.py new file mode 100644 index 0000000000000000000000000000000000000000..be6bddf1e45a7c27ac9c587e4bc7cad01d323a62 --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/join_text_units_to_covariate_ids.py @@ -0,0 +1,44 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "join_text_units_to_covariate_ids" + + +def build_steps( + _config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create the final text-units table. + + ## Dependencies + * `workflow:create_final_covariates` + """ + return [ + { + "verb": "select", + "args": {"columns": ["id", "text_unit_id"]}, + "input": {"source": "workflow:create_final_covariates"}, + }, + { + "verb": "aggregate_override", + "args": { + "groupby": ["text_unit_id"], + "aggregations": [ + { + "column": "id", + "operation": "array_agg_distinct", + "to": "covariate_ids", + }, + { + "column": "text_unit_id", + "operation": "any", + "to": "id", + }, + ], + }, + }, + ] diff --git a/graphrag/graphrag/index/workflows/v1/join_text_units_to_entity_ids.py b/graphrag/graphrag/index/workflows/v1/join_text_units_to_entity_ids.py new file mode 100644 index 0000000000000000000000000000000000000000..6337502d1abd84d1f9ad9d8223afdb5412ab846d --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/join_text_units_to_entity_ids.py @@ -0,0 +1,50 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "join_text_units_to_entity_ids" + + +def build_steps( + _config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create a join table from text unit ids to entity ids. + + ## Dependencies + * `workflow:create_final_entities` + """ + return [ + { + "verb": "select", + "args": {"columns": ["id", "text_unit_ids"]}, + "input": {"source": "workflow:create_final_entities"}, + }, + { + "verb": "unroll", + "args": { + "column": "text_unit_ids", + }, + }, + { + "verb": "aggregate_override", + "args": { + "groupby": ["text_unit_ids"], + "aggregations": [ + { + "column": "id", + "operation": "array_agg_distinct", + "to": "entity_ids", + }, + { + "column": "text_unit_ids", + "operation": "any", + "to": "id", + }, + ], + }, + }, + ] diff --git a/graphrag/graphrag/index/workflows/v1/join_text_units_to_relationship_ids.py b/graphrag/graphrag/index/workflows/v1/join_text_units_to_relationship_ids.py new file mode 100644 index 0000000000000000000000000000000000000000..fe6d6463beed246f12ad945cdf0e4272ed03ac61 --- /dev/null +++ b/graphrag/graphrag/index/workflows/v1/join_text_units_to_relationship_ids.py @@ -0,0 +1,55 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing build_steps method definition.""" + +from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep + +workflow_name = "join_text_units_to_relationship_ids" + + +def build_steps( + _config: PipelineWorkflowConfig, +) -> list[PipelineWorkflowStep]: + """ + Create a join table from text unit ids to relationship ids. + + ## Dependencies + * `workflow:create_final_relationships + """ + return [ + { + "verb": "select", + "args": {"columns": ["id", "text_unit_ids"]}, + "input": {"source": "workflow:create_final_relationships"}, + }, + { + "verb": "unroll", + "args": { + "column": "text_unit_ids", + }, + }, + { + "verb": "aggregate_override", + "args": { + "groupby": ["text_unit_ids"], + "aggregations": [ + { + "column": "id", + "operation": "array_agg_distinct", + "to": "relationship_ids", + }, + { + "column": "text_unit_ids", + "operation": "any", + "to": "id", + }, + ], + }, + }, + { + "id": "text_unit_id_to_relationship_ids", + "verb": "select", + "args": {"columns": ["id", "relationship_ids"]}, + }, + ] diff --git a/graphrag/graphrag/llm/__init__.py b/graphrag/graphrag/llm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..609be951b23e7ef0f936ab2a373bbc3e4cc8ff18 --- /dev/null +++ b/graphrag/graphrag/llm/__init__.py @@ -0,0 +1,91 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Datashaper OpenAI Utilities package.""" + +from .base import BaseLLM, CachingLLM, RateLimitingLLM +from .errors import RetriesExhaustedError +from .limiting import ( + CompositeLLMLimiter, + LLMLimiter, + NoopLLMLimiter, + TpmRpmLLMLimiter, + create_tpm_rpm_limiters, +) +from .mock import MockChatLLM, MockCompletionLLM +from .openai import ( + OpenAIChatLLM, + OpenAIClientTypes, + OpenAICompletionLLM, + OpenAIConfiguration, + OpenAIEmbeddingsLLM, + create_openai_chat_llm, + create_openai_client, + create_openai_completion_llm, + create_openai_embedding_llm, +) +from .types import ( + LLM, + CompletionInput, + CompletionLLM, + CompletionOutput, + EmbeddingInput, + EmbeddingLLM, + EmbeddingOutput, + ErrorHandlerFn, + IsResponseValidFn, + LLMCache, + LLMConfig, + LLMInput, + LLMInvocationFn, + LLMInvocationResult, + LLMOutput, + OnCacheActionFn, +) + +__all__ = [ + # LLM Types + "LLM", + "BaseLLM", + "CachingLLM", + "CompletionInput", + "CompletionLLM", + "CompletionOutput", + "CompositeLLMLimiter", + "EmbeddingInput", + "EmbeddingLLM", + "EmbeddingOutput", + # Callbacks + "ErrorHandlerFn", + "IsResponseValidFn", + # Cache + "LLMCache", + "LLMConfig", + # LLM I/O Types + "LLMInput", + "LLMInvocationFn", + "LLMInvocationResult", + "LLMLimiter", + "LLMOutput", + "MockChatLLM", + # Mock + "MockCompletionLLM", + "NoopLLMLimiter", + "OnCacheActionFn", + "OpenAIChatLLM", + "OpenAIClientTypes", + "OpenAICompletionLLM", + # OpenAI + "OpenAIConfiguration", + "OpenAIEmbeddingsLLM", + "RateLimitingLLM", + # Errors + "RetriesExhaustedError", + "TpmRpmLLMLimiter", + "create_openai_chat_llm", + "create_openai_client", + "create_openai_completion_llm", + "create_openai_embedding_llm", + # Limiters + "create_tpm_rpm_limiters", +] diff --git a/graphrag/graphrag/llm/base/__init__.py b/graphrag/graphrag/llm/base/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..dd5ebf9050376d88c4bd4bc883bdbd56d579fd9c --- /dev/null +++ b/graphrag/graphrag/llm/base/__init__.py @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Base LLM Implementations.""" + +from .base_llm import BaseLLM +from .caching_llm import CachingLLM +from .rate_limiting_llm import RateLimitingLLM + +__all__ = ["BaseLLM", "CachingLLM", "RateLimitingLLM"] diff --git a/graphrag/graphrag/llm/base/_create_cache_key.py b/graphrag/graphrag/llm/base/_create_cache_key.py new file mode 100644 index 0000000000000000000000000000000000000000..e435ba460d38abcb6145a1c46b2ba402b7669492 --- /dev/null +++ b/graphrag/graphrag/llm/base/_create_cache_key.py @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Cache key generation utils.""" + +import hashlib + + +def _llm_string(params: dict) -> str: + # New version of the cache is not including n in the params dictionary + # This avoids creating a new cache key for the same prompt + if "max_tokens" in params and "n" not in params: + params["n"] = None + return str(sorted((k, v) for k, v in params.items())) + + +def _hash(_input: str) -> str: + """Use a deterministic hashing approach.""" + return hashlib.md5(_input.encode()).hexdigest() # noqa S324 + + +def create_hash_key(operation: str, prompt: str, parameters: dict) -> str: + """Compute cache key from prompt and associated model and settings. + + Args: + prompt (str): The prompt run through the language model. + llm_string (str): The language model version and settings. + + Returns + ------- + str: The cache key. + """ + llm_string = _llm_string(parameters) + return f"{operation}-{_hash(prompt + llm_string)}" diff --git a/graphrag/graphrag/llm/base/base_llm.py b/graphrag/graphrag/llm/base/base_llm.py new file mode 100644 index 0000000000000000000000000000000000000000..66f1919cd43bc4ecb5c2f132e6aa4565e73562fa --- /dev/null +++ b/graphrag/graphrag/llm/base/base_llm.py @@ -0,0 +1,65 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Base LLM class definition.""" + +import traceback +from abc import ABC, abstractmethod +from typing import Generic, TypeVar + +from typing_extensions import Unpack + +from graphrag.llm.types import ( + LLM, + ErrorHandlerFn, + LLMInput, + LLMOutput, +) + +TIn = TypeVar("TIn") +TOut = TypeVar("TOut") + + +class BaseLLM(ABC, LLM[TIn, TOut], Generic[TIn, TOut]): + """LLM Implementation class definition.""" + + _on_error: ErrorHandlerFn | None + + def on_error(self, on_error: ErrorHandlerFn | None) -> None: + """Set the error handler function.""" + self._on_error = on_error + + @abstractmethod + async def _execute_llm( + self, + input: TIn, + **kwargs: Unpack[LLMInput], + ) -> TOut | None: + pass + + async def __call__( + self, + input: TIn, + **kwargs: Unpack[LLMInput], + ) -> LLMOutput[TOut]: + """Invoke the LLM.""" + is_json = kwargs.get("json") or False + if is_json: + return await self._invoke_json(input, **kwargs) + return await self._invoke(input, **kwargs) + + async def _invoke(self, input: TIn, **kwargs: Unpack[LLMInput]) -> LLMOutput[TOut]: + try: + output = await self._execute_llm(input, **kwargs) + return LLMOutput(output=output) + except Exception as e: + stack_trace = traceback.format_exc() + if self._on_error: + self._on_error(e, stack_trace, {"input": input}) + raise + + async def _invoke_json( + self, input: TIn, **kwargs: Unpack[LLMInput] + ) -> LLMOutput[TOut]: + msg = "JSON output not supported by this LLM" + raise NotImplementedError(msg) diff --git a/graphrag/graphrag/llm/base/caching_llm.py b/graphrag/graphrag/llm/base/caching_llm.py new file mode 100644 index 0000000000000000000000000000000000000000..51c99638f1ce0d078c6200f1b60f53eb47b0d5b8 --- /dev/null +++ b/graphrag/graphrag/llm/base/caching_llm.py @@ -0,0 +1,107 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A class to interact with the cache.""" + +import json +from typing import Any, Generic, TypeVar + +from typing_extensions import Unpack + +from graphrag.llm.types import LLM, LLMCache, LLMInput, LLMOutput, OnCacheActionFn + +from ._create_cache_key import create_hash_key + +# If there's a breaking change in what we cache, we should increment this version number to invalidate existing caches +_cache_strategy_version = 2 + +TIn = TypeVar("TIn") +TOut = TypeVar("TOut") + + +def _noop_cache_fn(_k: str, _v: str | None): + pass + + +class CachingLLM(LLM[TIn, TOut], Generic[TIn, TOut]): + """A class to interact with the cache.""" + + _cache: LLMCache + _delegate: LLM[TIn, TOut] + _operation: str + _llm_paramaters: dict + _on_cache_hit: OnCacheActionFn + _on_cache_miss: OnCacheActionFn + + def __init__( + self, + delegate: LLM[TIn, TOut], + llm_parameters: dict, + operation: str, + cache: LLMCache, + ): + self._delegate = delegate + self._llm_paramaters = llm_parameters + self._cache = cache + self._operation = operation + self._on_cache_hit = _noop_cache_fn + self._on_cache_miss = _noop_cache_fn + + def on_cache_hit(self, fn: OnCacheActionFn | None) -> None: + """Set the function to call when a cache hit occurs.""" + self._on_cache_hit = fn or _noop_cache_fn + + def on_cache_miss(self, fn: OnCacheActionFn | None) -> None: + """Set the function to call when a cache miss occurs.""" + self._on_cache_miss = fn or _noop_cache_fn + + def _cache_key(self, input: TIn, name: str | None, args: dict) -> str: + json_input = json.dumps(input) + tag = ( + f"{name}-{self._operation}-v{_cache_strategy_version}" + if name is not None + else self._operation + ) + return create_hash_key(tag, json_input, args) + + async def _cache_read(self, key: str) -> Any | None: + """Read a value from the cache.""" + return await self._cache.get(key) + + async def _cache_write( + self, key: str, input: TIn, result: TOut | None, args: dict + ) -> None: + """Write a value to the cache.""" + if result: + await self._cache.set( + key, + result, + { + "input": input, + "parameters": args, + }, + ) + + async def __call__( + self, + input: TIn, + **kwargs: Unpack[LLMInput], + ) -> LLMOutput[TOut]: + """Execute the LLM.""" + # Check for an Existing cache item + name = kwargs.get("name") + llm_args = {**self._llm_paramaters, **(kwargs.get("model_parameters") or {})} + cache_key = self._cache_key(input, name, llm_args) + cached_result = await self._cache_read(cache_key) + if cached_result: + self._on_cache_hit(cache_key, name) + return LLMOutput(output=cached_result) + + # Report the Cache Miss + self._on_cache_miss(cache_key, name) + + # Compute the new result + result = await self._delegate(input, **kwargs) + # Cache the new result + await self._cache_write(cache_key, input, result.output, llm_args) + return result diff --git a/graphrag/graphrag/llm/base/rate_limiting_llm.py b/graphrag/graphrag/llm/base/rate_limiting_llm.py new file mode 100644 index 0000000000000000000000000000000000000000..5e2082475f60f6cb2a96663bafc8095d50924b60 --- /dev/null +++ b/graphrag/graphrag/llm/base/rate_limiting_llm.py @@ -0,0 +1,208 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Rate limiting LLM implementation.""" + +import asyncio +import logging +from collections.abc import Callable +from typing import Any, Generic, TypeVar + +from tenacity import ( + AsyncRetrying, + retry_if_exception_type, + stop_after_attempt, + wait_exponential_jitter, +) +from typing_extensions import Unpack + +from graphrag.llm.errors import RetriesExhaustedError +from graphrag.llm.limiting import LLMLimiter +from graphrag.llm.types import ( + LLM, + LLMConfig, + LLMInput, + LLMInvocationFn, + LLMInvocationResult, + LLMOutput, +) + +TIn = TypeVar("TIn") +TOut = TypeVar("TOut") +TRateLimitError = TypeVar("TRateLimitError", bound=BaseException) + +_CANNOT_MEASURE_INPUT_TOKENS_MSG = "cannot measure input tokens" +_CANNOT_MEASURE_OUTPUT_TOKENS_MSG = "cannot measure output tokens" + +log = logging.getLogger(__name__) + + +class RateLimitingLLM(LLM[TIn, TOut], Generic[TIn, TOut]): + """A class to interact with the cache.""" + + _delegate: LLM[TIn, TOut] + _rate_limiter: LLMLimiter | None + _semaphore: asyncio.Semaphore | None + _count_tokens: Callable[[str], int] + _config: LLMConfig + _operation: str + _retryable_errors: list[type[Exception]] + _rate_limit_errors: list[type[Exception]] + _on_invoke: LLMInvocationFn + _extract_sleep_recommendation: Callable[[Any], float] + + def __init__( + self, + delegate: LLM[TIn, TOut], + config: LLMConfig, + operation: str, + retryable_errors: list[type[Exception]], + rate_limit_errors: list[type[Exception]], + rate_limiter: LLMLimiter | None = None, + semaphore: asyncio.Semaphore | None = None, + count_tokens: Callable[[str], int] | None = None, + get_sleep_time: Callable[[BaseException], float] | None = None, + ): + self._delegate = delegate + self._rate_limiter = rate_limiter + self._semaphore = semaphore + self._config = config + self._operation = operation + self._retryable_errors = retryable_errors + self._rate_limit_errors = rate_limit_errors + self._count_tokens = count_tokens or (lambda _s: -1) + self._extract_sleep_recommendation = get_sleep_time or (lambda _e: 0.0) + self._on_invoke = lambda _v: None + + def on_invoke(self, fn: LLMInvocationFn | None) -> None: + """Set the on_invoke function.""" + self._on_invoke = fn or (lambda _v: None) + + def count_request_tokens(self, input: TIn) -> int: + """Count the request tokens on an input request.""" + if isinstance(input, str): + return self._count_tokens(input) + if isinstance(input, list): + result = 0 + for item in input: + if isinstance(item, str): + result += self._count_tokens(item) + elif isinstance(item, dict): + result += self._count_tokens(item.get("content", "")) + else: + raise TypeError(_CANNOT_MEASURE_INPUT_TOKENS_MSG) + return result + raise TypeError(_CANNOT_MEASURE_INPUT_TOKENS_MSG) + + def count_response_tokens(self, output: TOut | None) -> int: + """Count the request tokens on an output response.""" + if output is None: + return 0 + if isinstance(output, str): + return self._count_tokens(output) + if isinstance(output, list) and all(isinstance(x, str) for x in output): + return sum(self._count_tokens(item) for item in output) + if isinstance(output, list): + # Embedding response, don't count it + return 0 + raise TypeError(_CANNOT_MEASURE_OUTPUT_TOKENS_MSG) + + async def __call__( + self, + input: TIn, + **kwargs: Unpack[LLMInput], + ) -> LLMOutput[TOut]: + """Execute the LLM with semaphore & rate limiting.""" + name = kwargs.get("name", "Process") + attempt_number = 0 + call_times: list[float] = [] + input_tokens = self.count_request_tokens(input) + max_retries = self._config.max_retries or 10 + max_retry_wait = self._config.max_retry_wait or 10 + follow_recommendation = self._config.sleep_on_rate_limit_recommendation + retryer = AsyncRetrying( + stop=stop_after_attempt(max_retries), + wait=wait_exponential_jitter(max=max_retry_wait), + reraise=True, + retry=retry_if_exception_type(tuple(self._retryable_errors)), + ) + + async def sleep_for(time: float | None) -> None: + log.warning( + "%s failed to invoke LLM %s/%s attempts. Cause: rate limit exceeded, will retry. Recommended sleep for %d seconds. Follow recommendation? %s", + name, + attempt_number, + max_retries, + time, + follow_recommendation, + ) + if follow_recommendation and time: + await asyncio.sleep(time) + raise + + async def do_attempt() -> LLMOutput[TOut]: + nonlocal call_times + call_start = asyncio.get_event_loop().time() + try: + return await self._delegate(input, **kwargs) + except BaseException as e: + if isinstance(e, tuple(self._rate_limit_errors)): + sleep_time = self._extract_sleep_recommendation(e) + await sleep_for(sleep_time) + raise + finally: + call_end = asyncio.get_event_loop().time() + call_times.append(call_end - call_start) + + async def execute_with_retry() -> tuple[LLMOutput[TOut], float]: + nonlocal attempt_number + async for attempt in retryer: + with attempt: + if self._rate_limiter and input_tokens > 0: + await self._rate_limiter.acquire(input_tokens) + start = asyncio.get_event_loop().time() + attempt_number += 1 + return await do_attempt(), start + + log.error("Retries exhausted for %s", name) + raise RetriesExhaustedError(name, max_retries) + + result: LLMOutput[TOut] + start = 0.0 + + if self._semaphore is None: + result, start = await execute_with_retry() + else: + async with self._semaphore: + result, start = await execute_with_retry() + + end = asyncio.get_event_loop().time() + output_tokens = self.count_response_tokens(result.output) + if self._rate_limiter and output_tokens > 0: + await self._rate_limiter.acquire(output_tokens) + + invocation_result = LLMInvocationResult( + result=result, + name=name, + num_retries=attempt_number - 1, + total_time=end - start, + call_times=call_times, + input_tokens=input_tokens, + output_tokens=output_tokens, + ) + self._handle_invoke_result(invocation_result) + return result + + def _handle_invoke_result( + self, result: LLMInvocationResult[LLMOutput[TOut]] + ) -> None: + log.info( + 'perf - llm.%s "%s" with %s retries took %s. input_tokens=%d, output_tokens=%d', + self._operation, + result.name, + result.num_retries, + result.total_time, + result.input_tokens, + result.output_tokens, + ) + self._on_invoke(result) diff --git a/graphrag/graphrag/llm/errors.py b/graphrag/graphrag/llm/errors.py new file mode 100644 index 0000000000000000000000000000000000000000..01136359de622d347a4c1e61ca5c51219f314086 --- /dev/null +++ b/graphrag/graphrag/llm/errors.py @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Error definitions for the OpenAI DataShaper package.""" + + +class RetriesExhaustedError(RuntimeError): + """Retries exhausted error.""" + + def __init__(self, name: str, num_retries: int) -> None: + """Init method definition.""" + super().__init__(f"Operation '{name}' failed - {num_retries} retries exhausted") diff --git a/graphrag/graphrag/llm/limiting/__init__.py b/graphrag/graphrag/llm/limiting/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4f7933d1a802557737196f228f2688e090fbc6b7 --- /dev/null +++ b/graphrag/graphrag/llm/limiting/__init__.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""LLM limiters module.""" + +from .composite_limiter import CompositeLLMLimiter +from .create_limiters import create_tpm_rpm_limiters +from .llm_limiter import LLMLimiter +from .noop_llm_limiter import NoopLLMLimiter +from .tpm_rpm_limiter import TpmRpmLLMLimiter + +__all__ = [ + "CompositeLLMLimiter", + "LLMLimiter", + "NoopLLMLimiter", + "TpmRpmLLMLimiter", + "create_tpm_rpm_limiters", +] diff --git a/graphrag/graphrag/llm/limiting/composite_limiter.py b/graphrag/graphrag/llm/limiting/composite_limiter.py new file mode 100644 index 0000000000000000000000000000000000000000..7bcf9195b2515eb4d255ac2bfadf00318dbf0e32 --- /dev/null +++ b/graphrag/graphrag/llm/limiting/composite_limiter.py @@ -0,0 +1,26 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing Composite Limiter class definition.""" + +from .llm_limiter import LLMLimiter + + +class CompositeLLMLimiter(LLMLimiter): + """Composite Limiter class definition.""" + + _limiters: list[LLMLimiter] + + def __init__(self, limiters: list[LLMLimiter]): + """Init method definition.""" + self._limiters = limiters + + @property + def needs_token_count(self) -> bool: + """Whether this limiter needs the token count to be passed in.""" + return any(limiter.needs_token_count for limiter in self._limiters) + + async def acquire(self, num_tokens: int = 1) -> None: + """Call method definition.""" + for limiter in self._limiters: + await limiter.acquire(num_tokens) diff --git a/graphrag/graphrag/llm/limiting/create_limiters.py b/graphrag/graphrag/llm/limiting/create_limiters.py new file mode 100644 index 0000000000000000000000000000000000000000..92df11c1a6780732cc2de88763c062d26469fdc8 --- /dev/null +++ b/graphrag/graphrag/llm/limiting/create_limiters.py @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Create limiters for OpenAI API requests.""" + +import logging + +from aiolimiter import AsyncLimiter + +from graphrag.llm.types import LLMConfig + +from .llm_limiter import LLMLimiter +from .tpm_rpm_limiter import TpmRpmLLMLimiter + +log = logging.getLogger(__name__) + +"""The global TPM limiters.""" + + +def create_tpm_rpm_limiters( + configuration: LLMConfig, +) -> LLMLimiter: + """Get the limiters for a given model name.""" + tpm = configuration.tokens_per_minute + rpm = configuration.requests_per_minute + return TpmRpmLLMLimiter( + None if tpm == 0 else AsyncLimiter(tpm or 50_000), + None if rpm == 0 else AsyncLimiter(rpm or 10_000), + ) diff --git a/graphrag/graphrag/llm/limiting/llm_limiter.py b/graphrag/graphrag/llm/limiting/llm_limiter.py new file mode 100644 index 0000000000000000000000000000000000000000..1264a84be58e5e23a3495f91ddf09e05fb66fdd9 --- /dev/null +++ b/graphrag/graphrag/llm/limiting/llm_limiter.py @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Limiting types.""" + +from abc import ABC, abstractmethod + + +class LLMLimiter(ABC): + """LLM Limiter Interface.""" + + @property + @abstractmethod + def needs_token_count(self) -> bool: + """Whether this limiter needs the token count to be passed in.""" + + @abstractmethod + async def acquire(self, num_tokens: int = 1) -> None: + """Acquire a pass through the limiter.""" diff --git a/graphrag/graphrag/llm/limiting/noop_llm_limiter.py b/graphrag/graphrag/llm/limiting/noop_llm_limiter.py new file mode 100644 index 0000000000000000000000000000000000000000..5147055255b5f854588856c023f34aae554b60c4 --- /dev/null +++ b/graphrag/graphrag/llm/limiting/noop_llm_limiter.py @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""TPM RPM Limiter module.""" + +from .llm_limiter import LLMLimiter + + +class NoopLLMLimiter(LLMLimiter): + """TPM RPM Limiter class definition.""" + + @property + def needs_token_count(self) -> bool: + """Whether this limiter needs the token count to be passed in.""" + return False + + async def acquire(self, num_tokens: int = 1) -> None: + """Call method definition.""" + # do nothing diff --git a/graphrag/graphrag/llm/limiting/tpm_rpm_limiter.py b/graphrag/graphrag/llm/limiting/tpm_rpm_limiter.py new file mode 100644 index 0000000000000000000000000000000000000000..cb6d84e377e25767011976ca753b6c97ecbc8941 --- /dev/null +++ b/graphrag/graphrag/llm/limiting/tpm_rpm_limiter.py @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""TPM RPM Limiter module.""" + +from aiolimiter import AsyncLimiter + +from .llm_limiter import LLMLimiter + + +class TpmRpmLLMLimiter(LLMLimiter): + """TPM RPM Limiter class definition.""" + + _tpm_limiter: AsyncLimiter | None + _rpm_limiter: AsyncLimiter | None + + def __init__( + self, tpm_limiter: AsyncLimiter | None, rpm_limiter: AsyncLimiter | None + ): + """Init method definition.""" + self._tpm_limiter = tpm_limiter + self._rpm_limiter = rpm_limiter + + @property + def needs_token_count(self) -> bool: + """Whether this limiter needs the token count to be passed in.""" + return self._tpm_limiter is not None + + async def acquire(self, num_tokens: int = 1) -> None: + """Call method definition.""" + if self._tpm_limiter is not None: + await self._tpm_limiter.acquire(num_tokens) + if self._rpm_limiter is not None: + await self._rpm_limiter.acquire() diff --git a/graphrag/graphrag/llm/mock/__init__.py b/graphrag/graphrag/llm/mock/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cd1f000dd16cd3c734b94d986f7fdc08abdd03fc --- /dev/null +++ b/graphrag/graphrag/llm/mock/__init__.py @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Mock LLM Implementations.""" + +from .mock_chat_llm import MockChatLLM +from .mock_completion_llm import MockCompletionLLM + +__all__ = [ + "MockChatLLM", + "MockCompletionLLM", +] diff --git a/graphrag/graphrag/llm/mock/mock_chat_llm.py b/graphrag/graphrag/llm/mock/mock_chat_llm.py new file mode 100644 index 0000000000000000000000000000000000000000..b8a6650b3142815e4a1d5a684c688711c543cd08 --- /dev/null +++ b/graphrag/graphrag/llm/mock/mock_chat_llm.py @@ -0,0 +1,52 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A mock ChatLLM that returns the given responses.""" + +from typing_extensions import Unpack + +from graphrag.llm.base import BaseLLM +from graphrag.llm.types import ( + CompletionInput, + CompletionOutput, + LLMInput, + LLMOutput, +) + + +class MockChatLLM( + BaseLLM[ + CompletionInput, + CompletionOutput, + ] +): + """A mock LLM that returns the given responses.""" + + responses: list[str] + i: int = 0 + + def __init__(self, responses: list[str]): + self.i = 0 + self.responses = responses + + def _create_output( + self, + output: CompletionOutput | None, + **kwargs: Unpack[LLMInput], + ) -> LLMOutput[CompletionOutput]: + history = kwargs.get("history") or [] + return LLMOutput[CompletionOutput]( + output=output, history=[*history, {"content": output}] + ) + + async def _execute_llm( + self, + input: CompletionInput, + **kwargs: Unpack[LLMInput], + ) -> CompletionOutput: + if self.i >= len(self.responses): + msg = f"No more responses, requested {self.i} but only have {len(self.responses)}" + raise ValueError(msg) + response = self.responses[self.i] + self.i += 1 + return response diff --git a/graphrag/graphrag/llm/mock/mock_completion_llm.py b/graphrag/graphrag/llm/mock/mock_completion_llm.py new file mode 100644 index 0000000000000000000000000000000000000000..8cb8e95083a1d5cad1201184f9706f79307aec09 --- /dev/null +++ b/graphrag/graphrag/llm/mock/mock_completion_llm.py @@ -0,0 +1,37 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""LLM Static Response method definition.""" + +import logging + +from typing_extensions import Unpack + +from graphrag.llm.base import BaseLLM +from graphrag.llm.types import ( + CompletionInput, + CompletionOutput, + LLMInput, +) + +log = logging.getLogger(__name__) + + +class MockCompletionLLM( + BaseLLM[ + CompletionInput, + CompletionOutput, + ] +): + """Mock Completion LLM for testing purposes.""" + + def __init__(self, responses: list[str]): + self.responses = responses + self._on_error = None + + async def _execute_llm( + self, + input: CompletionInput, + **kwargs: Unpack[LLMInput], + ) -> CompletionOutput: + return self.responses[0] diff --git a/graphrag/graphrag/llm/openai/__init__.py b/graphrag/graphrag/llm/openai/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9478e146d2dc82bc3c05d96b02e6be9eb539e351 --- /dev/null +++ b/graphrag/graphrag/llm/openai/__init__.py @@ -0,0 +1,28 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""OpenAI LLM implementations.""" + +from .create_openai_client import create_openai_client +from .factories import ( + create_openai_chat_llm, + create_openai_completion_llm, + create_openai_embedding_llm, +) +from .openai_chat_llm import OpenAIChatLLM +from .openai_completion_llm import OpenAICompletionLLM +from .openai_configuration import OpenAIConfiguration +from .openai_embeddings_llm import OpenAIEmbeddingsLLM +from .types import OpenAIClientTypes + +__all__ = [ + "OpenAIChatLLM", + "OpenAIClientTypes", + "OpenAICompletionLLM", + "OpenAIConfiguration", + "OpenAIEmbeddingsLLM", + "create_openai_chat_llm", + "create_openai_client", + "create_openai_completion_llm", + "create_openai_embedding_llm", +] diff --git a/graphrag/graphrag/llm/openai/_json.py b/graphrag/graphrag/llm/openai/_json.py new file mode 100644 index 0000000000000000000000000000000000000000..22184cc221bf10ab8ac3d352e47e1645a55eb17a --- /dev/null +++ b/graphrag/graphrag/llm/openai/_json.py @@ -0,0 +1,25 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""JSON cleaning and formatting utilities.""" + + +def clean_up_json(json_str: str) -> str: + """Clean up json string.""" + json_str = ( + json_str.replace("\\n", "") + .replace("\n", "") + .replace("\r", "") + .replace('"[{', "[{") + .replace('}]"', "}]") + .replace("\\", "") + .strip() + ) + + # Remove JSON Markdown Frame + if json_str.startswith("```json"): + json_str = json_str[len("```json") :] + if json_str.endswith("```"): + json_str = json_str[: len(json_str) - len("```")] + + return json_str diff --git a/graphrag/graphrag/llm/openai/_prompts.py b/graphrag/graphrag/llm/openai/_prompts.py new file mode 100644 index 0000000000000000000000000000000000000000..37d9f0fc70b6e7f3068be32ff5bd19dea90398c0 --- /dev/null +++ b/graphrag/graphrag/llm/openai/_prompts.py @@ -0,0 +1,39 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Utility prompts for low-level LLM invocations.""" + +JSON_CHECK_PROMPT = """ +You are going to be given a malformed JSON string that threw an error during json.loads. +It probably contains unnecessary escape sequences, or it is missing a comma or colon somewhere. +Your task is to fix this string and return a well-formed JSON string containing a single object. +Eliminate any unnecessary escape sequences. +Only return valid JSON, parseable with json.loads, without commentary. + +# Examples +----------- +Text: {{ \\"title\\": \\"abc\\", \\"summary\\": \\"def\\" }} +Output: {{"title": "abc", "summary": "def"}} +----------- +Text: {{"title": "abc", "summary": "def" +Output: {{"title": "abc", "summary": "def"}} +----------- +Text: {{"title': "abc", 'summary": "def" +Output: {{"title": "abc", "summary": "def"}} +----------- +Text: "{{"title": "abc", "summary": "def"}}" +Output: {{"title": "abc", "summary": "def"}} +----------- +Text: [{{"title": "abc", "summary": "def"}}] +Output: [{{"title": "abc", "summary": "def"}}] +----------- +Text: [{{"title": "abc", "summary": "def"}}, {{ \\"title\\": \\"abc\\", \\"summary\\": \\"def\\" }}] +Output: [{{"title": "abc", "summary": "def"}}, {{"title": "abc", "summary": "def"}}] +----------- +Text: ```json\n[{{"title": "abc", "summary": "def"}}, {{ \\"title\\": \\"abc\\", \\"summary\\": \\"def\\" }}]``` +Output: [{{"title": "abc", "summary": "def"}}, {{"title": "abc", "summary": "def"}}] + + +# Real Data +Text: {input_text} +Output:""" diff --git a/graphrag/graphrag/llm/openai/create_openai_client.py b/graphrag/graphrag/llm/openai/create_openai_client.py new file mode 100644 index 0000000000000000000000000000000000000000..218226189a5dc13ecf285793b8af36f39f85ca1b --- /dev/null +++ b/graphrag/graphrag/llm/openai/create_openai_client.py @@ -0,0 +1,79 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Create OpenAI client instance.""" + +import logging +from functools import cache +import re +from urllib.parse import urljoin + +from azure.identity import DefaultAzureCredential, get_bearer_token_provider +from openai import AsyncOpenAI + +from .openai_configuration import OpenAIConfiguration +from .types import OpenAIClientTypes + +log = logging.getLogger(__name__) + +API_BASE_REQUIRED_FOR_AZURE = "api_base is required for Azure OpenAI client" + + +def normalize_api_base(api_base: str) -> str: + # Remove trailing slashes + api_base = api_base.rstrip('/') + + # Check if the URL already ends with '/v1' + if not api_base.endswith('/v1'): + # If not, append '/v1' + api_base = urljoin(api_base, 'v1') + + return api_base + + +@cache +def create_openai_client( + configuration: OpenAIConfiguration, azure: bool +) -> OpenAIClientTypes: + """Create a new OpenAI client instance.""" + if azure: + api_base = configuration.api_base + if api_base is None: + raise ValueError(API_BASE_REQUIRED_FOR_AZURE) + + log.info( + "Creating Azure OpenAI client api_base=%s, deployment_name=%s", + api_base, + configuration.deployment_name, + ) + if configuration.cognitive_services_endpoint is None: + cognitive_services_endpoint = "https://cognitiveservices.azure.com/.default" + else: + cognitive_services_endpoint = configuration.cognitive_services_endpoint + + return AsyncOpenAI( + api_key=configuration.api_key if configuration.api_key else None, + azure_ad_token_provider=get_bearer_token_provider( + DefaultAzureCredential(), cognitive_services_endpoint + ) + if not configuration.api_key + else None, + organization=configuration.organization, + # Azure-Specifics + api_version=configuration.api_version, + azure_endpoint=api_base, + azure_deployment=configuration.deployment_name, + # Timeout/Retry Configuration - Use Tenacity for Retries, so disable them here + timeout=configuration.request_timeout or 180.0, + max_retries=0, + ) + + log.info("Creating OpenAI client base_url=%s", configuration.api_base) + return AsyncOpenAI( + api_key=configuration.api_key, + base_url=normalize_api_base(configuration.api_base), + organization=configuration.organization, + # Timeout/Retry Configuration - Use Tenacity for Retries, so disable them here + timeout=configuration.request_timeout or 180.0, + max_retries=0, + ) \ No newline at end of file diff --git a/graphrag/graphrag/llm/openai/factories.py b/graphrag/graphrag/llm/openai/factories.py new file mode 100644 index 0000000000000000000000000000000000000000..e595e2e55b69f82e12e8250a264621652180b2fc --- /dev/null +++ b/graphrag/graphrag/llm/openai/factories.py @@ -0,0 +1,140 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Factory functions for creating OpenAI LLMs.""" + +import asyncio + +from graphrag.llm.base import CachingLLM, RateLimitingLLM +from graphrag.llm.limiting import LLMLimiter +from graphrag.llm.types import ( + LLM, + CompletionLLM, + EmbeddingLLM, + ErrorHandlerFn, + LLMCache, + LLMInvocationFn, + OnCacheActionFn, +) + +from .json_parsing_llm import JsonParsingLLM +from .openai_chat_llm import OpenAIChatLLM +from .openai_completion_llm import OpenAICompletionLLM +from .openai_configuration import OpenAIConfiguration +from .openai_embeddings_llm import OpenAIEmbeddingsLLM +from .openai_history_tracking_llm import OpenAIHistoryTrackingLLM +from .openai_token_replacing_llm import OpenAITokenReplacingLLM +from .types import OpenAIClientTypes +from .utils import ( + RATE_LIMIT_ERRORS, + RETRYABLE_ERRORS, + get_completion_cache_args, + get_sleep_time_from_error, + get_token_counter, +) + + +def create_openai_chat_llm( + client: OpenAIClientTypes, + config: OpenAIConfiguration, + cache: LLMCache | None = None, + limiter: LLMLimiter | None = None, + semaphore: asyncio.Semaphore | None = None, + on_invoke: LLMInvocationFn | None = None, + on_error: ErrorHandlerFn | None = None, + on_cache_hit: OnCacheActionFn | None = None, + on_cache_miss: OnCacheActionFn | None = None, +) -> CompletionLLM: + """Create an OpenAI chat LLM.""" + operation = "chat" + result = OpenAIChatLLM(client, config) + result.on_error(on_error) + if limiter is not None or semaphore is not None: + result = _rate_limited(result, config, operation, limiter, semaphore, on_invoke) + if cache is not None: + result = _cached(result, config, operation, cache, on_cache_hit, on_cache_miss) + result = OpenAIHistoryTrackingLLM(result) + result = OpenAITokenReplacingLLM(result) + return JsonParsingLLM(result) + + +def create_openai_completion_llm( + client: OpenAIClientTypes, + config: OpenAIConfiguration, + cache: LLMCache | None = None, + limiter: LLMLimiter | None = None, + semaphore: asyncio.Semaphore | None = None, + on_invoke: LLMInvocationFn | None = None, + on_error: ErrorHandlerFn | None = None, + on_cache_hit: OnCacheActionFn | None = None, + on_cache_miss: OnCacheActionFn | None = None, +) -> CompletionLLM: + """Create an OpenAI completion LLM.""" + operation = "completion" + result = OpenAICompletionLLM(client, config) + result.on_error(on_error) + if limiter is not None or semaphore is not None: + result = _rate_limited(result, config, operation, limiter, semaphore, on_invoke) + if cache is not None: + result = _cached(result, config, operation, cache, on_cache_hit, on_cache_miss) + return OpenAITokenReplacingLLM(result) + + +def create_openai_embedding_llm( + client: OpenAIClientTypes, + config: OpenAIConfiguration, + cache: LLMCache | None = None, + limiter: LLMLimiter | None = None, + semaphore: asyncio.Semaphore | None = None, + on_invoke: LLMInvocationFn | None = None, + on_error: ErrorHandlerFn | None = None, + on_cache_hit: OnCacheActionFn | None = None, + on_cache_miss: OnCacheActionFn | None = None, +) -> EmbeddingLLM: + """Create an OpenAI embeddings LLM.""" + operation = "embedding" + result = OpenAIEmbeddingsLLM(client, config) + result.on_error(on_error) + if limiter is not None or semaphore is not None: + result = _rate_limited(result, config, operation, limiter, semaphore, on_invoke) + if cache is not None: + result = _cached(result, config, operation, cache, on_cache_hit, on_cache_miss) + return result + + +def _rate_limited( + delegate: LLM, + config: OpenAIConfiguration, + operation: str, + limiter: LLMLimiter | None, + semaphore: asyncio.Semaphore | None, + on_invoke: LLMInvocationFn | None, +): + result = RateLimitingLLM( + delegate, + config, + operation, + RETRYABLE_ERRORS, + RATE_LIMIT_ERRORS, + limiter, + semaphore, + get_token_counter(config), + get_sleep_time_from_error, + ) + result.on_invoke(on_invoke) + return result + + +def _cached( + delegate: LLM, + config: OpenAIConfiguration, + operation: str, + cache: LLMCache, + on_cache_hit: OnCacheActionFn | None, + on_cache_miss: OnCacheActionFn | None, +): + cache_args = get_completion_cache_args(config) + result = CachingLLM(delegate, cache_args, operation, cache) + result.on_cache_hit(on_cache_hit) + result.on_cache_miss(on_cache_miss) + return result diff --git a/graphrag/graphrag/llm/openai/json_parsing_llm.py b/graphrag/graphrag/llm/openai/json_parsing_llm.py new file mode 100644 index 0000000000000000000000000000000000000000..843ca0ecb738f6c886c40dcd0cdb4fb40ee968a8 --- /dev/null +++ b/graphrag/graphrag/llm/openai/json_parsing_llm.py @@ -0,0 +1,37 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""An LLM that unpacks cached JSON responses.""" + +from typing_extensions import Unpack + +from graphrag.llm.types import ( + LLM, + CompletionInput, + CompletionLLM, + CompletionOutput, + LLMInput, + LLMOutput, +) + +from .utils import try_parse_json_object + + +class JsonParsingLLM(LLM[CompletionInput, CompletionOutput]): + """An OpenAI History-Tracking LLM.""" + + _delegate: CompletionLLM + + def __init__(self, delegate: CompletionLLM): + self._delegate = delegate + + async def __call__( + self, + input: CompletionInput, + **kwargs: Unpack[LLMInput], + ) -> LLMOutput[CompletionOutput]: + """Call the LLM with the input and kwargs.""" + result = await self._delegate(input, **kwargs) + if kwargs.get("json") and result.json is None and result.output is not None: + result.json = try_parse_json_object(result.output) + return result diff --git a/graphrag/graphrag/llm/openai/openai_chat_llm.py b/graphrag/graphrag/llm/openai/openai_chat_llm.py new file mode 100644 index 0000000000000000000000000000000000000000..e4add8a25e7cef7e4ea5ffc30cfccf3f2ce8d438 --- /dev/null +++ b/graphrag/graphrag/llm/openai/openai_chat_llm.py @@ -0,0 +1,152 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Chat-based language model.""" + +import logging +from json import JSONDecodeError + +from typing_extensions import Unpack + +from graphrag.llm.base import BaseLLM +from graphrag.llm.types import ( + CompletionInput, + CompletionOutput, + LLMInput, + LLMOutput, +) + +from ._json import clean_up_json +from ._prompts import JSON_CHECK_PROMPT +from .openai_configuration import OpenAIConfiguration +from .types import OpenAIClientTypes +from .utils import ( + get_completion_llm_args, + try_parse_json_object, +) + +log = logging.getLogger(__name__) + +_MAX_GENERATION_RETRIES = 3 +FAILED_TO_CREATE_JSON_ERROR = "Failed to generate valid JSON output" + + +class OpenAIChatLLM(BaseLLM[CompletionInput, CompletionOutput]): + """A Chat-based LLM.""" + + _client: OpenAIClientTypes + _configuration: OpenAIConfiguration + + def __init__(self, client: OpenAIClientTypes, configuration: OpenAIConfiguration): + self.client = client + self.configuration = configuration + + async def _execute_llm( + self, input: CompletionInput, **kwargs: Unpack[LLMInput] + ) -> CompletionOutput | None: + args = get_completion_llm_args( + kwargs.get("model_parameters"), self.configuration + ) + history = kwargs.get("history") or [] + messages = [ + *history, + {"role": "user", "content": input}, + ] + completion = await self.client.chat.completions.create( + messages=messages, **args + ) + return completion.choices[0].message.content + + async def _invoke_json( + self, + input: CompletionInput, + **kwargs: Unpack[LLMInput], + ) -> LLMOutput[CompletionOutput]: + """Generate JSON output.""" + name = kwargs.get("name") or "unknown" + is_response_valid = kwargs.get("is_response_valid") or (lambda _x: True) + + async def generate( + attempt: int | None = None, + ) -> LLMOutput[CompletionOutput]: + call_name = name if attempt is None else f"{name}@{attempt}" + return ( + await self._native_json(input, **{**kwargs, "name": call_name}) + if self.configuration.model_supports_json + else await self._manual_json(input, **{**kwargs, "name": call_name}) + ) + + def is_valid(x: dict | None) -> bool: + return x is not None and is_response_valid(x) + + result = await generate() + retry = 0 + while not is_valid(result.json) and retry < _MAX_GENERATION_RETRIES: + result = await generate(retry) + retry += 1 + + if is_valid(result.json): + return result + raise RuntimeError(FAILED_TO_CREATE_JSON_ERROR) + + async def _native_json( + self, input: CompletionInput, **kwargs: Unpack[LLMInput] + ) -> LLMOutput[CompletionOutput]: + """Generate JSON output using a model's native JSON-output support.""" + result = await self._invoke( + input, + **{ + **kwargs, + "model_parameters": { + **(kwargs.get("model_parameters") or {}), + "response_format": {"type": "json_object"}, + }, + }, + ) + + raw_output = result.output or "" + json_output = try_parse_json_object(raw_output) + + return LLMOutput[CompletionOutput]( + output=raw_output, + json=json_output, + history=result.history, + ) + + async def _manual_json( + self, input: CompletionInput, **kwargs: Unpack[LLMInput] + ) -> LLMOutput[CompletionOutput]: + # Otherwise, clean up the output and try to parse it as json + result = await self._invoke(input, **kwargs) + history = result.history or [] + output = clean_up_json(result.output or "") + try: + json_output = try_parse_json_object(output) + return LLMOutput[CompletionOutput]( + output=output, json=json_output, history=history + ) + except (TypeError, JSONDecodeError): + log.warning("error parsing llm json, retrying") + # If cleaned up json is unparsable, use the LLM to reformat it (may throw) + result = await self._try_clean_json_with_llm(output, **kwargs) + output = clean_up_json(result.output or "") + json = try_parse_json_object(output) + + return LLMOutput[CompletionOutput]( + output=output, + json=json, + history=history, + ) + + async def _try_clean_json_with_llm( + self, output: str, **kwargs: Unpack[LLMInput] + ) -> LLMOutput[CompletionOutput]: + name = kwargs.get("name") or "unknown" + return await self._invoke( + JSON_CHECK_PROMPT, + **{ + **kwargs, + "variables": {"input_text": output}, + "name": f"fix_json@{name}", + }, + ) diff --git a/graphrag/graphrag/llm/openai/openai_completion_llm.py b/graphrag/graphrag/llm/openai/openai_completion_llm.py new file mode 100644 index 0000000000000000000000000000000000000000..87b074b03ba7dae67faf312aed0fcc550b451ef1 --- /dev/null +++ b/graphrag/graphrag/llm/openai/openai_completion_llm.py @@ -0,0 +1,53 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A text-completion based LLM.""" + +import logging +from typing import Any, Dict +from typing_extensions import Unpack + +from graphrag.llm.base import BaseLLM +from graphrag.llm.types import ( + CompletionInput, + CompletionOutput, + LLMInput, +) + +from .openai_configuration import OpenAIConfiguration +from .types import OpenAIClientTypes +from .utils import get_completion_llm_args + +log = logging.getLogger(__name__) + + +class OpenAICompletionLLM(BaseLLM[CompletionInput, CompletionOutput]): + """A text-completion based LLM.""" + + _client: OpenAIClientTypes + _configuration: OpenAIConfiguration + + def __init__(self, client: OpenAIClientTypes, configuration: OpenAIConfiguration): + super().__init__() + self._client = client + self._configuration = configuration + + async def _execute_llm( + self, + input: CompletionInput, + **kwargs: Dict[str, Any] + ) -> CompletionOutput | None: + args = get_completion_llm_args( + kwargs.get("model_parameters"), self._configuration + ) + try: + # Remove 'model' from args if it's there, as we'll use self._configuration.model + args.pop('model', None) + completion = await self._client.completions.create( + model=self._configuration.model, + prompt=input, + **args + ) + return completion.choices[0].text + except Exception as e: + raise RuntimeError(f"Error calling OpenAI API: {str(e)}") from e \ No newline at end of file diff --git a/graphrag/graphrag/llm/openai/openai_configuration.py b/graphrag/graphrag/llm/openai/openai_configuration.py new file mode 100644 index 0000000000000000000000000000000000000000..1bcd5694d6fe59d38e1a6d6de7b039dff4cee091 --- /dev/null +++ b/graphrag/graphrag/llm/openai/openai_configuration.py @@ -0,0 +1,288 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""OpenAI Configuration class definition.""" + +import json +from collections.abc import Hashable +from typing import Any, cast + +from graphrag.llm.types import LLMConfig + + +def _non_blank(value: str | None) -> str | None: + if value is None: + return None + stripped = value.strip() + return None if stripped == "" else value + + +class OpenAIConfiguration(Hashable, LLMConfig): + """OpenAI Configuration class definition.""" + + # Core Configuration + _api_key: str + _model: str + + _api_base: str | None + _api_version: str | None + _cognitive_services_endpoint: str | None + _deployment_name: str | None + _organization: str | None + _proxy: str | None + + # Operation Configuration + _n: int | None + _temperature: float | None + _frequency_penalty: float | None + _presence_penalty: float | None + _top_p: float | None + _max_tokens: int | None + _response_format: str | None + _logit_bias: dict[str, float] | None + _stop: list[str] | None + + # Retry Logic + _max_retries: int | None + _max_retry_wait: float | None + _request_timeout: float | None + + # The raw configuration object + _raw_config: dict + + # Feature Flags + _model_supports_json: bool | None + + # Custom Configuration + _tokens_per_minute: int | None + _requests_per_minute: int | None + _concurrent_requests: int | None + _encoding_model: str | None + _sleep_on_rate_limit_recommendation: bool | None + + def __init__( + self, + config: dict, + ): + """Init method definition.""" + + def lookup_required(key: str) -> str: + return cast(str, config.get(key)) + + def lookup_str(key: str) -> str | None: + return cast(str | None, config.get(key)) + + def lookup_int(key: str) -> int | None: + result = config.get(key) + if result is None: + return None + return int(cast(int, result)) + + def lookup_float(key: str) -> float | None: + result = config.get(key) + if result is None: + return None + return float(cast(float, result)) + + def lookup_dict(key: str) -> dict | None: + return cast(dict | None, config.get(key)) + + def lookup_list(key: str) -> list | None: + return cast(list | None, config.get(key)) + + def lookup_bool(key: str) -> bool | None: + value = config.get(key) + if isinstance(value, str): + return value.upper() == "TRUE" + if isinstance(value, int): + return value > 0 + return cast(bool | None, config.get(key)) + + self._api_key = lookup_required("api_key") + self._model = lookup_required("model") + self._deployment_name = lookup_str("deployment_name") + self._api_base = lookup_str("api_base") + self._api_version = lookup_str("api_version") + self._cognitive_services_endpoint = lookup_str("cognitive_services_endpoint") + self._organization = lookup_str("organization") + self._proxy = lookup_str("proxy") + self._n = lookup_int("n") + self._temperature = lookup_float("temperature") + self._frequency_penalty = lookup_float("frequency_penalty") + self._presence_penalty = lookup_float("presence_penalty") + self._top_p = lookup_float("top_p") + self._max_tokens = lookup_int("max_tokens") + self._response_format = lookup_str("response_format") + self._logit_bias = lookup_dict("logit_bias") + self._stop = lookup_list("stop") + self._max_retries = lookup_int("max_retries") + self._request_timeout = lookup_float("request_timeout") + self._model_supports_json = lookup_bool("model_supports_json") + self._tokens_per_minute = lookup_int("tokens_per_minute") + self._requests_per_minute = lookup_int("requests_per_minute") + self._concurrent_requests = lookup_int("concurrent_requests") + self._encoding_model = lookup_str("encoding_model") + self._max_retry_wait = lookup_float("max_retry_wait") + self._sleep_on_rate_limit_recommendation = lookup_bool( + "sleep_on_rate_limit_recommendation" + ) + self._raw_config = config + + @property + def api_key(self) -> str: + """API key property definition.""" + return self._api_key + + @property + def model(self) -> str: + """Model property definition.""" + return self._model + + @property + def deployment_name(self) -> str | None: + """Deployment name property definition.""" + return _non_blank(self._deployment_name) + + @property + def api_base(self) -> str | None: + """API base property definition.""" + result = _non_blank(self._api_base) + # Remove trailing slash + return result[:-1] if result and result.endswith("/") else result + + @property + def api_version(self) -> str | None: + """API version property definition.""" + return _non_blank(self._api_version) + + @property + def cognitive_services_endpoint(self) -> str | None: + """API version property definition.""" + return _non_blank(self._cognitive_services_endpoint) + + @property + def organization(self) -> str | None: + """Organization property definition.""" + return _non_blank(self._organization) + + @property + def proxy(self) -> str | None: + """Proxy property definition.""" + return _non_blank(self._proxy) + + @property + def n(self) -> int | None: + """N property definition.""" + return self._n + + @property + def temperature(self) -> float | None: + """Temperature property definition.""" + return self._temperature + + @property + def frequency_penalty(self) -> float | None: + """Frequency penalty property definition.""" + return self._frequency_penalty + + @property + def presence_penalty(self) -> float | None: + """Presence penalty property definition.""" + return self._presence_penalty + + @property + def top_p(self) -> float | None: + """Top p property definition.""" + return self._top_p + + @property + def max_tokens(self) -> int | None: + """Max tokens property definition.""" + return self._max_tokens + + @property + def response_format(self) -> str | None: + """Response format property definition.""" + return _non_blank(self._response_format) + + @property + def logit_bias(self) -> dict[str, float] | None: + """Logit bias property definition.""" + return self._logit_bias + + @property + def stop(self) -> list[str] | None: + """Stop property definition.""" + return self._stop + + @property + def max_retries(self) -> int | None: + """Max retries property definition.""" + return self._max_retries + + @property + def max_retry_wait(self) -> float | None: + """Max retry wait property definition.""" + return self._max_retry_wait + + @property + def request_timeout(self) -> float | None: + """Request timeout property definition.""" + return self._request_timeout + + @property + def model_supports_json(self) -> bool | None: + """Model supports json property definition.""" + return self._model_supports_json + + @property + def tokens_per_minute(self) -> int | None: + """Tokens per minute property definition.""" + return self._tokens_per_minute + + @property + def requests_per_minute(self) -> int | None: + """Requests per minute property definition.""" + return self._requests_per_minute + + @property + def concurrent_requests(self) -> int | None: + """Concurrent requests property definition.""" + return self._concurrent_requests + + @property + def encoding_model(self) -> str | None: + """Encoding model property definition.""" + return _non_blank(self._encoding_model) + + @property + def sleep_on_rate_limit_recommendation(self) -> bool | None: + """Whether to sleep for seconds when recommended by 429 errors (azure-specific).""" + return self._sleep_on_rate_limit_recommendation + + @property + def raw_config(self) -> dict: + """Raw config method definition.""" + return self._raw_config + + def lookup(self, name: str, default_value: Any = None) -> Any: + """Lookup method definition.""" + return self._raw_config.get(name, default_value) + + def __str__(self) -> str: + """Str method definition.""" + return json.dumps(self.raw_config, indent=4) + + def __repr__(self) -> str: + """Repr method definition.""" + return f"OpenAIConfiguration({self._raw_config})" + + def __eq__(self, other: object) -> bool: + """Eq method definition.""" + if not isinstance(other, OpenAIConfiguration): + return False + return self._raw_config == other._raw_config + + def __hash__(self) -> int: + """Hash method definition.""" + return hash(tuple(sorted(self._raw_config.items()))) diff --git a/graphrag/graphrag/llm/openai/openai_embeddings_llm.py b/graphrag/graphrag/llm/openai/openai_embeddings_llm.py new file mode 100644 index 0000000000000000000000000000000000000000..4c228ccde54674b2bc63fb3a4c5c4382b439ab53 --- /dev/null +++ b/graphrag/graphrag/llm/openai/openai_embeddings_llm.py @@ -0,0 +1,157 @@ +import logging +import aiohttp +import asyncio +import requests +from typing import List, Union, Dict, Any +import ollama +from typing_extensions import Unpack +from graphrag.llm.base import BaseLLM +from graphrag.llm.types import ( + EmbeddingInput, + EmbeddingOutput, + LLMInput, +) +from .openai_configuration import OpenAIConfiguration +from .types import OpenAIClientTypes + +class OpenAIEmbeddingsLLM(BaseLLM[EmbeddingInput, EmbeddingOutput]): + def __init__(self, client: OpenAIClientTypes, configuration: Union[OpenAIConfiguration, Dict[str, Any]]): + self._client = client + if isinstance(configuration, OpenAIConfiguration): + self._configuration = configuration + self._model = configuration.model + elif isinstance(configuration, dict): + self._configuration = configuration + self._model = configuration.get("model") + else: + raise TypeError("Configuration must be either OpenAIConfiguration or a dictionary") + + async def _execute_llm( + self, input: EmbeddingInput, **kwargs: Unpack[LLMInput] + ) -> EmbeddingOutput | None: + args = { + "model": self._model, + **(kwargs.get("model_parameters") or {}), + } + + try: + if self._is_ollama_model(args["model"]): + embeddings = await asyncio.gather(*[self._get_ollama_embedding(inp, args) for inp in input]) + else: # OpenAI compatible + embeddings = await self._get_openai_embeddings(input, args) + except Exception as e: + logging.error(f"Error getting embeddings from {args['model']}: {str(e)}") + if not self._is_ollama_model(args["model"]): + logging.info("Falling back to Ollama embeddings") + try: + embeddings = await asyncio.gather(*[self._get_ollama_embedding(inp, args) for inp in input]) + except Exception as e: + logging.error(f"Error getting Ollama embeddings: {str(e)}") + return None + + return [emb for emb in embeddings if emb is not None] + + async def _get_ollama_embedding(self, text: str, args: Dict[str, Any]) -> Union[List[float], None]: + try: + loop = asyncio.get_event_loop() + embedding = await loop.run_in_executor(None, ollama.embeddings, args["model"], text) + return embedding["embedding"] + except Exception as e: + logging.error(f"Error getting Ollama embedding: {str(e)}") + return None + + async def _get_openai_embeddings(self, input: List[str], args: Dict[str, Any]) -> List[Union[List[float], None]]: + endpoint = f"{self.get_api_base().rstrip('/')}/embeddings" + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {self.get_api_key()}" if self.get_api_key() != "dummy_key" else "" + } + async with aiohttp.ClientSession() as session: + tasks = [self._get_openai_embedding(session, endpoint, inp, headers, args) for inp in input] + return await asyncio.gather(*tasks) + + async def _get_openai_embedding(self, session: aiohttp.ClientSession, endpoint: str, text: str, headers: Dict[str, str], args: Dict[str, Any]) -> Union[List[float], None]: + data = { + "model": args["model"], + "input": text, + **{k: v for k, v in args.items() if k != "model"} + } + async with session.post(endpoint, json=data, headers=headers) as response: + if response.status == 200: + result = await response.json() + return result["data"][0]["embedding"] + else: + logging.error(f"Error getting OpenAI compatible embedding: {await response.text()}") + return None + + def execute_llm_sync(self, input: EmbeddingInput, **kwargs: Unpack[LLMInput]) -> EmbeddingOutput | None: + args = { + "model": self._model, + **(kwargs.get("model_parameters") or {}), + } + + try: + if self._is_ollama_model(args["model"]): + embeddings = [self._get_ollama_embedding_sync(inp, args) for inp in input] + else: # OpenAI compatible + embeddings = self._get_openai_embeddings_sync(input, args) + except Exception as e: + logging.error(f"Error getting embeddings from {args['model']}: {str(e)}") + if not self._is_ollama_model(args["model"]): + logging.info("Falling back to Ollama embeddings") + try: + embeddings = [self._get_ollama_embedding_sync(inp, args) for inp in input] + except Exception as e: + logging.error(f"Error getting Ollama embeddings: {str(e)}") + return None + + return [emb for emb in embeddings if emb is not None] + + def _get_ollama_embedding_sync(self, text: str, args: Dict[str, Any]) -> Union[List[float], None]: + try: + embedding = ollama.embeddings(model=args["model"], prompt=text) + return embedding["embedding"] + except Exception as e: + logging.error(f"Error getting Ollama embedding: {str(e)}") + return None + + def _get_openai_embeddings_sync(self, input: List[str], args: Dict[str, Any]) -> List[Union[List[float], None]]: + endpoint = f"{self.get_api_base().rstrip('/')}/embeddings" + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {self.get_api_key()}" if self.get_api_key() != "dummy_key" else "" + } + return [self._get_openai_embedding_sync(endpoint, inp, headers, args) for inp in input] + + def _get_openai_embedding_sync(self, endpoint: str, text: str, headers: Dict[str, str], args: Dict[str, Any]) -> Union[List[float], None]: + data = { + "model": args["model"], + "input": text, + **{k: v for k, v in args.items() if k != "model"} + } + response = requests.post(endpoint, json=data, headers=headers) + if response.status_code == 200: + result = response.json() + return result["data"][0]["embedding"] + else: + logging.error(f"Error getting OpenAI compatible embedding: {response.text}") + return None + + def _is_ollama_model(self, model: str) -> bool: + return model.lower().startswith("ollama:") + + def get_api_base(self) -> str: + if isinstance(self._configuration, OpenAIConfiguration): + return self._configuration.api_base + elif isinstance(self._configuration, dict): + return self._configuration.get("api_base") + else: + raise TypeError("Invalid configuration type") + + def get_api_key(self) -> str: + if isinstance(self._configuration, OpenAIConfiguration): + return self._configuration.api_key + elif isinstance(self._configuration, dict): + return self._configuration.get("api_key", "dummy_key") + else: + raise TypeError("Invalid configuration type") \ No newline at end of file diff --git a/graphrag/graphrag/llm/openai/openai_history_tracking_llm.py b/graphrag/graphrag/llm/openai/openai_history_tracking_llm.py new file mode 100644 index 0000000000000000000000000000000000000000..26ac8e227d2ed32a018f3930a66cb19f4ebd1a68 --- /dev/null +++ b/graphrag/graphrag/llm/openai/openai_history_tracking_llm.py @@ -0,0 +1,38 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Chat-based language model.""" + +from typing_extensions import Unpack + +from graphrag.llm.types import ( + LLM, + CompletionInput, + CompletionLLM, + CompletionOutput, + LLMInput, + LLMOutput, +) + + +class OpenAIHistoryTrackingLLM(LLM[CompletionInput, CompletionOutput]): + """An OpenAI History-Tracking LLM.""" + + _delegate: CompletionLLM + + def __init__(self, delegate: CompletionLLM): + self._delegate = delegate + + async def __call__( + self, + input: CompletionInput, + **kwargs: Unpack[LLMInput], + ) -> LLMOutput[CompletionOutput]: + """Call the LLM.""" + history = kwargs.get("history") or [] + output = await self._delegate(input, **kwargs) + return LLMOutput( + output=output.output, + json=output.json, + history=[*history, {"role": "system", "content": output.output}], + ) diff --git a/graphrag/graphrag/llm/openai/openai_token_replacing_llm.py b/graphrag/graphrag/llm/openai/openai_token_replacing_llm.py new file mode 100644 index 0000000000000000000000000000000000000000..e34c7ef5d7d58250a0eb4d8d0463a09a6c8ddeec --- /dev/null +++ b/graphrag/graphrag/llm/openai/openai_token_replacing_llm.py @@ -0,0 +1,37 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Chat-based language model.""" + +from typing_extensions import Unpack + +from graphrag.llm.types import ( + LLM, + CompletionInput, + CompletionLLM, + CompletionOutput, + LLMInput, + LLMOutput, +) + +from .utils import perform_variable_replacements + + +class OpenAITokenReplacingLLM(LLM[CompletionInput, CompletionOutput]): + """An OpenAI History-Tracking LLM.""" + + _delegate: CompletionLLM + + def __init__(self, delegate: CompletionLLM): + self._delegate = delegate + + async def __call__( + self, + input: CompletionInput, + **kwargs: Unpack[LLMInput], + ) -> LLMOutput[CompletionOutput]: + """Call the LLM with the input and kwargs.""" + variables = kwargs.get("variables") + history = kwargs.get("history") or [] + input = perform_variable_replacements(input, history, variables) + return await self._delegate(input, **kwargs) \ No newline at end of file diff --git a/graphrag/graphrag/llm/openai/types.py b/graphrag/graphrag/llm/openai/types.py new file mode 100644 index 0000000000000000000000000000000000000000..4aacf18c1c7437ac9f4ce8ec6019ca9421db45ba --- /dev/null +++ b/graphrag/graphrag/llm/openai/types.py @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A base class for OpenAI-based LLMs.""" + +from openai import ( + AsyncAzureOpenAI, + AsyncOpenAI, +) + +OpenAIClientTypes = AsyncOpenAI | AsyncAzureOpenAI diff --git a/graphrag/graphrag/llm/openai/utils.py b/graphrag/graphrag/llm/openai/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..d529a8c0691a76264ce4ea40d5237897ec048dc0 --- /dev/null +++ b/graphrag/graphrag/llm/openai/utils.py @@ -0,0 +1,113 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Utility functions for the OpenAI API.""" + +import json +import logging +from collections.abc import Callable +from typing import Any + +import tiktoken +from openai import ( + APIConnectionError, + InternalServerError, + RateLimitError, +) + +from .openai_configuration import OpenAIConfiguration + +DEFAULT_ENCODING = "cl100k_base" + +_encoders: dict[str, tiktoken.Encoding] = {} + +RETRYABLE_ERRORS: list[type[Exception]] = [ + RateLimitError, + APIConnectionError, + InternalServerError, +] +RATE_LIMIT_ERRORS: list[type[Exception]] = [RateLimitError] + +log = logging.getLogger(__name__) + + +def get_token_counter(config: OpenAIConfiguration) -> Callable[[str], int]: + """Get a function that counts the number of tokens in a string.""" + model = config.encoding_model or "cl100k_base" + enc = _encoders.get(model) + if enc is None: + enc = tiktoken.get_encoding(model) + _encoders[model] = enc + + return lambda s: len(enc.encode(s)) + + +def perform_variable_replacements( + input: str, history: list[dict], variables: dict | None +) -> str: + """Perform variable replacements on the input string and in a chat log.""" + result = input + + def replace_all(input: str) -> str: + result = input + if variables: + for entry in variables: + result = result.replace(f"{{{entry}}}", variables[entry]) + return result + + result = replace_all(result) + for i in range(len(history)): + entry = history[i] + if entry.get("role") == "system": + history[i]["content"] = replace_all(entry.get("content") or "") + + return result + + +def get_completion_cache_args(configuration: OpenAIConfiguration) -> dict: + """Get the cache arguments for a completion LLM.""" + return { + "model": configuration.model, + "temperature": configuration.temperature, + "frequency_penalty": configuration.frequency_penalty, + "presence_penalty": configuration.presence_penalty, + "top_p": configuration.top_p, + "max_tokens": configuration.max_tokens, + "n": configuration.n, + } + + +def get_completion_llm_args( + parameters: dict | None, configuration: OpenAIConfiguration +) -> dict: + """Get the arguments for a completion LLM.""" + return { + **get_completion_cache_args(configuration), + **(parameters or {}), + } + + +def try_parse_json_object(input: str) -> dict: + """Generate JSON-string output using best-attempt prompting & parsing techniques.""" + try: + result = json.loads(input) + except json.JSONDecodeError: + log.exception("error loading json, json=%s", input) + raise + else: + if not isinstance(result, dict): + raise TypeError + return result + + +def get_sleep_time_from_error(e: Any) -> float: + """Extract the sleep time value from a RateLimitError. This is usually only available in Azure.""" + sleep_time = 0.0 + if isinstance(e, RateLimitError) and _please_retry_after in str(e): + # could be second or seconds + sleep_time = int(str(e).split(_please_retry_after)[1].split(" second")[0]) + + return sleep_time + + +_please_retry_after = "Please retry after " diff --git a/graphrag/graphrag/llm/types/__init__.py b/graphrag/graphrag/llm/types/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c8277661d514344c0d548f007b13c95378e9c480 --- /dev/null +++ b/graphrag/graphrag/llm/types/__init__.py @@ -0,0 +1,46 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""LLM Typings.""" + +from .llm import LLM +from .llm_cache import LLMCache +from .llm_callbacks import ( + ErrorHandlerFn, + IsResponseValidFn, + LLMInvocationFn, + OnCacheActionFn, +) +from .llm_config import LLMConfig +from .llm_invocation_result import LLMInvocationResult +from .llm_io import ( + LLMInput, + LLMOutput, +) +from .llm_types import ( + CompletionInput, + CompletionLLM, + CompletionOutput, + EmbeddingInput, + EmbeddingLLM, + EmbeddingOutput, +) + +__all__ = [ + "LLM", + "CompletionInput", + "CompletionLLM", + "CompletionOutput", + "EmbeddingInput", + "EmbeddingLLM", + "EmbeddingOutput", + "ErrorHandlerFn", + "IsResponseValidFn", + "LLMCache", + "LLMConfig", + "LLMInput", + "LLMInvocationFn", + "LLMInvocationResult", + "LLMOutput", + "OnCacheActionFn", +] diff --git a/graphrag/graphrag/llm/types/llm.py b/graphrag/graphrag/llm/types/llm.py new file mode 100644 index 0000000000000000000000000000000000000000..fd8407e50e0bdc07bf456574eb186cdf05bda95c --- /dev/null +++ b/graphrag/graphrag/llm/types/llm.py @@ -0,0 +1,28 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""LLM Types.""" + +from typing import Generic, Protocol, TypeVar + +from typing_extensions import Unpack + +from .llm_io import ( + LLMInput, + LLMOutput, +) + +TIn = TypeVar("TIn", contravariant=True) +TOut = TypeVar("TOut") + + +class LLM(Protocol, Generic[TIn, TOut]): + """LLM Protocol definition.""" + + async def __call__( + self, + input: TIn, + **kwargs: Unpack[LLMInput], + ) -> LLMOutput[TOut]: + """Invoke the LLM, treating the LLM as a function.""" + ... diff --git a/graphrag/graphrag/llm/types/llm_cache.py b/graphrag/graphrag/llm/types/llm_cache.py new file mode 100644 index 0000000000000000000000000000000000000000..952b8d346d6c7d9a7812b31a3398e07a5af8784d --- /dev/null +++ b/graphrag/graphrag/llm/types/llm_cache.py @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Typing definitions for the OpenAI DataShaper package.""" + +from typing import Any, Protocol + + +class LLMCache(Protocol): + """LLM Cache interface.""" + + async def has(self, key: str) -> bool: + """Check if the cache has a value.""" + ... + + async def get(self, key: str) -> Any | None: + """Retrieve a value from the cache.""" + ... + + async def set(self, key: str, value: Any, debug_data: dict | None = None) -> None: + """Write a value into the cache.""" + ... diff --git a/graphrag/graphrag/llm/types/llm_callbacks.py b/graphrag/graphrag/llm/types/llm_callbacks.py new file mode 100644 index 0000000000000000000000000000000000000000..dc06dbff068a6651f95709152e063361ded708a9 --- /dev/null +++ b/graphrag/graphrag/llm/types/llm_callbacks.py @@ -0,0 +1,20 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Typing definitions for the OpenAI DataShaper package.""" + +from collections.abc import Callable + +from .llm_invocation_result import LLMInvocationResult + +ErrorHandlerFn = Callable[[BaseException | None, str | None, dict | None], None] +"""Error handler function type definition.""" + +LLMInvocationFn = Callable[[LLMInvocationResult], None] +"""Handler for LLM invocation results""" + +OnCacheActionFn = Callable[[str, str | None], None] +"""Handler for cache hits""" + +IsResponseValidFn = Callable[[dict], bool] +"""A function that checks if an LLM response is valid.""" diff --git a/graphrag/graphrag/llm/types/llm_config.py b/graphrag/graphrag/llm/types/llm_config.py new file mode 100644 index 0000000000000000000000000000000000000000..cd7ec255b263cc308077a98109cdc15acbc8f0fb --- /dev/null +++ b/graphrag/graphrag/llm/types/llm_config.py @@ -0,0 +1,35 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""LLM Configuration Protocol definition.""" + +from typing import Protocol + + +class LLMConfig(Protocol): + """LLM Configuration Protocol definition.""" + + @property + def max_retries(self) -> int | None: + """Get the maximum number of retries.""" + ... + + @property + def max_retry_wait(self) -> float | None: + """Get the maximum retry wait time.""" + ... + + @property + def sleep_on_rate_limit_recommendation(self) -> bool | None: + """Get whether to sleep on rate limit recommendation.""" + ... + + @property + def tokens_per_minute(self) -> int | None: + """Get the number of tokens per minute.""" + ... + + @property + def requests_per_minute(self) -> int | None: + """Get the number of requests per minute.""" + ... diff --git a/graphrag/graphrag/llm/types/llm_invocation_result.py b/graphrag/graphrag/llm/types/llm_invocation_result.py new file mode 100644 index 0000000000000000000000000000000000000000..1769aeb96de042a80aac17c01f466a1096a1020f --- /dev/null +++ b/graphrag/graphrag/llm/types/llm_invocation_result.py @@ -0,0 +1,35 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Typing definitions for the OpenAI DataShaper package.""" + +from dataclasses import dataclass +from typing import Generic, TypeVar + +T = TypeVar("T") + + +@dataclass +class LLMInvocationResult(Generic[T]): + """The result of an LLM invocation.""" + + result: T | None + """The result of the LLM invocation.""" + + name: str + """The operation name of the result""" + + num_retries: int + """The number of retries the invocation took.""" + + total_time: float + """The total time of the LLM invocation.""" + + call_times: list[float] + """The network times of individual invocations.""" + + input_tokens: int + """The number of input tokens.""" + + output_tokens: int + """The number of output tokens.""" diff --git a/graphrag/graphrag/llm/types/llm_io.py b/graphrag/graphrag/llm/types/llm_io.py new file mode 100644 index 0000000000000000000000000000000000000000..051b5b8288a2e7c8afd2e5c33a308b9eaf7f7115 --- /dev/null +++ b/graphrag/graphrag/llm/types/llm_io.py @@ -0,0 +1,50 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""LLM Types.""" + +from dataclasses import dataclass, field +from typing import Generic, TypeVar + +from typing_extensions import NotRequired, TypedDict + +from .llm_callbacks import IsResponseValidFn + + +class LLMInput(TypedDict): + """The input of an LLM invocation.""" + + name: NotRequired[str] + """The name of the LLM invocation, if available.""" + + json: NotRequired[bool] + """If true, will attempt to elicit JSON from the LLM. Parsed JSON will be returned in the `json_output` field.""" + + is_response_valid: NotRequired[IsResponseValidFn] + """A function that checks if an LLM response is valid. Only valid if `json=True`.""" + + variables: NotRequired[dict] + """The variable replacements to use in the prompt.""" + + history: NotRequired[list[dict]] + """The history of the LLM invocation, if available (e.g. chat mode)""" + + model_parameters: NotRequired[dict] + """Additional model parameters to use in the LLM invocation.""" + + +T = TypeVar("T") + + +@dataclass +class LLMOutput(Generic[T]): + """The output of an LLM invocation.""" + + output: T | None + """The output of the LLM invocation.""" + + json: dict | None = field(default=None) + """The JSON output from the LLM, if available.""" + + history: list[dict] | None = field(default=None) + """The history of the LLM invocation, if available (e.g. chat mode)""" diff --git a/graphrag/graphrag/llm/types/llm_types.py b/graphrag/graphrag/llm/types/llm_types.py new file mode 100644 index 0000000000000000000000000000000000000000..7ae76ef9bed56bbf9b49afe4858fae6575dca281 --- /dev/null +++ b/graphrag/graphrag/llm/types/llm_types.py @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""LLM Types.""" + +from typing import TypeAlias + +from .llm import LLM + +EmbeddingInput: TypeAlias = list[str] +EmbeddingOutput: TypeAlias = list[list[float]] +CompletionInput: TypeAlias = str +CompletionOutput: TypeAlias = str + +EmbeddingLLM: TypeAlias = LLM[EmbeddingInput, EmbeddingOutput] +CompletionLLM: TypeAlias = LLM[CompletionInput, CompletionOutput] diff --git a/graphrag/graphrag/model/__init__.py b/graphrag/graphrag/model/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..9dbec3d1dd24ba6301262898692ebed06b83feb9 --- /dev/null +++ b/graphrag/graphrag/model/__init__.py @@ -0,0 +1,31 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +""" +GraphRAG knowledge model package root. + +The GraphRAG knowledge model contains a set of classes that represent the target datamodels for our pipelines and analytics tools. +These models can be augmented and integrated into your own data infrastructure to suit your needs. +""" + +from .community import Community +from .community_report import CommunityReport +from .covariate import Covariate +from .document import Document +from .entity import Entity +from .identified import Identified +from .named import Named +from .relationship import Relationship +from .text_unit import TextUnit + +__all__ = [ + "Community", + "CommunityReport", + "Covariate", + "Document", + "Entity", + "Identified", + "Named", + "Relationship", + "TextUnit", +] diff --git a/graphrag/graphrag/model/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/model/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..231ccf437a32d710fb54f6fd484ae4272867ff05 Binary files /dev/null and b/graphrag/graphrag/model/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/model/__pycache__/community.cpython-311.pyc b/graphrag/graphrag/model/__pycache__/community.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7a735716d0392d9ae2d566890e8513f6ea81681 Binary files /dev/null and b/graphrag/graphrag/model/__pycache__/community.cpython-311.pyc differ diff --git a/graphrag/graphrag/model/__pycache__/community_report.cpython-311.pyc b/graphrag/graphrag/model/__pycache__/community_report.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ec36677c557368bc079cfd749452c2086f7e410 Binary files /dev/null and b/graphrag/graphrag/model/__pycache__/community_report.cpython-311.pyc differ diff --git a/graphrag/graphrag/model/__pycache__/covariate.cpython-311.pyc b/graphrag/graphrag/model/__pycache__/covariate.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..488c451435b89e1a6da7148978604606db3e13a5 Binary files /dev/null and b/graphrag/graphrag/model/__pycache__/covariate.cpython-311.pyc differ diff --git a/graphrag/graphrag/model/__pycache__/document.cpython-311.pyc b/graphrag/graphrag/model/__pycache__/document.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0c9dcc0b33a265a1aac0def809fbcffce0465de8 Binary files /dev/null and b/graphrag/graphrag/model/__pycache__/document.cpython-311.pyc differ diff --git a/graphrag/graphrag/model/__pycache__/entity.cpython-311.pyc b/graphrag/graphrag/model/__pycache__/entity.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..253b9aff4a1a136710894a8426159d8dfcae7bbe Binary files /dev/null and b/graphrag/graphrag/model/__pycache__/entity.cpython-311.pyc differ diff --git a/graphrag/graphrag/model/__pycache__/identified.cpython-311.pyc b/graphrag/graphrag/model/__pycache__/identified.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e7dbcdaf7c276e34b40acc6cec2a4d4bde9ca5e Binary files /dev/null and b/graphrag/graphrag/model/__pycache__/identified.cpython-311.pyc differ diff --git a/graphrag/graphrag/model/__pycache__/named.cpython-311.pyc b/graphrag/graphrag/model/__pycache__/named.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b565202def98abc3fdc8fcf1ce8f6f663e4b8cb7 Binary files /dev/null and b/graphrag/graphrag/model/__pycache__/named.cpython-311.pyc differ diff --git a/graphrag/graphrag/model/__pycache__/relationship.cpython-311.pyc b/graphrag/graphrag/model/__pycache__/relationship.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..599eba45339648c602cf7029e1a24bab49832c8a Binary files /dev/null and b/graphrag/graphrag/model/__pycache__/relationship.cpython-311.pyc differ diff --git a/graphrag/graphrag/model/__pycache__/text_unit.cpython-311.pyc b/graphrag/graphrag/model/__pycache__/text_unit.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6946534687c59aef6ffd4b5ef2dcb959a6c26f8 Binary files /dev/null and b/graphrag/graphrag/model/__pycache__/text_unit.cpython-311.pyc differ diff --git a/graphrag/graphrag/model/__pycache__/types.cpython-311.pyc b/graphrag/graphrag/model/__pycache__/types.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..504ed477def77355df1dff0d168adfe4abdce82c Binary files /dev/null and b/graphrag/graphrag/model/__pycache__/types.cpython-311.pyc differ diff --git a/graphrag/graphrag/model/community.py b/graphrag/graphrag/model/community.py new file mode 100644 index 0000000000000000000000000000000000000000..800a9a292a1bf0afdfb8a858d5050ed754398c12 --- /dev/null +++ b/graphrag/graphrag/model/community.py @@ -0,0 +1,54 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A package containing the 'Community' model.""" + +from dataclasses import dataclass +from typing import Any + +from .named import Named + + +@dataclass +class Community(Named): + """A protocol for a community in the system.""" + + level: str = "" + """Community level.""" + + entity_ids: list[str] | None = None + """List of entity IDs related to the community (optional).""" + + relationship_ids: list[str] | None = None + """List of relationship IDs related to the community (optional).""" + + covariate_ids: dict[str, list[str]] | None = None + """Dictionary of different types of covariates related to the community (optional), e.g. claims""" + + attributes: dict[str, Any] | None = None + """A dictionary of additional attributes associated with the community (optional). To be included in the search prompt.""" + + @classmethod + def from_dict( + cls, + d: dict[str, Any], + id_key: str = "id", + title_key: str = "title", + short_id_key: str = "short_id", + level_key: str = "level", + entities_key: str = "entity_ids", + relationships_key: str = "relationship_ids", + covariates_key: str = "covariate_ids", + attributes_key: str = "attributes", + ) -> "Community": + """Create a new community from the dict data.""" + return Community( + id=d[id_key], + title=d[title_key], + short_id=d.get(short_id_key), + level=d[level_key], + entity_ids=d.get(entities_key), + relationship_ids=d.get(relationships_key), + covariate_ids=d.get(covariates_key), + attributes=d.get(attributes_key), + ) diff --git a/graphrag/graphrag/model/community_report.py b/graphrag/graphrag/model/community_report.py new file mode 100644 index 0000000000000000000000000000000000000000..2666c0b5a81d5a57cebb06ed91bf184c36d2fa41 --- /dev/null +++ b/graphrag/graphrag/model/community_report.py @@ -0,0 +1,64 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A package containing the 'CommunityReport' model.""" + +from dataclasses import dataclass +from typing import Any + +from .named import Named + + +@dataclass +class CommunityReport(Named): + """Defines an LLM-generated summary report of a community.""" + + community_id: str + """The ID of the community this report is associated with.""" + + summary: str = "" + """Summary of the report.""" + + full_content: str = "" + """Full content of the report.""" + + rank: float | None = 1.0 + """Rank of the report, used for sorting (optional). Higher means more important""" + + summary_embedding: list[float] | None = None + """The semantic (i.e. text) embedding of the report summary (optional).""" + + full_content_embedding: list[float] | None = None + """The semantic (i.e. text) embedding of the full report content (optional).""" + + attributes: dict[str, Any] | None = None + """A dictionary of additional attributes associated with the report (optional).""" + + @classmethod + def from_dict( + cls, + d: dict[str, Any], + id_key: str = "id", + title_key: str = "title", + community_id_key: str = "community_id", + short_id_key: str = "short_id", + summary_key: str = "summary", + full_content_key: str = "full_content", + rank_key: str = "rank", + summary_embedding_key: str = "summary_embedding", + full_content_embedding_key: str = "full_content_embedding", + attributes_key: str = "attributes", + ) -> "CommunityReport": + """Create a new community report from the dict data.""" + return CommunityReport( + id=d[id_key], + title=d[title_key], + community_id=d[community_id_key], + short_id=d.get(short_id_key), + summary=d[summary_key], + full_content=d[full_content_key], + rank=d[rank_key], + summary_embedding=d.get(summary_embedding_key), + full_content_embedding=d.get(full_content_embedding_key), + attributes=d.get(attributes_key), + ) diff --git a/graphrag/graphrag/model/covariate.py b/graphrag/graphrag/model/covariate.py new file mode 100644 index 0000000000000000000000000000000000000000..b974b6b3273e5daafa0e15a2f9e32eb3a894bc23 --- /dev/null +++ b/graphrag/graphrag/model/covariate.py @@ -0,0 +1,61 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A package containing the 'Covariate' model.""" + +from dataclasses import dataclass +from typing import Any + +from .identified import Identified + + +@dataclass +class Covariate(Identified): + """ + A protocol for a covariate in the system. + + Covariates are metadata associated with a subject, e.g. entity claims. + Each subject (e.g. entity) may be associated with multiple types of covariates. + """ + + subject_id: str + """The subject id.""" + + subject_type: str = "entity" + """The subject type.""" + + covariate_type: str = "claim" + """The covariate type.""" + + text_unit_ids: list[str] | None = None + """List of text unit IDs in which the covariate info appears (optional).""" + + document_ids: list[str] | None = None + """List of document IDs in which the covariate info appears (optional).""" + + attributes: dict[str, Any] | None = None + + @classmethod + def from_dict( + cls, + d: dict[str, Any], + id_key: str = "id", + subject_id_key: str = "subject_id", + subject_type_key: str = "subject_type", + covariate_type_key: str = "covariate_type", + short_id_key: str = "short_id", + text_unit_ids_key: str = "text_unit_ids", + document_ids_key: str = "document_ids", + attributes_key: str = "attributes", + ) -> "Covariate": + """Create a new covariate from the dict data.""" + return Covariate( + id=d[id_key], + short_id=d.get(short_id_key), + subject_id=d[subject_id_key], + subject_type=d.get(subject_type_key, "entity"), + covariate_type=d.get(covariate_type_key, "claim"), + text_unit_ids=d.get(text_unit_ids_key), + document_ids=d.get(document_ids_key), + attributes=d.get(attributes_key), + ) diff --git a/graphrag/graphrag/model/document.py b/graphrag/graphrag/model/document.py new file mode 100644 index 0000000000000000000000000000000000000000..b54a39ac910379a334a3f6235fbab5fb2451827b --- /dev/null +++ b/graphrag/graphrag/model/document.py @@ -0,0 +1,64 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A package containing the 'Document' model.""" + +from dataclasses import dataclass, field +from typing import Any + +from .named import Named + + +@dataclass +class Document(Named): + """A protocol for a document in the system.""" + + type: str = "text" + """Type of the document.""" + + text_unit_ids: list[str] = field(default_factory=list) + """list of text units in the document.""" + + raw_content: str = "" + """The raw text content of the document.""" + + summary: str | None = None + """Summary of the document (optional).""" + + summary_embedding: list[float] | None = None + """The semantic embedding for the document summary (optional).""" + + raw_content_embedding: list[float] | None = None + """The semantic embedding for the document raw content (optional).""" + + attributes: dict[str, Any] | None = None + """A dictionary of structured attributes such as author, etc (optional).""" + + @classmethod + def from_dict( + cls, + d: dict[str, Any], + id_key: str = "id", + short_id_key: str = "short_id", + title_key: str = "title", + type_key: str = "type", + raw_content_key: str = "raw_content", + summary_key: str = "summary", + summary_embedding_key: str = "summary_embedding", + raw_content_embedding_key: str = "raw_content_embedding", + text_units_key: str = "text_units", + attributes_key: str = "attributes", + ) -> "Document": + """Create a new document from the dict data.""" + return Document( + id=d[id_key], + short_id=d.get(short_id_key), + title=d[title_key], + type=d.get(type_key, "text"), + raw_content=d[raw_content_key], + summary=d.get(summary_key), + summary_embedding=d.get(summary_embedding_key), + raw_content_embedding=d.get(raw_content_embedding_key), + text_unit_ids=d.get(text_units_key, []), + attributes=d.get(attributes_key), + ) diff --git a/graphrag/graphrag/model/entity.py b/graphrag/graphrag/model/entity.py new file mode 100644 index 0000000000000000000000000000000000000000..37c26342aa3169d54a21fe2455b8756823ba0d49 --- /dev/null +++ b/graphrag/graphrag/model/entity.py @@ -0,0 +1,79 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A package containing the 'Entity' model.""" + +from dataclasses import dataclass +from typing import Any + +from .named import Named + + +@dataclass +class Entity(Named): + """A protocol for an entity in the system.""" + + type: str | None = None + """Type of the entity (can be any string, optional).""" + + description: str | None = None + """Description of the entity (optional).""" + + description_embedding: list[float] | None = None + """The semantic (i.e. text) embedding of the entity (optional).""" + + name_embedding: list[float] | None = None + """The semantic (i.e. text) embedding of the entity (optional).""" + + graph_embedding: list[float] | None = None + """The graph embedding of the entity, likely from node2vec (optional).""" + + community_ids: list[str] | None = None + """The community IDs of the entity (optional).""" + + text_unit_ids: list[str] | None = None + """List of text unit IDs in which the entity appears (optional).""" + + document_ids: list[str] | None = None + """List of document IDs in which the entity appears (optional).""" + + rank: int | None = 1 + """Rank of the entity, used for sorting (optional). Higher rank indicates more important entity. This can be based on centrality or other metrics.""" + + attributes: dict[str, Any] | None = None + """Additional attributes associated with the entity (optional), e.g. start time, end time, etc. To be included in the search prompt.""" + + @classmethod + def from_dict( + cls, + d: dict[str, Any], + id_key: str = "id", + short_id_key: str = "short_id", + title_key: str = "title", + type_key: str = "type", + description_key: str = "description", + description_embedding_key: str = "description_embedding", + name_embedding_key: str = "name_embedding", + graph_embedding_key: str = "graph_embedding", + community_key: str = "community", + text_unit_ids_key: str = "text_unit_ids", + document_ids_key: str = "document_ids", + rank_key: str = "degree", + attributes_key: str = "attributes", + ) -> "Entity": + """Create a new entity from the dict data.""" + return Entity( + id=d[id_key], + title=d[title_key], + short_id=d.get(short_id_key), + type=d.get(type_key), + description=d.get(description_key), + name_embedding=d.get(name_embedding_key), + description_embedding=d.get(description_embedding_key), + graph_embedding=d.get(graph_embedding_key), + community_ids=d.get(community_key), + rank=d.get(rank_key, 1), + text_unit_ids=d.get(text_unit_ids_key), + document_ids=d.get(document_ids_key), + attributes=d.get(attributes_key), + ) diff --git a/graphrag/graphrag/model/identified.py b/graphrag/graphrag/model/identified.py new file mode 100644 index 0000000000000000000000000000000000000000..ca2c939526490588f1fa58f18c164e12d2a70617 --- /dev/null +++ b/graphrag/graphrag/model/identified.py @@ -0,0 +1,17 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A package containing the 'Identified' protocol.""" + +from dataclasses import dataclass + + +@dataclass +class Identified: + """A protocol for an item with an ID.""" + + id: str + """The ID of the item.""" + + short_id: str | None + """Human readable ID used to refer to this community in prompts or texts displayed to users, such as in a report text (optional).""" diff --git a/graphrag/graphrag/model/named.py b/graphrag/graphrag/model/named.py new file mode 100644 index 0000000000000000000000000000000000000000..5352c77c96f8a6a6f375bef5bb03bd92ba86f964 --- /dev/null +++ b/graphrag/graphrag/model/named.py @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A package containing the 'Named' protocol.""" + +from dataclasses import dataclass + +from .identified import Identified + + +@dataclass +class Named(Identified): + """A protocol for an item with a name/title.""" + + title: str + """The name/title of the item.""" diff --git a/graphrag/graphrag/model/relationship.py b/graphrag/graphrag/model/relationship.py new file mode 100644 index 0000000000000000000000000000000000000000..fadd0aaa6f1352592caf48911881c1c01d55e7eb --- /dev/null +++ b/graphrag/graphrag/model/relationship.py @@ -0,0 +1,65 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A package containing the 'Relationship' model.""" + +from dataclasses import dataclass +from typing import Any + +from .identified import Identified + + +@dataclass +class Relationship(Identified): + """A relationship between two entities. This is a generic relationship, and can be used to represent any type of relationship between any two entities.""" + + source: str + """The source entity name.""" + + target: str + """The target entity name.""" + + weight: float | None = 1.0 + """The edge weight.""" + + description: str | None = None + """A description of the relationship (optional).""" + + description_embedding: list[float] | None = None + """The semantic embedding for the relationship description (optional).""" + + text_unit_ids: list[str] | None = None + """List of text unit IDs in which the relationship appears (optional).""" + + document_ids: list[str] | None = None + """List of document IDs in which the relationship appears (optional).""" + + attributes: dict[str, Any] | None = None + """Additional attributes associated with the relationship (optional). To be included in the search prompt""" + + @classmethod + def from_dict( + cls, + d: dict[str, Any], + id_key: str = "id", + short_id_key: str = "short_id", + source_key: str = "source", + target_key: str = "target", + description_key: str = "description", + weight_key: str = "weight", + text_unit_ids_key: str = "text_unit_ids", + document_ids_key: str = "document_ids", + attributes_key: str = "attributes", + ) -> "Relationship": + """Create a new relationship from the dict data.""" + return Relationship( + id=d[id_key], + short_id=d.get(short_id_key), + source=d[source_key], + target=d[target_key], + description=d.get(description_key), + weight=d.get(weight_key, 1.0), + text_unit_ids=d.get(text_unit_ids_key), + document_ids=d.get(document_ids_key), + attributes=d.get(attributes_key), + ) diff --git a/graphrag/graphrag/model/text_unit.py b/graphrag/graphrag/model/text_unit.py new file mode 100644 index 0000000000000000000000000000000000000000..cff4ac01c1a9da26e0ca1e506d752042e5140393 --- /dev/null +++ b/graphrag/graphrag/model/text_unit.py @@ -0,0 +1,67 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A package containing the 'TextUnit' model.""" + +from dataclasses import dataclass +from typing import Any + +from .identified import Identified + + +@dataclass +class TextUnit(Identified): + """A protocol for a TextUnit item in a Document database.""" + + text: str + """The text of the unit.""" + + text_embedding: list[float] | None = None + """The text embedding for the text unit (optional).""" + + entity_ids: list[str] | None = None + """List of entity IDs related to the text unit (optional).""" + + relationship_ids: list[str] | None = None + """List of relationship IDs related to the text unit (optional).""" + + covariate_ids: dict[str, list[str]] | None = None + "Dictionary of different types of covariates related to the text unit (optional)." + + n_tokens: int | None = None + """The number of tokens in the text (optional).""" + + document_ids: list[str] | None = None + """List of document IDs in which the text unit appears (optional).""" + + attributes: dict[str, Any] | None = None + """A dictionary of additional attributes associated with the text unit (optional).""" + + @classmethod + def from_dict( + cls, + d: dict[str, Any], + id_key: str = "id", + short_id_key: str = "short_id", + text_key: str = "text", + text_embedding_key: str = "text_embedding", + entities_key: str = "entity_ids", + relationships_key: str = "relationship_ids", + covariates_key: str = "covariate_ids", + n_tokens_key: str = "n_tokens", + document_ids_key: str = "document_ids", + attributes_key: str = "attributes", + ) -> "TextUnit": + """Create a new text unit from the dict data.""" + return TextUnit( + id=d[id_key], + short_id=d.get(short_id_key), + text=d[text_key], + text_embedding=d.get(text_embedding_key), + entity_ids=d.get(entities_key), + relationship_ids=d.get(relationships_key), + covariate_ids=d.get(covariates_key), + n_tokens=d.get(n_tokens_key), + document_ids=d.get(document_ids_key), + attributes=d.get(attributes_key), + ) diff --git a/graphrag/graphrag/model/types.py b/graphrag/graphrag/model/types.py new file mode 100644 index 0000000000000000000000000000000000000000..6156e39969d978edc6e9175ee69b6f423111e9da --- /dev/null +++ b/graphrag/graphrag/model/types.py @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Common types for the GraphRAG knowledge model.""" + +from collections.abc import Callable + +TextEmbedder = Callable[[str], list[float]] diff --git a/graphrag/graphrag/prompt_tune/__init__.py b/graphrag/graphrag/prompt_tune/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2384b5793c01eba522d8e5288963cb06c38f2e96 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Command line interface for the fine_tune module.""" diff --git a/graphrag/graphrag/prompt_tune/__main__.py b/graphrag/graphrag/prompt_tune/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..dfa65e71bf7923628a1b95b0251ffdd77210ef6d --- /dev/null +++ b/graphrag/graphrag/prompt_tune/__main__.py @@ -0,0 +1,120 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Prompt auto templating package root.""" + +import argparse +import asyncio +from enum import Enum + +from graphrag.prompt_tune.generator import MAX_TOKEN_COUNT +from graphrag.prompt_tune.loader import MIN_CHUNK_SIZE + +from .cli import fine_tune + + +class DocSelectionType(Enum): + """The type of document selection to use.""" + + ALL = "all" + RANDOM = "random" + TOP = "top" + + def __str__(self): + """Return the string representation of the enum value.""" + return self.value + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument( + "--root", + help="The data project root. Including the config yml, json or .env", + required=False, + type=str, + default=".", + ) + + parser.add_argument( + "--domain", + help="The domain your input data is related to. For example 'space science', 'microbiology', 'environmental news'. If left empty, the domain will be inferred from the input data.", + required=False, + default="", + type=str, + ) + + parser.add_argument( + "--method", + help="The method to select documents, one of: all, random or top", + required=False, + type=DocSelectionType, + choices=list(DocSelectionType), + default=DocSelectionType.RANDOM, + ) + + parser.add_argument( + "--limit", + help="The limit of files to load when doing random or top selection", + type=int, + required=False, + default=15, + ) + + parser.add_argument( + "--max-tokens", + help="Max token count for prompt generation", + type=int, + required=False, + default=MAX_TOKEN_COUNT, + ) + + parser.add_argument( + "--chunk-size", + help="Max token count for prompt generation", + type=int, + required=False, + default=MIN_CHUNK_SIZE, + ) + + parser.add_argument( + "--language", + help="Primary language used for inputs and outputs on GraphRAG", + type=str, + required=False, + default="", + ) + + parser.add_argument( + "--no-entity-types", + help="Use untyped entity extraction generation", + action="store_true", + required=False, + default=False, + ) + + parser.add_argument( + "--output", + help="Folder to save the generated prompts to", + type=str, + required=False, + default="prompts", + ) + + args = parser.parse_args() + + loop = asyncio.get_event_loop() + + loop.run_until_complete( + fine_tune( + args.root, + args.domain, + str(args.method), + args.limit, + args.max_tokens, + args.chunk_size, + args.language, + args.no_entity_types, + args.output, + ) + ) diff --git a/graphrag/graphrag/prompt_tune/cli.py b/graphrag/graphrag/prompt_tune/cli.py new file mode 100644 index 0000000000000000000000000000000000000000..f26b1c09b11fb04c88dedd95b32b91094ea6d37a --- /dev/null +++ b/graphrag/graphrag/prompt_tune/cli.py @@ -0,0 +1,253 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Command line interface for the fine_tune module.""" + +from pathlib import Path + +from datashaper import NoopVerbCallbacks + +from graphrag.config.models.graph_rag_config import GraphRagConfig +from graphrag.index.llm import load_llm +from graphrag.index.progress import PrintProgressReporter +from graphrag.index.progress.types import ProgressReporter +from graphrag.llm.types.llm_types import CompletionLLM +from graphrag.prompt_tune.generator import ( + MAX_TOKEN_COUNT, + create_community_summarization_prompt, + create_entity_extraction_prompt, + create_entity_summarization_prompt, + detect_language, + generate_community_report_rating, + generate_community_reporter_role, + generate_domain, + generate_entity_relationship_examples, + generate_entity_types, + generate_persona, +) +from graphrag.prompt_tune.loader import ( + MIN_CHUNK_SIZE, + load_docs_in_chunks, + read_config_parameters, +) + + +async def fine_tune( + root: str, + domain: str, + select: str = "random", + limit: int = 15, + max_tokens: int = MAX_TOKEN_COUNT, + chunk_size: int = MIN_CHUNK_SIZE, + language: str | None = None, + skip_entity_types: bool = False, + output: str = "prompts", +): + """Fine tune the model. + + Parameters + ---------- + - root: The root directory. + - domain: The domain to map the input documents to. + - select: The chunk selection method. + - limit: The limit of chunks to load. + - max_tokens: The maximum number of tokens to use on entity extraction prompts. + - chunk_size: The chunk token size to use. + - skip_entity_types: Skip generating entity types. + - output: The output folder to store the prompts. + """ + reporter = PrintProgressReporter("") + config = read_config_parameters(root, reporter) + + await fine_tune_with_config( + root, + config, + domain, + select, + limit, + max_tokens, + chunk_size, + language, + skip_entity_types, + output, + reporter, + ) + + +async def fine_tune_with_config( + root: str, + config: GraphRagConfig, + domain: str, + select: str = "random", + limit: int = 15, + max_tokens: int = MAX_TOKEN_COUNT, + chunk_size: int = MIN_CHUNK_SIZE, + language: str | None = None, + skip_entity_types: bool = False, + output: str = "prompts", + reporter: ProgressReporter | None = None, +): + """Fine tune the model with a configuration. + + Parameters + ---------- + - root: The root directory. + - config: The GraphRag configuration. + - domain: The domain to map the input documents to. + - select: The chunk selection method. + - limit: The limit of chunks to load. + - max_tokens: The maximum number of tokens to use on entity extraction prompts. + - chunk_size: The chunk token size to use for input text units. + - skip_entity_types: Skip generating entity types. + - output: The output folder to store the prompts. + - reporter: The progress reporter. + + Returns + ------- + - None + """ + if not reporter: + reporter = PrintProgressReporter("") + + output_path = Path(config.root_dir) / output + + doc_list = await load_docs_in_chunks( + root=root, + config=config, + limit=limit, + select_method=select, + reporter=reporter, + chunk_size=chunk_size, + ) + + # Create LLM from config + llm = load_llm( + "fine_tuning", + config.llm.type, + NoopVerbCallbacks(), + None, + config.llm.model_dump(), + ) + + await generate_indexing_prompts( + llm, + config, + doc_list, + output_path, + reporter, + domain, + language, + max_tokens, + skip_entity_types, + ) + + +async def generate_indexing_prompts( + llm: CompletionLLM, + config: GraphRagConfig, + doc_list: list[str], + output_path: Path, + reporter: ProgressReporter, + domain: str | None = None, + language: str | None = None, + max_tokens: int = MAX_TOKEN_COUNT, + skip_entity_types: bool = False, +): + """Generate indexing prompts. + + Parameters + ---------- + - llm: The LLM model to use. + - config: The GraphRag configuration. + - doc_list: The list of documents to use. + - output_path: The path to store the prompts. + - reporter: The progress reporter. + - domain: The domain to map the input documents to. + - max_tokens: The maximum number of tokens to use on entity extraction prompts + - skip_entity_types: Skip generating entity types. + """ + if not domain: + reporter.info("Generating domain...") + domain = await generate_domain(llm, doc_list) + reporter.info(f"Generated domain: {domain}") + + if not language: + reporter.info("Detecting language...") + language = await detect_language(llm, doc_list) + reporter.info(f"Detected language: {language}") + + reporter.info("Generating persona...") + persona = await generate_persona(llm, domain) + reporter.info(f"Generated persona: {persona}") + + reporter.info("Generating community report ranking description...") + community_report_ranking = await generate_community_report_rating( + llm, domain=domain, persona=persona, docs=doc_list + ) + reporter.info( + f"Generated community report ranking description: {community_report_ranking}" + ) + + entity_types = None + if not skip_entity_types: + reporter.info("Generating entity types") + entity_types = await generate_entity_types( + llm, + domain=domain, + persona=persona, + docs=doc_list, + json_mode=config.llm.model_supports_json or False, + ) + reporter.info(f"Generated entity types: {entity_types}") + + reporter.info("Generating entity relationship examples...") + examples = await generate_entity_relationship_examples( + llm, + persona=persona, + entity_types=entity_types, + docs=doc_list, + language=language, + json_mode=False, # config.llm.model_supports_json should be used, but this prompts are used in non-json by the index engine + ) + reporter.info("Done generating entity relationship examples") + + reporter.info("Generating entity extraction prompt...") + create_entity_extraction_prompt( + entity_types=entity_types, + docs=doc_list, + examples=examples, + language=language, + json_mode=False, # config.llm.model_supports_json should be used, but this prompts are used in non-json by the index engine + output_path=output_path, + encoding_model=config.encoding_model, + max_token_count=max_tokens, + ) + reporter.info(f"Generated entity extraction prompt, stored in folder {output_path}") + + reporter.info("Generating entity summarization prompt...") + create_entity_summarization_prompt( + persona=persona, + language=language, + output_path=output_path, + ) + reporter.info( + f"Generated entity summarization prompt, stored in folder {output_path}" + ) + + reporter.info("Generating community reporter role...") + community_reporter_role = await generate_community_reporter_role( + llm, domain=domain, persona=persona, docs=doc_list + ) + reporter.info(f"Generated community reporter role: {community_reporter_role}") + + reporter.info("Generating community summarization prompt...") + create_community_summarization_prompt( + persona=persona, + role=community_reporter_role, + report_rating_description=community_report_ranking, + language=language, + output_path=output_path, + ) + reporter.info( + f"Generated community summarization prompt, stored in folder {output_path}" + ) diff --git a/graphrag/graphrag/prompt_tune/generator/__init__.py b/graphrag/graphrag/prompt_tune/generator/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..df45b460337621b95356c0d2c35c96efcba878eb --- /dev/null +++ b/graphrag/graphrag/prompt_tune/generator/__init__.py @@ -0,0 +1,30 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Prompt generation module.""" + +from .community_report_rating import generate_community_report_rating +from .community_report_summarization import create_community_summarization_prompt +from .community_reporter_role import generate_community_reporter_role +from .defaults import MAX_TOKEN_COUNT +from .domain import generate_domain +from .entity_extraction_prompt import create_entity_extraction_prompt +from .entity_relationship import generate_entity_relationship_examples +from .entity_summarization_prompt import create_entity_summarization_prompt +from .entity_types import generate_entity_types +from .language import detect_language +from .persona import generate_persona + +__all__ = [ + "MAX_TOKEN_COUNT", + "create_community_summarization_prompt", + "create_entity_extraction_prompt", + "create_entity_summarization_prompt", + "detect_language", + "generate_community_report_rating", + "generate_community_reporter_role", + "generate_domain", + "generate_entity_relationship_examples", + "generate_entity_types", + "generate_persona", +] diff --git a/graphrag/graphrag/prompt_tune/generator/community_report_rating.py b/graphrag/graphrag/prompt_tune/generator/community_report_rating.py new file mode 100644 index 0000000000000000000000000000000000000000..59f94d56987ccd36be1a534651c93d085dd09ccb --- /dev/null +++ b/graphrag/graphrag/prompt_tune/generator/community_report_rating.py @@ -0,0 +1,35 @@ +"""Generate a rating description for community report rating.""" + +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +from graphrag.llm.types.llm_types import CompletionLLM +from graphrag.prompt_tune.prompt import ( + GENERATE_REPORT_RATING_PROMPT, +) + + +async def generate_community_report_rating( + llm: CompletionLLM, domain: str, persona: str, docs: str | list[str] +) -> str: + """Generate an LLM persona to use for GraphRAG prompts. + + Parameters + ---------- + - llm (CompletionLLM): The LLM to use for generation + - domain (str): The domain to generate a rating for + - persona (str): The persona to generate a rating for for + - docs (str | list[str]): Documents used to contextualize the rating + + Returns + ------- + - str: The generated rating description prompt response. + """ + docs_str = " ".join(docs) if isinstance(docs, list) else docs + domain_prompt = GENERATE_REPORT_RATING_PROMPT.format( + domain=domain, persona=persona, input_text=docs_str + ) + + response = await llm(domain_prompt) + + return str(response.output).strip() diff --git a/graphrag/graphrag/prompt_tune/generator/community_report_summarization.py b/graphrag/graphrag/prompt_tune/generator/community_report_summarization.py new file mode 100644 index 0000000000000000000000000000000000000000..82a95ce6d68aabeaa51f8f30af31d5e54a33585e --- /dev/null +++ b/graphrag/graphrag/prompt_tune/generator/community_report_summarization.py @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Module for generating prompts for community report summarization.""" + +from pathlib import Path + +from graphrag.prompt_tune.template import COMMUNITY_REPORT_SUMMARIZATION_PROMPT + +COMMUNITY_SUMMARIZATION_FILENAME = "community_report.txt" + + +def create_community_summarization_prompt( + persona: str, + role: str, + report_rating_description: str, + language: str, + output_path: Path | None = None, +) -> str: + """Create a prompt for community summarization. If output_path is provided, write the prompt to a file. + + Parameters + ---------- + - persona (str): The persona to use for the community summarization prompt + - role (str): The role to use for the community summarization prompt + - language (str): The language to use for the community summarization prompt + - output_path (Path | None): The path to write the prompt to. Default is None. If None, the prompt is not written to a file. Default is None. + + Returns + ------- + - str: The community summarization prompt + """ + prompt = COMMUNITY_REPORT_SUMMARIZATION_PROMPT.format( + persona=persona, + role=role, + report_rating_description=report_rating_description, + language=language, + ) + + if output_path: + output_path.mkdir(parents=True, exist_ok=True) + + output_path = output_path / COMMUNITY_SUMMARIZATION_FILENAME + # Write file to output path + with output_path.open("w") as file: + file.write(prompt) + + return prompt diff --git a/graphrag/graphrag/prompt_tune/generator/community_reporter_role.py b/graphrag/graphrag/prompt_tune/generator/community_reporter_role.py new file mode 100644 index 0000000000000000000000000000000000000000..9abd5ed83f8b27808927d23a2f9e4da2df962087 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/generator/community_reporter_role.py @@ -0,0 +1,35 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Generate a community reporter role for community summarization.""" + +from graphrag.llm.types.llm_types import CompletionLLM +from graphrag.prompt_tune.prompt import ( + GENERATE_COMMUNITY_REPORTER_ROLE_PROMPT, +) + + +async def generate_community_reporter_role( + llm: CompletionLLM, domain: str, persona: str, docs: str | list[str] +) -> str: + """Generate an LLM persona to use for GraphRAG prompts. + + Parameters + ---------- + - llm (CompletionLLM): The LLM to use for generation + - domain (str): The domain to generate a persona for + - persona (str): The persona to generate a role for + - docs (str | list[str]): The domain to generate a persona for + + Returns + ------- + - str: The generated domain prompt response. + """ + docs_str = " ".join(docs) if isinstance(docs, list) else docs + domain_prompt = GENERATE_COMMUNITY_REPORTER_ROLE_PROMPT.format( + domain=domain, persona=persona, input_text=docs_str + ) + + response = await llm(domain_prompt) + + return str(response.output) diff --git a/graphrag/graphrag/prompt_tune/generator/defaults.py b/graphrag/graphrag/prompt_tune/generator/defaults.py new file mode 100644 index 0000000000000000000000000000000000000000..5b42f81332faebe32e6e2ea51a004c1b96fda362 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/generator/defaults.py @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Default values for the fine-tuning module.""" + +DEFAULT_TASK = """ +Identify the relations and structure of the community of interest, specifically within the {domain} domain. +""" + +MAX_TOKEN_COUNT = 2000 diff --git a/graphrag/graphrag/prompt_tune/generator/domain.py b/graphrag/graphrag/prompt_tune/generator/domain.py new file mode 100644 index 0000000000000000000000000000000000000000..49c698d1b431abedfc5ed7bc618bd560be5fe781 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/generator/domain.py @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Domain generation for GraphRAG prompts.""" + +from graphrag.llm.types.llm_types import CompletionLLM +from graphrag.prompt_tune.prompt.domain import GENERATE_DOMAIN_PROMPT + + +async def generate_domain(llm: CompletionLLM, docs: str | list[str]) -> str: + """Generate an LLM persona to use for GraphRAG prompts. + + Parameters + ---------- + - llm (CompletionLLM): The LLM to use for generation + - docs (str | list[str]): The domain to generate a persona for + + Returns + ------- + - str: The generated domain prompt response. + """ + docs_str = " ".join(docs) if isinstance(docs, list) else docs + domain_prompt = GENERATE_DOMAIN_PROMPT.format(input_text=docs_str) + + response = await llm(domain_prompt) + + return str(response.output) diff --git a/graphrag/graphrag/prompt_tune/generator/entity_extraction_prompt.py b/graphrag/graphrag/prompt_tune/generator/entity_extraction_prompt.py new file mode 100644 index 0000000000000000000000000000000000000000..faac8da0576bb28bfa8e10993abb91b6aab98c46 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/generator/entity_extraction_prompt.py @@ -0,0 +1,105 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Entity Extraction prompt generator module.""" + +from pathlib import Path + +import graphrag.config.defaults as defs +from graphrag.index.utils.tokens import num_tokens_from_string +from graphrag.prompt_tune.template import ( + EXAMPLE_EXTRACTION_TEMPLATE, + GRAPH_EXTRACTION_JSON_PROMPT, + GRAPH_EXTRACTION_PROMPT, + UNTYPED_EXAMPLE_EXTRACTION_TEMPLATE, + UNTYPED_GRAPH_EXTRACTION_PROMPT, +) + +ENTITY_EXTRACTION_FILENAME = "entity_extraction.txt" + + +def create_entity_extraction_prompt( + entity_types: str | list[str] | None, + docs: list[str], + examples: list[str], + language: str, + max_token_count: int, + encoding_model: str = defs.ENCODING_MODEL, + json_mode: bool = False, + output_path: Path | None = None, +) -> str: + """ + Create a prompt for entity extraction. + + Parameters + ---------- + - entity_types (str | list[str]): The entity types to extract + - docs (list[str]): The list of documents to extract entities from + - examples (list[str]): The list of examples to use for entity extraction + - language (str): The language of the inputs and outputs + - encoding_model (str): The name of the model to use for token counting + - max_token_count (int): The maximum number of tokens to use for the prompt + - json_mode (bool): Whether to use JSON mode for the prompt. Default is False + - output_path (Path | None): The path to write the prompt to. Default is None. If None, the prompt is not written to a file. Default is None. + + Returns + ------- + - str: The entity extraction prompt + """ + prompt = ( + (GRAPH_EXTRACTION_JSON_PROMPT if json_mode else GRAPH_EXTRACTION_PROMPT) + if entity_types + else UNTYPED_GRAPH_EXTRACTION_PROMPT + ) + if isinstance(entity_types, list): + entity_types = ", ".join(entity_types) + + tokens_left = ( + max_token_count + - num_tokens_from_string(prompt, model=encoding_model) + - num_tokens_from_string(entity_types, model=encoding_model) + if entity_types + else 0 + ) + + examples_prompt = "" + + # Iterate over examples, while we have tokens left or examples left + for i, output in enumerate(examples): + input = docs[i] + example_formatted = ( + EXAMPLE_EXTRACTION_TEMPLATE.format( + n=i + 1, input_text=input, entity_types=entity_types, output=output + ) + if entity_types + else UNTYPED_EXAMPLE_EXTRACTION_TEMPLATE.format( + n=i + 1, input_text=input, output=output + ) + ) + + example_tokens = num_tokens_from_string(example_formatted, model=encoding_model) + + # Squeeze in at least one example + if i > 0 and example_tokens > tokens_left: + break + + examples_prompt += example_formatted + tokens_left -= example_tokens + + prompt = ( + prompt.format( + entity_types=entity_types, examples=examples_prompt, language=language + ) + if entity_types + else prompt.format(examples=examples_prompt, language=language) + ) + + if output_path: + output_path.mkdir(parents=True, exist_ok=True) + + output_path = output_path / ENTITY_EXTRACTION_FILENAME + # Write file to output path + with output_path.open("w") as file: + file.write(prompt) + + return prompt diff --git a/graphrag/graphrag/prompt_tune/generator/entity_relationship.py b/graphrag/graphrag/prompt_tune/generator/entity_relationship.py new file mode 100644 index 0000000000000000000000000000000000000000..72ecb5f4daf3d0939516a3f719d1a0092d2ec040 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/generator/entity_relationship.py @@ -0,0 +1,65 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Entity relationship example generation module.""" + +import asyncio +import json + +from graphrag.llm.types.llm_types import CompletionLLM +from graphrag.prompt_tune.prompt import ( + ENTITY_RELATIONSHIPS_GENERATION_JSON_PROMPT, + ENTITY_RELATIONSHIPS_GENERATION_PROMPT, + UNTYPED_ENTITY_RELATIONSHIPS_GENERATION_PROMPT, +) + +MAX_EXAMPLES = 5 + + +async def generate_entity_relationship_examples( + llm: CompletionLLM, + persona: str, + entity_types: str | list[str] | None, + docs: str | list[str], + language: str, + json_mode: bool = False, +) -> list[str]: + """Generate a list of entity/relationships examples for use in generating an entity configuration. + + Will return entity/relationships examples as either JSON or in tuple_delimiter format depending + on the json_mode parameter. + """ + docs_list = [docs] if isinstance(docs, str) else docs + history = [{"role": "system", "content": persona}] + + if entity_types: + entity_types_str = ( + entity_types if isinstance(entity_types, str) else ", ".join(entity_types) + ) + + messages = [ + ( + ENTITY_RELATIONSHIPS_GENERATION_JSON_PROMPT + if json_mode + else ENTITY_RELATIONSHIPS_GENERATION_PROMPT + ).format(entity_types=entity_types_str, input_text=doc, language=language) + for doc in docs_list + ] + else: + messages = [ + UNTYPED_ENTITY_RELATIONSHIPS_GENERATION_PROMPT.format( + input_text=doc, language=language + ) + for doc in docs_list + ] + + messages = messages[:MAX_EXAMPLES] + + tasks = [llm(message, history=history, json=json_mode) for message in messages] + + responses = await asyncio.gather(*tasks) + + return [ + json.dumps(response.json or "") if json_mode else str(response.output) + for response in responses + ] diff --git a/graphrag/graphrag/prompt_tune/generator/entity_summarization_prompt.py b/graphrag/graphrag/prompt_tune/generator/entity_summarization_prompt.py new file mode 100644 index 0000000000000000000000000000000000000000..c6ee786338872576f3d78a910b0439a73243305e --- /dev/null +++ b/graphrag/graphrag/prompt_tune/generator/entity_summarization_prompt.py @@ -0,0 +1,36 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Entity summarization prompt generation module.""" + +from pathlib import Path + +from graphrag.prompt_tune.template import ENTITY_SUMMARIZATION_PROMPT + +ENTITY_SUMMARIZATION_FILENAME = "summarize_descriptions.txt" + + +def create_entity_summarization_prompt( + persona: str, + language: str, + output_path: Path | None = None, +) -> str: + """Create a prompt for entity summarization. If output_path is provided, write the prompt to a file. + + Parameters + ---------- + - persona (str): The persona to use for the entity summarization prompt + - language (str): The language to use for the entity summarization prompt + - output_path (Path | None): The path to write the prompt to. Default is None. If None, the prompt is not written to a file. Default is None. + """ + prompt = ENTITY_SUMMARIZATION_PROMPT.format(persona=persona, language=language) + + if output_path: + output_path.mkdir(parents=True, exist_ok=True) + + output_path = output_path / ENTITY_SUMMARIZATION_FILENAME + # Write file to output path + with output_path.open("w") as file: + file.write(prompt) + + return prompt diff --git a/graphrag/graphrag/prompt_tune/generator/entity_types.py b/graphrag/graphrag/prompt_tune/generator/entity_types.py new file mode 100644 index 0000000000000000000000000000000000000000..42518acd8cfa1283fcdc6e86d92847e8b5e60909 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/generator/entity_types.py @@ -0,0 +1,45 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Entity type generation module for fine-tuning.""" + +from graphrag.llm.types.llm_types import CompletionLLM +from graphrag.prompt_tune.generator.defaults import DEFAULT_TASK +from graphrag.prompt_tune.prompt.entity_types import ( + ENTITY_TYPE_GENERATION_JSON_PROMPT, + ENTITY_TYPE_GENERATION_PROMPT, +) + + +async def generate_entity_types( + llm: CompletionLLM, + domain: str, + persona: str, + docs: str | list[str], + task: str = DEFAULT_TASK, + json_mode: bool = False, +) -> str | list[str]: + """ + Generate entity type categories from a given set of (small) documents. + + Example Output: + "entity_types": ['military unit', 'organization', 'person', 'location', 'event', 'date', 'equipment'] + """ + formatted_task = task.format(domain=domain) + + docs_str = "\n".join(docs) if isinstance(docs, list) else docs + + entity_types_prompt = ( + ENTITY_TYPE_GENERATION_JSON_PROMPT + if json_mode + else ENTITY_TYPE_GENERATION_PROMPT + ).format(task=formatted_task, input_text=docs_str) + + history = [{"role": "system", "content": persona}] + + response = await llm(entity_types_prompt, history=history, json=json_mode) + + if json_mode: + return (response.json or {}).get("entity_types", []) + + return str(response.output) diff --git a/graphrag/graphrag/prompt_tune/generator/language.py b/graphrag/graphrag/prompt_tune/generator/language.py new file mode 100644 index 0000000000000000000000000000000000000000..38de531ca362014f4e8e31dfea50521a47d0e443 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/generator/language.py @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Language detection for GraphRAG prompts.""" + +from graphrag.llm.types.llm_types import CompletionLLM +from graphrag.prompt_tune.prompt import DETECT_LANGUAGE_PROMPT + + +async def detect_language(llm: CompletionLLM, docs: str | list[str]) -> str: + """Detect input language to use for GraphRAG prompts. + + Parameters + ---------- + - llm (CompletionLLM): The LLM to use for generation + - docs (str | list[str]): The docs to detect language from + + Returns + ------- + - str: The detected language. + """ + docs_str = " ".join(docs) if isinstance(docs, list) else docs + language_prompt = DETECT_LANGUAGE_PROMPT.format(input_text=docs_str) + + response = await llm(language_prompt) + + return str(response.output) diff --git a/graphrag/graphrag/prompt_tune/generator/persona.py b/graphrag/graphrag/prompt_tune/generator/persona.py new file mode 100644 index 0000000000000000000000000000000000000000..cdd57a655d9af2c69f86887293d119403c9b154e --- /dev/null +++ b/graphrag/graphrag/prompt_tune/generator/persona.py @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Persona generating module for fine-tuning GraphRAG prompts.""" + +from graphrag.llm.types.llm_types import CompletionLLM +from graphrag.prompt_tune.generator.defaults import DEFAULT_TASK +from graphrag.prompt_tune.prompt import GENERATE_PERSONA_PROMPT + + +async def generate_persona( + llm: CompletionLLM, domain: str, task: str = DEFAULT_TASK +) -> str: + """Generate an LLM persona to use for GraphRAG prompts. + + Parameters + ---------- + - llm (CompletionLLM): The LLM to use for generation + - domain (str): The domain to generate a persona for + - task (str): The task to generate a persona for. Default is DEFAULT_TASK + """ + formatted_task = task.format(domain=domain) + persona_prompt = GENERATE_PERSONA_PROMPT.format(sample_task=formatted_task) + + response = await llm(persona_prompt) + + return str(response.output) diff --git a/graphrag/graphrag/prompt_tune/loader/__init__.py b/graphrag/graphrag/prompt_tune/loader/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..94e64cbe87677542673d9d61f1f49db7c61f64be --- /dev/null +++ b/graphrag/graphrag/prompt_tune/loader/__init__.py @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Fine-tuning config and data loader module.""" + +from .config import read_config_parameters +from .input import MIN_CHUNK_OVERLAP, MIN_CHUNK_SIZE, load_docs_in_chunks + +__all__ = [ + "MIN_CHUNK_OVERLAP", + "MIN_CHUNK_SIZE", + "load_docs_in_chunks", + "read_config_parameters", +] diff --git a/graphrag/graphrag/prompt_tune/loader/config.py b/graphrag/graphrag/prompt_tune/loader/config.py new file mode 100644 index 0000000000000000000000000000000000000000..db451156cab7867a0d5ca9fb40ba37620ef0ced1 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/loader/config.py @@ -0,0 +1,43 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Config loading, parsing and handling module.""" + +from pathlib import Path + +from graphrag.config import create_graphrag_config +from graphrag.index.progress.types import ProgressReporter + + +def read_config_parameters(root: str, reporter: ProgressReporter): + """Read the configuration parameters from the settings file or environment variables. + + Parameters + ---------- + - root: The root directory where the parameters are. + - reporter: The progress reporter. + """ + _root = Path(root) + settings_yaml = _root / "settings.yaml" + if not settings_yaml.exists(): + settings_yaml = _root / "settings.yml" + settings_json = _root / "settings.json" + + if settings_yaml.exists(): + reporter.info(f"Reading settings from {settings_yaml}") + with settings_yaml.open("r") as file: + import yaml + + data = yaml.safe_load(file) + return create_graphrag_config(data, root) + + if settings_json.exists(): + reporter.info(f"Reading settings from {settings_json}") + with settings_json.open("r") as file: + import json + + data = json.loads(file.read()) + return create_graphrag_config(data, root) + + reporter.info("Reading settings from environment variables") + return create_graphrag_config(root_dir=root) diff --git a/graphrag/graphrag/prompt_tune/loader/input.py b/graphrag/graphrag/prompt_tune/loader/input.py new file mode 100644 index 0000000000000000000000000000000000000000..a8cc7db727b139a781043c5b77881b1d50e1069b --- /dev/null +++ b/graphrag/graphrag/prompt_tune/loader/input.py @@ -0,0 +1,62 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Input loading module.""" + +from typing import cast + +import pandas as pd +from datashaper import NoopVerbCallbacks, TableContainer, VerbInput + +from graphrag.config.models.graph_rag_config import GraphRagConfig +from graphrag.index.input import load_input +from graphrag.index.progress.types import ProgressReporter +from graphrag.index.verbs import chunk + +MIN_CHUNK_SIZE = 200 +MIN_CHUNK_OVERLAP = 0 + + +async def load_docs_in_chunks( + root: str, + config: GraphRagConfig, + select_method: str, + limit: int, + reporter: ProgressReporter, + chunk_size: int = MIN_CHUNK_SIZE, +) -> list[str]: + """Load docs into chunks for generating prompts.""" + dataset = await load_input(config.input, reporter, root) + + # covert to text units + input = VerbInput(input=TableContainer(table=dataset)) + chunk_strategy = config.chunks.resolved_strategy() + + # Use smaller chunks, to avoid huge prompts + chunk_strategy["chunk_size"] = chunk_size + chunk_strategy["chunk_overlap"] = MIN_CHUNK_OVERLAP + + dataset_chunks_table_container = chunk( + input, + column="text", + to="chunks", + callbacks=NoopVerbCallbacks(), + strategy=chunk_strategy, + ) + + dataset_chunks = cast(pd.DataFrame, dataset_chunks_table_container.table) + + # Select chunks into a new df and explode it + chunks_df = pd.DataFrame(dataset_chunks["chunks"].explode()) # type: ignore + + # Depending on the select method, build the dataset + if limit <= 0 or limit > len(chunks_df): + limit = len(chunks_df) + + if select_method == "top": + chunks_df = chunks_df[:limit] + elif select_method == "random": + chunks_df = chunks_df.sample(n=limit) + + # Convert the dataset to list form, so we have a list of documents + return chunks_df["chunks"].tolist() diff --git a/graphrag/graphrag/prompt_tune/prompt/__init__.py b/graphrag/graphrag/prompt_tune/prompt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..991d52856ee60881edf0d8a19894ecb0b4eb36ac --- /dev/null +++ b/graphrag/graphrag/prompt_tune/prompt/__init__.py @@ -0,0 +1,32 @@ +"""Persona, entity type, relationships and domain generation prompts module.""" + +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +from .community_report_rating import GENERATE_REPORT_RATING_PROMPT +from .community_reporter_role import GENERATE_COMMUNITY_REPORTER_ROLE_PROMPT +from .domain import GENERATE_DOMAIN_PROMPT +from .entity_relationship import ( + ENTITY_RELATIONSHIPS_GENERATION_JSON_PROMPT, + ENTITY_RELATIONSHIPS_GENERATION_PROMPT, + UNTYPED_ENTITY_RELATIONSHIPS_GENERATION_PROMPT, +) +from .entity_types import ( + ENTITY_TYPE_GENERATION_JSON_PROMPT, + ENTITY_TYPE_GENERATION_PROMPT, +) +from .language import DETECT_LANGUAGE_PROMPT +from .persona import GENERATE_PERSONA_PROMPT + +__all__ = [ + "DETECT_LANGUAGE_PROMPT", + "ENTITY_RELATIONSHIPS_GENERATION_JSON_PROMPT", + "ENTITY_RELATIONSHIPS_GENERATION_PROMPT", + "ENTITY_TYPE_GENERATION_JSON_PROMPT", + "ENTITY_TYPE_GENERATION_PROMPT", + "GENERATE_COMMUNITY_REPORTER_ROLE_PROMPT", + "GENERATE_DOMAIN_PROMPT", + "GENERATE_PERSONA_PROMPT", + "GENERATE_REPORT_RATING_PROMPT", + "UNTYPED_ENTITY_RELATIONSHIPS_GENERATION_PROMPT", +] diff --git a/graphrag/graphrag/prompt_tune/prompt/community_report_rating.py b/graphrag/graphrag/prompt_tune/prompt/community_report_rating.py new file mode 100644 index 0000000000000000000000000000000000000000..b061645b94718d49c1313feec8ffc4b21f1828fc --- /dev/null +++ b/graphrag/graphrag/prompt_tune/prompt/community_report_rating.py @@ -0,0 +1,132 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Fine tuning prompts for Community Reports Rating.""" + +GENERATE_REPORT_RATING_PROMPT = """ + +You are a helpful agent tasked with rating the importance of a given text in the context of the provided domain and persona. Your goal is to provide a rating that reflects the relevance and significance of the text to the specified domain and persona. Use your expertise to evaluate the text based on the importance criteria and assign a float score between 0-10. Only respond with the text description of the importance criteria. Use the provided example data format to guide your response. Ignore the content of the example data and focus on the structure. + +###################### +-Examples- +###################### + +### Example 1 + +# Domain + +Personal and Family Communication + +# Persona + +You are an expert in Social Network Analysis with a focus on the Personal and Family Communication domain. You are skilled at mapping and interpreting complex social networks, understanding the dynamics of interpersonal relationships, and identifying patterns of communication within communities. You are adept at helping people understand the structure and relations within their personal and family networks, providing insights into how information flows, how strong various connections are, and how these networks influence individual and group behavior. + +# Data + + +Subject: Re: Event +From: Alice Brown alice.brown@example.com +Date: 2012-11-14, 9:52 a.m. +To: John Smith john.smith@example.com +CC: Jane Doe jane.doe@example.com, Bob Johnson bob.johnson@example.com, Emma Davis emma.davis@example.com + +The event is at 6pm at City Hall (Queen street) event chamber. We +just need to get there by 5:45pm. It is 30-minute long so we will be +done by 6:30pm. We'll then head over to New Sky on Spadina for some +unique cuisine! + +Guests are you and Emma, and my uncle and auntie from London +who my folks have designated to act as their reps. Jane and Joe are +witnesses. + +Be there or be square! +Alice + +On Wed, Nov 14, 2012 at 9:40 AM, John Smith john.smith@example.com wrote: + +Thats the day after Bob's event! +Any more details on the event schedule? ITS NEXT WEEK! +On Tue, Nov 13, 2012 at 7:51 PM, Jane Doe +jane.doe@example.com wrote: +I am supposed to forward you the invitation to this year's celebration. +Date: Saturday, Nov. 24, 6 pm starting +Place as usual: Dean's house, 6 Cardish, Kleinburg L0J 1C0 +Jane Doe +jane.doe@example.com + +# Importance Criteria + +A float score between 0-10 that represents the relevance of the email's content to family communication, health concerns, travel plans, and interpersonal dynamics, with 1 being trivial or spam and 10 being highly relevant, urgent, and impactful to family cohesion or well-being. +############################# + +### Example 2 + +# Domain + +Literary Analysis + +# Persona + +You are a literary scholar with a focus on works from the 19th century. You are skilled at analyzing and interpreting texts, identifying themes and motifs, and understanding the historical and cultural contexts in which these works were written. You are adept at helping people understand the deeper meanings and significance of literary works, providing insights into the author's intentions, the social issues addressed in the text, and the impact of these works on contemporary society. + +# Data + +Had she found Jane in any apparent danger, Mrs. Bennet would have been very miserable; but being satisfied on seeing her that her illness was not alarming, she had no wish of her recovering immediately, as her restoration to health would probably remove her from Netherfield. She would not listen, therefore, to her daughter's proposal of being carried home; neither did the apothecary, who arrived about the same time, think it at all advisable. After sitting a little with Jane, on Miss Bingley's appearance and invitation, the mother and three daughters all attended her into the breakfast parlor. Bingley met them with hopes that Mrs. Bennet had not found Miss Bennet worse than she expected. + +"Indeed I have, Sir," was her answer. "She is a great deal too ill to be moved. Mr. Jones says we must not think of moving her. We must trespass a little longer on your kindness." + +"Removed!" cried Bingley. "It must not be thought of. My sister, I am sure, will not hear of her removal." + +# Importance Criteria + +A float score between 0-10 that represents the relevance of the text to literary analysis, historical context, thematic interpretation, and cultural significance, with 1 being trivial or irrelevant and 10 being highly significant, profound, and impactful to the understanding of the text and its implications. +############################# + +### Example 3 + +# Domain + +Environmental Science + +# Persona + +You are an environmental scientist with a focus on climate change and sustainability. You are skilled at analyzing data, interpreting social commentary and recommending policy changes. You are adept at helping people understand the causes and consequences of climate change, providing insights into how they can reduce their carbon footprint, adopt sustainable practices, and contribute to a healthier planet. + +# Data + +Host 1 (Anna): Welcome to "Green Living Today," the podcast where we explore practical tips and inspiring stories about sustainable living. I'm your host, Anna Green. + +Host 2 (Mark): And I'm Mark Smith. Today, we have a special episode focused on reducing plastic waste in our daily lives. We'll be talking to a special guest who has made significant strides in living a plastic-free lifestyle. + +Anna: That's right, Mark. Our guest today is Laura Thompson, the founder of "Plastic-Free Living," a blog dedicated to sharing tips and resources for reducing plastic use. Welcome to the show, Laura! + +Guest (Laura): Thanks, Anna and Mark. It's great to be here. + +Mark: Laura, let's start by talking about your journey. What inspired you to start living a plastic-free lifestyle? + +# Importance Criteria + +A float score between 0-10 that represents the relevance of the text to sustainability, plastic waste reduction, and environmental policies, with 1 being trivial or irrelevant and 10 being highly significant, impactful, and actionable in promoting environmental awareness. +############################# + + +############################# +-Real Data- +############################# + +# Domain + +{domain} + +# Persona + +{persona} + +# Data + +{input_text} + +# Importance Criteria + + +""" diff --git a/graphrag/graphrag/prompt_tune/prompt/community_reporter_role.py b/graphrag/graphrag/prompt_tune/prompt/community_reporter_role.py new file mode 100644 index 0000000000000000000000000000000000000000..b667bc294044b4c920f91ad17170d1154ea666b7 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/prompt/community_reporter_role.py @@ -0,0 +1,20 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Fine-tuning prompts for community reporter role generation.""" + +GENERATE_COMMUNITY_REPORTER_ROLE_PROMPT = """ +{persona} +Given a sample text, help the user by creating a role definition that will be tasked with community analysis. +Take a look at this example, determine its key parts, and using the domain provided and your expertise, create a new role definition for the provided inputs that follows the same pattern as the example. +Remember, your output should look just like the provided example in structure and content. + +Example: +A technologist reporter that is analyzing Kevin Scott's "Behind the Tech Podcast", given a list of entities +that belong to the community as well as their relationships and optional associated claims. +The report will be used to inform decision-makers about significant developments associated with the community and their potential impact. + + +Domain: {domain} +Text: {input_text} +Role:""" diff --git a/graphrag/graphrag/prompt_tune/prompt/domain.py b/graphrag/graphrag/prompt_tune/prompt/domain.py new file mode 100644 index 0000000000000000000000000000000000000000..4b4587f8d8d41ab260eda08e53444f4c20c2c0c0 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/prompt/domain.py @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Fine-tuning prompts for domain generation.""" + +GENERATE_DOMAIN_PROMPT = """ +You are an intelligent assistant that helps a human to analyze the information in a text document. +Given a sample text, help the user by assigning a descriptive domain that summarizes what the text is about. +Example domains are: "Social studies", "Algorithmic analysis", "Medical science", among others. + +Text: {input_text} +Domain:""" diff --git a/graphrag/graphrag/prompt_tune/prompt/entity_relationship.py b/graphrag/graphrag/prompt_tune/prompt/entity_relationship.py new file mode 100644 index 0000000000000000000000000000000000000000..af31d090035ad1cc217e4eb552f55dee6c543acf --- /dev/null +++ b/graphrag/graphrag/prompt_tune/prompt/entity_relationship.py @@ -0,0 +1,132 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Fine-tuning prompts for entity relationship generation.""" + +ENTITY_RELATIONSHIPS_GENERATION_PROMPT = """ +-Goal- +Given a text document that is potentially relevant to this activity and a list of entity types, identify all entities of those types from the text and all relationships among the identified entities. + +-Steps- +1. Identify all entities. For each identified entity, extract the following information: +- entity_name: Name of the entity, capitalized +- entity_type: One of the following types: [{entity_types}] +- entity_description: Comprehensive description of the entity's attributes and activities +Format each entity, include the parenthesis at the beginning and end, as ("entity"{{tuple_delimiter}}{{tuple_delimiter}}{{tuple_delimiter}}) +for example: ("entity"{{tuple_delimiter}}"Microsoft"{{tuple_delimiter}}"organization"{{tuple_delimiter}}"Microsoft is a technology company") + +2. From the entities identified in step 1, identify all pairs of (source_entity, target_entity) that are *clearly related* to each other. +For each pair of related entities, extract the following information: +- source_entity: name of the source entity, as identified in step 1 +- target_entity: name of the target entity, as identified in step 1 +- relationship_description: explanation as to why you think the source entity and the target entity are related to each other +- relationship_strength: an integer score between 1 to 10, indicating strength of the relationship between the source entity and target entity +Format each relationship, include the parenthesis at the beginning and end, as ("relationship"{{tuple_delimiter}}{{tuple_delimiter}}{{tuple_delimiter}}{{tuple_delimiter}}) +for example: ("relationship"{{tuple_delimiter}}"company A"{{tuple_delimiter}}"person A"{{tuple_delimiter}}"company A is currently owned by person A"{{tuple_delimiter}}8) + +3. Return output in {language} as a single list of all the entities and relationships identified in steps 1 and 2. Use **{{record_delimiter}}** as the list delimiter. If you have to translate, just translate the descriptions, nothing else! + +4. When finished, output {{completion_delimiter}}. + +-Real Data- +###################### +entity_types: {entity_types} +text: {input_text} +###################### +output: +""" + +ENTITY_RELATIONSHIPS_GENERATION_JSON_PROMPT = """ +-Goal- +Given a text document that is potentially relevant to this activity and a list of entity types, identify all entities of those types from the text and all relationships among the identified entities. + +-Steps- +1. Identify all entities. For each identified entity, extract the following information: +- entity_name: Name of the entity, capitalized +- entity_type: One of the following types: [{entity_types}] +- entity_description: Comprehensive description of the entity's attributes and activities + +Format each entity output as a JSON entry with the following format: + +{{"name": , "type": , "description": }} + +2. From the entities identified in step 1, identify all pairs of (source_entity, target_entity) that are *clearly related* to each other. +For each pair of related entities, extract the following information: +- source_entity: name of the source entity, as identified in step 1 +- target_entity: name of the target entity, as identified in step 1 +- relationship_description: explanation as to why you think the source entity and the target entity are related to each other +- relationship_strength: an integer score between 1 to 10, indicating strength of the relationship between the source entity and target entity + +Format each relationship as a JSON entry with the following format: + +{{"source": , "target": , "relationship": , "relationship_strength": }} + +3. Return output in {language} as a single list of all JSON entities and relationships identified in steps 1 and 2. If you have to translate, just translate the descriptions, nothing else! + +-Real Data- +###################### +entity_types: {entity_types} +text: {input_text} +###################### +output: +""" + +UNTYPED_ENTITY_RELATIONSHIPS_GENERATION_PROMPT = """ +-Goal- +Given a text document that is potentially relevant to this activity, first identify all entities needed from the text in order to capture the information and ideas in the text. +Next, report all relationships among the identified entities. + +-Steps- +1. Identify all entities. For each identified entity, extract the following information: +- entity_name: Name of the entity, capitalized +- entity_type: Suggest several labels or categories for the entity. The categories should not be specific, but should be as general as possible. +- entity_description: Comprehensive description of the entity's attributes and activities +Format each entity as ("entity"{{tuple_delimiter}}{{tuple_delimiter}}{{tuple_delimiter}} + +2. From the entities identified in step 1, identify all pairs of (source_entity, target_entity) that are *clearly related* to each other. +For each pair of related entities, extract the following information: +- source_entity: name of the source entity, as identified in step 1 +- target_entity: name of the target entity, as identified in step 1 +- relationship_description: explanation as to why you think the source entity and the target entity are related to each other +- relationship_strength: a numeric score indicating strength of the relationship between the source entity and target entity + Format each relationship as ("relationship"{{tuple_delimiter}}{{tuple_delimiter}}{{tuple_delimiter}}{{tuple_delimiter}}) + +3. Return output in {language} as a single list of all the entities and relationships identified in steps 1 and 2. Use **{{record_delimiter}}** as the list delimiter. If you have to translate, just translate the descriptions, nothing else! + +4. When finished, output {{completion_delimiter}} + +###################### +-Examples- +###################### +Text: +The Fed is scheduled to meet on Tuesday and Wednesday, with the central bank planning to release its latest policy decision on Wednesday at 2:00 p.m. ET, followed by a press conference where Fed Chair Jerome Powell will take questions. Investors expect the Federal Open Market Committee to hold its benchmark interest rate steady in a range of 5.25%-5.5%. +###################### +Output: +("entity"{{tuple_delimiter}}FED{{tuple_delimiter}}ORGANIZATION{{tuple_delimiter}}The Fed is the Federal Reserve, which is setting interest rates on Tuesday and Wednesday) +{{record_delimiter}} +("entity"{{tuple_delimiter}}JEROME POWELL{{tuple_delimiter}}PERSON{{tuple_delimiter}}Jerome Powell is the chair of the Federal Reserve) +{{record_delimiter}} +("entity"{{tuple_delimiter}}FEDERAL OPEN MARKET COMMITTEE{{tuple_delimiter}}ORGANIZATION{{tuple_delimiter}}The Federal Reserve committee makes key decisions about interest rates and the growth of the United States money supply) +{{record_delimiter}} +("relationship"{{tuple_delimiter}}JEROME POWELL{{tuple_delimiter}}FED{{tuple_delimiter}}Jerome Powell is the Chair of the Federal Reserve and will answer questions at a press conference{{tuple_delimiter}}9) +{{completion_delimiter}} +###################### +Text: +Arm's (ARM) stock skyrocketed in its opening day on the Nasdaq Thursday. But IPO experts warn that the British chipmaker's debut on the public markets isn't indicative of how other newly listed companies may perform. + +Arm, a formerly public company, was taken private by SoftBank in 2016. The well-established chip designer says it powers 99% of premium smartphones. +###################### +Output: +("entity"{{tuple_delimiter}}ARM{{tuple_delimiter}}ORGANIZATION, COMPANY{{tuple_delimiter}}Arm is a stock now listed on the Nasdaq which powers 99% of premium smartphones) +{{record_delimiter}} +("entity"{{tuple_delimiter}}SOFTBANK{{tuple_delimiter}}ORGANIZATION, COMPANY{{tuple_delimiter}}SoftBank is a firm that previously owned Arm) +{{record_delimiter}} +("relationship"{{tuple_delimiter}}ARM{{tuple_delimiter}}SOFTBANK{{tuple_delimiter}}SoftBank formerly owned Arm from 2016 until present{{tuple_delimiter}}5) +{{completion_delimiter}} +###################### +-Real Data- +###################### +Text: {input_text} +###################### +Output: +""" diff --git a/graphrag/graphrag/prompt_tune/prompt/entity_types.py b/graphrag/graphrag/prompt_tune/prompt/entity_types.py new file mode 100644 index 0000000000000000000000000000000000000000..99b21db6450771fe2bf0bd3acb0aa92e389eaeea --- /dev/null +++ b/graphrag/graphrag/prompt_tune/prompt/entity_types.py @@ -0,0 +1,89 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Fine-tuning prompts for entity types generation.""" + +ENTITY_TYPE_GENERATION_PROMPT = """ +The goal is to study the connections and relations between the entity types and their features in order to understand all available information from the text. +The user's task is to {task}. +As part of the analysis, you want to identify the entity types present in the following text. +The entity types must be relevant to the user task. +Avoid general entity types such as "other" or "unknown". +This is VERY IMPORTANT: Do not generate redundant or overlapping entity types. For example, if the text contains "company" and "organization" entity types, you should return only one of them. +Don't worry about quantity, always choose quality over quantity. And make sure EVERYTHING in your answer is relevant to the context of entity extraction. +And remember, it is ENTITY TYPES what we need. +Return the entity types in as a list of comma sepparated of strings. +===================================================================== +EXAMPLE SECTION: The following section includes example output. These examples **must be excluded from your answer**. + +EXAMPLE 1 +Task: Determine the connections and organizational hierarchy within the specified community. +Text: Example_Org_A is a company in Sweden. Example_Org_A's director is Example_Individual_B. +RESPONSE: +organization, person +END OF EXAMPLE 1 + +EXAMPLE 2 +Task: Identify the key concepts, principles, and arguments shared among different philosophical schools of thought, and trace the historical or ideological influences they have on each other. +Text: Rationalism, epitomized by thinkers such as René Descartes, holds that reason is the primary source of knowledge. Key concepts within this school include the emphasis on the deductive method of reasoning. +RESPONSE: +concept, person, school of thought +END OF EXAMPLE 2 + +EXAMPLE 3 +Task: Identify the full range of basic forces, factors, and trends that would indirectly shape an issue. +Text: Industry leaders such as Panasonic are vying for supremacy in the battery production sector. They are investing heavily in research and development and are exploring new technologies to gain a competitive edge. +RESPONSE: +organization, technology, sectors, investment strategies +END OF EXAMPLE 3 +====================================================================== + +====================================================================== +REAL DATA: The following section is the real data. You should use only this real data to prepare your answer. Generate Entity Types only. +Task: {task} +Text: {input_text} +RESPONSE: +{{}} +""" + +ENTITY_TYPE_GENERATION_JSON_PROMPT = """ +The goal is to study the connections and relations between the entity types and their features in order to understand all available information from the text. +The user's task is to {task}. +As part of the analysis, you want to identify the entity types present in the following text. +The entity types must be relevant to the user task. +Avoid general entity types such as "other" or "unknown". +This is VERY IMPORTANT: Do not generate redundant or overlapping entity types. For example, if the text contains "company" and "organization" entity types, you should return only one of them. +Don't worry about quantity, always choose quality over quantity. And make sure EVERYTHING in your answer is relevant to the context of entity extraction. +Return the entity types in JSON format with "entities" as the key and the entity types as an array of strings. +===================================================================== +EXAMPLE SECTION: The following section includes example output. These examples **must be excluded from your answer**. + +EXAMPLE 1 +Task: Determine the connections and organizational hierarchy within the specified community. +Text: Example_Org_A is a company in Sweden. Example_Org_A's director is Example_Individual_B. +JSON RESPONSE: +{{"entity_types": [organization, person] }} +END OF EXAMPLE 1 + +EXAMPLE 2 +Task: Identify the key concepts, principles, and arguments shared among different philosophical schools of thought, and trace the historical or ideological influences they have on each other. +Text: Rationalism, epitomized by thinkers such as René Descartes, holds that reason is the primary source of knowledge. Key concepts within this school include the emphasis on the deductive method of reasoning. +JSON RESPONSE: +{{"entity_types": [concept, person, school of thought] }} +END OF EXAMPLE 2 + +EXAMPLE 3 +Task: Identify the full range of basic forces, factors, and trends that would indirectly shape an issue. +Text: Industry leaders such as Panasonic are vying for supremacy in the battery production sector. They are investing heavily in research and development and are exploring new technologies to gain a competitive edge. +JSON RESPONSE: +{{"entity_types": [organization, technology, sectors, investment strategies] }} +END OF EXAMPLE 3 +====================================================================== + +====================================================================== +REAL DATA: The following section is the real data. You should use only this real data to prepare your answer. Generate Entity Types only. +Task: {task} +Text: {input_text} +JSON response: +{{"entity_types": [] }} +""" diff --git a/graphrag/graphrag/prompt_tune/prompt/language.py b/graphrag/graphrag/prompt_tune/prompt/language.py new file mode 100644 index 0000000000000000000000000000000000000000..68fd04029f23dac50260a561059ef461f5853778 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/prompt/language.py @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Fine-tuning prompts for language detection.""" + +DETECT_LANGUAGE_PROMPT = """ +You are an intelligent assistant that helps a human to analyze the information in a text document. +Given a sample text, help the user by determining what's the primary language of the provided texts. +Examples are: "English", "Spanish", "Japanese", "Portuguese" among others. + +Text: {input_text} +Language:""" diff --git a/graphrag/graphrag/prompt_tune/prompt/persona.py b/graphrag/graphrag/prompt_tune/prompt/persona.py new file mode 100644 index 0000000000000000000000000000000000000000..58515fd2043838d21c7692513b9ba7597584caac --- /dev/null +++ b/graphrag/graphrag/prompt_tune/prompt/persona.py @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Fine-tuning prompts for persona generation.""" + +GENERATE_PERSONA_PROMPT = """ +You are an intelligent assistant that helps a human to analyze the information in a text document. +Given a specific type of task and sample text, help the user by generating a 3 to 4 sentence description of an expert who could help solve the problem. +Use a format similar to the following: +You are an expert {{role}}. You are skilled at {{relevant skills}}. You are adept at helping people with {{specific task}}. + +task: {sample_task} +persona description:""" diff --git a/graphrag/graphrag/prompt_tune/template/__init__.py b/graphrag/graphrag/prompt_tune/template/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e056762ff723ee05a01606a342c0e0b3c12bf8a4 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/template/__init__.py @@ -0,0 +1,24 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Fine-tuning prompts for entity extraction, entity summarization, and community report summarization.""" + +from .community_report_summarization import COMMUNITY_REPORT_SUMMARIZATION_PROMPT +from .entity_extraction import ( + EXAMPLE_EXTRACTION_TEMPLATE, + GRAPH_EXTRACTION_JSON_PROMPT, + GRAPH_EXTRACTION_PROMPT, + UNTYPED_EXAMPLE_EXTRACTION_TEMPLATE, + UNTYPED_GRAPH_EXTRACTION_PROMPT, +) +from .entity_summarization import ENTITY_SUMMARIZATION_PROMPT + +__all__ = [ + "COMMUNITY_REPORT_SUMMARIZATION_PROMPT", + "ENTITY_SUMMARIZATION_PROMPT", + "EXAMPLE_EXTRACTION_TEMPLATE", + "GRAPH_EXTRACTION_JSON_PROMPT", + "GRAPH_EXTRACTION_PROMPT", + "UNTYPED_EXAMPLE_EXTRACTION_TEMPLATE", + "UNTYPED_GRAPH_EXTRACTION_PROMPT", +] diff --git a/graphrag/graphrag/prompt_tune/template/community_report_summarization.py b/graphrag/graphrag/prompt_tune/template/community_report_summarization.py new file mode 100644 index 0000000000000000000000000000000000000000..14e039ba41bb60a3a349396551e6981af64c0e18 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/template/community_report_summarization.py @@ -0,0 +1,95 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Fine-tuning prompts for community report summarization.""" + +COMMUNITY_REPORT_SUMMARIZATION_PROMPT = """ +{persona} + +# Goal +Write a comprehensive assessment report of a community taking on the role of a {role}. The content of this report includes an overview of the community's key entities and relationships. + +# Report Structure +The report should include the following sections: +- TITLE: community's name that represents its key entities - title should be short but specific. When possible, include representative named entities in the title. +- SUMMARY: An executive summary of the community's overall structure, how its entities are related to each other, and significant points associated with its entities. +- REPORT RATING: {report_rating_description} +- RATING EXPLANATION: Give a single sentence explanation of the rating. +- DETAILED FINDINGS: A list of 5-10 key insights about the community. Each insight should have a short summary followed by multiple paragraphs of explanatory text grounded according to the grounding rules below. Be comprehensive. + +Return output as a well-formed JSON-formatted string with the following format. Don't use any unnecessary escape sequences. The output should be a single JSON object that can be parsed by json.loads. + {{ + "title": "", + "summary": "", + "rating": , + "rating_explanation": "" + "findings": "[{{"summary":"", "explanation": "", "explanation": " (, ... ()]. If there are more than 10 data records, show the top 10 most relevant records. +Each paragraph should contain multiple sentences of explanation and concrete examples with specific named entities. All paragraphs must have these references at the start and end. Use "NONE" if there are no related roles or records. Everything should be in {language}. + +Example paragraph with references added: +This is a paragraph of the output text [records: Entities (1, 2, 3), Claims (2, 5), Relationships (10, 12)] + +# Example Input +----------- +Text: + +Entities + +id,entity,description +5,ABILA CITY PARK,Abila City Park is the location of the POK rally + +Relationships + +id,source,target,description +37,ABILA CITY PARK,POK RALLY,Abila City Park is the location of the POK rally +38,ABILA CITY PARK,POK,POK is holding a rally in Abila City Park +39,ABILA CITY PARK,POKRALLY,The POKRally is taking place at Abila City Park +40,ABILA CITY PARK,CENTRAL BULLETIN,Central Bulletin is reporting on the POK rally taking place in Abila City Park + +Output: +{{ + "title": "Abila City Park and POK Rally", + "summary": "The community revolves around the Abila City Park, which is the location of the POK rally. The park has relationships with POK, POKRALLY, and Central Bulletin, all +of which are associated with the rally event.", + "rating": 5.0, + "rating_explanation": "The impact rating is moderate due to the potential for unrest or conflict during the POK rally.", + "findings": [ + {{ + "summary": "Abila City Park as the central location", + "explanation": "Abila City Park is the central entity in this community, serving as the location for the POK rally. This park is the common link between all other +entities, suggesting its significance in the community. The park's association with the rally could potentially lead to issues such as public disorder or conflict, depending on the +nature of the rally and the reactions it provokes. [records: Entities (5), Relationships (37, 38, 39, 40)]" + }}, + {{ + "summary": "POK's role in the community", + "explanation": "POK is another key entity in this community, being the organizer of the rally at Abila City Park. The nature of POK and its rally could be a potential +source of threat, depending on their objectives and the reactions they provoke. The relationship between POK and the park is crucial in understanding the dynamics of this community. +[records: Relationships (38)]" + }}, + {{ + "summary": "POKRALLY as a significant event", + "explanation": "The POKRALLY is a significant event taking place at Abila City Park. This event is a key factor in the community's dynamics and could be a potential +source of threat, depending on the nature of the rally and the reactions it provokes. The relationship between the rally and the park is crucial in understanding the dynamics of this +community. [records: Relationships (39)]" + }}, + {{ + "summary": "Role of Central Bulletin", + "explanation": "Central Bulletin is reporting on the POK rally taking place in Abila City Park. This suggests that the event has attracted media attention, which could +amplify its impact on the community. The role of Central Bulletin could be significant in shaping public perception of the event and the entities involved. [records: Relationships +(40)]" + }} + ] + +}} + +# Real Data + +Use the following text for your answer. Do not make anything up in your answer. + +Text: +{{input_text}} +Output:""" diff --git a/graphrag/graphrag/prompt_tune/template/entity_extraction.py b/graphrag/graphrag/prompt_tune/template/entity_extraction.py new file mode 100644 index 0000000000000000000000000000000000000000..65c0cfb584a893ec5bbbd0188aa4c695a6f0f1b8 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/template/entity_extraction.py @@ -0,0 +1,136 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Fine-tuning prompts for entity extraction.""" + +GRAPH_EXTRACTION_PROMPT = """ +-Goal- +Given a text document that is potentially relevant to this activity and a list of entity types, identify all entities of those types from the text and all relationships among the identified entities. + +-Steps- +1. Identify all entities. For each identified entity, extract the following information: +- entity_name: Name of the entity, capitalized +- entity_type: One of the following types: [{entity_types}] +- entity_description: Comprehensive description of the entity's attributes and activities +Format each entity as ("entity"{{tuple_delimiter}}{{tuple_delimiter}}{{tuple_delimiter}} + +2. From the entities identified in step 1, identify all pairs of (source_entity, target_entity) that are *clearly related* to each other. +For each pair of related entities, extract the following information: +- source_entity: name of the source entity, as identified in step 1 +- target_entity: name of the target entity, as identified in step 1 +- relationship_description: explanation as to why you think the source entity and the target entity are related to each other +- relationship_strength: an integer score between 1 to 10, indicating strength of the relationship between the source entity and target entity + +Format each relationship as ("relationship"{{tuple_delimiter}}{{tuple_delimiter}}{{tuple_delimiter}}{{tuple_delimiter}}) + +3. Return output in {language} as a single list of all the entities and relationships identified in steps 1 and 2. Use **{{record_delimiter}}** as the list delimiter. If you have to translate, just translate the descriptions, nothing else! + +4. When finished, output {{completion_delimiter}} + +-Examples- +###################### +{examples} + +-Real Data- +###################### +entity_types: [{entity_types}] +text: {{input_text}} +###################### +output:""" + +GRAPH_EXTRACTION_JSON_PROMPT = """ +-Goal- +Given a text document that is potentially relevant to this activity and a list of entity types, identify all entities of those types from the text and all relationships among the identified entities. + +-Steps- +1. Identify all entities. For each identified entity, extract the following information: +- entity_name: Name of the entity, capitalized +- entity_type: One of the following types: [{entity_types}] +- entity_description: Comprehensive description of the entity's attributes and activities +Format each entity output as a JSON entry with the following format: + +{{"name": , "type": , "description": }} + +2. From the entities identified in step 1, identify all pairs of (source_entity, target_entity) that are *clearly related* to each other. +For each pair of related entities, extract the following information: +- source_entity: name of the source entity, as identified in step 1 +- target_entity: name of the target entity, as identified in step 1 +- relationship_description: explanation as to why you think the source entity and the target entity are related to each other +- relationship_strength: an integer score between 1 to 10, indicating strength of the relationship between the source entity and target entity +Format each relationship as a JSON entry with the following format: + +{{"source": , "target": , "relationship": , "relationship_strength": }} + +3. Return output in {language} as a single list of all JSON entities and relationships identified in steps 1 and 2. If you have to translate, just translate the descriptions, nothing else! + +-Examples- +###################### +{examples} + +-Real Data- +###################### +entity_types: {entity_types} +text: {{input_text}} +###################### +output:""" + +EXAMPLE_EXTRACTION_TEMPLATE = """ +Example {n}: + +entity_types: [{entity_types}] +text: +{input_text} +------------------------ +output: +{output} +############################# + +""" + +UNTYPED_EXAMPLE_EXTRACTION_TEMPLATE = """ +Example {n}: + +text: +{input_text} +------------------------ +output: +{output} +############################# + +""" + + +UNTYPED_GRAPH_EXTRACTION_PROMPT = """ +-Goal- +Given a text document that is potentially relevant to this activity, first identify all entities needed from the text in order to capture the information and ideas in the text. +Next, report all relationships among the identified entities. + +-Steps- +1. Identify all entities. For each identified entity, extract the following information: +- entity_name: Name of the entity, capitalized +- entity_type: Suggest several labels or categories for the entity. The categories should not be specific, but should be as general as possible. +- entity_description: Comprehensive description of the entity's attributes and activities +Format each entity as ("entity"{{tuple_delimiter}}{{tuple_delimiter}}{{tuple_delimiter}} + +2. From the entities identified in step 1, identify all pairs of (source_entity, target_entity) that are *clearly related* to each other. +For each pair of related entities, extract the following information: +- source_entity: name of the source entity, as identified in step 1 +- target_entity: name of the target entity, as identified in step 1 +- relationship_description: explanation as to why you think the source entity and the target entity are related to each other +- relationship_strength: a numeric score indicating strength of the relationship between the source entity and target entity + Format each relationship as ("relationship"{{tuple_delimiter}}{{tuple_delimiter}}{{tuple_delimiter}}{{tuple_delimiter}}) + +3. Return output in {language} as a single list of all the entities and relationships identified in steps 1 and 2. Use **{{record_delimiter}}** as the list delimiter. If you have to translate, just translate the descriptions, nothing else! + +4. When finished, output {{completion_delimiter}} + +-Examples- +###################### +{examples} + +-Real Data- +###################### +text: {{input_text}} +###################### +output: +""" diff --git a/graphrag/graphrag/prompt_tune/template/entity_summarization.py b/graphrag/graphrag/prompt_tune/template/entity_summarization.py new file mode 100644 index 0000000000000000000000000000000000000000..60294a291b8e3e5005d3d322c3e1b05d09899561 --- /dev/null +++ b/graphrag/graphrag/prompt_tune/template/entity_summarization.py @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Fine-tuning prompts for entity summarization.""" + +ENTITY_SUMMARIZATION_PROMPT = """ +{persona} +Using your expertise, you're asked to generate a comprehensive summary of the data provided below. +Given one or two entities, and a list of descriptions, all related to the same entity or group of entities. +Please concatenate all of these into a single, concise description in {language}. Make sure to include information collected from all the descriptions. +If the provided descriptions are contradictory, please resolve the contradictions and provide a single, coherent summary. +Make sure it is written in third person, and include the entity names so we the have full context. + +Enrich it as much as you can with relevant information from the nearby text, this is very important. + +If no answer is possible, or the description is empty, only convey information that is provided within the text. +####### +-Data- +Entities: {{entity_name}} +Description List: {{description_list}} +####### +Output:""" diff --git a/graphrag/graphrag/query/__init__.py b/graphrag/graphrag/query/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..58a557f8a2fcff92f4968a48b53bdd55d5cb956a --- /dev/null +++ b/graphrag/graphrag/query/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""GraphRAG Orchestration Module.""" diff --git a/graphrag/graphrag/query/__main__.py b/graphrag/graphrag/query/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..9367f9a9cf7d05456e4365468bec02efb24c9f9e --- /dev/null +++ b/graphrag/graphrag/query/__main__.py @@ -0,0 +1,92 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The Query Engine package root.""" + +import argparse +from enum import Enum + +from .cli import run_global_search, run_local_search + +INVALID_METHOD_ERROR = "Invalid method" + + +class SearchType(Enum): + """The type of search to run.""" + + LOCAL = "local" + GLOBAL = "global" + + def __str__(self): + """Return the string representation of the enum value.""" + return self.value + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument( + "--data", + help="The path with the output data from the pipeline", + required=False, + type=str, + ) + + parser.add_argument( + "--root", + help="The data project root. Default value: the current directory", + required=False, + default=".", + type=str, + ) + + parser.add_argument( + "--method", + help="The method to run, one of: local or global", + required=True, + type=SearchType, + choices=list(SearchType), + ) + + parser.add_argument( + "--community_level", + help="Community level in the Leiden community hierarchy from which we will load the community reports higher value means we use reports on smaller communities", + type=int, + default=2, + ) + + parser.add_argument( + "--response_type", + help="Free form text describing the response type and format, can be anything, e.g. Multiple Paragraphs, Single Paragraph, Single Sentence, List of 3-7 Points, Single Page, Multi-Page Report", + type=str, + default="Multiple Paragraphs", + ) + + parser.add_argument( + "query", + nargs=1, + help="The query to run", + type=str, + ) + + args = parser.parse_args() + + match args.method: + case SearchType.LOCAL: + run_local_search( + args.data, + args.root, + args.community_level, + args.response_type, + args.query[0], + ) + case SearchType.GLOBAL: + run_global_search( + args.data, + args.root, + args.community_level, + args.response_type, + args.query[0], + ) + case _: + raise ValueError(INVALID_METHOD_ERROR) diff --git a/graphrag/graphrag/query/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/query/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82995e199f04cd5c633a4f4b347f54f3c292706d Binary files /dev/null and b/graphrag/graphrag/query/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/__pycache__/indexer_adapters.cpython-311.pyc b/graphrag/graphrag/query/__pycache__/indexer_adapters.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1bae44743c4e1510fcbd6cd94aee66ff9255ea6 Binary files /dev/null and b/graphrag/graphrag/query/__pycache__/indexer_adapters.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/__pycache__/progress.cpython-311.pyc b/graphrag/graphrag/query/__pycache__/progress.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b5a7843137175dfddaf10b6ae057e3e65931afa Binary files /dev/null and b/graphrag/graphrag/query/__pycache__/progress.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/cli.py b/graphrag/graphrag/query/cli.py new file mode 100644 index 0000000000000000000000000000000000000000..aef7c2965bd4d1c4f5b3e4f58ab482b05ef6ad03 --- /dev/null +++ b/graphrag/graphrag/query/cli.py @@ -0,0 +1,212 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Command line interface for the query module.""" + +import os +from pathlib import Path +from typing import cast + +import pandas as pd + +from graphrag.config import ( + GraphRagConfig, + create_graphrag_config, +) +from graphrag.index.progress import PrintProgressReporter +from graphrag.query.input.loaders.dfs import ( + store_entity_semantic_embeddings, +) +from graphrag.vector_stores import VectorStoreFactory, VectorStoreType + +from .factories import get_global_search_engine, get_local_search_engine +from .indexer_adapters import ( + read_indexer_covariates, + read_indexer_entities, + read_indexer_relationships, + read_indexer_reports, + read_indexer_text_units, +) + +reporter = PrintProgressReporter("") + + +def __get_embedding_description_store( + vector_store_type: str = VectorStoreType.LanceDB, config_args: dict | None = None +): + """Get the embedding description store.""" + if not config_args: + config_args = {} + + config_args.update({ + "collection_name": config_args.get( + "query_collection_name", + config_args.get("collection_name", "description_embedding"), + ), + }) + + description_embedding_store = VectorStoreFactory.get_vector_store( + vector_store_type=vector_store_type, kwargs=config_args + ) + + description_embedding_store.connect(**config_args) + return description_embedding_store + + +def run_global_search( + data_dir: str | None, + root_dir: str | None, + community_level: int, + response_type: str, + query: str, +): + """Run a global search with the given query.""" + data_dir, root_dir, config = _configure_paths_and_settings(data_dir, root_dir) + data_path = Path(data_dir) + + final_nodes: pd.DataFrame = pd.read_parquet( + data_path / "create_final_nodes.parquet" + ) + final_entities: pd.DataFrame = pd.read_parquet( + data_path / "create_final_entities.parquet" + ) + final_community_reports: pd.DataFrame = pd.read_parquet( + data_path / "create_final_community_reports.parquet" + ) + + reports = read_indexer_reports( + final_community_reports, final_nodes, community_level + ) + entities = read_indexer_entities(final_nodes, final_entities, community_level) + search_engine = get_global_search_engine( + config, + reports=reports, + entities=entities, + response_type=response_type, + ) + + result = search_engine.search(query=query) + + reporter.success(f"Global Search Response: {result.response}") + return result.response + + +def run_local_search( + data_dir: str | None, + root_dir: str | None, + community_level: int, + response_type: str, + query: str, +): + """Run a local search with the given query.""" + data_dir, root_dir, config = _configure_paths_and_settings(data_dir, root_dir) + data_path = Path(data_dir) + + final_nodes = pd.read_parquet(data_path / "create_final_nodes.parquet") + final_community_reports = pd.read_parquet( + data_path / "create_final_community_reports.parquet" + ) + final_text_units = pd.read_parquet(data_path / "create_final_text_units.parquet") + final_relationships = pd.read_parquet( + data_path / "create_final_relationships.parquet" + ) + final_nodes = pd.read_parquet(data_path / "create_final_nodes.parquet") + final_entities = pd.read_parquet(data_path / "create_final_entities.parquet") + final_covariates_path = data_path / "create_final_covariates.parquet" + final_covariates = ( + pd.read_parquet(final_covariates_path) + if final_covariates_path.exists() + else None + ) + + vector_store_args = ( + config.embeddings.vector_store if config.embeddings.vector_store else {} + ) + vector_store_type = vector_store_args.get("type", VectorStoreType.LanceDB) + + description_embedding_store = __get_embedding_description_store( + vector_store_type=vector_store_type, + config_args=vector_store_args, + ) + entities = read_indexer_entities(final_nodes, final_entities, community_level) + store_entity_semantic_embeddings( + entities=entities, vectorstore=description_embedding_store + ) + covariates = ( + read_indexer_covariates(final_covariates) + if final_covariates is not None + else [] + ) + + search_engine = get_local_search_engine( + config, + reports=read_indexer_reports( + final_community_reports, final_nodes, community_level + ), + text_units=read_indexer_text_units(final_text_units), + entities=entities, + relationships=read_indexer_relationships(final_relationships), + covariates={"claims": covariates}, + description_embedding_store=description_embedding_store, + response_type=response_type, + ) + + result = search_engine.search(query=query) + reporter.success(f"Local Search Response: {result.response}") + return result.response + + +def _configure_paths_and_settings( + data_dir: str | None, root_dir: str | None +) -> tuple[str, str | None, GraphRagConfig]: + if data_dir is None and root_dir is None: + msg = "Either data_dir or root_dir must be provided." + raise ValueError(msg) + if data_dir is None: + data_dir = _infer_data_dir(cast(str, root_dir)) + config = _create_graphrag_config(root_dir, data_dir) + return data_dir, root_dir, config + + +def _infer_data_dir(root: str) -> str: + output = Path(root) / "output" + # use the latest data-run folder + if output.exists(): + folders = sorted(output.iterdir(), key=os.path.getmtime, reverse=True) + if len(folders) > 0: + folder = folders[0] + return str((folder / "artifacts").absolute()) + msg = f"Could not infer data directory from root={root}" + raise ValueError(msg) + + +def _create_graphrag_config(root: str | None, data_dir: str | None) -> GraphRagConfig: + """Create a GraphRag configuration.""" + return _read_config_parameters(cast(str, root or data_dir)) + + +def _read_config_parameters(root: str): + _root = Path(root) + settings_yaml = _root / "settings.yaml" + if not settings_yaml.exists(): + settings_yaml = _root / "settings.yml" + settings_json = _root / "settings.json" + + if settings_yaml.exists(): + reporter.info(f"Reading settings from {settings_yaml}") + with settings_yaml.open("r") as file: + import yaml + + data = yaml.safe_load(file) + return create_graphrag_config(data, root) + + if settings_json.exists(): + reporter.info(f"Reading settings from {settings_json}") + with settings_json.open("r") as file: + import json + + data = json.loads(file.read()) + return create_graphrag_config(data, root) + + reporter.info("Reading settings from environment variables") + return create_graphrag_config(root_dir=root) diff --git a/graphrag/graphrag/query/context_builder/__init__.py b/graphrag/graphrag/query/context_builder/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7e27364e1ec98983be1768ed56681030d54b00b9 --- /dev/null +++ b/graphrag/graphrag/query/context_builder/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Functions to build context for system prompt to generate responses for a user query.""" diff --git a/graphrag/graphrag/query/context_builder/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/query/context_builder/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7ff9be5a7c9e8689a44adae1a75c580b04b5d376 Binary files /dev/null and b/graphrag/graphrag/query/context_builder/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/context_builder/__pycache__/builders.cpython-311.pyc b/graphrag/graphrag/query/context_builder/__pycache__/builders.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..035cc5c23924286c09f47c00f21d0c01a2f2151a Binary files /dev/null and b/graphrag/graphrag/query/context_builder/__pycache__/builders.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/context_builder/__pycache__/community_context.cpython-311.pyc b/graphrag/graphrag/query/context_builder/__pycache__/community_context.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6243284905c7bb46354a3cc466d9ae3627d86d0c Binary files /dev/null and b/graphrag/graphrag/query/context_builder/__pycache__/community_context.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/context_builder/__pycache__/conversation_history.cpython-311.pyc b/graphrag/graphrag/query/context_builder/__pycache__/conversation_history.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c660cafe86e3cb7337c102a90e317bed4970640 Binary files /dev/null and b/graphrag/graphrag/query/context_builder/__pycache__/conversation_history.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/context_builder/__pycache__/entity_extraction.cpython-311.pyc b/graphrag/graphrag/query/context_builder/__pycache__/entity_extraction.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..222ceee10b0ad7a8201958b1cb4048b7a04e636c Binary files /dev/null and b/graphrag/graphrag/query/context_builder/__pycache__/entity_extraction.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/context_builder/__pycache__/local_context.cpython-311.pyc b/graphrag/graphrag/query/context_builder/__pycache__/local_context.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf5c899d9c5fdbf7373f78e1639c0dd7301e810b Binary files /dev/null and b/graphrag/graphrag/query/context_builder/__pycache__/local_context.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/context_builder/__pycache__/source_context.cpython-311.pyc b/graphrag/graphrag/query/context_builder/__pycache__/source_context.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..702d35c0681df0ec55874f23e51df968d455ec8f Binary files /dev/null and b/graphrag/graphrag/query/context_builder/__pycache__/source_context.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/context_builder/builders.py b/graphrag/graphrag/query/context_builder/builders.py new file mode 100644 index 0000000000000000000000000000000000000000..7a4ba277ae809e09ce15c475754ffda6cd388edd --- /dev/null +++ b/graphrag/graphrag/query/context_builder/builders.py @@ -0,0 +1,35 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Base classes for global and local context builders.""" + +from abc import ABC, abstractmethod + +import pandas as pd + +from graphrag.query.context_builder.conversation_history import ( + ConversationHistory, +) + + +class GlobalContextBuilder(ABC): + """Base class for global-search context builders.""" + + @abstractmethod + def build_context( + self, conversation_history: ConversationHistory | None = None, **kwargs + ) -> tuple[str | list[str], dict[str, pd.DataFrame]]: + """Build the context for the global search mode.""" + + +class LocalContextBuilder(ABC): + """Base class for local-search context builders.""" + + @abstractmethod + def build_context( + self, + query: str, + conversation_history: ConversationHistory | None = None, + **kwargs, + ) -> tuple[str | list[str], dict[str, pd.DataFrame]]: + """Build the context for the local search mode.""" diff --git a/graphrag/graphrag/query/context_builder/community_context.py b/graphrag/graphrag/query/context_builder/community_context.py new file mode 100644 index 0000000000000000000000000000000000000000..dba7f729d27d8070b32daab6a9b6ce22cd88573c --- /dev/null +++ b/graphrag/graphrag/query/context_builder/community_context.py @@ -0,0 +1,241 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Community Context.""" + +import logging +import random +from typing import Any, cast + +import pandas as pd +import tiktoken + +from graphrag.model import CommunityReport, Entity +from graphrag.query.llm.text_utils import num_tokens + +log = logging.getLogger(__name__) + + +def build_community_context( + community_reports: list[CommunityReport], + entities: list[Entity] | None = None, + token_encoder: tiktoken.Encoding | None = None, + use_community_summary: bool = True, + column_delimiter: str = "|", + shuffle_data: bool = True, + include_community_rank: bool = False, + min_community_rank: int = 0, + community_rank_name: str = "rank", + include_community_weight: bool = True, + community_weight_name: str = "occurrence weight", + normalize_community_weight: bool = True, + max_tokens: int = 8000, + single_batch: bool = True, + context_name: str = "Reports", + random_state: int = 86, +) -> tuple[str | list[str], dict[str, pd.DataFrame]]: + """ + Prepare community report data table as context data for system prompt. + + If entities are provided, the community weight is calculated as the count of text units associated with entities within the community. + + The calculated weight is added as an attribute to the community reports and added to the context data table. + """ + if ( + entities + and len(community_reports) > 0 + and include_community_weight + and ( + community_reports[0].attributes is None + or community_weight_name not in community_reports[0].attributes + ) + ): + log.info("Computing community weights...") + community_reports = _compute_community_weights( + community_reports=community_reports, + entities=entities, + weight_attribute=community_weight_name, + normalize=normalize_community_weight, + ) + + selected_reports = [ + report + for report in community_reports + if report.rank and report.rank >= min_community_rank + ] + if selected_reports is None or len(selected_reports) == 0: + return ([], {}) + + if shuffle_data: + random.seed(random_state) + random.shuffle(selected_reports) + + # add context header + current_context_text = f"-----{context_name}-----" + "\n" + + # add header + header = ["id", "title"] + attribute_cols = ( + list(selected_reports[0].attributes.keys()) + if selected_reports[0].attributes + else [] + ) + attribute_cols = [col for col in attribute_cols if col not in header] + if not include_community_weight: + attribute_cols = [col for col in attribute_cols if col != community_weight_name] + header.extend(attribute_cols) + header.append("summary" if use_community_summary else "content") + if include_community_rank: + header.append(community_rank_name) + + current_context_text += column_delimiter.join(header) + "\n" + current_tokens = num_tokens(current_context_text, token_encoder) + current_context_records = [header] + all_context_text = [] + all_context_records = [] + + for report in selected_reports: + new_context = [ + report.short_id, + report.title, + *[ + str(report.attributes.get(field, "")) if report.attributes else "" + for field in attribute_cols + ], + ] + new_context.append( + report.summary if use_community_summary else report.full_content + ) + if include_community_rank: + new_context.append(str(report.rank)) + new_context_text = column_delimiter.join(new_context) + "\n" + + new_tokens = num_tokens(new_context_text, token_encoder) + if current_tokens + new_tokens > max_tokens: + # convert the current context records to pandas dataframe and sort by weight and rank if exist + if len(current_context_records) > 1: + record_df = _convert_report_context_to_df( + context_records=current_context_records[1:], + header=current_context_records[0], + weight_column=community_weight_name + if entities and include_community_weight + else None, + rank_column=community_rank_name if include_community_rank else None, + ) + + else: + record_df = pd.DataFrame() + current_context_text = record_df.to_csv(index=False, sep=column_delimiter) + + if single_batch: + return current_context_text, {context_name.lower(): record_df} + + all_context_text.append(current_context_text) + all_context_records.append(record_df) + + # start a new batch + current_context_text = ( + f"-----{context_name}-----" + + "\n" + + column_delimiter.join(header) + + "\n" + ) + current_tokens = num_tokens(current_context_text, token_encoder) + current_context_records = [header] + else: + current_context_text += new_context_text + current_tokens += new_tokens + current_context_records.append(new_context) + + # add the last batch if it has not been added + if current_context_text not in all_context_text: + if len(current_context_records) > 1: + record_df = _convert_report_context_to_df( + context_records=current_context_records[1:], + header=current_context_records[0], + weight_column=community_weight_name + if entities and include_community_weight + else None, + rank_column=community_rank_name if include_community_rank else None, + ) + else: + record_df = pd.DataFrame() + all_context_records.append(record_df) + current_context_text = record_df.to_csv(index=False, sep=column_delimiter) + all_context_text.append(current_context_text) + + return all_context_text, { + context_name.lower(): pd.concat(all_context_records, ignore_index=True) + } + + +def _compute_community_weights( + community_reports: list[CommunityReport], + entities: list[Entity], + weight_attribute: str = "occurrence", + normalize: bool = True, +) -> list[CommunityReport]: + """Calculate a community's weight as count of text units associated with entities within the community.""" + community_text_units = {} + for entity in entities: + if entity.community_ids: + for community_id in entity.community_ids: + if community_id not in community_text_units: + community_text_units[community_id] = [] + community_text_units[community_id].extend(entity.text_unit_ids) + for report in community_reports: + if not report.attributes: + report.attributes = {} + report.attributes[weight_attribute] = len( + set(community_text_units.get(report.community_id, [])) + ) + if normalize: + # normalize by max weight + all_weights = [ + report.attributes[weight_attribute] + for report in community_reports + if report.attributes + ] + max_weight = max(all_weights) + for report in community_reports: + if report.attributes: + report.attributes[weight_attribute] = ( + report.attributes[weight_attribute] / max_weight + ) + return community_reports + + +def _rank_report_context( + report_df: pd.DataFrame, + weight_column: str | None = "occurrence weight", + rank_column: str | None = "rank", +) -> pd.DataFrame: + """Sort report context by community weight and rank if exist.""" + rank_attributes = [] + if weight_column: + rank_attributes.append(weight_column) + report_df[weight_column] = report_df[weight_column].astype(float) + if rank_column: + rank_attributes.append(rank_column) + report_df[rank_column] = report_df[rank_column].astype(float) + if len(rank_attributes) > 0: + report_df.sort_values(by=rank_attributes, ascending=False, inplace=True) + return report_df + + +def _convert_report_context_to_df( + context_records: list[list[str]], + header: list[str], + weight_column: str | None = None, + rank_column: str | None = None, +) -> pd.DataFrame: + """Convert report context records to pandas dataframe and sort by weight and rank if exist.""" + record_df = pd.DataFrame( + context_records, + columns=cast(Any, header), + ) + return _rank_report_context( + report_df=record_df, + weight_column=weight_column, + rank_column=rank_column, + ) diff --git a/graphrag/graphrag/query/context_builder/conversation_history.py b/graphrag/graphrag/query/context_builder/conversation_history.py new file mode 100644 index 0000000000000000000000000000000000000000..33f516dbd4f9680cc6c199538773435afbd53287 --- /dev/null +++ b/graphrag/graphrag/query/context_builder/conversation_history.py @@ -0,0 +1,212 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Classes for storing and managing conversation history.""" + +from dataclasses import dataclass +from enum import Enum + +import pandas as pd +import tiktoken + +from graphrag.query.llm.text_utils import num_tokens + +""" +Enum for conversation roles +""" + + +class ConversationRole(str, Enum): + """Enum for conversation roles.""" + + SYSTEM = "system" + USER = "user" + ASSISTANT = "assistant" + + @staticmethod + def from_string(value: str) -> "ConversationRole": + """Convert string to ConversationRole.""" + if value == "system": + return ConversationRole.SYSTEM + if value == "user": + return ConversationRole.USER + if value == "assistant": + return ConversationRole.ASSISTANT + + msg = f"Invalid Role: {value}" + raise ValueError(msg) + + def __str__(self) -> str: + """Return string representation of the enum value.""" + return self.value + + +""" +Data class for storing a single conversation turn +""" + + +@dataclass +class ConversationTurn: + """Data class for storing a single conversation turn.""" + + role: ConversationRole + content: str + + def __str__(self) -> str: + """Return string representation of the conversation turn.""" + return f"{self.role}: {self.content}" + + +@dataclass +class QATurn: + """ + Data class for storing a QA turn. + + A QA turn contains a user question and one more multiple assistant answers. + """ + + user_query: ConversationTurn + assistant_answers: list[ConversationTurn] | None = None + + def get_answer_text(self) -> str | None: + """Get the text of the assistant answers.""" + return ( + "\n".join([answer.content for answer in self.assistant_answers]) + if self.assistant_answers + else None + ) + + def __str__(self) -> str: + """Return string representation of the QA turn.""" + answers = self.get_answer_text() + return ( + f"Question: {self.user_query.content}\nAnswer: {answers}" + if answers + else f"Question: {self.user_query.content}" + ) + + +class ConversationHistory: + """Class for storing a conversation history.""" + + turns: list[ConversationTurn] + + def __init__(self): + self.turns = [] + + @classmethod + def from_list( + cls, conversation_turns: list[dict[str, str]] + ) -> "ConversationHistory": + """ + Create a conversation history from a list of conversation turns. + + Each turn is a dictionary in the form of {"role": "", "content": ""} + """ + history = cls() + for turn in conversation_turns: + history.turns.append( + ConversationTurn( + role=ConversationRole.from_string( + turn.get("role", ConversationRole.USER) + ), + content=turn.get("content", ""), + ) + ) + return history + + def add_turn(self, role: ConversationRole, content: str): + """Add a new turn to the conversation history.""" + self.turns.append(ConversationTurn(role=role, content=content)) + + def to_qa_turns(self) -> list[QATurn]: + """Convert conversation history to a list of QA turns.""" + qa_turns = list[QATurn]() + current_qa_turn = None + for turn in self.turns: + if turn.role == ConversationRole.USER: + if current_qa_turn: + qa_turns.append(current_qa_turn) + current_qa_turn = QATurn(user_query=turn, assistant_answers=[]) + else: + if current_qa_turn: + current_qa_turn.assistant_answers.append(turn) # type: ignore + if current_qa_turn: + qa_turns.append(current_qa_turn) + return qa_turns + + def get_user_turns(self, max_user_turns: int | None = 1) -> list[str]: + """Get the last user turns in the conversation history.""" + user_turns = [] + for turn in self.turns[::-1]: + if turn.role == ConversationRole.USER: + user_turns.append(turn.content) + if max_user_turns and len(user_turns) >= max_user_turns: + break + return user_turns + + def build_context( + self, + token_encoder: tiktoken.Encoding | None = None, + include_user_turns_only: bool = True, + max_qa_turns: int | None = 5, + max_tokens: int = 8000, + recency_bias: bool = True, + column_delimiter: str = "|", + context_name: str = "Conversation History", + ) -> tuple[str, dict[str, pd.DataFrame]]: + """ + Prepare conversation history as context data for system prompt. + + Parameters + ---------- + user_queries_only: If True, only user queries (not assistant responses) will be included in the context, default is True. + max_qa_turns: Maximum number of QA turns to include in the context, default is 1. + recency_bias: If True, reverse the order of the conversation history to ensure last QA got prioritized. + column_delimiter: Delimiter to use for separating columns in the context data, default is "|". + context_name: Name of the context, default is "Conversation History". + + """ + qa_turns = self.to_qa_turns() + if include_user_turns_only: + qa_turns = [ + QATurn(user_query=qa_turn.user_query, assistant_answers=None) + for qa_turn in qa_turns + ] + if recency_bias: + qa_turns = qa_turns[::-1] + if max_qa_turns and len(qa_turns) > max_qa_turns: + qa_turns = qa_turns[:max_qa_turns] + + # build context for qa turns + # add context header + if len(qa_turns) == 0 or not qa_turns: + return ("", {context_name: pd.DataFrame()}) + + # add table header + header = f"-----{context_name}-----" + "\n" + + turn_list = [] + current_context_df = pd.DataFrame() + for turn in qa_turns: + turn_list.append({ + "turn": ConversationRole.USER.__str__(), + "content": turn.user_query.content, + }) + if turn.assistant_answers: + turn_list.append({ + "turn": ConversationRole.ASSISTANT.__str__(), + "content": turn.get_answer_text(), + }) + + context_df = pd.DataFrame(turn_list) + context_text = header + context_df.to_csv(sep=column_delimiter, index=False) + if num_tokens(context_text, token_encoder) > max_tokens: + break + + current_context_df = context_df + context_text = header + current_context_df.to_csv( + sep=column_delimiter, index=False + ) + return (context_text, {context_name.lower(): current_context_df}) diff --git a/graphrag/graphrag/query/context_builder/entity_extraction.py b/graphrag/graphrag/query/context_builder/entity_extraction.py new file mode 100644 index 0000000000000000000000000000000000000000..82a0699cd84f4d44c0b04f9a988647a755f7e465 --- /dev/null +++ b/graphrag/graphrag/query/context_builder/entity_extraction.py @@ -0,0 +1,159 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Orchestration Context Builders.""" + +from enum import Enum + +from graphrag.model import Entity, Relationship +from graphrag.query.input.retrieval.entities import ( + get_entity_by_key, + get_entity_by_name, +) +from graphrag.query.llm.base import BaseTextEmbedding +from graphrag.vector_stores import BaseVectorStore + + +class EntityVectorStoreKey(str, Enum): + """Keys used as ids in the entity embedding vectorstores.""" + + ID = "id" + TITLE = "title" + + @staticmethod + def from_string(value: str) -> "EntityVectorStoreKey": + """Convert string to EntityVectorStoreKey.""" + if value == "id": + return EntityVectorStoreKey.ID + if value == "title": + return EntityVectorStoreKey.TITLE + + msg = f"Invalid EntityVectorStoreKey: {value}" + raise ValueError(msg) + + +def map_query_to_entities( + query: str, + text_embedding_vectorstore: BaseVectorStore, + text_embedder: BaseTextEmbedding, + all_entities: list[Entity], + embedding_vectorstore_key: str = EntityVectorStoreKey.ID, + include_entity_names: list[str] | None = None, + exclude_entity_names: list[str] | None = None, + k: int = 10, + oversample_scaler: int = 2, +) -> list[Entity]: + """Extract entities that match a given query using semantic similarity of text embeddings of query and entity descriptions.""" + if include_entity_names is None: + include_entity_names = [] + if exclude_entity_names is None: + exclude_entity_names = [] + matched_entities = [] + if query != "": + # get entities with highest semantic similarity to query + # oversample to account for excluded entities + search_results = text_embedding_vectorstore.similarity_search_by_text( + text=query, + text_embedder=lambda t: text_embedder.embed(t), + k=k * oversample_scaler, + ) + for result in search_results: + matched = get_entity_by_key( + entities=all_entities, + key=embedding_vectorstore_key, + value=result.document.id, + ) + if matched: + matched_entities.append(matched) + else: + all_entities.sort(key=lambda x: x.rank if x.rank else 0, reverse=True) + matched_entities = all_entities[:k] + + # filter out excluded entities + if exclude_entity_names: + matched_entities = [ + entity + for entity in matched_entities + if entity.title not in exclude_entity_names + ] + + # add entities in the include_entity list + included_entities = [] + for entity_name in include_entity_names: + included_entities.extend(get_entity_by_name(all_entities, entity_name)) + return included_entities + matched_entities + + +def find_nearest_neighbors_by_graph_embeddings( + entity_id: str, + graph_embedding_vectorstore: BaseVectorStore, + all_entities: list[Entity], + exclude_entity_names: list[str] | None = None, + embedding_vectorstore_key: str = EntityVectorStoreKey.ID, + k: int = 10, + oversample_scaler: int = 2, +) -> list[Entity]: + """Retrieve related entities by graph embeddings.""" + if exclude_entity_names is None: + exclude_entity_names = [] + # find nearest neighbors of this entity using graph embedding + query_entity = get_entity_by_key( + entities=all_entities, key=embedding_vectorstore_key, value=entity_id + ) + query_embedding = query_entity.graph_embedding if query_entity else None + + # oversample to account for excluded entities + if query_embedding: + matched_entities = [] + search_results = graph_embedding_vectorstore.similarity_search_by_vector( + query_embedding=query_embedding, k=k * oversample_scaler + ) + for result in search_results: + matched = get_entity_by_key( + entities=all_entities, + key=embedding_vectorstore_key, + value=result.document.id, + ) + if matched: + matched_entities.append(matched) + + # filter out excluded entities + if exclude_entity_names: + matched_entities = [ + entity + for entity in matched_entities + if entity.title not in exclude_entity_names + ] + matched_entities.sort(key=lambda x: x.rank, reverse=True) + return matched_entities[:k] + + return [] + + +def find_nearest_neighbors_by_entity_rank( + entity_name: str, + all_entities: list[Entity], + all_relationships: list[Relationship], + exclude_entity_names: list[str] | None = None, + k: int | None = 10, +) -> list[Entity]: + """Retrieve entities that have direct connections with the target entity, sorted by entity rank.""" + if exclude_entity_names is None: + exclude_entity_names = [] + entity_relationships = [ + rel + for rel in all_relationships + if rel.source == entity_name or rel.target == entity_name + ] + source_entity_names = {rel.source for rel in entity_relationships} + target_entity_names = {rel.target for rel in entity_relationships} + related_entity_names = (source_entity_names.union(target_entity_names)).difference( + set(exclude_entity_names) + ) + top_relations = [ + entity for entity in all_entities if entity.title in related_entity_names + ] + top_relations.sort(key=lambda x: x.rank if x.rank else 0, reverse=True) + if k: + return top_relations[:k] + return top_relations diff --git a/graphrag/graphrag/query/context_builder/local_context.py b/graphrag/graphrag/query/context_builder/local_context.py new file mode 100644 index 0000000000000000000000000000000000000000..c2f7527e33559b3a2c74c5b38051ee00ca3bd297 --- /dev/null +++ b/graphrag/graphrag/query/context_builder/local_context.py @@ -0,0 +1,346 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Local Context Builder.""" + +from collections import defaultdict +from typing import Any, cast + +import pandas as pd +import tiktoken + +from graphrag.model import Covariate, Entity, Relationship +from graphrag.query.input.retrieval.covariates import ( + get_candidate_covariates, + to_covariate_dataframe, +) +from graphrag.query.input.retrieval.entities import to_entity_dataframe +from graphrag.query.input.retrieval.relationships import ( + get_candidate_relationships, + get_entities_from_relationships, + get_in_network_relationships, + get_out_network_relationships, + to_relationship_dataframe, +) +from graphrag.query.llm.text_utils import num_tokens + + +def build_entity_context( + selected_entities: list[Entity], + token_encoder: tiktoken.Encoding | None = None, + max_tokens: int = 8000, + include_entity_rank: bool = True, + rank_description: str = "number of relationships", + column_delimiter: str = "|", + context_name="Entities", +) -> tuple[str, pd.DataFrame]: + """Prepare entity data table as context data for system prompt.""" + if len(selected_entities) == 0: + return "", pd.DataFrame() + + # add headers + current_context_text = f"-----{context_name}-----" + "\n" + header = ["id", "entity", "description"] + if include_entity_rank: + header.append(rank_description) + attribute_cols = ( + list(selected_entities[0].attributes.keys()) + if selected_entities[0].attributes + else [] + ) + header.extend(attribute_cols) + current_context_text += column_delimiter.join(header) + "\n" + current_tokens = num_tokens(current_context_text, token_encoder) + + all_context_records = [header] + for entity in selected_entities: + new_context = [ + entity.short_id if entity.short_id else "", + entity.title, + entity.description if entity.description else "", + ] + if include_entity_rank: + new_context.append(str(entity.rank)) + for field in attribute_cols: + field_value = ( + str(entity.attributes.get(field)) + if entity.attributes and entity.attributes.get(field) + else "" + ) + new_context.append(field_value) + new_context_text = column_delimiter.join(new_context) + "\n" + new_tokens = num_tokens(new_context_text, token_encoder) + if current_tokens + new_tokens > max_tokens: + break + current_context_text += new_context_text + all_context_records.append(new_context) + current_tokens += new_tokens + + if len(all_context_records) > 1: + record_df = pd.DataFrame( + all_context_records[1:], columns=cast(Any, all_context_records[0]) + ) + else: + record_df = pd.DataFrame() + + return current_context_text, record_df + + +def build_covariates_context( + selected_entities: list[Entity], + covariates: list[Covariate], + token_encoder: tiktoken.Encoding | None = None, + max_tokens: int = 8000, + column_delimiter: str = "|", + context_name: str = "Covariates", +) -> tuple[str, pd.DataFrame]: + """Prepare covariate data tables as context data for system prompt.""" + # create an empty list of covariates + if len(selected_entities) == 0 or len(covariates) == 0: + return "", pd.DataFrame() + + selected_covariates = list[Covariate]() + record_df = pd.DataFrame() + + # add context header + current_context_text = f"-----{context_name}-----" + "\n" + + # add header + header = ["id", "entity"] + attributes = covariates[0].attributes or {} if len(covariates) > 0 else {} + attribute_cols = list(attributes.keys()) if len(covariates) > 0 else [] + header.extend(attribute_cols) + current_context_text += column_delimiter.join(header) + "\n" + current_tokens = num_tokens(current_context_text, token_encoder) + + all_context_records = [header] + for entity in selected_entities: + selected_covariates.extend([ + cov for cov in covariates if cov.subject_id == entity.title + ]) + + for covariate in selected_covariates: + new_context = [ + covariate.short_id if covariate.short_id else "", + covariate.subject_id, + ] + for field in attribute_cols: + field_value = ( + str(covariate.attributes.get(field)) + if covariate.attributes and covariate.attributes.get(field) + else "" + ) + new_context.append(field_value) + + new_context_text = column_delimiter.join(new_context) + "\n" + new_tokens = num_tokens(new_context_text, token_encoder) + if current_tokens + new_tokens > max_tokens: + break + current_context_text += new_context_text + all_context_records.append(new_context) + current_tokens += new_tokens + + if len(all_context_records) > 1: + record_df = pd.DataFrame( + all_context_records[1:], columns=cast(Any, all_context_records[0]) + ) + else: + record_df = pd.DataFrame() + + return current_context_text, record_df + + +def build_relationship_context( + selected_entities: list[Entity], + relationships: list[Relationship], + token_encoder: tiktoken.Encoding | None = None, + include_relationship_weight: bool = False, + max_tokens: int = 8000, + top_k_relationships: int = 10, + relationship_ranking_attribute: str = "rank", + column_delimiter: str = "|", + context_name: str = "Relationships", +) -> tuple[str, pd.DataFrame]: + """Prepare relationship data tables as context data for system prompt.""" + selected_relationships = _filter_relationships( + selected_entities=selected_entities, + relationships=relationships, + top_k_relationships=top_k_relationships, + relationship_ranking_attribute=relationship_ranking_attribute, + ) + + if len(selected_entities) == 0 or len(selected_relationships) == 0: + return "", pd.DataFrame() + + # add headers + current_context_text = f"-----{context_name}-----" + "\n" + header = ["id", "source", "target", "description"] + if include_relationship_weight: + header.append("weight") + attribute_cols = ( + list(selected_relationships[0].attributes.keys()) + if selected_relationships[0].attributes + else [] + ) + attribute_cols = [col for col in attribute_cols if col not in header] + header.extend(attribute_cols) + + current_context_text += column_delimiter.join(header) + "\n" + current_tokens = num_tokens(current_context_text, token_encoder) + + all_context_records = [header] + for rel in selected_relationships: + new_context = [ + rel.short_id if rel.short_id else "", + rel.source, + rel.target, + rel.description if rel.description else "", + ] + if include_relationship_weight: + new_context.append(str(rel.weight if rel.weight else "")) + for field in attribute_cols: + field_value = ( + str(rel.attributes.get(field)) + if rel.attributes and rel.attributes.get(field) + else "" + ) + new_context.append(field_value) + new_context_text = column_delimiter.join(new_context) + "\n" + new_tokens = num_tokens(new_context_text, token_encoder) + if current_tokens + new_tokens > max_tokens: + break + current_context_text += new_context_text + all_context_records.append(new_context) + current_tokens += new_tokens + + if len(all_context_records) > 1: + record_df = pd.DataFrame( + all_context_records[1:], columns=cast(Any, all_context_records[0]) + ) + else: + record_df = pd.DataFrame() + + return current_context_text, record_df + + +def _filter_relationships( + selected_entities: list[Entity], + relationships: list[Relationship], + top_k_relationships: int = 10, + relationship_ranking_attribute: str = "rank", +) -> list[Relationship]: + """Filter and sort relationships based on a set of selected entities and a ranking attribute.""" + # First priority: in-network relationships (i.e. relationships between selected entities) + in_network_relationships = get_in_network_relationships( + selected_entities=selected_entities, + relationships=relationships, + ranking_attribute=relationship_ranking_attribute, + ) + + # Second priority - out-of-network relationships + # (i.e. relationships between selected entities and other entities that are not within the selected entities) + out_network_relationships = get_out_network_relationships( + selected_entities=selected_entities, + relationships=relationships, + ranking_attribute=relationship_ranking_attribute, + ) + if len(out_network_relationships) <= 1: + return in_network_relationships + out_network_relationships + + # within out-of-network relationships, prioritize mutual relationships + # (i.e. relationships with out-network entities that are shared with multiple selected entities) + selected_entity_names = [entity.title for entity in selected_entities] + out_network_source_names = [ + relationship.source + for relationship in out_network_relationships + if relationship.source not in selected_entity_names + ] + out_network_target_names = [ + relationship.target + for relationship in out_network_relationships + if relationship.target not in selected_entity_names + ] + out_network_entity_names = list( + set(out_network_source_names + out_network_target_names) + ) + out_network_entity_links = defaultdict(int) + for entity_name in out_network_entity_names: + targets = [ + relationship.target + for relationship in out_network_relationships + if relationship.source == entity_name + ] + sources = [ + relationship.source + for relationship in out_network_relationships + if relationship.target == entity_name + ] + out_network_entity_links[entity_name] = len(set(targets + sources)) + + # sort out-network relationships by number of links and rank_attributes + for rel in out_network_relationships: + if rel.attributes is None: + rel.attributes = {} + rel.attributes["links"] = ( + out_network_entity_links[rel.source] + if rel.source in out_network_entity_links + else out_network_entity_links[rel.target] + ) + + # sort by attributes[links] first, then by ranking_attribute + if relationship_ranking_attribute == "weight": + out_network_relationships.sort( + key=lambda x: (x.attributes["links"], x.weight), # type: ignore + reverse=True, # type: ignore + ) + else: + out_network_relationships.sort( + key=lambda x: ( + x.attributes["links"], # type: ignore + x.attributes[relationship_ranking_attribute], # type: ignore + ), # type: ignore + reverse=True, + ) + + relationship_budget = top_k_relationships * len(selected_entities) + return in_network_relationships + out_network_relationships[:relationship_budget] + + +def get_candidate_context( + selected_entities: list[Entity], + entities: list[Entity], + relationships: list[Relationship], + covariates: dict[str, list[Covariate]], + include_entity_rank: bool = True, + entity_rank_description: str = "number of relationships", + include_relationship_weight: bool = False, +) -> dict[str, pd.DataFrame]: + """Prepare entity, relationship, and covariate data tables as context data for system prompt.""" + candidate_context = {} + candidate_relationships = get_candidate_relationships( + selected_entities=selected_entities, + relationships=relationships, + ) + candidate_context["relationships"] = to_relationship_dataframe( + relationships=candidate_relationships, + include_relationship_weight=include_relationship_weight, + ) + candidate_entities = get_entities_from_relationships( + relationships=candidate_relationships, entities=entities + ) + candidate_context["entities"] = to_entity_dataframe( + entities=candidate_entities, + include_entity_rank=include_entity_rank, + rank_description=entity_rank_description, + ) + + for covariate in covariates: + candidate_covariates = get_candidate_covariates( + selected_entities=selected_entities, + covariates=covariates[covariate], + ) + candidate_context[covariate.lower()] = to_covariate_dataframe( + candidate_covariates + ) + + return candidate_context diff --git a/graphrag/graphrag/query/context_builder/source_context.py b/graphrag/graphrag/query/context_builder/source_context.py new file mode 100644 index 0000000000000000000000000000000000000000..99b7791ca65bb696c5486fba2f9882d3e9a60379 --- /dev/null +++ b/graphrag/graphrag/query/context_builder/source_context.py @@ -0,0 +1,110 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Context Build utility methods.""" + +import random +from typing import Any, cast + +import pandas as pd +import tiktoken + +from graphrag.model import Entity, Relationship, TextUnit +from graphrag.query.llm.text_utils import num_tokens + +""" +Contain util functions to build text unit context for the search's system prompt +""" + + +def build_text_unit_context( + text_units: list[TextUnit], + token_encoder: tiktoken.Encoding | None = None, + column_delimiter: str = "|", + shuffle_data: bool = True, + max_tokens: int = 8000, + context_name: str = "Sources", + random_state: int = 86, +) -> tuple[str, dict[str, pd.DataFrame]]: + """Prepare text-unit data table as context data for system prompt.""" + if text_units is None or len(text_units) == 0: + return ("", {}) + + if shuffle_data: + random.seed(random_state) + random.shuffle(text_units) + + # add context header + current_context_text = f"-----{context_name}-----" + "\n" + + # add header + header = ["id", "text"] + attribute_cols = ( + list(text_units[0].attributes.keys()) if text_units[0].attributes else [] + ) + attribute_cols = [col for col in attribute_cols if col not in header] + header.extend(attribute_cols) + + current_context_text += column_delimiter.join(header) + "\n" + current_tokens = num_tokens(current_context_text, token_encoder) + all_context_records = [header] + + for unit in text_units: + new_context = [ + unit.short_id, + unit.text, + *[ + str(unit.attributes.get(field, "")) if unit.attributes else "" + for field in attribute_cols + ], + ] + new_context_text = column_delimiter.join(new_context) + "\n" + new_tokens = num_tokens(new_context_text, token_encoder) + + if current_tokens + new_tokens > max_tokens: + break + + current_context_text += new_context_text + all_context_records.append(new_context) + current_tokens += new_tokens + + if len(all_context_records) > 1: + record_df = pd.DataFrame( + all_context_records[1:], columns=cast(Any, all_context_records[0]) + ) + else: + record_df = pd.DataFrame() + return current_context_text, {context_name.lower(): record_df} + + +def count_relationships( + text_unit: TextUnit, entity: Entity, relationships: dict[str, Relationship] +) -> int: + """Count the number of relationships of the selected entity that are associated with the text unit.""" + matching_relationships = list[Relationship]() + if text_unit.relationship_ids is None: + entity_relationships = [ + rel + for rel in relationships.values() + if rel.source == entity.title or rel.target == entity.title + ] + entity_relationships = [ + rel for rel in entity_relationships if rel.text_unit_ids + ] + matching_relationships = [ + rel + for rel in entity_relationships + if text_unit.id in rel.text_unit_ids # type: ignore + ] # type: ignore + else: + text_unit_relationships = [ + relationships[rel_id] + for rel_id in text_unit.relationship_ids + if rel_id in relationships + ] + matching_relationships = [ + rel + for rel in text_unit_relationships + if rel.source == entity.title or rel.target == entity.title + ] + return len(matching_relationships) diff --git a/graphrag/graphrag/query/factories.py b/graphrag/graphrag/query/factories.py new file mode 100644 index 0000000000000000000000000000000000000000..533fa153488e2cd4b564d115baa3db71448398aa --- /dev/null +++ b/graphrag/graphrag/query/factories.py @@ -0,0 +1,200 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Query Factory methods to support CLI.""" + +import tiktoken +from azure.identity import DefaultAzureCredential, get_bearer_token_provider + +from graphrag.config import ( + GraphRagConfig, + LLMType, +) +from graphrag.model import ( + CommunityReport, + Covariate, + Entity, + Relationship, + TextUnit, +) +from graphrag.query.context_builder.entity_extraction import EntityVectorStoreKey +from graphrag.query.llm.oai.chat_openai import ChatOpenAI +from graphrag.query.llm.oai.embedding import OpenAIEmbedding +from graphrag.query.llm.oai.typing import OpenaiApiType +from graphrag.query.structured_search.global_search.community_context import ( + GlobalCommunityContext, +) +from graphrag.query.structured_search.global_search.search import GlobalSearch +from graphrag.query.structured_search.local_search.mixed_context import ( + LocalSearchMixedContext, +) +from graphrag.query.structured_search.local_search.search import LocalSearch +from graphrag.vector_stores import BaseVectorStore + + +def get_llm(config: GraphRagConfig) -> ChatOpenAI: + """Get the LLM client.""" + is_azure_client = ( + config.llm.type == LLMType.AzureOpenAIChat + or config.llm.type == LLMType.AzureOpenAI + ) + debug_llm_key = config.llm.api_key or "" + llm_debug_info = { + **config.llm.model_dump(), + "api_key": f"REDACTED,len={len(debug_llm_key)}", + } + if config.llm.cognitive_services_endpoint is None: + cognitive_services_endpoint = "https://cognitiveservices.azure.com/.default" + else: + cognitive_services_endpoint = config.llm.cognitive_services_endpoint + print(f"creating llm client with {llm_debug_info}") # noqa T201 + return ChatOpenAI( + api_key=config.llm.api_key, + azure_ad_token_provider=( + get_bearer_token_provider( + DefaultAzureCredential(), cognitive_services_endpoint + ) + if is_azure_client and not config.llm.api_key + else None + ), + api_base=config.llm.api_base, + model=config.llm.model, + api_type=OpenaiApiType.AzureOpenAI if is_azure_client else OpenaiApiType.OpenAI, + deployment_name=config.llm.deployment_name, + api_version=config.llm.api_version, + max_retries=config.llm.max_retries, + ) + + +def get_text_embedder(config: GraphRagConfig) -> OpenAIEmbedding: + """Get the LLM client for embeddings.""" + is_azure_client = config.embeddings.llm.type == LLMType.AzureOpenAIEmbedding + debug_embedding_api_key = config.embeddings.llm.api_key or "" + llm_debug_info = { + **config.embeddings.llm.model_dump(), + "api_key": f"REDACTED,len={len(debug_embedding_api_key)}", + } + if config.embeddings.llm.cognitive_services_endpoint is None: + cognitive_services_endpoint = "https://cognitiveservices.azure.com/.default" + else: + cognitive_services_endpoint = config.embeddings.llm.cognitive_services_endpoint + print(f"creating embedding llm client with {llm_debug_info}") # noqa T201 + return OpenAIEmbedding( + api_key=config.embeddings.llm.api_key, + azure_ad_token_provider=( + get_bearer_token_provider( + DefaultAzureCredential(), cognitive_services_endpoint + ) + if is_azure_client and not config.embeddings.llm.api_key + else None + ), + api_base=config.embeddings.llm.api_base, + api_type=OpenaiApiType.AzureOpenAI if is_azure_client else OpenaiApiType.OpenAI, + model=config.embeddings.llm.model, + deployment_name=config.embeddings.llm.deployment_name, + api_version=config.embeddings.llm.api_version, + max_retries=config.embeddings.llm.max_retries, + ) + + +def get_local_search_engine( + config: GraphRagConfig, + reports: list[CommunityReport], + text_units: list[TextUnit], + entities: list[Entity], + relationships: list[Relationship], + covariates: dict[str, list[Covariate]], + response_type: str, + description_embedding_store: BaseVectorStore, +) -> LocalSearch: + """Create a local search engine based on data + configuration.""" + llm = get_llm(config) + text_embedder = get_text_embedder(config) + token_encoder = tiktoken.get_encoding(config.encoding_model) + + ls_config = config.local_search + + return LocalSearch( + llm=llm, + context_builder=LocalSearchMixedContext( + community_reports=reports, + text_units=text_units, + entities=entities, + relationships=relationships, + covariates=covariates, + entity_text_embeddings=description_embedding_store, + embedding_vectorstore_key=EntityVectorStoreKey.ID, # if the vectorstore uses entity title as ids, set this to EntityVectorStoreKey.TITLE + text_embedder=text_embedder, + token_encoder=token_encoder, + ), + token_encoder=token_encoder, + llm_params={ + "max_tokens": ls_config.llm_max_tokens, # change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 1000=1500) + "temperature": ls_config.temperature, + "top_p": ls_config.top_p, + "n": ls_config.n, + }, + context_builder_params={ + "text_unit_prop": ls_config.text_unit_prop, + "community_prop": ls_config.community_prop, + "conversation_history_max_turns": ls_config.conversation_history_max_turns, + "conversation_history_user_turns_only": True, + "top_k_mapped_entities": ls_config.top_k_entities, + "top_k_relationships": ls_config.top_k_relationships, + "include_entity_rank": True, + "include_relationship_weight": True, + "include_community_rank": False, + "return_candidate_context": False, + "embedding_vectorstore_key": EntityVectorStoreKey.ID, # set this to EntityVectorStoreKey.TITLE if the vectorstore uses entity title as ids + "max_tokens": ls_config.max_tokens, # change this based on the token limit you have on your model (if you are using a model with 8k limit, a good setting could be 5000) + }, + response_type=response_type, + ) + + +def get_global_search_engine( + config: GraphRagConfig, + reports: list[CommunityReport], + entities: list[Entity], + response_type: str, +): + """Create a global search engine based on data + configuration.""" + token_encoder = tiktoken.get_encoding(config.encoding_model) + gs_config = config.global_search + + return GlobalSearch( + llm=get_llm(config), + context_builder=GlobalCommunityContext( + community_reports=reports, entities=entities, token_encoder=token_encoder + ), + token_encoder=token_encoder, + max_data_tokens=gs_config.data_max_tokens, + map_llm_params={ + "max_tokens": gs_config.map_max_tokens, + "temperature": gs_config.temperature, + "top_p": gs_config.top_p, + "n": gs_config.n, + }, + reduce_llm_params={ + "max_tokens": gs_config.reduce_max_tokens, + "temperature": gs_config.temperature, + "top_p": gs_config.top_p, + "n": gs_config.n, + }, + allow_general_knowledge=False, + json_mode=False, + context_builder_params={ + "use_community_summary": False, + "shuffle_data": True, + "include_community_rank": True, + "min_community_rank": 0, + "community_rank_name": "rank", + "include_community_weight": True, + "community_weight_name": "occurrence weight", + "normalize_community_weight": True, + "max_tokens": gs_config.max_tokens, + "context_name": "Reports", + }, + concurrent_coroutines=gs_config.concurrency, + response_type=response_type, + ) diff --git a/graphrag/graphrag/query/indexer_adapters.py b/graphrag/graphrag/query/indexer_adapters.py new file mode 100644 index 0000000000000000000000000000000000000000..4ce90d9215a285be9a1439e77c3990f2fd1727d0 --- /dev/null +++ b/graphrag/graphrag/query/indexer_adapters.py @@ -0,0 +1,141 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +"""Indexing-Engine to Query Read Adapters. + +The parts of these functions that do type adaptation, renaming, collating, etc. should eventually go away. +Ideally this is just a straight read-thorugh into the object model. +""" + +from typing import cast + +import pandas as pd + +from graphrag.model import CommunityReport, Covariate, Entity, Relationship, TextUnit +from graphrag.query.input.loaders.dfs import ( + read_community_reports, + read_covariates, + read_entities, + read_relationships, + read_text_units, +) + + +def read_indexer_text_units(final_text_units: pd.DataFrame) -> list[TextUnit]: + """Read in the Text Units from the raw indexing outputs.""" + return read_text_units( + df=final_text_units, + short_id_col=None, + # expects a covariate map of type -> ids + covariates_col=None, + ) + + +def read_indexer_covariates(final_covariates: pd.DataFrame) -> list[Covariate]: + """Read in the Claims from the raw indexing outputs.""" + covariate_df = final_covariates + covariate_df["id"] = covariate_df["id"].astype(str) + return read_covariates( + df=covariate_df, + short_id_col="human_readable_id", + attributes_cols=[ + "object_id", + "status", + "start_date", + "end_date", + "description", + ], + text_unit_ids_col=None, + ) + + +def read_indexer_relationships(final_relationships: pd.DataFrame) -> list[Relationship]: + """Read in the Relationships from the raw indexing outputs.""" + return read_relationships( + df=final_relationships, + short_id_col="human_readable_id", + description_embedding_col=None, + document_ids_col=None, + attributes_cols=["rank"], + ) + + +def read_indexer_reports( + final_community_reports: pd.DataFrame, + final_nodes: pd.DataFrame, + community_level: int, +) -> list[CommunityReport]: + """Read in the Community Reports from the raw indexing outputs.""" + report_df = final_community_reports + entity_df = final_nodes + entity_df = _filter_under_community_level(entity_df, community_level) + entity_df["community"] = entity_df["community"].fillna(-1) + entity_df["community"] = entity_df["community"].astype(int) + + entity_df = entity_df.groupby(["title"]).agg({"community": "max"}).reset_index() + entity_df["community"] = entity_df["community"].astype(str) + filtered_community_df = entity_df["community"].drop_duplicates() + + report_df = _filter_under_community_level(report_df, community_level) + report_df = report_df.merge(filtered_community_df, on="community", how="inner") + + return read_community_reports( + df=report_df, + id_col="community", + short_id_col="community", + summary_embedding_col=None, + content_embedding_col=None, + ) + + +def read_indexer_entities( + final_nodes: pd.DataFrame, + final_entities: pd.DataFrame, + community_level: int, +) -> list[Entity]: + """Read in the Entities from the raw indexing outputs.""" + entity_df = final_nodes + entity_embedding_df = final_entities + + entity_df = _filter_under_community_level(entity_df, community_level) + entity_df = cast(pd.DataFrame, entity_df[["title", "degree", "community"]]).rename( + columns={"title": "name", "degree": "rank"} + ) + + entity_df["community"] = entity_df["community"].fillna(-1) + entity_df["community"] = entity_df["community"].astype(int) + entity_df["rank"] = entity_df["rank"].astype(int) + + # for duplicate entities, keep the one with the highest community level + entity_df = ( + entity_df.groupby(["name", "rank"]).agg({"community": "max"}).reset_index() + ) + entity_df["community"] = entity_df["community"].apply(lambda x: [str(x)]) + entity_df = entity_df.merge( + entity_embedding_df, on="name", how="inner" + ).drop_duplicates(subset=["name"]) + + # read entity dataframe to knowledge model objects + return read_entities( + df=entity_df, + id_col="id", + title_col="name", + type_col="type", + short_id_col="human_readable_id", + description_col="description", + community_col="community", + rank_col="rank", + name_embedding_col=None, + description_embedding_col="description_embedding", + graph_embedding_col=None, + text_unit_ids_col="text_unit_ids", + document_ids_col=None, + ) + + +def _filter_under_community_level( + df: pd.DataFrame, community_level: int +) -> pd.DataFrame: + return cast( + pd.DataFrame, + df[df.level <= community_level], + ) diff --git a/graphrag/graphrag/query/input/__init__.py b/graphrag/graphrag/query/input/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..94ae973477305adbc608c820f3a8b41249ab1838 --- /dev/null +++ b/graphrag/graphrag/query/input/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""GraphRAG Orchestration Inputs.""" diff --git a/graphrag/graphrag/query/input/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/query/input/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1101b7f8f0b47a62f6a87157c4455ebf739116c2 Binary files /dev/null and b/graphrag/graphrag/query/input/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/input/loaders/__init__.py b/graphrag/graphrag/query/input/loaders/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8f19dac0ddec38f964892b884512300b9848d844 --- /dev/null +++ b/graphrag/graphrag/query/input/loaders/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""GraphRAG Orchestartion Input Loaders.""" diff --git a/graphrag/graphrag/query/input/loaders/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/query/input/loaders/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ea448dce48623c345e3bbe3348c0f0c4078706f Binary files /dev/null and b/graphrag/graphrag/query/input/loaders/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/input/loaders/__pycache__/dfs.cpython-311.pyc b/graphrag/graphrag/query/input/loaders/__pycache__/dfs.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c46a5e772ed7b8efaeba8989a70389c6bb49507f Binary files /dev/null and b/graphrag/graphrag/query/input/loaders/__pycache__/dfs.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/input/loaders/__pycache__/utils.cpython-311.pyc b/graphrag/graphrag/query/input/loaders/__pycache__/utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5cc80702edc8d3ff1e6a3f1e5b96fba96a4c2144 Binary files /dev/null and b/graphrag/graphrag/query/input/loaders/__pycache__/utils.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/input/loaders/dfs.py b/graphrag/graphrag/query/input/loaders/dfs.py new file mode 100644 index 0000000000000000000000000000000000000000..7312963bb88c0a04af6a22cdf129733151322c8f --- /dev/null +++ b/graphrag/graphrag/query/input/loaders/dfs.py @@ -0,0 +1,340 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Load data from dataframes into collections of data objects.""" + +import pandas as pd + +from graphrag.model import ( + Community, + CommunityReport, + Covariate, + Document, + Entity, + Relationship, + TextUnit, +) +from graphrag.query.input.loaders.utils import ( + to_list, + to_optional_dict, + to_optional_float, + to_optional_int, + to_optional_list, + to_optional_str, + to_str, +) +from graphrag.vector_stores import BaseVectorStore, VectorStoreDocument + + +def read_entities( + df: pd.DataFrame, + id_col: str = "id", + short_id_col: str | None = "short_id", + title_col: str = "title", + type_col: str | None = "type", + description_col: str | None = "description", + name_embedding_col: str | None = "name_embedding", + description_embedding_col: str | None = "description_embedding", + graph_embedding_col: str | None = "graph_embedding", + community_col: str | None = "community_ids", + text_unit_ids_col: str | None = "text_unit_ids", + document_ids_col: str | None = "document_ids", + rank_col: str | None = "degree", + attributes_cols: list[str] | None = None, +) -> list[Entity]: + """Read entities from a dataframe.""" + entities = [] + for idx, row in df.iterrows(): + entity = Entity( + id=to_str(row, id_col), + short_id=to_optional_str(row, short_id_col) if short_id_col else str(idx), + title=to_str(row, title_col), + type=to_optional_str(row, type_col), + description=to_optional_str(row, description_col), + name_embedding=to_optional_list(row, name_embedding_col, item_type=float), + description_embedding=to_optional_list( + row, description_embedding_col, item_type=float + ), + graph_embedding=to_optional_list(row, graph_embedding_col, item_type=float), + community_ids=to_optional_list(row, community_col, item_type=str), + text_unit_ids=to_optional_list(row, text_unit_ids_col), + document_ids=to_optional_list(row, document_ids_col), + rank=to_optional_int(row, rank_col), + attributes=( + {col: row.get(col) for col in attributes_cols} + if attributes_cols + else None + ), + ) + entities.append(entity) + return entities + + +def store_entity_semantic_embeddings( + entities: list[Entity], + vectorstore: BaseVectorStore, +) -> BaseVectorStore: + """Store entity semantic embeddings in a vectorstore.""" + documents = [ + VectorStoreDocument( + id=entity.id, + text=entity.description, + vector=entity.description_embedding, + attributes=( + {"title": entity.title, **entity.attributes} + if entity.attributes + else {"title": entity.title} + ), + ) + for entity in entities + ] + vectorstore.load_documents(documents=documents) + return vectorstore + + +def store_entity_behavior_embeddings( + entities: list[Entity], + vectorstore: BaseVectorStore, +) -> BaseVectorStore: + """Store entity behavior embeddings in a vectorstore.""" + documents = [ + VectorStoreDocument( + id=entity.id, + text=entity.description, + vector=entity.graph_embedding, + attributes=( + {"title": entity.title, **entity.attributes} + if entity.attributes + else {"title": entity.title} + ), + ) + for entity in entities + ] + vectorstore.load_documents(documents=documents) + return vectorstore + + +def read_relationships( + df: pd.DataFrame, + id_col: str = "id", + short_id_col: str | None = "short_id", + source_col: str = "source", + target_col: str = "target", + description_col: str | None = "description", + description_embedding_col: str | None = "description_embedding", + weight_col: str | None = "weight", + text_unit_ids_col: str | None = "text_unit_ids", + document_ids_col: str | None = "document_ids", + attributes_cols: list[str] | None = None, +) -> list[Relationship]: + """Read relationships from a dataframe.""" + relationships = [] + for idx, row in df.iterrows(): + rel = Relationship( + id=to_str(row, id_col), + short_id=to_optional_str(row, short_id_col) if short_id_col else str(idx), + source=to_str(row, source_col), + target=to_str(row, target_col), + description=to_optional_str(row, description_col), + description_embedding=to_optional_list( + row, description_embedding_col, item_type=float + ), + weight=to_optional_float(row, weight_col), + text_unit_ids=to_optional_list(row, text_unit_ids_col, item_type=str), + document_ids=to_optional_list(row, document_ids_col, item_type=str), + attributes=( + {col: row.get(col) for col in attributes_cols} + if attributes_cols + else None + ), + ) + relationships.append(rel) + return relationships + + +def read_covariates( + df: pd.DataFrame, + id_col: str = "id", + short_id_col: str | None = "short_id", + subject_col: str = "subject_id", + subject_type_col: str | None = "subject_type", + covariate_type_col: str | None = "covariate_type", + text_unit_ids_col: str | None = "text_unit_ids", + document_ids_col: str | None = "document_ids", + attributes_cols: list[str] | None = None, +) -> list[Covariate]: + """Read covariates from a dataframe.""" + covariates = [] + for idx, row in df.iterrows(): + cov = Covariate( + id=to_str(row, id_col), + short_id=to_optional_str(row, short_id_col) if short_id_col else str(idx), + subject_id=to_str(row, subject_col), + subject_type=( + to_str(row, subject_type_col) if subject_type_col else "entity" + ), + covariate_type=( + to_str(row, covariate_type_col) if covariate_type_col else "claim" + ), + text_unit_ids=to_optional_list(row, text_unit_ids_col, item_type=str), + document_ids=to_optional_list(row, document_ids_col, item_type=str), + attributes=( + {col: row.get(col) for col in attributes_cols} + if attributes_cols + else None + ), + ) + covariates.append(cov) + return covariates + + +def read_communities( + df: pd.DataFrame, + id_col: str = "id", + short_id_col: str | None = "short_id", + title_col: str = "title", + level_col: str = "level", + entities_col: str | None = "entity_ids", + relationships_col: str | None = "relationship_ids", + covariates_col: str | None = "covariate_ids", + attributes_cols: list[str] | None = None, +) -> list[Community]: + """Read communities from a dataframe.""" + communities = [] + for idx, row in df.iterrows(): + comm = Community( + id=to_str(row, id_col), + short_id=to_optional_str(row, short_id_col) if short_id_col else str(idx), + title=to_str(row, title_col), + level=to_str(row, level_col), + entity_ids=to_optional_list(row, entities_col, item_type=str), + relationship_ids=to_optional_list(row, relationships_col, item_type=str), + covariate_ids=to_optional_dict( + row, covariates_col, key_type=str, value_type=str + ), + attributes=( + {col: row.get(col) for col in attributes_cols} + if attributes_cols + else None + ), + ) + communities.append(comm) + return communities + + +def read_community_reports( + df: pd.DataFrame, + id_col: str = "id", + short_id_col: str | None = "short_id", + title_col: str = "title", + community_col: str = "community", + summary_col: str = "summary", + content_col: str = "full_content", + rank_col: str | None = "rank", + summary_embedding_col: str | None = "summary_embedding", + content_embedding_col: str | None = "full_content_embedding", + attributes_cols: list[str] | None = None, +) -> list[CommunityReport]: + """Read community reports from a dataframe.""" + reports = [] + for idx, row in df.iterrows(): + report = CommunityReport( + id=to_str(row, id_col), + short_id=to_optional_str(row, short_id_col) if short_id_col else str(idx), + title=to_str(row, title_col), + community_id=to_str(row, community_col), + summary=to_str(row, summary_col), + full_content=to_str(row, content_col), + rank=to_optional_float(row, rank_col), + summary_embedding=to_optional_list( + row, summary_embedding_col, item_type=float + ), + full_content_embedding=to_optional_list( + row, content_embedding_col, item_type=float + ), + attributes=( + {col: row.get(col) for col in attributes_cols} + if attributes_cols + else None + ), + ) + reports.append(report) + return reports + + +def read_text_units( + df: pd.DataFrame, + id_col: str = "id", + short_id_col: str | None = "short_id", + text_col: str = "text", + entities_col: str | None = "entity_ids", + relationships_col: str | None = "relationship_ids", + covariates_col: str | None = "covariate_ids", + tokens_col: str | None = "n_tokens", + document_ids_col: str | None = "document_ids", + embedding_col: str | None = "text_embedding", + attributes_cols: list[str] | None = None, +) -> list[TextUnit]: + """Read text units from a dataframe.""" + text_units = [] + for idx, row in df.iterrows(): + chunk = TextUnit( + id=to_str(row, id_col), + short_id=to_optional_str(row, short_id_col) if short_id_col else str(idx), + text=to_str(row, text_col), + entity_ids=to_optional_list(row, entities_col, item_type=str), + relationship_ids=to_optional_list(row, relationships_col, item_type=str), + covariate_ids=to_optional_dict( + row, covariates_col, key_type=str, value_type=str + ), + text_embedding=to_optional_list(row, embedding_col, item_type=float), # type: ignore + n_tokens=to_optional_int(row, tokens_col), + document_ids=to_optional_list(row, document_ids_col, item_type=str), + attributes=( + {col: row.get(col) for col in attributes_cols} + if attributes_cols + else None + ), + ) + text_units.append(chunk) + return text_units + + +def read_documents( + df: pd.DataFrame, + id_col: str = "id", + short_id_col: str = "short_id", + title_col: str = "title", + type_col: str = "type", + summary_col: str | None = "entities", + raw_content_col: str | None = "relationships", + summary_embedding_col: str | None = "summary_embedding", + content_embedding_col: str | None = "raw_content_embedding", + text_units_col: str | None = "text_units", + attributes_cols: list[str] | None = None, +) -> list[Document]: + """Read documents from a dataframe.""" + docs = [] + for idx, row in df.iterrows(): + doc = Document( + id=to_str(row, id_col), + short_id=to_optional_str(row, short_id_col) if short_id_col else str(idx), + title=to_str(row, title_col), + type=to_str(row, type_col), + summary=to_optional_str(row, summary_col), + raw_content=to_str(row, raw_content_col), + summary_embedding=to_optional_list( + row, summary_embedding_col, item_type=float + ), + raw_content_embedding=to_optional_list( + row, content_embedding_col, item_type=float + ), + text_units=to_list(row, text_units_col, item_type=str), # type: ignore + attributes=( + {col: row.get(col) for col in attributes_cols} + if attributes_cols + else None + ), + ) + docs.append(doc) + return docs diff --git a/graphrag/graphrag/query/input/loaders/utils.py b/graphrag/graphrag/query/input/loaders/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..e0fffd2467bb86bc4957a87420c950c4407c2d13 --- /dev/null +++ b/graphrag/graphrag/query/input/loaders/utils.py @@ -0,0 +1,245 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Data load utils.""" + +import numpy as np +import pandas as pd + + +def to_str(data: pd.Series, column_name: str | None) -> str: + """Convert and validate a value to a string.""" + if column_name is None: + msg = "Column name is None" + raise ValueError(msg) + + if column_name in data: + return str(data[column_name]) + msg = f"Column {column_name} not found in data" + raise ValueError(msg) + + +def to_optional_str(data: pd.Series, column_name: str | None) -> str | None: + """Convert and validate a value to an optional string.""" + if column_name is None: + msg = "Column name is None" + raise ValueError(msg) + + if column_name in data: + value = data[column_name] + if value is None: + return None + return str(data[column_name]) + msg = f"Column {column_name} not found in data" + raise ValueError(msg) + + +def to_list( + data: pd.Series, column_name: str | None, item_type: type | None = None +) -> list: + """Convert and validate a value to a list.""" + if column_name is None: + msg = "Column name is None" + raise ValueError(msg) + + if column_name in data: + value = data[column_name] + if isinstance(value, np.ndarray): + value = value.tolist() + + if not isinstance(value, list): + msg = f"value is not a list: {value} ({type(value)})" + raise ValueError(msg) + + if item_type is not None: + for v in value: + if not isinstance(v, item_type): + msg = f"list item has item that is not {item_type}: {v} ({type(v)})" + raise TypeError(msg) + return value + + msg = f"Column {column_name} not found in data" + raise ValueError(msg) + + +def to_optional_list( + data: pd.Series, column_name: str | None, item_type: type | None = None +) -> list | None: + """Convert and validate a value to an optional list.""" + if column_name is None: + return None + + if column_name in data: + value = data[column_name] # type: ignore + if value is None: + return None + + if isinstance(value, np.ndarray): + value = value.tolist() + + if not isinstance(value, list): + msg = f"value is not a list: {value} ({type(value)})" + raise ValueError(msg) + + if item_type is not None: + for v in value: + if not isinstance(v, item_type): + msg = f"list item has item that is not {item_type}: {v} ({type(v)})" + raise TypeError(msg) + return value + + return None + + +def to_int(data: pd.Series, column_name: str | None) -> int: + """Convert and validate a value to an int.""" + if column_name is None: + msg = "Column name is None" + raise ValueError(msg) + + if column_name in data: + value = data[column_name] + if isinstance(value, float): + value = int(value) + if not isinstance(value, int): + msg = f"value is not an int: {value} ({type(value)})" + raise ValueError(msg) + else: + msg = f"Column {column_name} not found in data" + raise ValueError(msg) + + return int(value) + + +def to_optional_int(data: pd.Series, column_name: str | None) -> int | None: + """Convert and validate a value to an optional int.""" + if column_name is None: + return None + + if column_name in data: + value = data[column_name] + + if value is None: + return None + + if isinstance(value, float): + value = int(value) + if not isinstance(value, int): + msg = f"value is not an int: {value} ({type(value)})" + raise ValueError(msg) + else: + msg = f"Column {column_name} not found in data" + raise ValueError(msg) + + return int(value) + + +def to_float(data: pd.Series, column_name: str | None) -> float: + """Convert and validate a value to a float.""" + if column_name is None: + msg = "Column name is None" + raise ValueError(msg) + + if column_name in data: + value = data[column_name] + if not isinstance(value, float): + msg = f"value is not a float: {value} ({type(value)})" + raise ValueError(msg) + else: + msg = f"Column {column_name} not found in data" + raise ValueError(msg) + + return float(value) + + +def to_optional_float(data: pd.Series, column_name: str | None) -> float | None: + """Convert and validate a value to an optional float.""" + if column_name is None: + return None + + if column_name in data: + value = data[column_name] + if value is None: + return None + if not isinstance(value, float): + msg = f"value is not a float: {value} ({type(value)})" + raise ValueError(msg) + else: + msg = f"Column {column_name} not found in data" + raise ValueError(msg) + + return float(value) + + +def to_dict( + data: pd.Series, + column_name: str | None, + key_type: type | None = None, + value_type: type | None = None, +) -> dict: + """Convert and validate a value to a dict.""" + if column_name is None: + msg = "Column name is None" + raise ValueError(msg) + + if column_name in data: + value = data[column_name] + if not isinstance(value, dict): + msg = f"value is not a dict: {value} ({type(value)})" + raise ValueError(msg) + + if key_type is not None: + for v in value: + if not isinstance(v, key_type): + msg = f"dict key has item that is not {key_type}: {v} ({type(v)})" + raise TypeError(msg) + + if value_type is not None: + for v in value.values(): + if not isinstance(v, value_type): + msg = ( + f"dict value has item that is not {value_type}: {v} ({type(v)})" + ) + raise TypeError(msg) + return value + + msg = f"Column {column_name} not found in data" + raise ValueError(msg) + + +def to_optional_dict( + data: pd.Series, + column_name: str | None, + key_type: type | None = None, + value_type: type | None = None, +) -> dict | None: + """Convert and validate a value to an optional dict.""" + if column_name is None: + return None + + if column_name in data: + value = data[column_name] + if value is None: + return None + if not isinstance(value, dict): + msg = f"value is not a dict: {value} ({type(value)})" + raise TypeError(msg) + + if key_type is not None: + for v in value: + if not isinstance(v, key_type): + msg = f"dict key has item that is not {key_type}: {v} ({type(v)})" + raise TypeError(msg) + + if value_type is not None: + for v in value.values(): + if not isinstance(v, value_type): + msg = ( + f"dict value has item that is not {value_type}: {v} ({type(v)})" + ) + raise TypeError(msg) + + return value + + msg = f"Column {column_name} not found in data" + raise ValueError(msg) diff --git a/graphrag/graphrag/query/input/retrieval/__init__.py b/graphrag/graphrag/query/input/retrieval/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..75c2f9f095749633795705c50898bbed099e891d --- /dev/null +++ b/graphrag/graphrag/query/input/retrieval/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""GraphRAG Orchestration Input Retrieval.""" diff --git a/graphrag/graphrag/query/input/retrieval/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/query/input/retrieval/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be260099f74a4945b62beb85296298004da0b4ce Binary files /dev/null and b/graphrag/graphrag/query/input/retrieval/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/input/retrieval/__pycache__/community_reports.cpython-311.pyc b/graphrag/graphrag/query/input/retrieval/__pycache__/community_reports.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd2ad9c30426c4cd12c02390276d5170168359b5 Binary files /dev/null and b/graphrag/graphrag/query/input/retrieval/__pycache__/community_reports.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/input/retrieval/__pycache__/covariates.cpython-311.pyc b/graphrag/graphrag/query/input/retrieval/__pycache__/covariates.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30d25e6e7c732105223525e375b3c660d61c62c3 Binary files /dev/null and b/graphrag/graphrag/query/input/retrieval/__pycache__/covariates.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/input/retrieval/__pycache__/entities.cpython-311.pyc b/graphrag/graphrag/query/input/retrieval/__pycache__/entities.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd25076247518bbcfa5bbd14a8cd7e33dfb20ea5 Binary files /dev/null and b/graphrag/graphrag/query/input/retrieval/__pycache__/entities.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/input/retrieval/__pycache__/relationships.cpython-311.pyc b/graphrag/graphrag/query/input/retrieval/__pycache__/relationships.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..db334ce91d396897e8c9216077948a85e77e944d Binary files /dev/null and b/graphrag/graphrag/query/input/retrieval/__pycache__/relationships.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/input/retrieval/__pycache__/text_units.cpython-311.pyc b/graphrag/graphrag/query/input/retrieval/__pycache__/text_units.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d092d0651cbaf958c212c47743159018ffe0b22 Binary files /dev/null and b/graphrag/graphrag/query/input/retrieval/__pycache__/text_units.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/input/retrieval/community_reports.py b/graphrag/graphrag/query/input/retrieval/community_reports.py new file mode 100644 index 0000000000000000000000000000000000000000..bd4933f1f9465d8d81ddb92f601f84989ecfa306 --- /dev/null +++ b/graphrag/graphrag/query/input/retrieval/community_reports.py @@ -0,0 +1,74 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Util functions to retrieve community reports from a collection.""" + +from typing import Any, cast + +import pandas as pd + +from graphrag.model import CommunityReport, Entity + + +def get_candidate_communities( + selected_entities: list[Entity], + community_reports: list[CommunityReport], + include_community_rank: bool = False, + use_community_summary: bool = False, +) -> pd.DataFrame: + """Get all communities that are related to selected entities.""" + selected_community_ids = [ + entity.community_ids for entity in selected_entities if entity.community_ids + ] + selected_community_ids = [ + item for sublist in selected_community_ids for item in sublist + ] + selected_reports = [ + community + for community in community_reports + if community.id in selected_community_ids + ] + return to_community_report_dataframe( + reports=selected_reports, + include_community_rank=include_community_rank, + use_community_summary=use_community_summary, + ) + + +def to_community_report_dataframe( + reports: list[CommunityReport], + include_community_rank: bool = False, + use_community_summary: bool = False, +) -> pd.DataFrame: + """Convert a list of communities to a pandas dataframe.""" + if len(reports) == 0: + return pd.DataFrame() + + # add header + header = ["id", "title"] + attribute_cols = list(reports[0].attributes.keys()) if reports[0].attributes else [] + attribute_cols = [col for col in attribute_cols if col not in header] + header.extend(attribute_cols) + header.append("summary" if use_community_summary else "content") + if include_community_rank: + header.append("rank") + + records = [] + for report in reports: + new_record = [ + report.short_id if report.short_id else "", + report.title, + *[ + str(report.attributes.get(field, "")) + if report.attributes and report.attributes.get(field) + else "" + for field in attribute_cols + ], + ] + new_record.append( + report.summary if use_community_summary else report.full_content + ) + if include_community_rank: + new_record.append(str(report.rank)) + records.append(new_record) + return pd.DataFrame(records, columns=cast(Any, header)) diff --git a/graphrag/graphrag/query/input/retrieval/covariates.py b/graphrag/graphrag/query/input/retrieval/covariates.py new file mode 100644 index 0000000000000000000000000000000000000000..1c45203d01428fb1475abb94375ac54abbde2eff --- /dev/null +++ b/graphrag/graphrag/query/input/retrieval/covariates.py @@ -0,0 +1,52 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Util functions to retrieve covariates from a collection.""" + +from typing import Any, cast + +import pandas as pd + +from graphrag.model import Covariate, Entity + + +def get_candidate_covariates( + selected_entities: list[Entity], + covariates: list[Covariate], +) -> list[Covariate]: + """Get all covariates that are related to selected entities.""" + selected_entity_names = [entity.title for entity in selected_entities] + return [ + covariate + for covariate in covariates + if covariate.subject_id in selected_entity_names + ] + + +def to_covariate_dataframe(covariates: list[Covariate]) -> pd.DataFrame: + """Convert a list of covariates to a pandas dataframe.""" + if len(covariates) == 0: + return pd.DataFrame() + + # add header + header = ["id", "entity"] + attributes = covariates[0].attributes or {} if len(covariates) > 0 else {} + attribute_cols = list(attributes.keys()) if len(covariates) > 0 else [] + attribute_cols = [col for col in attribute_cols if col not in header] + header.extend(attribute_cols) + + records = [] + for covariate in covariates: + new_record = [ + covariate.short_id if covariate.short_id else "", + covariate.subject_id, + ] + for field in attribute_cols: + field_value = ( + str(covariate.attributes.get(field)) + if covariate.attributes and covariate.attributes.get(field) + else "" + ) + new_record.append(field_value) + records.append(new_record) + return pd.DataFrame(records, columns=cast(Any, header)) diff --git a/graphrag/graphrag/query/input/retrieval/entities.py b/graphrag/graphrag/query/input/retrieval/entities.py new file mode 100644 index 0000000000000000000000000000000000000000..5465f9f59ebd02a614de434ed7d50a93c972cfd2 --- /dev/null +++ b/graphrag/graphrag/query/input/retrieval/entities.py @@ -0,0 +1,93 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Util functions to get entities from a collection.""" + +import uuid +from collections.abc import Iterable +from typing import Any, cast + +import pandas as pd + +from graphrag.model import Entity + + +def get_entity_by_key( + entities: Iterable[Entity], key: str, value: str | int +) -> Entity | None: + """Get entity by key.""" + for entity in entities: + if isinstance(value, str) and is_valid_uuid(value): + if getattr(entity, key) == value or getattr(entity, key) == value.replace( + "-", "" + ): + return entity + else: + if getattr(entity, key) == value: + return entity + return None + + +def get_entity_by_name(entities: Iterable[Entity], entity_name: str) -> list[Entity]: + """Get entities by name.""" + return [entity for entity in entities if entity.title == entity_name] + + +def get_entity_by_attribute( + entities: Iterable[Entity], attribute_name: str, attribute_value: Any +) -> list[Entity]: + """Get entities by attribute.""" + return [ + entity + for entity in entities + if entity.attributes + and entity.attributes.get(attribute_name) == attribute_value + ] + + +def to_entity_dataframe( + entities: list[Entity], + include_entity_rank: bool = True, + rank_description: str = "number of relationships", +) -> pd.DataFrame: + """Convert a list of entities to a pandas dataframe.""" + if len(entities) == 0: + return pd.DataFrame() + header = ["id", "entity", "description"] + if include_entity_rank: + header.append(rank_description) + attribute_cols = ( + list(entities[0].attributes.keys()) if entities[0].attributes else [] + ) + attribute_cols = [col for col in attribute_cols if col not in header] + header.extend(attribute_cols) + + records = [] + for entity in entities: + new_record = [ + entity.short_id if entity.short_id else "", + entity.title, + entity.description if entity.description else "", + ] + if include_entity_rank: + new_record.append(str(entity.rank)) + + for field in attribute_cols: + field_value = ( + str(entity.attributes.get(field)) + if entity.attributes and entity.attributes.get(field) + else "" + ) + new_record.append(field_value) + records.append(new_record) + return pd.DataFrame(records, columns=cast(Any, header)) + + +def is_valid_uuid(value: str) -> bool: + """Determine if a string is a valid UUID.""" + try: + uuid.UUID(str(value)) + except ValueError: + return False + else: + return True diff --git a/graphrag/graphrag/query/input/retrieval/relationships.py b/graphrag/graphrag/query/input/retrieval/relationships.py new file mode 100644 index 0000000000000000000000000000000000000000..2ef5ba38cb069a02084ec366879e865afb597c96 --- /dev/null +++ b/graphrag/graphrag/query/input/retrieval/relationships.py @@ -0,0 +1,173 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Util functions to retrieve relationships from a collection.""" + +from typing import Any, cast + +import pandas as pd + +from graphrag.model import Entity, Relationship + + +def get_in_network_relationships( + selected_entities: list[Entity], + relationships: list[Relationship], + ranking_attribute: str = "rank", +) -> list[Relationship]: + """Get all directed relationships between selected entities, sorted by ranking_attribute.""" + selected_entity_names = [entity.title for entity in selected_entities] + selected_relationships = [ + relationship + for relationship in relationships + if relationship.source in selected_entity_names + and relationship.target in selected_entity_names + ] + if len(selected_relationships) <= 1: + return selected_relationships + + # sort by ranking attribute + return sort_relationships_by_ranking_attribute( + selected_relationships, selected_entities, ranking_attribute + ) + + +def get_out_network_relationships( + selected_entities: list[Entity], + relationships: list[Relationship], + ranking_attribute: str = "rank", +) -> list[Relationship]: + """Get relationships from selected entities to other entities that are not within the selected entities, sorted by ranking_attribute.""" + selected_entity_names = [entity.title for entity in selected_entities] + source_relationships = [ + relationship + for relationship in relationships + if relationship.source in selected_entity_names + and relationship.target not in selected_entity_names + ] + target_relationships = [ + relationship + for relationship in relationships + if relationship.target in selected_entity_names + and relationship.source not in selected_entity_names + ] + selected_relationships = source_relationships + target_relationships + return sort_relationships_by_ranking_attribute( + selected_relationships, selected_entities, ranking_attribute + ) + + +def get_candidate_relationships( + selected_entities: list[Entity], + relationships: list[Relationship], +) -> list[Relationship]: + """Get all relationships that are associated with the selected entities.""" + selected_entity_names = [entity.title for entity in selected_entities] + return [ + relationship + for relationship in relationships + if relationship.source in selected_entity_names + or relationship.target in selected_entity_names + ] + + +def get_entities_from_relationships( + relationships: list[Relationship], entities: list[Entity] +) -> list[Entity]: + """Get all entities that are associated with the selected relationships.""" + selected_entity_names = [relationship.source for relationship in relationships] + [ + relationship.target for relationship in relationships + ] + return [entity for entity in entities if entity.title in selected_entity_names] + + +def calculate_relationship_combined_rank( + relationships: list[Relationship], + entities: list[Entity], + ranking_attribute: str = "rank", +) -> list[Relationship]: + """Calculate default rank for a relationship based on the combined rank of source and target entities.""" + entity_mappings = {entity.title: entity for entity in entities} + + for relationship in relationships: + if relationship.attributes is None: + relationship.attributes = {} + source = entity_mappings.get(relationship.source) + target = entity_mappings.get(relationship.target) + source_rank = source.rank if source and source.rank else 0 + target_rank = target.rank if target and target.rank else 0 + relationship.attributes[ranking_attribute] = source_rank + target_rank # type: ignore + return relationships + + +def sort_relationships_by_ranking_attribute( + relationships: list[Relationship], + entities: list[Entity], + ranking_attribute: str = "rank", +) -> list[Relationship]: + """ + Sort relationships by a ranking_attribute. + + If no ranking attribute exists, sort by combined rank of source and target entities. + """ + if len(relationships) == 0: + return relationships + + # sort by ranking attribute + attribute_names = ( + list(relationships[0].attributes.keys()) if relationships[0].attributes else [] + ) + if ranking_attribute in attribute_names: + relationships.sort( + key=lambda x: int(x.attributes[ranking_attribute]) if x.attributes else 0, + reverse=True, + ) + elif ranking_attribute == "weight": + relationships.sort(key=lambda x: x.weight if x.weight else 0.0, reverse=True) + else: + # ranking attribute do not exist, calculate rank = combined ranks of source and target + relationships = calculate_relationship_combined_rank( + relationships, entities, ranking_attribute + ) + relationships.sort( + key=lambda x: int(x.attributes[ranking_attribute]) if x.attributes else 0, + reverse=True, + ) + return relationships + + +def to_relationship_dataframe( + relationships: list[Relationship], include_relationship_weight: bool = True +) -> pd.DataFrame: + """Convert a list of relationships to a pandas dataframe.""" + if len(relationships) == 0: + return pd.DataFrame() + + header = ["id", "source", "target", "description"] + if include_relationship_weight: + header.append("weight") + attribute_cols = ( + list(relationships[0].attributes.keys()) if relationships[0].attributes else [] + ) + attribute_cols = [col for col in attribute_cols if col not in header] + header.extend(attribute_cols) + + records = [] + for rel in relationships: + new_record = [ + rel.short_id if rel.short_id else "", + rel.source, + rel.target, + rel.description if rel.description else "", + ] + if include_relationship_weight: + new_record.append(str(rel.weight if rel.weight else "")) + for field in attribute_cols: + field_value = ( + str(rel.attributes.get(field)) + if rel.attributes and rel.attributes.get(field) + else "" + ) + new_record.append(field_value) + records.append(new_record) + return pd.DataFrame(records, columns=cast(Any, header)) diff --git a/graphrag/graphrag/query/input/retrieval/text_units.py b/graphrag/graphrag/query/input/retrieval/text_units.py new file mode 100644 index 0000000000000000000000000000000000000000..a00dc20a0a2f25cf97071801ca15f5606c5ee038 --- /dev/null +++ b/graphrag/graphrag/query/input/retrieval/text_units.py @@ -0,0 +1,52 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Util functions to retrieve text units from a collection.""" + +from typing import Any, cast + +import pandas as pd + +from graphrag.model import Entity, TextUnit + + +def get_candidate_text_units( + selected_entities: list[Entity], + text_units: list[TextUnit], +) -> pd.DataFrame: + """Get all text units that are associated to selected entities.""" + selected_text_ids = [ + entity.text_unit_ids for entity in selected_entities if entity.text_unit_ids + ] + selected_text_ids = [item for sublist in selected_text_ids for item in sublist] + selected_text_units = [unit for unit in text_units if unit.id in selected_text_ids] + return to_text_unit_dataframe(selected_text_units) + + +def to_text_unit_dataframe(text_units: list[TextUnit]) -> pd.DataFrame: + """Convert a list of text units to a pandas dataframe.""" + if len(text_units) == 0: + return pd.DataFrame() + + # add header + header = ["id", "text"] + attribute_cols = ( + list(text_units[0].attributes.keys()) if text_units[0].attributes else [] + ) + attribute_cols = [col for col in attribute_cols if col not in header] + header.extend(attribute_cols) + + records = [] + for unit in text_units: + new_record = [ + unit.short_id, + unit.text, + *[ + str(unit.attributes.get(field, "")) + if unit.attributes and unit.attributes.get(field) + else "" + for field in attribute_cols + ], + ] + records.append(new_record) + return pd.DataFrame(records, columns=cast(Any, header)) diff --git a/graphrag/graphrag/query/llm/__init__.py b/graphrag/graphrag/query/llm/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8f507b138ffb98eca02e3bd82be34b9848bc522 --- /dev/null +++ b/graphrag/graphrag/query/llm/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Orchestration LLM utilities.""" diff --git a/graphrag/graphrag/query/llm/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/query/llm/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..633aed9967f67a3f142ee95188f40f23f3647566 Binary files /dev/null and b/graphrag/graphrag/query/llm/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/llm/__pycache__/base.cpython-311.pyc b/graphrag/graphrag/query/llm/__pycache__/base.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40b36f43ac403826a876a25cd7ede33cbd650db2 Binary files /dev/null and b/graphrag/graphrag/query/llm/__pycache__/base.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/llm/__pycache__/text_utils.cpython-311.pyc b/graphrag/graphrag/query/llm/__pycache__/text_utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b9b94fcd391bd40019a2a9655637a740f36aef86 Binary files /dev/null and b/graphrag/graphrag/query/llm/__pycache__/text_utils.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/llm/base.py b/graphrag/graphrag/query/llm/base.py new file mode 100644 index 0000000000000000000000000000000000000000..228150af50707713f44767dcca679f387bfccb02 --- /dev/null +++ b/graphrag/graphrag/query/llm/base.py @@ -0,0 +1,54 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Base classes for LLM and Embedding models.""" + +from abc import ABC, abstractmethod +from typing import Any + + +class BaseLLMCallback: + """Base class for LLM callbacks.""" + + def __init__(self): + self.response = [] + + def on_llm_new_token(self, token: str): + """Handle when a new token is generated.""" + self.response.append(token) + + +class BaseLLM(ABC): + """The Base LLM implementation.""" + + @abstractmethod + def generate( + self, + messages: str | list[Any], + streaming: bool = True, + callbacks: list[BaseLLMCallback] | None = None, + **kwargs: Any, + ) -> str: + """Generate a response.""" + + @abstractmethod + async def agenerate( + self, + messages: str | list[Any], + streaming: bool = True, + callbacks: list[BaseLLMCallback] | None = None, + **kwargs: Any, + ) -> str: + """Generate a response asynchronously.""" + + +class BaseTextEmbedding(ABC): + """The text embedding interface.""" + + @abstractmethod + def embed(self, text: str, **kwargs: Any) -> list[float]: + """Embed a text string.""" + + @abstractmethod + async def aembed(self, text: str, **kwargs: Any) -> list[float]: + """Embed a text string asynchronously.""" diff --git a/graphrag/graphrag/query/llm/oai/__init__.py b/graphrag/graphrag/query/llm/oai/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cbb257905e9ade08e3f41d734afe8b5215a67fe1 --- /dev/null +++ b/graphrag/graphrag/query/llm/oai/__init__.py @@ -0,0 +1,21 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""GraphRAG Orchestration OpenAI Wrappers.""" + +from .base import BaseOpenAILLM, OpenAILLMImpl, OpenAITextEmbeddingImpl +from .chat_openai import ChatOpenAI +from .embedding import OpenAIEmbedding +from .openai import OpenAI +from .typing import OPENAI_RETRY_ERROR_TYPES, OpenaiApiType + +__all__ = [ + "OPENAI_RETRY_ERROR_TYPES", + "BaseOpenAILLM", + "ChatOpenAI", + "OpenAI", + "OpenAIEmbedding", + "OpenAILLMImpl", + "OpenAITextEmbeddingImpl", + "OpenaiApiType", +] diff --git a/graphrag/graphrag/query/llm/oai/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/query/llm/oai/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c306b16b0fdfac34ba6e38754f99730025258f4 Binary files /dev/null and b/graphrag/graphrag/query/llm/oai/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/llm/oai/__pycache__/base.cpython-311.pyc b/graphrag/graphrag/query/llm/oai/__pycache__/base.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0c92b2526abfd5f3b3003c8032c68e8d08fb9e94 Binary files /dev/null and b/graphrag/graphrag/query/llm/oai/__pycache__/base.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/llm/oai/__pycache__/chat_openai.cpython-311.pyc b/graphrag/graphrag/query/llm/oai/__pycache__/chat_openai.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..640273a30060e2604b6b81cefa9f6a0df9ca63a8 Binary files /dev/null and b/graphrag/graphrag/query/llm/oai/__pycache__/chat_openai.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/llm/oai/__pycache__/embedding.cpython-311.pyc b/graphrag/graphrag/query/llm/oai/__pycache__/embedding.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..041fe4093956e2ca081dde74a1a8841dc6ddf3c7 Binary files /dev/null and b/graphrag/graphrag/query/llm/oai/__pycache__/embedding.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/llm/oai/__pycache__/openai.cpython-311.pyc b/graphrag/graphrag/query/llm/oai/__pycache__/openai.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a3cdd442ce38fd6cdf5a4077139c2f5e68fdf0b Binary files /dev/null and b/graphrag/graphrag/query/llm/oai/__pycache__/openai.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/llm/oai/__pycache__/typing.cpython-311.pyc b/graphrag/graphrag/query/llm/oai/__pycache__/typing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..763291cb068e52892bcf8e488a5f2214a0bd18f7 Binary files /dev/null and b/graphrag/graphrag/query/llm/oai/__pycache__/typing.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/llm/oai/base.py b/graphrag/graphrag/query/llm/oai/base.py new file mode 100644 index 0000000000000000000000000000000000000000..6181c0b2a5f40b297142ebc0351fe8d1e19466b4 --- /dev/null +++ b/graphrag/graphrag/query/llm/oai/base.py @@ -0,0 +1,187 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Base classes for LLM and Embedding models.""" + +from abc import ABC, abstractmethod +from collections.abc import Callable + +from openai import AsyncAzureOpenAI, AsyncOpenAI, AzureOpenAI, OpenAI + +from graphrag.query.llm.base import BaseTextEmbedding +from graphrag.query.llm.oai.typing import OpenaiApiType +from graphrag.query.progress import ConsoleStatusReporter, StatusReporter + + +class BaseOpenAILLM(ABC): + """The Base OpenAI LLM implementation.""" + + _async_client: AsyncOpenAI | AsyncAzureOpenAI + _sync_client: OpenAI | AzureOpenAI + + def __init__(self): + self._create_openai_client() + + @abstractmethod + def _create_openai_client(self): + """Create a new synchronous and asynchronous OpenAI client instance.""" + + def set_clients( + self, + sync_client: OpenAI | AzureOpenAI, + async_client: AsyncOpenAI | AsyncAzureOpenAI, + ): + """ + Set the synchronous and asynchronous clients used for making API requests. + + Args: + sync_client (OpenAI | AzureOpenAI): The sync client object. + async_client (AsyncOpenAI | AsyncAzureOpenAI): The async client object. + """ + self._sync_client = sync_client + self._async_client = async_client + + @property + def async_client(self) -> AsyncOpenAI | AsyncAzureOpenAI | None: + """ + Get the asynchronous client used for making API requests. + + Returns + ------- + AsyncOpenAI | AsyncAzureOpenAI: The async client object. + """ + return self._async_client + + @property + def sync_client(self) -> OpenAI | AzureOpenAI | None: + """ + Get the synchronous client used for making API requests. + + Returns + ------- + AsyncOpenAI | AsyncAzureOpenAI: The async client object. + """ + return self._sync_client + + @async_client.setter + def async_client(self, client: AsyncOpenAI | AsyncAzureOpenAI): + """ + Set the asynchronous client used for making API requests. + + Args: + client (AsyncOpenAI | AsyncAzureOpenAI): The async client object. + """ + self._async_client = client + + @sync_client.setter + def sync_client(self, client: OpenAI | AzureOpenAI): + """ + Set the synchronous client used for making API requests. + + Args: + client (OpenAI | AzureOpenAI): The sync client object. + """ + self._sync_client = client + + +class OpenAILLMImpl(BaseOpenAILLM): + """Orchestration OpenAI LLM Implementation.""" + + _reporter: StatusReporter = ConsoleStatusReporter() + + def __init__( + self, + api_key: str | None = None, + azure_ad_token_provider: Callable | None = None, + deployment_name: str | None = None, + api_base: str | None = None, + api_version: str | None = None, + api_type: OpenaiApiType = OpenaiApiType.OpenAI, + organization: str | None = None, + max_retries: int = 10, + request_timeout: float = 180.0, + reporter: StatusReporter | None = None, + ): + self.api_key = api_key + self.azure_ad_token_provider = azure_ad_token_provider + self.deployment_name = deployment_name + self.api_base = api_base + self.api_version = api_version + self.api_type = api_type + self.organization = organization + self.max_retries = max_retries + self.request_timeout = request_timeout + self.reporter = reporter or ConsoleStatusReporter() + + try: + # Create OpenAI sync and async clients + super().__init__() + except Exception as e: + self._reporter.error( + message="Failed to create OpenAI client", + details={self.__class__.__name__: str(e)}, + ) + raise + + def _create_openai_client(self): + """Create a new OpenAI client instance.""" + if self.api_type == OpenaiApiType.AzureOpenAI: + if self.api_base is None: + msg = "api_base is required for Azure OpenAI" + raise ValueError(msg) + + sync_client = AzureOpenAI( + api_key=self.api_key, + azure_ad_token_provider=self.azure_ad_token_provider, + organization=self.organization, + # Azure-Specifics + api_version=self.api_version, + azure_endpoint=self.api_base, + azure_deployment=self.deployment_name, + # Retry Configuration + timeout=self.request_timeout, + max_retries=self.max_retries, + ) + + async_client = AsyncAzureOpenAI( + api_key=self.api_key, + azure_ad_token_provider=self.azure_ad_token_provider, + organization=self.organization, + # Azure-Specifics + api_version=self.api_version, + azure_endpoint=self.api_base, + azure_deployment=self.deployment_name, + # Retry Configuration + timeout=self.request_timeout, + max_retries=self.max_retries, + ) + self.set_clients(sync_client=sync_client, async_client=async_client) + + else: + sync_client = OpenAI( + api_key=self.api_key, + base_url=self.api_base, + organization=self.organization, + # Retry Configuration + timeout=self.request_timeout, + max_retries=self.max_retries, + ) + + async_client = AsyncOpenAI( + api_key=self.api_key, + base_url=self.api_base, + organization=self.organization, + # Retry Configuration + timeout=self.request_timeout, + max_retries=self.max_retries, + ) + self.set_clients(sync_client=sync_client, async_client=async_client) + + +class OpenAITextEmbeddingImpl(BaseTextEmbedding): + """Orchestration OpenAI Text Embedding Implementation.""" + + _reporter: StatusReporter | None = None + + def _create_openai_client(self, api_type: OpenaiApiType): + """Create a new synchronous and asynchronous OpenAI client instance.""" diff --git a/graphrag/graphrag/query/llm/oai/chat_openai.py b/graphrag/graphrag/query/llm/oai/chat_openai.py new file mode 100644 index 0000000000000000000000000000000000000000..92a9755b1072f9e0761dc2649466184e28b56ff7 --- /dev/null +++ b/graphrag/graphrag/query/llm/oai/chat_openai.py @@ -0,0 +1,206 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Chat-based OpenAI LLM implementation.""" + +from collections.abc import Callable +from typing import Any + +from tenacity import ( + AsyncRetrying, + RetryError, + Retrying, + retry_if_exception_type, + stop_after_attempt, + wait_exponential_jitter, +) + +from graphrag.query.llm.base import BaseLLM, BaseLLMCallback +from graphrag.query.llm.oai.base import OpenAILLMImpl +from graphrag.query.llm.oai.typing import ( + OPENAI_RETRY_ERROR_TYPES, + OpenaiApiType, +) +from graphrag.query.progress import StatusReporter + +_MODEL_REQUIRED_MSG = "model is required" + + +class ChatOpenAI(BaseLLM, OpenAILLMImpl): + """Wrapper for OpenAI ChatCompletion models.""" + + def __init__( + self, + api_key: str | None = None, + model: str | None = None, + azure_ad_token_provider: Callable | None = None, + deployment_name: str | None = None, + api_base: str | None = None, + api_version: str | None = None, + api_type: OpenaiApiType = OpenaiApiType.OpenAI, + organization: str | None = None, + max_retries: int = 10, + request_timeout: float = 180.0, + retry_error_types: tuple[type[BaseException]] = OPENAI_RETRY_ERROR_TYPES, # type: ignore + reporter: StatusReporter | None = None, + ): + OpenAILLMImpl.__init__( + self=self, + api_key=api_key, + azure_ad_token_provider=azure_ad_token_provider, + deployment_name=deployment_name, + api_base=api_base, + api_version=api_version, + api_type=api_type, # type: ignore + organization=organization, + max_retries=max_retries, + request_timeout=request_timeout, + reporter=reporter, + ) + self.model = model + self.retry_error_types = retry_error_types + + def generate( + self, + messages: str | list[Any], + streaming: bool = True, + callbacks: list[BaseLLMCallback] | None = None, + **kwargs: Any, + ) -> str: + """Generate text.""" + try: + retryer = Retrying( + stop=stop_after_attempt(self.max_retries), + wait=wait_exponential_jitter(max=10), + reraise=True, + retry=retry_if_exception_type(self.retry_error_types), + ) + for attempt in retryer: + with attempt: + return self._generate( + messages=messages, + streaming=streaming, + callbacks=callbacks, + **kwargs, + ) + except RetryError as e: + self._reporter.error( + message="Error at generate()", details={self.__class__.__name__: str(e)} + ) + return "" + else: + # TODO: why not just throw in this case? + return "" + + async def agenerate( + self, + messages: str | list[Any], + streaming: bool = True, + callbacks: list[BaseLLMCallback] | None = None, + **kwargs: Any, + ) -> str: + """Generate text asynchronously.""" + try: + retryer = AsyncRetrying( + stop=stop_after_attempt(self.max_retries), + wait=wait_exponential_jitter(max=10), + reraise=True, + retry=retry_if_exception_type(self.retry_error_types), # type: ignore + ) + async for attempt in retryer: + with attempt: + return await self._agenerate( + messages=messages, + streaming=streaming, + callbacks=callbacks, + **kwargs, + ) + except RetryError as e: + self._reporter.error(f"Error at agenerate(): {e}") + return "" + else: + # TODO: why not just throw in this case? + return "" + + def _generate( + self, + messages: str | list[Any], + streaming: bool = True, + callbacks: list[BaseLLMCallback] | None = None, + **kwargs: Any, + ) -> str: + model = self.model + if not model: + raise ValueError(_MODEL_REQUIRED_MSG) + response = self.sync_client.chat.completions.create( # type: ignore + model=model, + messages=messages, # type: ignore + stream=streaming, + **kwargs, + ) # type: ignore + if streaming: + full_response = "" + while True: + try: + chunk = response.__next__() # type: ignore + if not chunk or not chunk.choices: + continue + + delta = ( + chunk.choices[0].delta.content + if chunk.choices[0].delta and chunk.choices[0].delta.content + else "" + ) # type: ignore + + full_response += delta + if callbacks: + for callback in callbacks: + callback.on_llm_new_token(delta) + if chunk.choices[0].finish_reason == "stop": # type: ignore + break + except StopIteration: + break + return full_response + return response.choices[0].message.content or "" # type: ignore + + async def _agenerate( + self, + messages: str | list[Any], + streaming: bool = True, + callbacks: list[BaseLLMCallback] | None = None, + **kwargs: Any, + ) -> str: + model = self.model + if not model: + raise ValueError(_MODEL_REQUIRED_MSG) + response = await self.async_client.chat.completions.create( # type: ignore + model=model, + messages=messages, # type: ignore + stream=streaming, + **kwargs, + ) + if streaming: + full_response = "" + while True: + try: + chunk = await response.__anext__() # type: ignore + if not chunk or not chunk.choices: + continue + + delta = ( + chunk.choices[0].delta.content + if chunk.choices[0].delta and chunk.choices[0].delta.content + else "" + ) # type: ignore + + full_response += delta + if callbacks: + for callback in callbacks: + callback.on_llm_new_token(delta) + if chunk.choices[0].finish_reason == "stop": # type: ignore + break + except StopIteration: + break + return full_response + + return response.choices[0].message.content or "" # type: ignore diff --git a/graphrag/graphrag/query/llm/oai/embedding.py b/graphrag/graphrag/query/llm/oai/embedding.py new file mode 100644 index 0000000000000000000000000000000000000000..f40372dbcea655fb94702156e719ca7ed04cf2e4 --- /dev/null +++ b/graphrag/graphrag/query/llm/oai/embedding.py @@ -0,0 +1,182 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""OpenAI Embedding model implementation.""" + +import asyncio +from collections.abc import Callable +from typing import Any + +import numpy as np +import tiktoken +from tenacity import ( + AsyncRetrying, + RetryError, + Retrying, + retry_if_exception_type, + stop_after_attempt, + wait_exponential_jitter, +) + +from graphrag.query.llm.base import BaseTextEmbedding +from graphrag.query.llm.oai.base import OpenAILLMImpl +from graphrag.query.llm.oai.typing import ( + OPENAI_RETRY_ERROR_TYPES, + OpenaiApiType, +) +from graphrag.query.llm.text_utils import chunk_text +from graphrag.query.progress import StatusReporter + + +class OpenAIEmbedding(BaseTextEmbedding, OpenAILLMImpl): + """Wrapper for OpenAI Embedding models.""" + + def __init__( + self, + api_key: str | None = None, + azure_ad_token_provider: Callable | None = None, + model: str = "text-embedding-3-small", + deployment_name: str | None = None, + api_base: str | None = None, + api_version: str | None = None, + api_type: OpenaiApiType = OpenaiApiType.OpenAI, + organization: str | None = None, + encoding_name: str = "cl100k_base", + max_tokens: int = 8191, + max_retries: int = 10, + request_timeout: float = 180.0, + retry_error_types: tuple[type[BaseException]] = OPENAI_RETRY_ERROR_TYPES, # type: ignore + reporter: StatusReporter | None = None, + ): + OpenAILLMImpl.__init__( + self=self, + api_key=api_key, + azure_ad_token_provider=azure_ad_token_provider, + deployment_name=deployment_name, + api_base=api_base, + api_version=api_version, + api_type=api_type, # type: ignore + organization=organization, + max_retries=max_retries, + request_timeout=request_timeout, + reporter=reporter, + ) + + self.model = model + self.encoding_name = encoding_name + self.max_tokens = max_tokens + self.token_encoder = tiktoken.get_encoding(self.encoding_name) + self.retry_error_types = retry_error_types + + def embed(self, text: str, **kwargs: Any) -> list[float]: + """ + Embed text using OpenAI Embedding's sync function. + + For text longer than max_tokens, chunk texts into max_tokens, embed each chunk, then combine using weighted average. + Please refer to: https://github.com/openai/openai-cookbook/blob/main/examples/Embedding_long_inputs.ipynb + """ + token_chunks = chunk_text( + text=text, token_encoder=self.token_encoder, max_tokens=self.max_tokens + ) + chunk_embeddings = [] + chunk_lens = [] + for chunk in token_chunks: + try: + embedding, chunk_len = self._embed_with_retry(chunk, **kwargs) + chunk_embeddings.append(embedding) + chunk_lens.append(chunk_len) + # TODO: catch a more specific exception + except Exception as e: # noqa BLE001 + self._reporter.error( + message="Error embedding chunk", + details={self.__class__.__name__: str(e)}, + ) + + continue + chunk_embeddings = np.average(chunk_embeddings, axis=0, weights=chunk_lens) + chunk_embeddings = chunk_embeddings / np.linalg.norm(chunk_embeddings) + return chunk_embeddings.tolist() + + async def aembed(self, text: str, **kwargs: Any) -> list[float]: + """ + Embed text using OpenAI Embedding's async function. + + For text longer than max_tokens, chunk texts into max_tokens, embed each chunk, then combine using weighted average. + """ + token_chunks = chunk_text( + text=text, token_encoder=self.token_encoder, max_tokens=self.max_tokens + ) + chunk_embeddings = [] + chunk_lens = [] + embedding_results = await asyncio.gather(*[ + self._aembed_with_retry(chunk, **kwargs) for chunk in token_chunks + ]) + embedding_results = [result for result in embedding_results if result[0]] + chunk_embeddings = [result[0] for result in embedding_results] + chunk_lens = [result[1] for result in embedding_results] + chunk_embeddings = np.average(chunk_embeddings, axis=0, weights=chunk_lens) # type: ignore + chunk_embeddings = chunk_embeddings / np.linalg.norm(chunk_embeddings) + return chunk_embeddings.tolist() + + def _embed_with_retry( + self, text: str | tuple, **kwargs: Any + ) -> tuple[list[float], int]: + try: + retryer = Retrying( + stop=stop_after_attempt(self.max_retries), + wait=wait_exponential_jitter(max=10), + reraise=True, + retry=retry_if_exception_type(self.retry_error_types), + ) + for attempt in retryer: + with attempt: + embedding = ( + self.sync_client.embeddings.create( # type: ignore + input=text, + model=self.model, + **kwargs, # type: ignore + ) + .data[0] + .embedding + or [] + ) + return (embedding, len(text)) + except RetryError as e: + self._reporter.error( + message="Error at embed_with_retry()", + details={self.__class__.__name__: str(e)}, + ) + return ([], 0) + else: + # TODO: why not just throw in this case? + return ([], 0) + + async def _aembed_with_retry( + self, text: str | tuple, **kwargs: Any + ) -> tuple[list[float], int]: + try: + retryer = AsyncRetrying( + stop=stop_after_attempt(self.max_retries), + wait=wait_exponential_jitter(max=10), + reraise=True, + retry=retry_if_exception_type(self.retry_error_types), + ) + async for attempt in retryer: + with attempt: + embedding = ( + await self.async_client.embeddings.create( # type: ignore + input=text, + model=self.model, + **kwargs, # type: ignore + ) + ).data[0].embedding or [] + return (embedding, len(text)) + except RetryError as e: + self._reporter.error( + message="Error at embed_with_retry()", + details={self.__class__.__name__: str(e)}, + ) + return ([], 0) + else: + # TODO: why not just throw in this case? + return ([], 0) diff --git a/graphrag/graphrag/query/llm/oai/openai.py b/graphrag/graphrag/query/llm/oai/openai.py new file mode 100644 index 0000000000000000000000000000000000000000..76bb5fe52c9cba35444749e726c866308cb46aee --- /dev/null +++ b/graphrag/graphrag/query/llm/oai/openai.py @@ -0,0 +1,187 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""OpenAI Wrappers for Orchestration.""" + +import logging +from typing import Any + +from tenacity import ( + AsyncRetrying, + RetryError, + Retrying, + retry_if_exception_type, + stop_after_attempt, + wait_exponential_jitter, +) + +from graphrag.query.llm.base import BaseLLMCallback +from graphrag.query.llm.oai.base import OpenAILLMImpl +from graphrag.query.llm.oai.typing import ( + OPENAI_RETRY_ERROR_TYPES, + OpenaiApiType, +) + +log = logging.getLogger(__name__) + + +class OpenAI(OpenAILLMImpl): + """Wrapper for OpenAI Completion models.""" + + def __init__( + self, + api_key: str, + model: str, + deployment_name: str | None = None, + api_base: str | None = None, + api_version: str | None = None, + api_type: OpenaiApiType = OpenaiApiType.OpenAI, + organization: str | None = None, + max_retries: int = 10, + retry_error_types: tuple[type[BaseException]] = OPENAI_RETRY_ERROR_TYPES, # type: ignore + ): + self.api_key = api_key + self.model = model + self.deployment_name = deployment_name + self.api_base = api_base + self.api_version = api_version + self.api_type = api_type + self.organization = organization + self.max_retries = max_retries + self.retry_error_types = retry_error_types + + def generate( + self, + messages: str | list[str], + streaming: bool = True, + callbacks: list[BaseLLMCallback] | None = None, + **kwargs: Any, + ) -> str: + """Generate text.""" + try: + retryer = Retrying( + stop=stop_after_attempt(self.max_retries), + wait=wait_exponential_jitter(max=10), + reraise=True, + retry=retry_if_exception_type(self.retry_error_types), + ) + for attempt in retryer: + with attempt: + return self._generate( + messages=messages, + streaming=streaming, + callbacks=callbacks, + **kwargs, + ) + except RetryError: + log.exception("RetryError at generate(): %s") + return "" + else: + # TODO: why not just throw in this case? + return "" + + async def agenerate( + self, + messages: str | list[str], + streaming: bool = True, + callbacks: list[BaseLLMCallback] | None = None, + **kwargs: Any, + ) -> str: + """Generate Text Asynchronously.""" + try: + retryer = AsyncRetrying( + stop=stop_after_attempt(self.max_retries), + wait=wait_exponential_jitter(max=10), + reraise=True, + retry=retry_if_exception_type(self.retry_error_types), + ) + async for attempt in retryer: + with attempt: + return await self._agenerate( + messages=messages, + streaming=streaming, + callbacks=callbacks, + **kwargs, + ) + except RetryError: + log.exception("Error at agenerate()") + return "" + else: + # TODO: why not just throw in this case? + return "" + + def _generate( + self, + messages: str | list[str], + streaming: bool = True, + callbacks: list[BaseLLMCallback] | None = None, + **kwargs: Any, + ) -> str: + response = self.sync_client.chat.completions.create( # type: ignore + model=self.model, + messages=messages, # type: ignore + stream=streaming, + **kwargs, + ) # type: ignore + if streaming: + full_response = "" + while True: + try: + chunk = response.__next__() # type: ignore + if not chunk or not chunk.choices: + continue + + delta = ( + chunk.choices[0].delta.content + if chunk.choices[0].delta and chunk.choices[0].delta.content + else "" + ) # type: ignore + + full_response += delta + if callbacks: + for callback in callbacks: + callback.on_llm_new_token(delta) + if chunk.choices[0].finish_reason == "stop": # type: ignore + break + except StopIteration: + break + return full_response + return response.choices[0].message.content or "" # type: ignore + + async def _agenerate( + self, + messages: str | list[str], + streaming: bool = True, + callbacks: list[BaseLLMCallback] | None = None, + **kwargs: Any, + ) -> str: + response = await self.async_client.chat.completions.create( # type: ignore + model=self.model, + messages=messages, # type: ignore + stream=streaming, + **kwargs, + ) + if streaming: + full_response = "" + while True: + try: + chunk = await response.__anext__() # type: ignore + if not chunk or not chunk.choices: + continue + + delta = ( + chunk.choices[0].delta.content + if chunk.choices[0].delta and chunk.choices[0].delta.content + else "" + ) # type: ignore + + full_response += delta + if callbacks: + for callback in callbacks: + callback.on_llm_new_token(delta) + if chunk.choices[0].finish_reason == "stop": # type: ignore + break + except StopIteration: + break + return full_response + return response.choices[0].message.content or "" # type: ignore diff --git a/graphrag/graphrag/query/llm/oai/typing.py b/graphrag/graphrag/query/llm/oai/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..399a82f6999ebf6f24a6eebbb62f7c9629dde949 --- /dev/null +++ b/graphrag/graphrag/query/llm/oai/typing.py @@ -0,0 +1,23 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""OpenAI wrapper options.""" + +from enum import Enum +from typing import Any, cast + +import openai + +OPENAI_RETRY_ERROR_TYPES = ( + # TODO: update these when we update to OpenAI 1+ library + cast(Any, openai).RateLimitError, + cast(Any, openai).APIConnectionError, + # TODO: replace with comparable OpenAI 1+ error +) + + +class OpenaiApiType(str, Enum): + """The OpenAI Flavor.""" + + OpenAI = "openai" + AzureOpenAI = "azure" diff --git a/graphrag/graphrag/query/llm/text_utils.py b/graphrag/graphrag/query/llm/text_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..d60e630488c2eb83affbb580fa1be19262393f31 --- /dev/null +++ b/graphrag/graphrag/query/llm/text_utils.py @@ -0,0 +1,42 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Text Utilities for LLM.""" + +from collections.abc import Iterator +from itertools import islice + +import tiktoken + + +def num_tokens(text: str, token_encoder: tiktoken.Encoding | None = None) -> int: + """Return the number of tokens in the given text.""" + if token_encoder is None: + token_encoder = tiktoken.get_encoding("cl100k_base") + return len(token_encoder.encode(text)) # type: ignore + + +def batched(iterable: Iterator, n: int): + """ + Batch data into tuples of length n. The last batch may be shorter. + + Taken from Python's cookbook: https://docs.python.org/3/library/itertools.html#itertools.batched + """ + # batched('ABCDEFG', 3) --> ABC DEF G + if n < 1: + value_error = "n must be at least one" + raise ValueError(value_error) + it = iter(iterable) + while batch := tuple(islice(it, n)): + yield batch + + +def chunk_text( + text: str, max_tokens: int, token_encoder: tiktoken.Encoding | None = None +): + """Chunk text by token length.""" + if token_encoder is None: + token_encoder = tiktoken.get_encoding("cl100k_base") + tokens = token_encoder.encode(text) # type: ignore + chunk_iterator = batched(iter(tokens), max_tokens) + yield from chunk_iterator diff --git a/graphrag/graphrag/query/progress.py b/graphrag/graphrag/query/progress.py new file mode 100644 index 0000000000000000000000000000000000000000..ad5bcee7343658242ad9a415c75dcf67c36cd3a2 --- /dev/null +++ b/graphrag/graphrag/query/progress.py @@ -0,0 +1,43 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Status Reporter for orchestration.""" + +from abc import ABCMeta, abstractmethod +from typing import Any + + +class StatusReporter(metaclass=ABCMeta): + """Provides a way to report status updates from the pipeline.""" + + @abstractmethod + def error(self, message: str, details: dict[str, Any] | None = None): + """Report an error.""" + + @abstractmethod + def warning(self, message: str, details: dict[str, Any] | None = None): + """Report a warning.""" + + @abstractmethod + def log(self, message: str, details: dict[str, Any] | None = None): + """Report a log.""" + + +class ConsoleStatusReporter(StatusReporter): + """A reporter that writes to a console.""" + + def error(self, message: str, details: dict[str, Any] | None = None): + """Report an error.""" + print(message, details) # noqa T201 + + def warning(self, message: str, details: dict[str, Any] | None = None): + """Report a warning.""" + _print_warning(message) + + def log(self, message: str, details: dict[str, Any] | None = None): + """Report a log.""" + print(message, details) # noqa T201 + + +def _print_warning(skk): + print(f"\033[93m {skk}\033[00m") # noqa T201 diff --git a/graphrag/graphrag/query/question_gen/__init__.py b/graphrag/graphrag/query/question_gen/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d7329277c25e2ef20838d981a3f29f8a24316f91 --- /dev/null +++ b/graphrag/graphrag/query/question_gen/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Question Generation Module.""" diff --git a/graphrag/graphrag/query/question_gen/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/query/question_gen/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..38c68df0e3673d632bc81c145773808004f99b99 Binary files /dev/null and b/graphrag/graphrag/query/question_gen/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/question_gen/__pycache__/base.cpython-311.pyc b/graphrag/graphrag/query/question_gen/__pycache__/base.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d20d40c1bc6acdbfa4f64f924b06f500a09be0d3 Binary files /dev/null and b/graphrag/graphrag/query/question_gen/__pycache__/base.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/question_gen/__pycache__/local_gen.cpython-311.pyc b/graphrag/graphrag/query/question_gen/__pycache__/local_gen.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6c845d96733ba410a8bf9827a940325776e11f4b Binary files /dev/null and b/graphrag/graphrag/query/question_gen/__pycache__/local_gen.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/question_gen/__pycache__/system_prompt.cpython-311.pyc b/graphrag/graphrag/query/question_gen/__pycache__/system_prompt.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24cf791a220af45b76884ac0834bf67b07217d43 Binary files /dev/null and b/graphrag/graphrag/query/question_gen/__pycache__/system_prompt.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/question_gen/base.py b/graphrag/graphrag/query/question_gen/base.py new file mode 100644 index 0000000000000000000000000000000000000000..959b63d79134275ac07ac70733bc8ec63521098c --- /dev/null +++ b/graphrag/graphrag/query/question_gen/base.py @@ -0,0 +1,65 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Base classes for generating questions based on previously asked questions and most recent context data.""" + +from abc import ABC, abstractmethod +from dataclasses import dataclass +from typing import Any + +import tiktoken + +from graphrag.query.context_builder.builders import ( + GlobalContextBuilder, + LocalContextBuilder, +) +from graphrag.query.llm.base import BaseLLM + + +@dataclass +class QuestionResult: + """A Structured Question Result.""" + + response: list[str] + context_data: str | dict[str, Any] + completion_time: float + llm_calls: int + prompt_tokens: int + + +class BaseQuestionGen(ABC): + """The Base Question Gen implementation.""" + + def __init__( + self, + llm: BaseLLM, + context_builder: GlobalContextBuilder | LocalContextBuilder, + token_encoder: tiktoken.Encoding | None = None, + llm_params: dict[str, Any] | None = None, + context_builder_params: dict[str, Any] | None = None, + ): + self.llm = llm + self.context_builder = context_builder + self.token_encoder = token_encoder + self.llm_params = llm_params or {} + self.context_builder_params = context_builder_params or {} + + @abstractmethod + def generate( + self, + question_history: list[str], + context_data: str | None, + question_count: int, + **kwargs, + ) -> QuestionResult: + """Generate questions.""" + + @abstractmethod + async def agenerate( + self, + question_history: list[str], + context_data: str | None, + question_count: int, + **kwargs, + ) -> QuestionResult: + """Generate questions asynchronously.""" diff --git a/graphrag/graphrag/query/question_gen/local_gen.py b/graphrag/graphrag/query/question_gen/local_gen.py new file mode 100644 index 0000000000000000000000000000000000000000..ca703a66e34833074f027968af2b9584f215ae07 --- /dev/null +++ b/graphrag/graphrag/query/question_gen/local_gen.py @@ -0,0 +1,194 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Local question generation.""" + +import logging +import time +from typing import Any + +import tiktoken + +from graphrag.query.context_builder.builders import LocalContextBuilder +from graphrag.query.context_builder.conversation_history import ( + ConversationHistory, +) +from graphrag.query.llm.base import BaseLLM, BaseLLMCallback +from graphrag.query.llm.text_utils import num_tokens +from graphrag.query.question_gen.base import BaseQuestionGen, QuestionResult +from graphrag.query.question_gen.system_prompt import QUESTION_SYSTEM_PROMPT + +log = logging.getLogger(__name__) + + +class LocalQuestionGen(BaseQuestionGen): + """Search orchestration for global search mode.""" + + def __init__( + self, + llm: BaseLLM, + context_builder: LocalContextBuilder, + token_encoder: tiktoken.Encoding | None = None, + system_prompt: str = QUESTION_SYSTEM_PROMPT, + callbacks: list[BaseLLMCallback] | None = None, + llm_params: dict[str, Any] | None = None, + context_builder_params: dict[str, Any] | None = None, + ): + super().__init__( + llm=llm, + context_builder=context_builder, + token_encoder=token_encoder, + llm_params=llm_params, + context_builder_params=context_builder_params, + ) + self.system_prompt = system_prompt + self.callbacks = callbacks + + async def agenerate( + self, + question_history: list[str], + context_data: str | None, + question_count: int, + **kwargs, + ) -> QuestionResult: + """ + Generate a question based on the question history and context data. + + If context data is not provided, it will be generated by the local context builder + """ + start_time = time.time() + + if len(question_history) == 0: + question_text = "" + conversation_history = None + else: + # construct current query and conversation history + question_text = question_history[-1] + history = [ + {"role": "user", "content": query} for query in question_history[:-1] + ] + conversation_history = ConversationHistory.from_list(history) + + if context_data is None: + # generate context data based on the question history + context_data, context_records = self.context_builder.build_context( + query=question_text, + conversation_history=conversation_history, + **kwargs, + **self.context_builder_params, + ) # type: ignore + else: + context_records = {"context_data": context_data} + log.info("GENERATE QUESTION: %s. LAST QUESTION: %s", start_time, question_text) + system_prompt = "" + try: + system_prompt = self.system_prompt.format( + context_data=context_data, question_count=question_count + ) + question_messages = [ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": question_text}, + ] + + response = await self.llm.agenerate( + messages=question_messages, + streaming=True, + callbacks=self.callbacks, + **self.llm_params, + ) + + return QuestionResult( + response=response.split("\n"), + context_data={ + "question_context": question_text, + **context_records, + }, + completion_time=time.time() - start_time, + llm_calls=1, + prompt_tokens=num_tokens(system_prompt, self.token_encoder), + ) + + except Exception: + log.exception("Exception in generating question") + return QuestionResult( + response=[], + context_data=context_records, + completion_time=time.time() - start_time, + llm_calls=1, + prompt_tokens=num_tokens(system_prompt, self.token_encoder), + ) + + def generate( + self, + question_history: list[str], + context_data: str | None, + question_count: int, + **kwargs, + ) -> QuestionResult: + """ + Generate a question based on the question history and context data. + + If context data is not provided, it will be generated by the local context builder + """ + start_time = time.time() + if len(question_history) == 0: + question_text = "" + conversation_history = None + else: + # construct current query and conversation history + question_text = question_history[-1] + history = [ + {"role": "user", "content": query} for query in question_history[:-1] + ] + conversation_history = ConversationHistory.from_list(history) + + if context_data is None: + # generate context data based on the question history + context_data, context_records = self.context_builder.build_context( + query=question_text, + conversation_history=conversation_history, + **kwargs, + **self.context_builder_params, + ) # type: ignore + else: + context_records = {"context_data": context_data} + log.info( + "GENERATE QUESTION: %s. QUESTION HISTORY: %s", start_time, question_text + ) + system_prompt = "" + try: + system_prompt = self.system_prompt.format( + context_data=context_data, question_count=question_count + ) + question_messages = [ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": question_text}, + ] + + response = self.llm.generate( + messages=question_messages, + streaming=True, + callbacks=self.callbacks, + **self.llm_params, + ) + + return QuestionResult( + response=response.split("\n"), + context_data={ + "question_context": question_text, + **context_records, + }, + completion_time=time.time() - start_time, + llm_calls=1, + prompt_tokens=num_tokens(system_prompt, self.token_encoder), + ) + + except Exception: + log.exception("Exception in generating questions") + return QuestionResult( + response=[], + context_data=context_records, + completion_time=time.time() - start_time, + llm_calls=1, + prompt_tokens=num_tokens(system_prompt, self.token_encoder), + ) diff --git a/graphrag/graphrag/query/question_gen/system_prompt.py b/graphrag/graphrag/query/question_gen/system_prompt.py new file mode 100644 index 0000000000000000000000000000000000000000..904ede2435307ad4fde3e16798cacd50906a107b --- /dev/null +++ b/graphrag/graphrag/query/question_gen/system_prompt.py @@ -0,0 +1,28 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Question Generation system prompts.""" + +QUESTION_SYSTEM_PROMPT = """ +---Role--- + +You are a helpful assistant generating a bulleted list of {question_count} questions about data in the tables provided. + + +---Data tables--- + +{context_data} + + +---Goal--- + +Given a series of example questions provided by the user, generate a bulleted list of {question_count} candidates for the next question. Use - marks as bullet points. + +These candidate questions should represent the most important or urgent information content or themes in the data tables. + +The candidate questions should be answerable using the data tables provided, but should not mention any specific data fields or data tables in the question text. + +If the user's questions reference several named entities, then each candidate question should reference all named entities. + +---Example questions--- +""" diff --git a/graphrag/graphrag/query/structured_search/__init__.py b/graphrag/graphrag/query/structured_search/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b41baaf340404151dd0228298bd5a43adcd77ccb --- /dev/null +++ b/graphrag/graphrag/query/structured_search/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Structured Search package.""" diff --git a/graphrag/graphrag/query/structured_search/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/query/structured_search/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bef301db49167dfdb023170a56e7f457ae576aad Binary files /dev/null and b/graphrag/graphrag/query/structured_search/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/structured_search/__pycache__/base.cpython-311.pyc b/graphrag/graphrag/query/structured_search/__pycache__/base.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..963ba10d0babfbd876de81e61df38f3aac3bb554 Binary files /dev/null and b/graphrag/graphrag/query/structured_search/__pycache__/base.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/structured_search/base.py b/graphrag/graphrag/query/structured_search/base.py new file mode 100644 index 0000000000000000000000000000000000000000..6dd02485f8b09ca718cc19f13856557731618399 --- /dev/null +++ b/graphrag/graphrag/query/structured_search/base.py @@ -0,0 +1,69 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Base classes for search algos.""" + +from abc import ABC, abstractmethod +from dataclasses import dataclass +from typing import Any + +import pandas as pd +import tiktoken + +from graphrag.query.context_builder.builders import ( + GlobalContextBuilder, + LocalContextBuilder, +) +from graphrag.query.context_builder.conversation_history import ( + ConversationHistory, +) +from graphrag.query.llm.base import BaseLLM + + +@dataclass +class SearchResult: + """A Structured Search Result.""" + + response: str | dict[str, Any] | list[dict[str, Any]] + context_data: str | list[pd.DataFrame] | dict[str, pd.DataFrame] + # actual text strings that are in the context window, built from context_data + context_text: str | list[str] | dict[str, str] + completion_time: float + llm_calls: int + prompt_tokens: int + + +class BaseSearch(ABC): + """The Base Search implementation.""" + + def __init__( + self, + llm: BaseLLM, + context_builder: GlobalContextBuilder | LocalContextBuilder, + token_encoder: tiktoken.Encoding | None = None, + llm_params: dict[str, Any] | None = None, + context_builder_params: dict[str, Any] | None = None, + ): + self.llm = llm + self.context_builder = context_builder + self.token_encoder = token_encoder + self.llm_params = llm_params or {} + self.context_builder_params = context_builder_params or {} + + @abstractmethod + def search( + self, + query: str, + conversation_history: ConversationHistory | None = None, + **kwargs, + ) -> SearchResult: + """Search for the given query.""" + + @abstractmethod + async def asearch( + self, + query: str, + conversation_history: ConversationHistory | None = None, + **kwargs, + ) -> SearchResult: + """Search for the given query asynchronously.""" diff --git a/graphrag/graphrag/query/structured_search/global_search/__init__.py b/graphrag/graphrag/query/structured_search/global_search/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ba73b6090039ecf8f852449eb219b753dd7ab559 --- /dev/null +++ b/graphrag/graphrag/query/structured_search/global_search/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""GlobalSearch module.""" diff --git a/graphrag/graphrag/query/structured_search/global_search/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/query/structured_search/global_search/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92a179b2cdee46bc772be81197cc70efe22ecd26 Binary files /dev/null and b/graphrag/graphrag/query/structured_search/global_search/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/structured_search/global_search/__pycache__/community_context.cpython-311.pyc b/graphrag/graphrag/query/structured_search/global_search/__pycache__/community_context.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..871da8beed76ce6d5a3958d0edbc8a05ef8e52e0 Binary files /dev/null and b/graphrag/graphrag/query/structured_search/global_search/__pycache__/community_context.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/structured_search/global_search/__pycache__/search.cpython-311.pyc b/graphrag/graphrag/query/structured_search/global_search/__pycache__/search.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d122dc562b47e4d513470d3eea856aa70ae7924f Binary files /dev/null and b/graphrag/graphrag/query/structured_search/global_search/__pycache__/search.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/structured_search/global_search/callbacks.py b/graphrag/graphrag/query/structured_search/global_search/callbacks.py new file mode 100644 index 0000000000000000000000000000000000000000..f48bb79b828f6b9bd3adaa6fa7fafab1227a8c1e --- /dev/null +++ b/graphrag/graphrag/query/structured_search/global_search/callbacks.py @@ -0,0 +1,24 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""GlobalSearch LLM Callbacks.""" + +from graphrag.query.llm.base import BaseLLMCallback +from graphrag.query.structured_search.base import SearchResult + + +class GlobalSearchLLMCallback(BaseLLMCallback): + """GlobalSearch LLM Callbacks.""" + + def __init__(self): + super().__init__() + self.map_response_contexts = [] + self.map_response_outputs = [] + + def on_map_response_start(self, map_response_contexts: list[str]): + """Handle the start of map response.""" + self.map_response_contexts = map_response_contexts + + def on_map_response_end(self, map_response_outputs: list[SearchResult]): + """Handle the end of map response.""" + self.map_response_outputs = map_response_outputs diff --git a/graphrag/graphrag/query/structured_search/global_search/community_context.py b/graphrag/graphrag/query/structured_search/global_search/community_context.py new file mode 100644 index 0000000000000000000000000000000000000000..d63320c85ba9355f6d875c6344bc4a7ace329434 --- /dev/null +++ b/graphrag/graphrag/query/structured_search/global_search/community_context.py @@ -0,0 +1,99 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Contains algorithms to build context data for global search prompt.""" + +from typing import Any + +import pandas as pd +import tiktoken + +from graphrag.model import CommunityReport, Entity +from graphrag.query.context_builder.community_context import ( + build_community_context, +) +from graphrag.query.context_builder.conversation_history import ( + ConversationHistory, +) +from graphrag.query.structured_search.base import GlobalContextBuilder + + +class GlobalCommunityContext(GlobalContextBuilder): + """GlobalSearch community context builder.""" + + def __init__( + self, + community_reports: list[CommunityReport], + entities: list[Entity] | None = None, + token_encoder: tiktoken.Encoding | None = None, + random_state: int = 86, + ): + self.community_reports = community_reports + self.entities = entities + self.token_encoder = token_encoder + self.random_state = random_state + + def build_context( + self, + conversation_history: ConversationHistory | None = None, + use_community_summary: bool = True, + column_delimiter: str = "|", + shuffle_data: bool = True, + include_community_rank: bool = False, + min_community_rank: int = 0, + community_rank_name: str = "rank", + include_community_weight: bool = True, + community_weight_name: str = "occurrence", + normalize_community_weight: bool = True, + max_tokens: int = 8000, + context_name: str = "Reports", + conversation_history_user_turns_only: bool = True, + conversation_history_max_turns: int | None = 5, + **kwargs: Any, + ) -> tuple[str | list[str], dict[str, pd.DataFrame]]: + """Prepare batches of community report data table as context data for global search.""" + conversation_history_context = "" + final_context_data = {} + if conversation_history: + # build conversation history context + ( + conversation_history_context, + conversation_history_context_data, + ) = conversation_history.build_context( + include_user_turns_only=conversation_history_user_turns_only, + max_qa_turns=conversation_history_max_turns, + column_delimiter=column_delimiter, + max_tokens=max_tokens, + recency_bias=False, + ) + if conversation_history_context != "": + final_context_data = conversation_history_context_data + + community_context, community_context_data = build_community_context( + community_reports=self.community_reports, + entities=self.entities, + token_encoder=self.token_encoder, + use_community_summary=use_community_summary, + column_delimiter=column_delimiter, + shuffle_data=shuffle_data, + include_community_rank=include_community_rank, + min_community_rank=min_community_rank, + community_rank_name=community_rank_name, + include_community_weight=include_community_weight, + community_weight_name=community_weight_name, + normalize_community_weight=normalize_community_weight, + max_tokens=max_tokens, + single_batch=False, + context_name=context_name, + random_state=self.random_state, + ) + if isinstance(community_context, list): + final_context = [ + f"{conversation_history_context}\n\n{context}" + for context in community_context + ] + else: + final_context = f"{conversation_history_context}\n\n{community_context}" + + final_context_data.update(community_context_data) + return (final_context, final_context_data) diff --git a/graphrag/graphrag/query/structured_search/global_search/map_system_prompt.py b/graphrag/graphrag/query/structured_search/global_search/map_system_prompt.py new file mode 100644 index 0000000000000000000000000000000000000000..db1a649df336f5a83971017d5eb45e02345d8372 --- /dev/null +++ b/graphrag/graphrag/query/structured_search/global_search/map_system_prompt.py @@ -0,0 +1,82 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""System prompts for global search.""" + +MAP_SYSTEM_PROMPT = """ +---Role--- + +You are a helpful assistant responding to questions about data in the tables provided. + + +---Goal--- + +Generate a response consisting of a list of key points that responds to the user's question, summarizing all relevant information in the input data tables. + +You should use the data provided in the data tables below as the primary context for generating the response. +If you don't know the answer or if the input data tables do not contain sufficient information to provide an answer, just say so. Do not make anything up. + +Each key point in the response should have the following element: +- Description: A comprehensive description of the point. +- Importance Score: An integer score between 0-100 that indicates how important the point is in answering the user's question. An 'I don't know' type of response should have a score of 0. + +The response should be JSON formatted as follows: +{{ + "points": [ + {{"description": "Description of point 1 [Data: Reports (report ids)]", "score": score_value}}, + {{"description": "Description of point 2 [Data: Reports (report ids)]", "score": score_value}} + ] +}} + +The response shall preserve the original meaning and use of modal verbs such as "shall", "may" or "will". + +Points supported by data should list the relevant reports as references as follows: +"This is an example sentence supported by data references [Data: Reports (report ids)]" + +**Do not list more than 5 record ids in a single reference**. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + +For example: +"Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (2, 7, 64, 46, 34, +more)]. He is also CEO of company X [Data: Reports (1, 3)]" + +where 1, 2, 3, 7, 34, 46, and 64 represent the id (not the index) of the relevant data report in the provided tables. + +Do not include information where the supporting evidence for it is not provided. + + +---Data tables--- + +{context_data} + +---Goal--- + +Generate a response consisting of a list of key points that responds to the user's question, summarizing all relevant information in the input data tables. + +You should use the data provided in the data tables below as the primary context for generating the response. +If you don't know the answer or if the input data tables do not contain sufficient information to provide an answer, just say so. Do not make anything up. + +Each key point in the response should have the following element: +- Description: A comprehensive description of the point. +- Importance Score: An integer score between 0-100 that indicates how important the point is in answering the user's question. An 'I don't know' type of response should have a score of 0. + +The response shall preserve the original meaning and use of modal verbs such as "shall", "may" or "will". + +Points supported by data should list the relevant reports as references as follows: +"This is an example sentence supported by data references [Data: Reports (report ids)]" + +**Do not list more than 5 record ids in a single reference**. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + +For example: +"Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (2, 7, 64, 46, 34, +more)]. He is also CEO of company X [Data: Reports (1, 3)]" + +where 1, 2, 3, 7, 34, 46, and 64 represent the id (not the index) of the relevant data report in the provided tables. + +Do not include information where the supporting evidence for it is not provided. + +The response should be JSON formatted as follows: +{{ + "points": [ + {{"description": "Description of point 1 [Data: Reports (report ids)]", "score": score_value}}, + {{"description": "Description of point 2 [Data: Reports (report ids)]", "score": score_value}} + ] +}} +""" diff --git a/graphrag/graphrag/query/structured_search/global_search/reduce_system_prompt.py b/graphrag/graphrag/query/structured_search/global_search/reduce_system_prompt.py new file mode 100644 index 0000000000000000000000000000000000000000..701717817c99975c935697a68e3f6024ad06e91a --- /dev/null +++ b/graphrag/graphrag/query/structured_search/global_search/reduce_system_prompt.py @@ -0,0 +1,88 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Global Search system prompts.""" + +REDUCE_SYSTEM_PROMPT = """ +---Role--- + +You are a helpful assistant responding to questions about a dataset by synthesizing perspectives from multiple analysts. + + +---Goal--- + +Generate a response of the target length and format that responds to the user's question, summarize all the reports from multiple analysts who focused on different parts of the dataset. + +Note that the analysts' reports provided below are ranked in the **descending order of importance**. + +If you don't know the answer or if the provided reports do not contain sufficient information to provide an answer, just say so. Do not make anything up. + +The final response should remove all irrelevant information from the analysts' reports and merge the cleaned information into a comprehensive answer that provides explanations of all the key points and implications appropriate for the response length and format. + +Add sections and commentary to the response as appropriate for the length and format. Style the response in markdown. + +The response shall preserve the original meaning and use of modal verbs such as "shall", "may" or "will". + +The response should also preserve all the data references previously included in the analysts' reports, but do not mention the roles of multiple analysts in the analysis process. + +**Do not list more than 5 record ids in a single reference**. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + +For example: + +"Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (2, 7, 34, 46, 64, +more)]. He is also CEO of company X [Data: Reports (1, 3)]" + +where 1, 2, 3, 7, 34, 46, and 64 represent the id (not the index) of the relevant data record. + +Do not include information where the supporting evidence for it is not provided. + + +---Target response length and format--- + +{response_type} + + +---Analyst Reports--- + +{report_data} + + +---Goal--- + +Generate a response of the target length and format that responds to the user's question, summarize all the reports from multiple analysts who focused on different parts of the dataset. + +Note that the analysts' reports provided below are ranked in the **descending order of importance**. + +If you don't know the answer or if the provided reports do not contain sufficient information to provide an answer, just say so. Do not make anything up. + +The final response should remove all irrelevant information from the analysts' reports and merge the cleaned information into a comprehensive answer that provides explanations of all the key points and implications appropriate for the response length and format. + +The response shall preserve the original meaning and use of modal verbs such as "shall", "may" or "will". + +The response should also preserve all the data references previously included in the analysts' reports, but do not mention the roles of multiple analysts in the analysis process. + +**Do not list more than 5 record ids in a single reference**. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + +For example: + +"Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (2, 7, 34, 46, 64, +more)]. He is also CEO of company X [Data: Reports (1, 3)]" + +where 1, 2, 3, 7, 34, 46, and 64 represent the id (not the index) of the relevant data record. + +Do not include information where the supporting evidence for it is not provided. + + +---Target response length and format--- + +{response_type} + +Add sections and commentary to the response as appropriate for the length and format. Style the response in markdown. +""" + +NO_DATA_ANSWER = ( + "I am sorry but I am unable to answer this question given the provided data." +) + +GENERAL_KNOWLEDGE_INSTRUCTION = """ +The response may also include relevant real-world knowledge outside the dataset, but it must be explicitly annotated with a verification tag [LLM: verify]. For example: +"This is an example sentence supported by real-world knowledge [LLM: verify]." +""" diff --git a/graphrag/graphrag/query/structured_search/global_search/search.py b/graphrag/graphrag/query/structured_search/global_search/search.py new file mode 100644 index 0000000000000000000000000000000000000000..3b52ecbd8ca8f0ea08316b2cdfa334950fe201d1 --- /dev/null +++ b/graphrag/graphrag/query/structured_search/global_search/search.py @@ -0,0 +1,347 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The GlobalSearch Implementation.""" + +import asyncio +import json +import logging +import time +from dataclasses import dataclass +from typing import Any + +import pandas as pd +import tiktoken + +from graphrag.index.utils.json import clean_up_json +from graphrag.query.context_builder.builders import GlobalContextBuilder +from graphrag.query.context_builder.conversation_history import ( + ConversationHistory, +) +from graphrag.query.llm.base import BaseLLM +from graphrag.query.llm.text_utils import num_tokens +from graphrag.query.structured_search.base import BaseSearch, SearchResult +from graphrag.query.structured_search.global_search.callbacks import ( + GlobalSearchLLMCallback, +) +from graphrag.query.structured_search.global_search.map_system_prompt import ( + MAP_SYSTEM_PROMPT, +) +from graphrag.query.structured_search.global_search.reduce_system_prompt import ( + GENERAL_KNOWLEDGE_INSTRUCTION, + NO_DATA_ANSWER, + REDUCE_SYSTEM_PROMPT, +) + +DEFAULT_MAP_LLM_PARAMS = { + "max_tokens": 1000, + "temperature": 0.0, +} + +DEFAULT_REDUCE_LLM_PARAMS = { + "max_tokens": 2000, + "temperature": 0.0, +} + +log = logging.getLogger(__name__) + + +@dataclass +class GlobalSearchResult(SearchResult): + """A GlobalSearch result.""" + + map_responses: list[SearchResult] + reduce_context_data: str | list[pd.DataFrame] | dict[str, pd.DataFrame] + reduce_context_text: str | list[str] | dict[str, str] + + +class GlobalSearch(BaseSearch): + """Search orchestration for global search mode.""" + + def __init__( + self, + llm: BaseLLM, + context_builder: GlobalContextBuilder, + token_encoder: tiktoken.Encoding | None = None, + map_system_prompt: str = MAP_SYSTEM_PROMPT, + reduce_system_prompt: str = REDUCE_SYSTEM_PROMPT, + response_type: str = "multiple paragraphs", + allow_general_knowledge: bool = False, + general_knowledge_inclusion_prompt: str = GENERAL_KNOWLEDGE_INSTRUCTION, + json_mode: bool = True, + callbacks: list[GlobalSearchLLMCallback] | None = None, + max_data_tokens: int = 8000, + map_llm_params: dict[str, Any] = DEFAULT_MAP_LLM_PARAMS, + reduce_llm_params: dict[str, Any] = DEFAULT_REDUCE_LLM_PARAMS, + context_builder_params: dict[str, Any] | None = None, + concurrent_coroutines: int = 32, + ): + super().__init__( + llm=llm, + context_builder=context_builder, + token_encoder=token_encoder, + context_builder_params=context_builder_params, + ) + self.map_system_prompt = map_system_prompt + self.reduce_system_prompt = reduce_system_prompt + self.response_type = response_type + self.allow_general_knowledge = allow_general_knowledge + self.general_knowledge_inclusion_prompt = general_knowledge_inclusion_prompt + self.callbacks = callbacks + self.max_data_tokens = max_data_tokens + + self.map_llm_params = map_llm_params + self.reduce_llm_params = reduce_llm_params + if json_mode: + self.map_llm_params["response_format"] = {"type": "json_object"} + else: + # remove response_format key if json_mode is False + self.map_llm_params.pop("response_format", None) + + self.semaphore = asyncio.Semaphore(concurrent_coroutines) + + async def asearch( + self, + query: str, + conversation_history: ConversationHistory | None = None, + **kwargs: Any, + ) -> GlobalSearchResult: + """ + Perform a global search. + + Global search mode includes two steps: + + - Step 1: Run parallel LLM calls on communities' short summaries to generate answer for each batch + - Step 2: Combine the answers from step 2 to generate the final answer + """ + # Step 1: Generate answers for each batch of community short summaries + start_time = time.time() + context_chunks, context_records = self.context_builder.build_context( + conversation_history=conversation_history, **self.context_builder_params + ) + + if self.callbacks: + for callback in self.callbacks: + callback.on_map_response_start(context_chunks) # type: ignore + map_responses = await asyncio.gather(*[ + self._map_response_single_batch( + context_data=data, query=query, **self.map_llm_params + ) + for data in context_chunks + ]) + if self.callbacks: + for callback in self.callbacks: + callback.on_map_response_end(map_responses) + map_llm_calls = sum(response.llm_calls for response in map_responses) + map_prompt_tokens = sum(response.prompt_tokens for response in map_responses) + + # Step 2: Combine the intermediate answers from step 2 to generate the final answer + reduce_response = await self._reduce_response( + map_responses=map_responses, + query=query, + **self.reduce_llm_params, + ) + + return GlobalSearchResult( + response=reduce_response.response, + context_data=context_records, + context_text=context_chunks, + map_responses=map_responses, + reduce_context_data=reduce_response.context_data, + reduce_context_text=reduce_response.context_text, + completion_time=time.time() - start_time, + llm_calls=map_llm_calls + reduce_response.llm_calls, + prompt_tokens=map_prompt_tokens + reduce_response.prompt_tokens, + ) + + def search( + self, + query: str, + conversation_history: ConversationHistory | None = None, + **kwargs: Any, + ) -> GlobalSearchResult: + """Perform a global search synchronously.""" + return asyncio.run(self.asearch(query, conversation_history)) + + async def _map_response_single_batch( + self, + context_data: str, + query: str, + **llm_kwargs, + ) -> SearchResult: + """Generate answer for a single chunk of community reports.""" + start_time = time.time() + search_prompt = "" + try: + search_prompt = self.map_system_prompt.format(context_data=context_data) + search_messages = [ + {"role": "system", "content": search_prompt}, + {"role": "user", "content": query}, + ] + async with self.semaphore: + search_response = await self.llm.agenerate( + messages=search_messages, streaming=False, **llm_kwargs + ) + log.info("Map response: %s", search_response) + try: + # parse search response json + processed_response = self.parse_search_response(search_response) + except ValueError: + # Clean up and retry parse + search_response = clean_up_json(search_response) + try: + # parse search response json + processed_response = self.parse_search_response(search_response) + except ValueError: + log.exception("Error parsing search response json") + processed_response = [] + + return SearchResult( + response=processed_response, + context_data=context_data, + context_text=context_data, + completion_time=time.time() - start_time, + llm_calls=1, + prompt_tokens=num_tokens(search_prompt, self.token_encoder), + ) + + except Exception: + log.exception("Exception in _map_response_single_batch") + return SearchResult( + response=[{"answer": "", "score": 0}], + context_data=context_data, + context_text=context_data, + completion_time=time.time() - start_time, + llm_calls=1, + prompt_tokens=num_tokens(search_prompt, self.token_encoder), + ) + + def parse_search_response(self, search_response: str) -> list[dict[str, Any]]: + """Parse the search response json and return a list of key points. + + Parameters + ---------- + search_response: str + The search response json string + + Returns + ------- + list[dict[str, Any]] + A list of key points, each key point is a dictionary with "answer" and "score" keys + """ + parsed_elements = json.loads(search_response)["points"] + return [ + { + "answer": element["description"], + "score": int(element["score"]), + } + for element in parsed_elements + ] + + async def _reduce_response( + self, + map_responses: list[SearchResult], + query: str, + **llm_kwargs, + ) -> SearchResult: + """Combine all intermediate responses from single batches into a final answer to the user query.""" + text_data = "" + search_prompt = "" + start_time = time.time() + try: + # collect all key points into a single list to prepare for sorting + key_points = [] + for index, response in enumerate(map_responses): + if not isinstance(response.response, list): + continue + for element in response.response: + if not isinstance(element, dict): + continue + if "answer" not in element or "score" not in element: + continue + key_points.append({ + "analyst": index, + "answer": element["answer"], + "score": element["score"], + }) + + # filter response with score = 0 and rank responses by descending order of score + filtered_key_points = [ + point + for point in key_points + if point["score"] > 0 # type: ignore + ] + + if len(filtered_key_points) == 0 and not self.allow_general_knowledge: + # return no data answer if no key points are found + return SearchResult( + response=NO_DATA_ANSWER, + context_data="", + context_text="", + completion_time=time.time() - start_time, + llm_calls=0, + prompt_tokens=0, + ) + + filtered_key_points = sorted( + filtered_key_points, + key=lambda x: x["score"], # type: ignore + reverse=True, # type: ignore + ) + + data = [] + total_tokens = 0 + for point in filtered_key_points: + formatted_response_data = [] + formatted_response_data.append( + f'----Analyst {point["analyst"] + 1}----' + ) + formatted_response_data.append( + f'Importance Score: {point["score"]}' # type: ignore + ) + formatted_response_data.append(point["answer"]) # type: ignore + formatted_response_text = "\n".join(formatted_response_data) + if ( + total_tokens + + num_tokens(formatted_response_text, self.token_encoder) + > self.max_data_tokens + ): + break + data.append(formatted_response_text) + total_tokens += num_tokens(formatted_response_text, self.token_encoder) + text_data = "\n\n".join(data) + + search_prompt = self.reduce_system_prompt.format( + report_data=text_data, response_type=self.response_type + ) + if self.allow_general_knowledge: + search_prompt += "\n" + self.general_knowledge_inclusion_prompt + search_messages = [ + {"role": "system", "content": search_prompt}, + {"role": "user", "content": query}, + ] + + search_response = await self.llm.agenerate( + search_messages, + streaming=True, + callbacks=self.callbacks, # type: ignore + **llm_kwargs, # type: ignore + ) + return SearchResult( + response=search_response, + context_data=text_data, + context_text=text_data, + completion_time=time.time() - start_time, + llm_calls=1, + prompt_tokens=num_tokens(search_prompt, self.token_encoder), + ) + except Exception: + log.exception("Exception in reduce_response") + return SearchResult( + response="", + context_data=text_data, + context_text=text_data, + completion_time=time.time() - start_time, + llm_calls=1, + prompt_tokens=num_tokens(search_prompt, self.token_encoder), + ) diff --git a/graphrag/graphrag/query/structured_search/local_search/__init__.py b/graphrag/graphrag/query/structured_search/local_search/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8b8b1e790e0006d71bbbadeba7b751fa263bd894 --- /dev/null +++ b/graphrag/graphrag/query/structured_search/local_search/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The LocalSearch package.""" diff --git a/graphrag/graphrag/query/structured_search/local_search/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/query/structured_search/local_search/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aeb7e300ab28d8a59d52a578fea4dc2d9cf79847 Binary files /dev/null and b/graphrag/graphrag/query/structured_search/local_search/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/structured_search/local_search/__pycache__/mixed_context.cpython-311.pyc b/graphrag/graphrag/query/structured_search/local_search/__pycache__/mixed_context.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..56c3e1a4b3e843c7cbef14fb266839e0bd9b656d Binary files /dev/null and b/graphrag/graphrag/query/structured_search/local_search/__pycache__/mixed_context.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/structured_search/local_search/__pycache__/search.cpython-311.pyc b/graphrag/graphrag/query/structured_search/local_search/__pycache__/search.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f790ddab2b08042df7d970f34cb70ea09c0e21d Binary files /dev/null and b/graphrag/graphrag/query/structured_search/local_search/__pycache__/search.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/structured_search/local_search/__pycache__/system_prompt.cpython-311.pyc b/graphrag/graphrag/query/structured_search/local_search/__pycache__/system_prompt.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed1605af23210eff9f0c01cc7dc309b9cd3f0bcc Binary files /dev/null and b/graphrag/graphrag/query/structured_search/local_search/__pycache__/system_prompt.cpython-311.pyc differ diff --git a/graphrag/graphrag/query/structured_search/local_search/mixed_context.py b/graphrag/graphrag/query/structured_search/local_search/mixed_context.py new file mode 100644 index 0000000000000000000000000000000000000000..117101e913597bcf4772d3a453939fa531d61cf9 --- /dev/null +++ b/graphrag/graphrag/query/structured_search/local_search/mixed_context.py @@ -0,0 +1,497 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +"""Algorithms to build context data for local search prompt.""" + +import logging +from typing import Any + +import pandas as pd +import tiktoken + +from graphrag.model import ( + CommunityReport, + Covariate, + Entity, + Relationship, + TextUnit, +) +from graphrag.query.context_builder.community_context import ( + build_community_context, +) +from graphrag.query.context_builder.conversation_history import ( + ConversationHistory, +) +from graphrag.query.context_builder.entity_extraction import ( + EntityVectorStoreKey, + map_query_to_entities, +) +from graphrag.query.context_builder.local_context import ( + build_covariates_context, + build_entity_context, + build_relationship_context, + get_candidate_context, +) +from graphrag.query.context_builder.source_context import ( + build_text_unit_context, + count_relationships, +) +from graphrag.query.input.retrieval.community_reports import ( + get_candidate_communities, +) +from graphrag.query.input.retrieval.text_units import get_candidate_text_units +from graphrag.query.llm.base import BaseTextEmbedding +from graphrag.query.llm.text_utils import num_tokens +from graphrag.query.structured_search.base import LocalContextBuilder +from graphrag.vector_stores import BaseVectorStore + +log = logging.getLogger(__name__) + + +class LocalSearchMixedContext(LocalContextBuilder): + """Build data context for local search prompt combining community reports and entity/relationship/covariate tables.""" + + def __init__( + self, + entities: list[Entity], + entity_text_embeddings: BaseVectorStore, + text_embedder: BaseTextEmbedding, + text_units: list[TextUnit] | None = None, + community_reports: list[CommunityReport] | None = None, + relationships: list[Relationship] | None = None, + covariates: dict[str, list[Covariate]] | None = None, + token_encoder: tiktoken.Encoding | None = None, + embedding_vectorstore_key: str = EntityVectorStoreKey.ID, + ): + if community_reports is None: + community_reports = [] + if relationships is None: + relationships = [] + if covariates is None: + covariates = {} + if text_units is None: + text_units = [] + self.entities = {entity.id: entity for entity in entities} + self.community_reports = { + community.id: community for community in community_reports + } + self.text_units = {unit.id: unit for unit in text_units} + self.relationships = { + relationship.id: relationship for relationship in relationships + } + self.covariates = covariates + self.entity_text_embeddings = entity_text_embeddings + self.text_embedder = text_embedder + self.token_encoder = token_encoder + self.embedding_vectorstore_key = embedding_vectorstore_key + + def filter_by_entity_keys(self, entity_keys: list[int] | list[str]): + """Filter entity text embeddings by entity keys.""" + self.entity_text_embeddings.filter_by_id(entity_keys) + + def build_context( + self, + query: str, + conversation_history: ConversationHistory | None = None, + include_entity_names: list[str] | None = None, + exclude_entity_names: list[str] | None = None, + conversation_history_max_turns: int | None = 5, + conversation_history_user_turns_only: bool = True, + max_tokens: int = 8000, + text_unit_prop: float = 0.5, + community_prop: float = 0.25, + top_k_mapped_entities: int = 10, + top_k_relationships: int = 10, + include_community_rank: bool = False, + include_entity_rank: bool = False, + rank_description: str = "number of relationships", + include_relationship_weight: bool = False, + relationship_ranking_attribute: str = "rank", + return_candidate_context: bool = False, + use_community_summary: bool = False, + min_community_rank: int = 0, + community_context_name: str = "Reports", + column_delimiter: str = "|", + **kwargs: dict[str, Any], + ) -> tuple[str | list[str], dict[str, pd.DataFrame]]: + """ + Build data context for local search prompt. + + Build a context by combining community reports and entity/relationship/covariate tables, and text units using a predefined ratio set by summary_prop. + """ + if include_entity_names is None: + include_entity_names = [] + if exclude_entity_names is None: + exclude_entity_names = [] + if community_prop + text_unit_prop > 1: + value_error = ( + "The sum of community_prop and text_unit_prop should not exceed 1." + ) + raise ValueError(value_error) + + # map user query to entities + # if there is conversation history, attached the previous user questions to the current query + if conversation_history: + pre_user_questions = "\n".join( + conversation_history.get_user_turns(conversation_history_max_turns) + ) + query = f"{query}\n{pre_user_questions}" + + selected_entities = map_query_to_entities( + query=query, + text_embedding_vectorstore=self.entity_text_embeddings, + text_embedder=self.text_embedder, + all_entities=list(self.entities.values()), + embedding_vectorstore_key=self.embedding_vectorstore_key, + include_entity_names=include_entity_names, + exclude_entity_names=exclude_entity_names, + k=top_k_mapped_entities, + oversample_scaler=2, + ) + + # build context + final_context = list[str]() + final_context_data = dict[str, pd.DataFrame]() + + if conversation_history: + # build conversation history context + ( + conversation_history_context, + conversation_history_context_data, + ) = conversation_history.build_context( + include_user_turns_only=conversation_history_user_turns_only, + max_qa_turns=conversation_history_max_turns, + column_delimiter=column_delimiter, + max_tokens=max_tokens, + recency_bias=False, + ) + if conversation_history_context.strip() != "": + final_context.append(conversation_history_context) + final_context_data = conversation_history_context_data + max_tokens = max_tokens - num_tokens( + conversation_history_context, self.token_encoder + ) + + # build community context + community_tokens = max(int(max_tokens * community_prop), 0) + community_context, community_context_data = self._build_community_context( + selected_entities=selected_entities, + max_tokens=community_tokens, + use_community_summary=use_community_summary, + column_delimiter=column_delimiter, + include_community_rank=include_community_rank, + min_community_rank=min_community_rank, + return_candidate_context=return_candidate_context, + context_name=community_context_name, + ) + if community_context.strip() != "": + final_context.append(community_context) + final_context_data = {**final_context_data, **community_context_data} + + # build local (i.e. entity-relationship-covariate) context + local_prop = 1 - community_prop - text_unit_prop + local_tokens = max(int(max_tokens * local_prop), 0) + local_context, local_context_data = self._build_local_context( + selected_entities=selected_entities, + max_tokens=local_tokens, + include_entity_rank=include_entity_rank, + rank_description=rank_description, + include_relationship_weight=include_relationship_weight, + top_k_relationships=top_k_relationships, + relationship_ranking_attribute=relationship_ranking_attribute, + return_candidate_context=return_candidate_context, + column_delimiter=column_delimiter, + ) + if local_context.strip() != "": + final_context.append(str(local_context)) + final_context_data = {**final_context_data, **local_context_data} + + # build text unit context + text_unit_tokens = max(int(max_tokens * text_unit_prop), 0) + text_unit_context, text_unit_context_data = self._build_text_unit_context( + selected_entities=selected_entities, + max_tokens=text_unit_tokens, + return_candidate_context=return_candidate_context, + ) + if text_unit_context.strip() != "": + final_context.append(text_unit_context) + final_context_data = {**final_context_data, **text_unit_context_data} + + return ("\n\n".join(final_context), final_context_data) + + def _build_community_context( + self, + selected_entities: list[Entity], + max_tokens: int = 4000, + use_community_summary: bool = False, + column_delimiter: str = "|", + include_community_rank: bool = False, + min_community_rank: int = 0, + return_candidate_context: bool = False, + context_name: str = "Reports", + ) -> tuple[str, dict[str, pd.DataFrame]]: + """Add community data to the context window until it hits the max_tokens limit.""" + if len(selected_entities) == 0 or len(self.community_reports) == 0: + return ("", {context_name.lower(): pd.DataFrame()}) + + community_matches = {} + for entity in selected_entities: + # increase count of the community that this entity belongs to + if entity.community_ids: + for community_id in entity.community_ids: + community_matches[community_id] = ( + community_matches.get(community_id, 0) + 1 + ) + + # sort communities by number of matched entities and rank + selected_communities = [ + self.community_reports[community_id] + for community_id in community_matches + if community_id in self.community_reports + ] + for community in selected_communities: + if community.attributes is None: + community.attributes = {} + community.attributes["matches"] = community_matches[community.id] + selected_communities.sort( + key=lambda x: (x.attributes["matches"], x.rank), # type: ignore + reverse=True, # type: ignore + ) + for community in selected_communities: + del community.attributes["matches"] # type: ignore + + context_text, context_data = build_community_context( + community_reports=selected_communities, + token_encoder=self.token_encoder, + use_community_summary=use_community_summary, + column_delimiter=column_delimiter, + shuffle_data=False, + include_community_rank=include_community_rank, + min_community_rank=min_community_rank, + max_tokens=max_tokens, + single_batch=True, + context_name=context_name, + ) + if isinstance(context_text, list) and len(context_text) > 0: + context_text = "\n\n".join(context_text) + + if return_candidate_context: + candidate_context_data = get_candidate_communities( + selected_entities=selected_entities, + community_reports=list(self.community_reports.values()), + use_community_summary=use_community_summary, + include_community_rank=include_community_rank, + ) + context_key = context_name.lower() + if context_key not in context_data: + context_data[context_key] = candidate_context_data + context_data[context_key]["in_context"] = False + else: + if ( + "id" in candidate_context_data.columns + and "id" in context_data[context_key].columns + ): + candidate_context_data["in_context"] = candidate_context_data[ + "id" + ].isin( # cspell:disable-line + context_data[context_key]["id"] + ) + context_data[context_key] = candidate_context_data + else: + context_data[context_key]["in_context"] = True + return (str(context_text), context_data) + + def _build_text_unit_context( + self, + selected_entities: list[Entity], + max_tokens: int = 8000, + return_candidate_context: bool = False, + column_delimiter: str = "|", + context_name: str = "Sources", + ) -> tuple[str, dict[str, pd.DataFrame]]: + """Rank matching text units and add them to the context window until it hits the max_tokens limit.""" + if len(selected_entities) == 0 or len(self.text_units) == 0: + return ("", {context_name.lower(): pd.DataFrame()}) + + selected_text_units = list[TextUnit]() + # for each matching text unit, rank first by the order of the entities that match it, then by the number of matching relationships + # that the text unit has with the matching entities + for index, entity in enumerate(selected_entities): + if entity.text_unit_ids: + for text_id in entity.text_unit_ids: + if ( + text_id not in [unit.id for unit in selected_text_units] + and text_id in self.text_units + ): + selected_unit = self.text_units[text_id] + num_relationships = count_relationships( + selected_unit, entity, self.relationships + ) + if selected_unit.attributes is None: + selected_unit.attributes = {} + selected_unit.attributes["entity_order"] = index + selected_unit.attributes["num_relationships"] = ( + num_relationships + ) + selected_text_units.append(selected_unit) + + # sort selected text units by ascending order of entity order and descending order of number of relationships + selected_text_units.sort( + key=lambda x: ( + x.attributes["entity_order"], # type: ignore + -x.attributes["num_relationships"], # type: ignore + ) + ) + + for unit in selected_text_units: + del unit.attributes["entity_order"] # type: ignore + del unit.attributes["num_relationships"] # type: ignore + + context_text, context_data = build_text_unit_context( + text_units=selected_text_units, + token_encoder=self.token_encoder, + max_tokens=max_tokens, + shuffle_data=False, + context_name=context_name, + column_delimiter=column_delimiter, + ) + + if return_candidate_context: + candidate_context_data = get_candidate_text_units( + selected_entities=selected_entities, + text_units=list(self.text_units.values()), + ) + context_key = context_name.lower() + if context_key not in context_data: + context_data[context_key] = candidate_context_data + context_data[context_key]["in_context"] = False + else: + if ( + "id" in candidate_context_data.columns + and "id" in context_data[context_key].columns + ): + candidate_context_data["in_context"] = candidate_context_data[ + "id" + ].isin( # cspell:disable-line + context_data[context_key]["id"] + ) + context_data[context_key] = candidate_context_data + else: + context_data[context_key]["in_context"] = True + return (str(context_text), context_data) + + def _build_local_context( + self, + selected_entities: list[Entity], + max_tokens: int = 8000, + include_entity_rank: bool = False, + rank_description: str = "relationship count", + include_relationship_weight: bool = False, + top_k_relationships: int = 10, + relationship_ranking_attribute: str = "rank", + return_candidate_context: bool = False, + column_delimiter: str = "|", + ) -> tuple[str, dict[str, pd.DataFrame]]: + """Build data context for local search prompt combining entity/relationship/covariate tables.""" + # build entity context + entity_context, entity_context_data = build_entity_context( + selected_entities=selected_entities, + token_encoder=self.token_encoder, + max_tokens=max_tokens, + column_delimiter=column_delimiter, + include_entity_rank=include_entity_rank, + rank_description=rank_description, + context_name="Entities", + ) + entity_tokens = num_tokens(entity_context, self.token_encoder) + + # build relationship-covariate context + added_entities = [] + final_context = [] + final_context_data = {} + + # gradually add entities and associated metadata to the context until we reach limit + for entity in selected_entities: + current_context = [] + current_context_data = {} + added_entities.append(entity) + + # build relationship context + ( + relationship_context, + relationship_context_data, + ) = build_relationship_context( + selected_entities=added_entities, + relationships=list(self.relationships.values()), + token_encoder=self.token_encoder, + max_tokens=max_tokens, + column_delimiter=column_delimiter, + top_k_relationships=top_k_relationships, + include_relationship_weight=include_relationship_weight, + relationship_ranking_attribute=relationship_ranking_attribute, + context_name="Relationships", + ) + current_context.append(relationship_context) + current_context_data["relationships"] = relationship_context_data + total_tokens = entity_tokens + num_tokens( + relationship_context, self.token_encoder + ) + + # build covariate context + for covariate in self.covariates: + covariate_context, covariate_context_data = build_covariates_context( + selected_entities=added_entities, + covariates=self.covariates[covariate], + token_encoder=self.token_encoder, + max_tokens=max_tokens, + column_delimiter=column_delimiter, + context_name=covariate, + ) + total_tokens += num_tokens(covariate_context, self.token_encoder) + current_context.append(covariate_context) + current_context_data[covariate.lower()] = covariate_context_data + + if total_tokens > max_tokens: + log.info("Reached token limit - reverting to previous context state") + break + + final_context = current_context + final_context_data = current_context_data + + # attach entity context to final context + final_context_text = entity_context + "\n\n" + "\n\n".join(final_context) + final_context_data["entities"] = entity_context_data + + if return_candidate_context: + # we return all the candidate entities/relationships/covariates (not only those that were fitted into the context window) + # and add a tag to indicate which records were included in the context window + candidate_context_data = get_candidate_context( + selected_entities=selected_entities, + entities=list(self.entities.values()), + relationships=list(self.relationships.values()), + covariates=self.covariates, + include_entity_rank=include_entity_rank, + entity_rank_description=rank_description, + include_relationship_weight=include_relationship_weight, + ) + for key in candidate_context_data: + candidate_df = candidate_context_data[key] + if key not in final_context_data: + final_context_data[key] = candidate_df + final_context_data[key]["in_context"] = False + else: + in_context_df = final_context_data[key] + + if "id" in in_context_df.columns and "id" in candidate_df.columns: + candidate_df["in_context"] = candidate_df[ + "id" + ].isin( # cspell:disable-line + in_context_df["id"] + ) + final_context_data[key] = candidate_df + else: + final_context_data[key]["in_context"] = True + + else: + for key in final_context_data: + final_context_data[key]["in_context"] = True + return (final_context_text, final_context_data) diff --git a/graphrag/graphrag/query/structured_search/local_search/search.py b/graphrag/graphrag/query/structured_search/local_search/search.py new file mode 100644 index 0000000000000000000000000000000000000000..80dd6670041ba15fe760b482b689335b3d6a7dbf --- /dev/null +++ b/graphrag/graphrag/query/structured_search/local_search/search.py @@ -0,0 +1,159 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""LocalSearch implementation.""" + +import logging +import time +from typing import Any + +import tiktoken + +from graphrag.query.context_builder.builders import LocalContextBuilder +from graphrag.query.context_builder.conversation_history import ( + ConversationHistory, +) +from graphrag.query.llm.base import BaseLLM, BaseLLMCallback +from graphrag.query.llm.text_utils import num_tokens +from graphrag.query.structured_search.base import BaseSearch, SearchResult +from graphrag.query.structured_search.local_search.system_prompt import ( + LOCAL_SEARCH_SYSTEM_PROMPT, +) + +DEFAULT_LLM_PARAMS = { + "max_tokens": 1500, + "temperature": 0.0, +} + +log = logging.getLogger(__name__) + + +class LocalSearch(BaseSearch): + """Search orchestration for local search mode.""" + + def __init__( + self, + llm: BaseLLM, + context_builder: LocalContextBuilder, + token_encoder: tiktoken.Encoding | None = None, + system_prompt: str = LOCAL_SEARCH_SYSTEM_PROMPT, + response_type: str = "multiple paragraphs", + callbacks: list[BaseLLMCallback] | None = None, + llm_params: dict[str, Any] = DEFAULT_LLM_PARAMS, + context_builder_params: dict | None = None, + ): + super().__init__( + llm=llm, + context_builder=context_builder, + token_encoder=token_encoder, + llm_params=llm_params, + context_builder_params=context_builder_params or {}, + ) + self.system_prompt = system_prompt + self.callbacks = callbacks + self.response_type = response_type + + async def asearch( + self, + query: str, + conversation_history: ConversationHistory | None = None, + **kwargs, + ) -> SearchResult: + """Build local search context that fits a single context window and generate answer for the user query.""" + start_time = time.time() + search_prompt = "" + + context_text, context_records = self.context_builder.build_context( + query=query, + conversation_history=conversation_history, + **kwargs, + **self.context_builder_params, + ) + log.info("GENERATE ANSWER: %s. QUERY: %s", start_time, query) + try: + search_prompt = self.system_prompt.format( + context_data=context_text, response_type=self.response_type + ) + search_messages = [ + {"role": "system", "content": search_prompt}, + {"role": "user", "content": query}, + ] + + response = await self.llm.agenerate( + messages=search_messages, + streaming=True, + callbacks=self.callbacks, + **self.llm_params, + ) + + return SearchResult( + response=response, + context_data=context_records, + context_text=context_text, + completion_time=time.time() - start_time, + llm_calls=1, + prompt_tokens=num_tokens(search_prompt, self.token_encoder), + ) + + except Exception: + log.exception("Exception in _asearch") + return SearchResult( + response="", + context_data=context_records, + context_text=context_text, + completion_time=time.time() - start_time, + llm_calls=1, + prompt_tokens=num_tokens(search_prompt, self.token_encoder), + ) + + def search( + self, + query: str, + conversation_history: ConversationHistory | None = None, + **kwargs, + ) -> SearchResult: + """Build local search context that fits a single context window and generate answer for the user question.""" + start_time = time.time() + search_prompt = "" + context_text, context_records = self.context_builder.build_context( + query=query, + conversation_history=conversation_history, + **kwargs, + **self.context_builder_params, + ) + log.info("GENERATE ANSWER: %d. QUERY: %s", start_time, query) + try: + search_prompt = self.system_prompt.format( + context_data=context_text, response_type=self.response_type + ) + search_messages = [ + {"role": "system", "content": search_prompt}, + {"role": "user", "content": query}, + ] + + response = self.llm.generate( + messages=search_messages, + streaming=True, + callbacks=self.callbacks, + **self.llm_params, + ) + + return SearchResult( + response=response, + context_data=context_records, + context_text=context_text, + completion_time=time.time() - start_time, + llm_calls=1, + prompt_tokens=num_tokens(search_prompt, self.token_encoder), + ) + + except Exception: + log.exception("Exception in _map_response_single_batch") + return SearchResult( + response="", + context_data=context_records, + context_text=context_text, + completion_time=time.time() - start_time, + llm_calls=1, + prompt_tokens=num_tokens(search_prompt, self.token_encoder), + ) diff --git a/graphrag/graphrag/query/structured_search/local_search/system_prompt.py b/graphrag/graphrag/query/structured_search/local_search/system_prompt.py new file mode 100644 index 0000000000000000000000000000000000000000..70b1d12fc3883811d033a681bba04154eacc249f --- /dev/null +++ b/graphrag/graphrag/query/structured_search/local_search/system_prompt.py @@ -0,0 +1,69 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Local search system prompts.""" + +LOCAL_SEARCH_SYSTEM_PROMPT = """ +---Role--- + +You are a helpful assistant responding to questions about data in the tables provided. + + +---Goal--- + +Generate a response of the target length and format that responds to the user's question, summarizing all information in the input data tables appropriate for the response length and format, and incorporating any relevant general knowledge. + +If you don't know the answer, just say so. Do not make anything up. + +Points supported by data should list their data references as follows: + +"This is an example sentence supported by multiple data references [Data: (record ids); (record ids)]." + +Do not list more than 5 record ids in a single reference. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + +For example: + +"Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Sources (15, 16), Reports (1), Entities (5, 7); Relationships (23); Claims (2, 7, 34, 46, 64, +more)]." + +where 15, 16, 1, 5, 7, 23, 2, 7, 34, 46, and 64 represent the id (not the index) of the relevant data record. + +Do not include information where the supporting evidence for it is not provided. + + +---Target response length and format--- + +{response_type} + + +---Data tables--- + +{context_data} + + +---Goal--- + +Generate a response of the target length and format that responds to the user's question, summarizing all information in the input data tables appropriate for the response length and format, and incorporating any relevant general knowledge. + +If you don't know the answer, just say so. Do not make anything up. + +Points supported by data should list their data references as follows: + +"This is an example sentence supported by multiple data references [Data: (record ids); (record ids)]." + +Do not list more than 5 record ids in a single reference. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + +For example: + +"Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Sources (15, 16), Reports (1), Entities (5, 7); Relationships (23); Claims (2, 7, 34, 46, 64, +more)]." + +where 15, 16, 1, 5, 7, 23, 2, 7, 34, 46, and 64 represent the id (not the index) of the relevant data record. + +Do not include information where the supporting evidence for it is not provided. + + +---Target response length and format--- + +{response_type} + +Add sections and commentary to the response as appropriate for the length and format. Style the response in markdown. +""" diff --git a/graphrag/graphrag/vector_stores/__init__.py b/graphrag/graphrag/vector_stores/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d4c11760aab9c29d020f7bb3053453971bdd9935 --- /dev/null +++ b/graphrag/graphrag/vector_stores/__init__.py @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A package containing vector-storage implementations.""" + +from .azure_ai_search import AzureAISearch +from .base import BaseVectorStore, VectorStoreDocument, VectorStoreSearchResult +from .lancedb import LanceDBVectorStore +from .typing import VectorStoreFactory, VectorStoreType + +__all__ = [ + "AzureAISearch", + "BaseVectorStore", + "LanceDBVectorStore", + "VectorStoreDocument", + "VectorStoreFactory", + "VectorStoreSearchResult", + "VectorStoreType", +] diff --git a/graphrag/graphrag/vector_stores/__pycache__/__init__.cpython-311.pyc b/graphrag/graphrag/vector_stores/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..908ab77a85481bbddd5da8c51e801e63fbc8da93 Binary files /dev/null and b/graphrag/graphrag/vector_stores/__pycache__/__init__.cpython-311.pyc differ diff --git a/graphrag/graphrag/vector_stores/__pycache__/azure_ai_search.cpython-311.pyc b/graphrag/graphrag/vector_stores/__pycache__/azure_ai_search.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f15fcdc9cfadd88446056c4702a2f7baafa55982 Binary files /dev/null and b/graphrag/graphrag/vector_stores/__pycache__/azure_ai_search.cpython-311.pyc differ diff --git a/graphrag/graphrag/vector_stores/__pycache__/base.cpython-311.pyc b/graphrag/graphrag/vector_stores/__pycache__/base.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3461a6fd0de0b4119272549d41d9ec3a74c4e927 Binary files /dev/null and b/graphrag/graphrag/vector_stores/__pycache__/base.cpython-311.pyc differ diff --git a/graphrag/graphrag/vector_stores/__pycache__/lancedb.cpython-311.pyc b/graphrag/graphrag/vector_stores/__pycache__/lancedb.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7205d3688f79a7aec6b604dc60ea286f163e9de3 Binary files /dev/null and b/graphrag/graphrag/vector_stores/__pycache__/lancedb.cpython-311.pyc differ diff --git a/graphrag/graphrag/vector_stores/__pycache__/typing.cpython-311.pyc b/graphrag/graphrag/vector_stores/__pycache__/typing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b45a70d7101b06674f65e4943f30785aa84eccc Binary files /dev/null and b/graphrag/graphrag/vector_stores/__pycache__/typing.cpython-311.pyc differ diff --git a/graphrag/graphrag/vector_stores/azure_ai_search.py b/graphrag/graphrag/vector_stores/azure_ai_search.py new file mode 100644 index 0000000000000000000000000000000000000000..c503fca1c1b0160feef31dad4820c69e79a2e401 --- /dev/null +++ b/graphrag/graphrag/vector_stores/azure_ai_search.py @@ -0,0 +1,194 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A package containing the Azure AI Search vector store implementation.""" + +import json +from typing import Any + +from azure.core.credentials import AzureKeyCredential +from azure.identity import DefaultAzureCredential +from azure.search.documents import SearchClient +from azure.search.documents.indexes import SearchIndexClient +from azure.search.documents.indexes.models import ( + HnswAlgorithmConfiguration, + HnswParameters, + SearchableField, + SearchField, + SearchFieldDataType, + SearchIndex, + SimpleField, + VectorSearch, + VectorSearchAlgorithmMetric, + VectorSearchProfile, +) +from azure.search.documents.models import VectorizedQuery + +from graphrag.model.types import TextEmbedder + +from .base import ( + DEFAULT_VECTOR_SIZE, + BaseVectorStore, + VectorStoreDocument, + VectorStoreSearchResult, +) + + +class AzureAISearch(BaseVectorStore): + """The Azure AI Search vector storage implementation.""" + + index_client: SearchIndexClient + + def connect(self, **kwargs: Any) -> Any: + """Connect to the AzureAI vector store.""" + url = kwargs.get("url", None) + api_key = kwargs.get("api_key", None) + audience = kwargs.get("audience", None) + self.vector_size = kwargs.get("vector_size", DEFAULT_VECTOR_SIZE) + + self.vector_search_profile_name = kwargs.get( + "vector_search_profile_name", "vectorSearchProfile" + ) + + if url: + audience_arg = {"audience": audience} if audience else {} + self.db_connection = SearchClient( + endpoint=url, + index_name=self.collection_name, + credential=AzureKeyCredential(api_key) + if api_key + else DefaultAzureCredential(), + **audience_arg, + ) + self.index_client = SearchIndexClient( + endpoint=url, + credential=AzureKeyCredential(api_key) + if api_key + else DefaultAzureCredential(), + **audience_arg, + ) + else: + not_supported_error = "AAISearchDBClient is not supported on local host." + raise ValueError(not_supported_error) + + def load_documents( + self, documents: list[VectorStoreDocument], overwrite: bool = True + ) -> None: + """Load documents into the Azure AI Search index.""" + if overwrite: + if self.collection_name in self.index_client.list_index_names(): + self.index_client.delete_index(self.collection_name) + + # Configure the vector search profile + vector_search = VectorSearch( + algorithms=[ + HnswAlgorithmConfiguration( + name="HnswAlg", + parameters=HnswParameters( + metric=VectorSearchAlgorithmMetric.COSINE + ), + ) + ], + profiles=[ + VectorSearchProfile( + name=self.vector_search_profile_name, + algorithm_configuration_name="HnswAlg", + ) + ], + ) + + index = SearchIndex( + name=self.collection_name, + fields=[ + SimpleField( + name="id", + type=SearchFieldDataType.String, + key=True, + ), + SearchField( + name="vector", + type=SearchFieldDataType.Collection(SearchFieldDataType.Single), + searchable=True, + vector_search_dimensions=self.vector_size, + vector_search_profile_name=self.vector_search_profile_name, + ), + SearchableField(name="text", type=SearchFieldDataType.String), + SimpleField( + name="attributes", + type=SearchFieldDataType.String, + ), + ], + vector_search=vector_search, + ) + + self.index_client.create_or_update_index( + index, + ) + + batch = [ + { + "id": doc.id, + "vector": doc.vector, + "text": doc.text, + "attributes": json.dumps(doc.attributes), + } + for doc in documents + if doc.vector is not None + ] + + if batch and len(batch) > 0: + self.db_connection.upload_documents(batch) + + def filter_by_id(self, include_ids: list[str] | list[int]) -> Any: + """Build a query filter to filter documents by a list of ids.""" + if include_ids is None or len(include_ids) == 0: + self.query_filter = None + # Returning to keep consistency with other methods, but not needed + return self.query_filter + + # More info about odata filtering here: https://learn.microsoft.com/en-us/azure/search/search-query-odata-search-in-function + # search.in is faster that joined and/or conditions + id_filter = ",".join([f"{id!s}" for id in include_ids]) + self.query_filter = f"search.in(id, '{id_filter}', ',')" + + # Returning to keep consistency with other methods, but not needed + # TODO: Refactor on a future PR + return self.query_filter + + def similarity_search_by_vector( + self, query_embedding: list[float], k: int = 10, **kwargs: Any + ) -> list[VectorStoreSearchResult]: + """Perform a vector-based similarity search.""" + vectorized_query = VectorizedQuery( + vector=query_embedding, k_nearest_neighbors=k, fields="vector" + ) + + response = self.db_connection.search( + vector_queries=[vectorized_query], + ) + + return [ + VectorStoreSearchResult( + document=VectorStoreDocument( + id=doc.get("id", ""), + text=doc.get("text", ""), + vector=doc.get("vector", []), + attributes=(json.loads(doc.get("attributes", "{}"))), + ), + # Cosine similarity between 0.333 and 1.000 + # https://learn.microsoft.com/en-us/azure/search/hybrid-search-ranking#scores-in-a-hybrid-search-results + score=doc["@search.score"], + ) + for doc in response + ] + + def similarity_search_by_text( + self, text: str, text_embedder: TextEmbedder, k: int = 10, **kwargs: Any + ) -> list[VectorStoreSearchResult]: + """Perform a text-based similarity search.""" + query_embedding = text_embedder(text) + if query_embedding: + return self.similarity_search_by_vector( + query_embedding=query_embedding, k=k + ) + return [] diff --git a/graphrag/graphrag/vector_stores/base.py b/graphrag/graphrag/vector_stores/base.py new file mode 100644 index 0000000000000000000000000000000000000000..38f0e584fc022180a48274611f16c521b3b13161 --- /dev/null +++ b/graphrag/graphrag/vector_stores/base.py @@ -0,0 +1,81 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""Base classes for vector stores.""" + +from abc import ABC, abstractmethod +from dataclasses import dataclass, field +from typing import Any + +from graphrag.model.types import TextEmbedder + +DEFAULT_VECTOR_SIZE: int = 1536 + + +@dataclass +class VectorStoreDocument: + """A document that is stored in vector storage.""" + + id: str | int + """unique id for the document""" + + text: str | None + vector: list[float] | None + + attributes: dict[str, Any] = field(default_factory=dict) + """store any additional metadata, e.g. title, date ranges, etc""" + + +@dataclass +class VectorStoreSearchResult: + """A vector storage search result.""" + + document: VectorStoreDocument + """Document that was found.""" + + score: float + """Similarity score between 0 and 1. Higher is more similar.""" + + +class BaseVectorStore(ABC): + """The base class for vector storage data-access classes.""" + + def __init__( + self, + collection_name: str, + db_connection: Any | None = None, + document_collection: Any | None = None, + query_filter: Any | None = None, + **kwargs: Any, + ): + self.collection_name = collection_name + self.db_connection = db_connection + self.document_collection = document_collection + self.query_filter = query_filter + self.kwargs = kwargs + + @abstractmethod + def connect(self, **kwargs: Any) -> None: + """Connect to vector storage.""" + + @abstractmethod + def load_documents( + self, documents: list[VectorStoreDocument], overwrite: bool = True + ) -> None: + """Load documents into the vector-store.""" + + @abstractmethod + def similarity_search_by_vector( + self, query_embedding: list[float], k: int = 10, **kwargs: Any + ) -> list[VectorStoreSearchResult]: + """Perform ANN search by vector.""" + + @abstractmethod + def similarity_search_by_text( + self, text: str, text_embedder: TextEmbedder, k: int = 10, **kwargs: Any + ) -> list[VectorStoreSearchResult]: + """Perform ANN search by text.""" + + @abstractmethod + def filter_by_id(self, include_ids: list[str] | list[int]) -> Any: + """Build a query filter to filter documents by id.""" diff --git a/graphrag/graphrag/vector_stores/lancedb.py b/graphrag/graphrag/vector_stores/lancedb.py new file mode 100644 index 0000000000000000000000000000000000000000..0c9ea17f546aefdc5ebac7c5d278ca95c4cc0d81 --- /dev/null +++ b/graphrag/graphrag/vector_stores/lancedb.py @@ -0,0 +1,121 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""The LanceDB vector storage implementation package.""" + +import lancedb as lancedb # noqa: I001 (Ruff was breaking on this file imports, even tho they were sorted and passed local tests) +from graphrag.model.types import TextEmbedder + +import json +from typing import Any + +import pyarrow as pa + +from .base import ( + BaseVectorStore, + VectorStoreDocument, + VectorStoreSearchResult, +) + + +class LanceDBVectorStore(BaseVectorStore): + """The LanceDB vector storage implementation.""" + + def connect(self, **kwargs: Any) -> Any: + """Connect to the vector storage.""" + db_uri = kwargs.get("db_uri", "./lancedb") + self.db_connection = lancedb.connect(db_uri) # type: ignore + + def load_documents( + self, documents: list[VectorStoreDocument], overwrite: bool = True + ) -> None: + """Load documents into vector storage.""" + data = [ + { + "id": document.id, + "text": document.text, + "vector": document.vector, + "attributes": json.dumps(document.attributes), + } + for document in documents + if document.vector is not None + ] + + if len(data) == 0: + data = None + + schema = pa.schema([ + pa.field("id", pa.string()), + pa.field("text", pa.string()), + pa.field("vector", pa.list_(pa.float64())), + pa.field("attributes", pa.string()), + ]) + if overwrite: + if data: + self.document_collection = self.db_connection.create_table( + self.collection_name, data=data, mode="overwrite" + ) + else: + self.document_collection = self.db_connection.create_table( + self.collection_name, schema=schema, mode="overwrite" + ) + else: + # add data to existing table + self.document_collection = self.db_connection.open_table( + self.collection_name + ) + if data: + self.document_collection.add(data) + + def filter_by_id(self, include_ids: list[str] | list[int]) -> Any: + """Build a query filter to filter documents by id.""" + if len(include_ids) == 0: + self.query_filter = None + else: + if isinstance(include_ids[0], str): + id_filter = ", ".join([f"'{id}'" for id in include_ids]) + self.query_filter = f"id in ({id_filter})" + else: + self.query_filter = ( + f"id in ({', '.join([str(id) for id in include_ids])})" + ) + return self.query_filter + + def similarity_search_by_vector( + self, query_embedding: list[float], k: int = 10, **kwargs: Any + ) -> list[VectorStoreSearchResult]: + """Perform a vector-based similarity search.""" + if self.query_filter: + docs = ( + self.document_collection.search(query=query_embedding) + .where(self.query_filter, prefilter=True) + .limit(k) + .to_list() + ) + else: + docs = ( + self.document_collection.search(query=query_embedding) + .limit(k) + .to_list() + ) + return [ + VectorStoreSearchResult( + document=VectorStoreDocument( + id=doc["id"], + text=doc["text"], + vector=doc["vector"], + attributes=json.loads(doc["attributes"]), + ), + score=1 - abs(float(doc["_distance"])), + ) + for doc in docs + ] + + def similarity_search_by_text( + self, text: str, text_embedder: TextEmbedder, k: int = 10, **kwargs: Any + ) -> list[VectorStoreSearchResult]: + """Perform a similarity search using a given input text.""" + query_embedding = text_embedder(text) + if query_embedding: + return self.similarity_search_by_vector(query_embedding, k) + return [] diff --git a/graphrag/graphrag/vector_stores/typing.py b/graphrag/graphrag/vector_stores/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..0b5a5cd19552d5f55aa4840e94b1eea1a3e185ea --- /dev/null +++ b/graphrag/graphrag/vector_stores/typing.py @@ -0,0 +1,44 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A package containing the supported vector store types.""" + +from enum import Enum +from typing import ClassVar + +from .azure_ai_search import AzureAISearch +from .lancedb import LanceDBVectorStore + + +class VectorStoreType(str, Enum): + """The supported vector store types.""" + + LanceDB = "lancedb" + AzureAISearch = "azure_ai_search" + + +class VectorStoreFactory: + """A factory class for creating vector stores.""" + + vector_store_types: ClassVar[dict[str, type]] = {} + + @classmethod + def register(cls, vector_store_type: str, vector_store: type): + """Register a vector store type.""" + cls.vector_store_types[vector_store_type] = vector_store + + @classmethod + def get_vector_store( + cls, vector_store_type: VectorStoreType | str, kwargs: dict + ) -> LanceDBVectorStore | AzureAISearch: + """Get the vector store type from a string.""" + match vector_store_type: + case VectorStoreType.LanceDB: + return LanceDBVectorStore(**kwargs) + case VectorStoreType.AzureAISearch: + return AzureAISearch(**kwargs) + case _: + if vector_store_type in cls.vector_store_types: + return cls.vector_store_types[vector_store_type](**kwargs) + msg = f"Unknown vector store type: {vector_store_type}" + raise ValueError(msg) diff --git a/graphrag/poetry.lock b/graphrag/poetry.lock new file mode 100644 index 0000000000000000000000000000000000000000..c4158330b2622ba62353be8087efb1ad0930b609 --- /dev/null +++ b/graphrag/poetry.lock @@ -0,0 +1,5107 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + +[[package]] +name = "aiofiles" +version = "24.1.0" +description = "File support for asyncio." +optional = false +python-versions = ">=3.8" +files = [ + {file = "aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5"}, + {file = "aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c"}, +] + +[[package]] +name = "aiolimiter" +version = "1.1.0" +description = "asyncio rate limiter, a leaky bucket implementation" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "aiolimiter-1.1.0-py3-none-any.whl", hash = "sha256:0b4997961fc58b8df40279e739f9cf0d3e255e63e9a44f64df567a8c17241e24"}, + {file = "aiolimiter-1.1.0.tar.gz", hash = "sha256:461cf02f82a29347340d031626c92853645c099cb5ff85577b831a7bd21132b5"}, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[[package]] +name = "anyio" +version = "4.4.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.8" +files = [ + {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, + {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, +] + +[package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} +idna = ">=2.8" +sniffio = ">=1.1" +typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} + +[package.extras] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.23)"] + +[[package]] +name = "anytree" +version = "2.12.1" +description = "Powerful and Lightweight Python Tree Data Structure with various plugins" +optional = false +python-versions = ">=3.7.2,<4" +files = [ + {file = "anytree-2.12.1-py3-none-any.whl", hash = "sha256:5ea9e61caf96db1e5b3d0a914378d2cd83c269dfce1fb8242ce96589fa3382f0"}, + {file = "anytree-2.12.1.tar.gz", hash = "sha256:244def434ccf31b668ed282954e5d315b4e066c4940b94aff4a7962d85947830"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "appnope" +version = "0.1.4" +description = "Disable App Nap on macOS >= 10.9" +optional = false +python-versions = ">=3.6" +files = [ + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, +] + +[[package]] +name = "argon2-cffi" +version = "23.1.0" +description = "Argon2 for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea"}, + {file = "argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08"}, +] + +[package.dependencies] +argon2-cffi-bindings = "*" + +[package.extras] +dev = ["argon2-cffi[tests,typing]", "tox (>4)"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-copybutton", "sphinx-notfound-page"] +tests = ["hypothesis", "pytest"] +typing = ["mypy"] + +[[package]] +name = "argon2-cffi-bindings" +version = "21.2.0" +description = "Low-level CFFI bindings for Argon2" +optional = false +python-versions = ">=3.6" +files = [ + {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f"}, + {file = "argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"}, +] + +[package.dependencies] +cffi = ">=1.0.1" + +[package.extras] +dev = ["cogapp", "pre-commit", "pytest", "wheel"] +tests = ["pytest"] + +[[package]] +name = "arrow" +version = "1.3.0" +description = "Better dates & times for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"}, + {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"}, +] + +[package.dependencies] +python-dateutil = ">=2.7.0" +types-python-dateutil = ">=2.8.10" + +[package.extras] +doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] +test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] + +[[package]] +name = "asttokens" +version = "2.4.1" +description = "Annotate AST trees with source code positions" +optional = false +python-versions = "*" +files = [ + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, +] + +[package.dependencies] +six = ">=1.12.0" + +[package.extras] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] + +[[package]] +name = "async-lru" +version = "2.0.4" +description = "Simple LRU cache for asyncio" +optional = false +python-versions = ">=3.8" +files = [ + {file = "async-lru-2.0.4.tar.gz", hash = "sha256:b8a59a5df60805ff63220b2a0c5b5393da5521b113cd5465a44eb037d81a5627"}, + {file = "async_lru-2.0.4-py3-none-any.whl", hash = "sha256:ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} + +[[package]] +name = "attrs" +version = "23.2.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, +] + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] + +[[package]] +name = "autograd" +version = "1.6.2" +description = "Efficiently computes derivatives of numpy code." +optional = false +python-versions = "*" +files = [ + {file = "autograd-1.6.2-py3-none-any.whl", hash = "sha256:208dde2a938e63b4f8f5049b1985505139e529068b0d26f8cd7771fd3eb145d5"}, + {file = "autograd-1.6.2.tar.gz", hash = "sha256:8731e08a0c4e389d8695a40072ada4512641c113b6cace8f4cfbe8eb7e9aedeb"}, +] + +[package.dependencies] +future = ">=0.15.2" +numpy = ">=1.12" + +[[package]] +name = "azure-common" +version = "1.1.28" +description = "Microsoft Azure Client Library for Python (Common)" +optional = false +python-versions = "*" +files = [ + {file = "azure-common-1.1.28.zip", hash = "sha256:4ac0cd3214e36b6a1b6a442686722a5d8cc449603aa833f3f0f40bda836704a3"}, + {file = "azure_common-1.1.28-py2.py3-none-any.whl", hash = "sha256:5c12d3dcf4ec20599ca6b0d3e09e86e146353d443e7fcc050c9a19c1f9df20ad"}, +] + +[[package]] +name = "azure-core" +version = "1.30.2" +description = "Microsoft Azure Core Library for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "azure-core-1.30.2.tar.gz", hash = "sha256:a14dc210efcd608821aa472d9fb8e8d035d29b68993819147bc290a8ac224472"}, + {file = "azure_core-1.30.2-py3-none-any.whl", hash = "sha256:cf019c1ca832e96274ae85abd3d9f752397194d9fea3b41487290562ac8abe4a"}, +] + +[package.dependencies] +requests = ">=2.21.0" +six = ">=1.11.0" +typing-extensions = ">=4.6.0" + +[package.extras] +aio = ["aiohttp (>=3.0)"] + +[[package]] +name = "azure-identity" +version = "1.17.1" +description = "Microsoft Azure Identity Library for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "azure-identity-1.17.1.tar.gz", hash = "sha256:32ecc67cc73f4bd0595e4f64b1ca65cd05186f4fe6f98ed2ae9f1aa32646efea"}, + {file = "azure_identity-1.17.1-py3-none-any.whl", hash = "sha256:db8d59c183b680e763722bfe8ebc45930e6c57df510620985939f7f3191e0382"}, +] + +[package.dependencies] +azure-core = ">=1.23.0" +cryptography = ">=2.5" +msal = ">=1.24.0" +msal-extensions = ">=0.3.0" +typing-extensions = ">=4.0.0" + +[[package]] +name = "azure-search-documents" +version = "11.5.0" +description = "Microsoft Azure Cognitive Search Client Library for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "azure_search_documents-11.5.0-py3-none-any.whl", hash = "sha256:e973df13fc46c1c1bfa3760d74b45ca6ef928816e0f8c7df0c68171a428365ac"}, + {file = "azure_search_documents-11.5.0.tar.gz", hash = "sha256:13883d12c833b66546c188cce847de6fa67b83545cb21163d8956ac031e53cf8"}, +] + +[package.dependencies] +azure-common = ">=1.1" +azure-core = ">=1.28.0" +isodate = ">=0.6.0" +typing-extensions = ">=4.6.0" + +[[package]] +name = "azure-storage-blob" +version = "12.20.0" +description = "Microsoft Azure Blob Storage Client Library for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "azure-storage-blob-12.20.0.tar.gz", hash = "sha256:eeb91256e41d4b5b9bad6a87fd0a8ade07dd58aa52344e2c8d2746e27a017d3b"}, + {file = "azure_storage_blob-12.20.0-py3-none-any.whl", hash = "sha256:de6b3bf3a90e9341a6bcb96a2ebe981dffff993e9045818f6549afea827a52a9"}, +] + +[package.dependencies] +azure-core = ">=1.28.0" +cryptography = ">=2.1.4" +isodate = ">=0.6.1" +typing-extensions = ">=4.6.0" + +[package.extras] +aio = ["azure-core[aio] (>=1.28.0)"] + +[[package]] +name = "babel" +version = "2.15.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.8" +files = [ + {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, + {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, +] + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + +[[package]] +name = "beartype" +version = "0.18.5" +description = "Unbearably fast runtime type checking in pure Python." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "beartype-0.18.5-py3-none-any.whl", hash = "sha256:5301a14f2a9a5540fe47ec6d34d758e9cd8331d36c4760fc7a5499ab86310089"}, + {file = "beartype-0.18.5.tar.gz", hash = "sha256:264ddc2f1da9ec94ff639141fbe33d22e12a9f75aa863b83b7046ffff1381927"}, +] + +[package.extras] +all = ["typing-extensions (>=3.10.0.0)"] +dev = ["autoapi (>=0.9.0)", "coverage (>=5.5)", "equinox", "mypy (>=0.800)", "numpy", "pandera", "pydata-sphinx-theme (<=0.7.2)", "pytest (>=4.0.0)", "sphinx", "sphinx (>=4.2.0,<6.0.0)", "sphinxext-opengraph (>=0.7.5)", "tox (>=3.20.1)", "typing-extensions (>=3.10.0.0)"] +doc-rtd = ["autoapi (>=0.9.0)", "pydata-sphinx-theme (<=0.7.2)", "sphinx (>=4.2.0,<6.0.0)", "sphinxext-opengraph (>=0.7.5)"] +test-tox = ["equinox", "mypy (>=0.800)", "numpy", "pandera", "pytest (>=4.0.0)", "sphinx", "typing-extensions (>=3.10.0.0)"] +test-tox-coverage = ["coverage (>=5.5)"] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +cchardet = ["cchardet"] +chardet = ["chardet"] +charset-normalizer = ["charset-normalizer"] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[[package]] +name = "bleach" +version = "6.1.0" +description = "An easy safelist-based HTML-sanitizing tool." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"}, + {file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"}, +] + +[package.dependencies] +six = ">=1.9.0" +webencodings = "*" + +[package.extras] +css = ["tinycss2 (>=1.1.0,<1.3)"] + +[[package]] +name = "cachetools" +version = "5.4.0" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.4.0-py3-none-any.whl", hash = "sha256:3ae3b49a3d5e28a77a0be2b37dbcb89005058959cb2323858c2657c4a8cab474"}, + {file = "cachetools-5.4.0.tar.gz", hash = "sha256:b8adc2e7c07f105ced7bc56dbb6dfbe7c4a00acce20e2227b3f355be89bc6827"}, +] + +[[package]] +name = "certifi" +version = "2024.7.4" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, +] + +[[package]] +name = "cffi" +version = "1.16.0" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, + {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, + {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, + {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, + {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, + {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, + {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, + {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, + {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, + {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, + {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, + {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, + {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, + {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "cloudpickle" +version = "3.0.0" +description = "Pickler class to extend the standard pickle.Pickler functionality" +optional = false +python-versions = ">=3.8" +files = [ + {file = "cloudpickle-3.0.0-py3-none-any.whl", hash = "sha256:246ee7d0c295602a036e86369c77fecda4ab17b506496730f2f576d9016fd9c7"}, + {file = "cloudpickle-3.0.0.tar.gz", hash = "sha256:996d9a482c6fb4f33c1a35335cf8afd065d2a56e973270364840712d9131a882"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "comm" +version = "0.2.2" +description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." +optional = false +python-versions = ">=3.8" +files = [ + {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"}, + {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, +] + +[package.dependencies] +traitlets = ">=4" + +[package.extras] +test = ["pytest"] + +[[package]] +name = "contourpy" +version = "1.2.1" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = false +python-versions = ">=3.9" +files = [ + {file = "contourpy-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040"}, + {file = "contourpy-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b"}, + {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd"}, + {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619"}, + {file = "contourpy-1.2.1-cp310-cp310-win32.whl", hash = "sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8"}, + {file = "contourpy-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9"}, + {file = "contourpy-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5"}, + {file = "contourpy-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df"}, + {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205"}, + {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8"}, + {file = "contourpy-1.2.1-cp311-cp311-win32.whl", hash = "sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec"}, + {file = "contourpy-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922"}, + {file = "contourpy-1.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc"}, + {file = "contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b"}, + {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce"}, + {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4"}, + {file = "contourpy-1.2.1-cp312-cp312-win32.whl", hash = "sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f"}, + {file = "contourpy-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce"}, + {file = "contourpy-1.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb6834cbd983b19f06908b45bfc2dad6ac9479ae04abe923a275b5f48f1a186b"}, + {file = "contourpy-1.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1d59e739ab0e3520e62a26c60707cc3ab0365d2f8fecea74bfe4de72dc56388f"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd3db01f59fdcbce5b22afad19e390260d6d0222f35a1023d9adc5690a889364"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a12a813949e5066148712a0626895c26b2578874e4cc63160bb007e6df3436fe"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe0ccca550bb8e5abc22f530ec0466136379c01321fd94f30a22231e8a48d985"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1d59258c3c67c865435d8fbeb35f8c59b8bef3d6f46c1f29f6123556af28445"}, + {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f32c38afb74bd98ce26de7cc74a67b40afb7b05aae7b42924ea990d51e4dac02"}, + {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d31a63bc6e6d87f77d71e1abbd7387ab817a66733734883d1fc0021ed9bfa083"}, + {file = "contourpy-1.2.1-cp39-cp39-win32.whl", hash = "sha256:ddcb8581510311e13421b1f544403c16e901c4e8f09083c881fab2be80ee31ba"}, + {file = "contourpy-1.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:10a37ae557aabf2509c79715cd20b62e4c7c28b8cd62dd7d99e5ed3ce28c3fd9"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a31f94983fecbac95e58388210427d68cd30fe8a36927980fab9c20062645609"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef2b055471c0eb466033760a521efb9d8a32b99ab907fc8358481a1dd29e3bd3"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b33d2bc4f69caedcd0a275329eb2198f560b325605810895627be5d4b876bf7f"}, + {file = "contourpy-1.2.1.tar.gz", hash = "sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c"}, +] + +[package.dependencies] +numpy = ">=1.20" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.8.0)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] + +[[package]] +name = "coverage" +version = "7.6.0" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, + {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, + {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, + {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, + {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, + {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, + {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"}, + {file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"}, + {file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, + {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, + {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, + {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, + {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, +] + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "cramjam" +version = "2.8.3" +description = "Thin Python bindings to de/compression algorithms in Rust" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cramjam-2.8.3-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8c8aa6d08c135ae7f0da01e6559a332c5d8fe4989a594db401040e385d04dffd"}, + {file = "cramjam-2.8.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:bd8c601fe8717e52517a2f2eef78217086acf449627bfdda97e3f53fd79c92af"}, + {file = "cramjam-2.8.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:dac42b2b4c3950e7eda9b5551e0e904784ed0c0428accc29171c230fb919ec72"}, + {file = "cramjam-2.8.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab8146faa5d8c52edf23724843c36469fc32ff2c4a174eba72f4da6de5016688"}, + {file = "cramjam-2.8.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb5f4d061e9abdc6663551446c332a58c101efb31fd1746229872600274c2b20"}, + {file = "cramjam-2.8.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d1ac94e00c64258330105473c641441db02b4dc3e9e9f2963d204e53ed93025"}, + {file = "cramjam-2.8.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ed658f36a2bf667d5b8c7c6690103ad99f81cc62a1b64891b69298447329d4b"}, + {file = "cramjam-2.8.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f6303c8cc583dfe5054cf84717674f75b18bca4ae8e576dc863958d5494dc4b"}, + {file = "cramjam-2.8.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:04b31d427a8902e5c2eec4b8f29873de7a3ade202e3d68e7f2354b9f0aa00bc7"}, + {file = "cramjam-2.8.3-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:9728861bc0390681824961778b36f7f0b95039e8b90d46f1b67f51232f1ee159"}, + {file = "cramjam-2.8.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:87e26e3e1d5fed1cac5b41be648d0daf0793f94cf4a7aebefce1f4f6656e2d21"}, + {file = "cramjam-2.8.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4c1d2d39c2193a77c5e5b327944f90e6ecf2caa1b55e7176cc83d80706ea15de"}, + {file = "cramjam-2.8.3-cp310-none-win32.whl", hash = "sha256:6721edd8f911ad84db83ee4902b7579fc01c55849062f3f1f4171b58fccf98eb"}, + {file = "cramjam-2.8.3-cp310-none-win_amd64.whl", hash = "sha256:4f7c16d358df366e308137411125a2bb50d1b19924fced3a390898fa8c9a074d"}, + {file = "cramjam-2.8.3-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:24c2b426dd8fafb894f93a88f42e2827e14199d66836cb100582037e5371c724"}, + {file = "cramjam-2.8.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:007aa9444cb27b8691baae73ca907133cd939987438f874774011b4c740732dd"}, + {file = "cramjam-2.8.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:29987b54e31efed66738e8f236c597c4c9a91ec9d57bcb74307712e07505b4bb"}, + {file = "cramjam-2.8.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65bfd41aa92c0025f32ba09214b48e9367a81122586b2617439b4327c4bd179c"}, + {file = "cramjam-2.8.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7337bd8218bd8508f35904274a38cce843a237fe6e23104238bbeb2f337107ed"}, + {file = "cramjam-2.8.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:269f94d2efe6b6a97624782cd3b541e60535dd5874f4a8d5d0ba66ef59424ae3"}, + {file = "cramjam-2.8.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bec9ca5431c32ba94996b7c1c56695b37d48713b97ee1d2a456f4046f009e82f"}, + {file = "cramjam-2.8.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2cb64a97e625ca029b55e37769b8c354e64cbea042c75471915dc385935d30ed"}, + {file = "cramjam-2.8.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c28830ecf76501356d678dac4f37563554ec1c651a53a990cdf595f7ed75c651"}, + {file = "cramjam-2.8.3-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35647a0e37a4dfec85a44c7966ae476b7db0e6cd65d91c08f1fb3007ed774d92"}, + {file = "cramjam-2.8.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e954599c6369f429a868852eff453b894d88866acba439b65131ea93f5400b47"}, + {file = "cramjam-2.8.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:86e238b6de79e045f5197df2c9dfaf8d10b37a6517ff4ffc4775fe5a3cf4d4a4"}, + {file = "cramjam-2.8.3-cp311-none-win32.whl", hash = "sha256:fe6434d3ee0899bc9396801d1abbc5d1fe77662bd3d1f1c1573fac6708459138"}, + {file = "cramjam-2.8.3-cp311-none-win_amd64.whl", hash = "sha256:e8ec1d4f27eb9d0412f0c567e7ffd14fbeb2b318a1ac394d5de4047c431fe94c"}, + {file = "cramjam-2.8.3-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:24990be4010b2185dcecc67133cd727657036e7b132d7de598148f5b1eb8e452"}, + {file = "cramjam-2.8.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:572cb9a8dc5a189691d6e03a9bf9b4305fd9a9f36bb0f9fde55fc36837c2e6b3"}, + {file = "cramjam-2.8.3-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9efe6915aa7ef176f3a7f42a4e46504573215953331b139abefd20d07d8aba82"}, + {file = "cramjam-2.8.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe84440100e7045190da7f80219be9989b0b6db6acadb3ae9cfe0935d93ebf8c"}, + {file = "cramjam-2.8.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:00524bb23f4abb3a3bfff08aa32b9274843170c5b43855807e0f59670e2ac98c"}, + {file = "cramjam-2.8.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ab67f29094165f0771acad8dd16e840259cfedcc94067af229530496dbf1a24c"}, + {file = "cramjam-2.8.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:be6fb5dd5bf1c89c717a73a1057505959f35c08e0e97a76d4cc6391b90d2263b"}, + {file = "cramjam-2.8.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93b42d22bf3e17290c5e4cf58e715a419330bb5255c35933c14db82ecf3872c"}, + {file = "cramjam-2.8.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:afa065bab70e27565695441f69f493af3d379b8723030f2c3d2547d2e312a4be"}, + {file = "cramjam-2.8.3-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:832224f52fa1e601e0ab678dba9bdfde3686fc4cd1a9f2ed4748f29eaf1cb553"}, + {file = "cramjam-2.8.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:962b7106287bcc463150766b5b8c69f32dcc69713a8dbce00e0ca6936f95c55b"}, + {file = "cramjam-2.8.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2be92c6f0bcffaf8ea6a8164fe0388a188fec2fa9eff1828e8b64dc3a83740f9"}, + {file = "cramjam-2.8.3-cp312-none-win32.whl", hash = "sha256:080f3eb7b648f5ba9d35084d8dddc68246a8f365df239792f6712908f0aa568e"}, + {file = "cramjam-2.8.3-cp312-none-win_amd64.whl", hash = "sha256:c14728e3360cd212d5b606ca703c3bd1c8912efcdbc1aa032c81c2882509ebd5"}, + {file = "cramjam-2.8.3-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:c7e8329cde48740df8d332dade2f52b74612b8ea86005341c99bb192c82a5ce7"}, + {file = "cramjam-2.8.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:77346ac669f5445d14b74476a4e8f3a259fd22681bd73790e92b8956d7e225fc"}, + {file = "cramjam-2.8.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:274878883e7fadf95a6b5bc58f9c1dd39fef2c31d68e18a0fb8594226457fba7"}, + {file = "cramjam-2.8.3-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7871e1fd3ee8ca16799ba22d49fc1e52e78976fa8c659be41630eeb2914475a7"}, + {file = "cramjam-2.8.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:345a952c5d4b922830efaa67dc0b42d21e18c182c1a1bda6d20bb78235f31d6f"}, + {file = "cramjam-2.8.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fb5d7739e2bc573ade12327ef7717b1ac5876c62938fab20eb54d762da23cae2"}, + {file = "cramjam-2.8.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:440a18fd4ae42e06dbbd7aee91d8248b61da9fef7610ffbd553d1ba93931394b"}, + {file = "cramjam-2.8.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:476890974229713fc7b4c16fb050b756ba926c67e4d1200b3e03c5c051e9b552"}, + {file = "cramjam-2.8.3-cp37-cp37m-musllinux_1_1_armv7l.whl", hash = "sha256:771b44e549f90b5532508782e25d1c40b8054dd83d52253d05945fc05836b252"}, + {file = "cramjam-2.8.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d824fd98364bc946c38ed324a3ec7befba055285aaf2c1ca61894bb7616226e8"}, + {file = "cramjam-2.8.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2476828dea4089aa3cb9160391f8b36f793ca651afdcba80de1e341373928397"}, + {file = "cramjam-2.8.3-cp37-none-win32.whl", hash = "sha256:4a554bcfd068e831affd64a4f067c7c9b00b359742597c4fdadd18ff673baf30"}, + {file = "cramjam-2.8.3-cp37-none-win_amd64.whl", hash = "sha256:246f1f7d32cac2b64617d2dddba11a82851e73cdcf9d1abb799b08dcd9d2ea49"}, + {file = "cramjam-2.8.3-cp38-cp38-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:bc8f24c32124bb47536882c6b941cdb88cc16e4fa64d5bf347cb8dd72a193fc3"}, + {file = "cramjam-2.8.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:28c30078effc100739d3f9b227276a8360c1b32aac65efb4f641630552213548"}, + {file = "cramjam-2.8.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ef0173fb457f73cf9c2553092419db0eba4d582890db95e542a4d93e11340421"}, + {file = "cramjam-2.8.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a1943f2cc0deee037ddcf92beff6049e12d4e6d557f568ddf59fb3b848f2152"}, + {file = "cramjam-2.8.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5023a737d8d9cf5d123e6d87d088929c3cfb2aae90e0f584204427f74882150a"}, + {file = "cramjam-2.8.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eec7e985f35708c234542721863d82781d0f7f6a71b45e14ce6d2625d4b131d"}, + {file = "cramjam-2.8.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b188e750b95172c01defcfcfbba629cad797718b34402ec61b3bc9ff99403599"}, + {file = "cramjam-2.8.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30e2d745cd4d244b7973d15aaebeedb537b980f9d3da80e6dea75ee1a872f9fa"}, + {file = "cramjam-2.8.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c9d54a4aa475d5e902f2ee518bdaa02f26c089e9f72950d00d1643c090f0deb3"}, + {file = "cramjam-2.8.3-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:19b8c97350c8d65daea26267dd1becb59073569aac2ae5743952d7f48da5d37a"}, + {file = "cramjam-2.8.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3277fd42399755d6d3730edec4a192174ee64d219e0ffbc90613f15cbabf711f"}, + {file = "cramjam-2.8.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1fd25201f1278dc6faa2ae35e67b7a5bb352b7fc6ed1ee939637414ca8115863"}, + {file = "cramjam-2.8.3-cp38-none-win32.whl", hash = "sha256:594477faff7f4380fa123cfbcf10ab8ee5af1a28b95750b66931ffafcb11ab5c"}, + {file = "cramjam-2.8.3-cp38-none-win_amd64.whl", hash = "sha256:8ea1dc11538842ff20d9872a17214994f5913cbf3be5594b54aad2422becdf19"}, + {file = "cramjam-2.8.3-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:6379b92912f7569e126bd48d10e7087ddd20ea88a939532e3c4a85c2fa05d600"}, + {file = "cramjam-2.8.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:11d2e9eebc7d202eda0ae09fb56a2cdbeb5a1563e89d2118bf18cf0030f35f77"}, + {file = "cramjam-2.8.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d5a0a2fe240c97587df07f3d5e1027673d599b3a6a7a0ab540aea69f09e9ff7a"}, + {file = "cramjam-2.8.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba542f07fe3f41475d78626973533539e6cf2d5b6af37923fe6c7e7f0f74b9b2"}, + {file = "cramjam-2.8.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1374fe9a4431e546bb4501a16b84875d0bf80fc4e6c8942f0d5608ae48474267"}, + {file = "cramjam-2.8.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dcf7791e1cedb982ccc873ec9392c6cfb9c714a64ebf1ed4e8310b9cb44655f2"}, + {file = "cramjam-2.8.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:990e65c2bf1c155a9ddec5ecabf431cf77596432f697d3c6e0831b5174c51c40"}, + {file = "cramjam-2.8.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9b244d04cef82872d12c227a2f202f080a454d664c05db351626e6ad4aaa307"}, + {file = "cramjam-2.8.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:80b088d15866b37851fd53e2b471becc9ec487257dceca1878621072a18e833e"}, + {file = "cramjam-2.8.3-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:f667843e7a8fca208eecfe44e04088242f8ca60d74d4950fac3722043538d700"}, + {file = "cramjam-2.8.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6f838d06d06709b9ce8b1ceae36aea4e1c7e613365185a91edcbeb5884f5e606"}, + {file = "cramjam-2.8.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4822eb5fe6839cd3d0439e5431e766ad010b2a388ca9617aa6372b6030897782"}, + {file = "cramjam-2.8.3-cp39-none-win32.whl", hash = "sha256:67e09b42e744efd08b93ac56f6100a859a31617d7146725516f3f2c744149d97"}, + {file = "cramjam-2.8.3-cp39-none-win_amd64.whl", hash = "sha256:11c9d30bc53892c57a3b296756c23659323ab1419a2b4bf22bbafc07b247bb67"}, + {file = "cramjam-2.8.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:51e847dcfe74fba379fed2bc2b45f5c2f11c3ece5e9eebcf63f39a9594184588"}, + {file = "cramjam-2.8.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07af94191f6a245226dc8a8bc6c94808e382ce9dfcca4bab0e8015fbc7fc3322"}, + {file = "cramjam-2.8.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc9c45469914099897c47bfc501616fb377f28a865adebf90ea6f3c8ae6dd4e6"}, + {file = "cramjam-2.8.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ef29fb916fe74be65d0ab8871ab8d964b0f5eb8028bb84b325be43675a59d6e7"}, + {file = "cramjam-2.8.3-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3850dac9a2f6dcb3249d23f9d505117643b967bdc1c572ed0cc492a48fd69daf"}, + {file = "cramjam-2.8.3-pp310-pypy310_pp73-musllinux_1_1_i686.whl", hash = "sha256:e23e323ad28ed3e4e3a24ceffdab0ff235954109a88b536ea7b3b7886bd0a536"}, + {file = "cramjam-2.8.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:1ba1a8ff855b30b4069a9b45ea9e7f2b5d882c7953bdfccda8d4b275fa7057ce"}, + {file = "cramjam-2.8.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:eea606b01b43b91626e3aafd463bd19b6ed739bdb8b2b309e5d7ff72afc0e89d"}, + {file = "cramjam-2.8.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:97c706c520c3f8b0184278cc86187528458350216c6e4fa85d3f16bcad0d365d"}, + {file = "cramjam-2.8.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d08f1bab949ffd6dd6f25a89e4f7062d147aeea9c067e4dd155bdb190e5a519"}, + {file = "cramjam-2.8.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba1e45074757ab0482ac544e60613b6b8658100ac9985c91868a4598cdfb63ba"}, + {file = "cramjam-2.8.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a2fededed05a042f093dbf1b11d69afb1874a2c9197fcf1d58c142ba9111db5a"}, + {file = "cramjam-2.8.3-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:fc0c6eb8185c68f79a25bb298825e345cc09b826f5828bd8146e3600ca6e9981"}, + {file = "cramjam-2.8.3-pp39-pypy39_pp73-musllinux_1_1_i686.whl", hash = "sha256:6653c262ad71e6c0ae08eeca3af2ee89ad47483b6312f2c6094518cb77872406"}, + {file = "cramjam-2.8.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:6c04f363cb4b316719421724521432b6e7f6490e5baaaf7692af961c28d0279b"}, + {file = "cramjam-2.8.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e30f1f00de913b440baa36647817b9b7120a69b04eca05f3354aaf5b40f95ee5"}, + {file = "cramjam-2.8.3.tar.gz", hash = "sha256:6b1fa0a6ea8183831d04572597c182bd6cece62d583a36cde1e6a86e72ce2389"}, +] + +[package.extras] +dev = ["black (==22.3.0)", "hypothesis", "numpy", "pytest (>=5.30)", "pytest-xdist"] + +[[package]] +name = "cryptography" +version = "42.0.8" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, + {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, + {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, + {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, + {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, + {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, + {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, + {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, + {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, + {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, + {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, + {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, + {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, + {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, + {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, + {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, + {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, + {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, + {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, + {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, + {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, + {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, + {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, + {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, + {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, + {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, + {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, + {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, + {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, + {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, + {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, + {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, +] + +[package.dependencies] +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] +nox = ["nox"] +pep8test = ["check-sdist", "click", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "cycler" +version = "0.12.1" +description = "Composable style cycles" +optional = false +python-versions = ">=3.8" +files = [ + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, +] + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + +[[package]] +name = "dask" +version = "2024.7.0" +description = "Parallel PyData with Task Scheduling" +optional = false +python-versions = ">=3.9" +files = [ + {file = "dask-2024.7.0-py3-none-any.whl", hash = "sha256:0f30f218a1fe1c8e9a6ba8add1207088ba9ff049098d4ea4ce045fd5ff7ca914"}, + {file = "dask-2024.7.0.tar.gz", hash = "sha256:0060bae9a58b5b3ce7e0d97040e903b4d3db09ba49222101cfc40f9834a8a6bc"}, +] + +[package.dependencies] +click = ">=8.1" +cloudpickle = ">=1.5.0" +dask-expr = {version = ">=1.1,<1.2", optional = true, markers = "extra == \"dataframe\""} +fsspec = ">=2021.09.0" +importlib-metadata = {version = ">=4.13.0", markers = "python_version < \"3.12\""} +numpy = {version = ">=1.21", optional = true, markers = "extra == \"array\""} +packaging = ">=20.0" +pandas = {version = ">=2.0", optional = true, markers = "extra == \"dataframe\""} +partd = ">=1.4.0" +pyyaml = ">=5.3.1" +toolz = ">=0.10.0" + +[package.extras] +array = ["numpy (>=1.21)"] +complete = ["dask[array,dataframe,diagnostics,distributed]", "lz4 (>=4.3.2)", "pyarrow (>=7.0)", "pyarrow-hotfix"] +dataframe = ["dask-expr (>=1.1,<1.2)", "dask[array]", "pandas (>=2.0)"] +diagnostics = ["bokeh (>=2.4.2)", "jinja2 (>=2.10.3)"] +distributed = ["distributed (==2024.7.0)"] +test = ["pandas[test]", "pre-commit", "pytest", "pytest-cov", "pytest-rerunfailures", "pytest-timeout", "pytest-xdist"] + +[[package]] +name = "dask-expr" +version = "1.1.7" +description = "High Level Expressions for Dask" +optional = false +python-versions = ">=3.9" +files = [ + {file = "dask_expr-1.1.7-py3-none-any.whl", hash = "sha256:6f45468499b50839e9d9a43f599f7f70a50f50048bce93557c2dea24bfcad3bb"}, + {file = "dask_expr-1.1.7.tar.gz", hash = "sha256:90a0afae1fcdc2071914daf8f32673d59ee027c12ae041941043bdede63c993c"}, +] + +[package.dependencies] +dask = "2024.7.0" +pandas = ">=2" +pyarrow = ">=7.0.0" + +[package.extras] +analyze = ["crick", "distributed"] + +[[package]] +name = "datashaper" +version = "0.0.49" +description = "This project provides a collection of utilities for doing lightweight data wrangling." +optional = false +python-versions = ">=3.10,<4" +files = [ + {file = "datashaper-0.0.49-py3-none-any.whl", hash = "sha256:7f58cabacc834765595c6e04cfbbd05be6af71907e46ebc7a91d2a4add7c2643"}, + {file = "datashaper-0.0.49.tar.gz", hash = "sha256:05bfba5964474a62bdd5259ec3fa0173d01e365208b6a4aff4ea0e63096a7533"}, +] + +[package.dependencies] +diskcache = ">=5.6.3,<6.0.0" +jsonschema = ">=4.21.1,<5.0.0" +pandas = ">=2.2.0,<3.0.0" +pyarrow = ">=15.0.0,<16.0.0" + +[[package]] +name = "debugpy" +version = "1.8.2" +description = "An implementation of the Debug Adapter Protocol for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "debugpy-1.8.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:7ee2e1afbf44b138c005e4380097d92532e1001580853a7cb40ed84e0ef1c3d2"}, + {file = "debugpy-1.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f8c3f7c53130a070f0fc845a0f2cee8ed88d220d6b04595897b66605df1edd6"}, + {file = "debugpy-1.8.2-cp310-cp310-win32.whl", hash = "sha256:f179af1e1bd4c88b0b9f0fa153569b24f6b6f3de33f94703336363ae62f4bf47"}, + {file = "debugpy-1.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:0600faef1d0b8d0e85c816b8bb0cb90ed94fc611f308d5fde28cb8b3d2ff0fe3"}, + {file = "debugpy-1.8.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:8a13417ccd5978a642e91fb79b871baded925d4fadd4dfafec1928196292aa0a"}, + {file = "debugpy-1.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acdf39855f65c48ac9667b2801234fc64d46778021efac2de7e50907ab90c634"}, + {file = "debugpy-1.8.2-cp311-cp311-win32.whl", hash = "sha256:2cbd4d9a2fc5e7f583ff9bf11f3b7d78dfda8401e8bb6856ad1ed190be4281ad"}, + {file = "debugpy-1.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:d3408fddd76414034c02880e891ea434e9a9cf3a69842098ef92f6e809d09afa"}, + {file = "debugpy-1.8.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:5d3ccd39e4021f2eb86b8d748a96c766058b39443c1f18b2dc52c10ac2757835"}, + {file = "debugpy-1.8.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62658aefe289598680193ff655ff3940e2a601765259b123dc7f89c0239b8cd3"}, + {file = "debugpy-1.8.2-cp312-cp312-win32.whl", hash = "sha256:bd11fe35d6fd3431f1546d94121322c0ac572e1bfb1f6be0e9b8655fb4ea941e"}, + {file = "debugpy-1.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:15bc2f4b0f5e99bf86c162c91a74c0631dbd9cef3c6a1d1329c946586255e859"}, + {file = "debugpy-1.8.2-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:5a019d4574afedc6ead1daa22736c530712465c0c4cd44f820d803d937531b2d"}, + {file = "debugpy-1.8.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40f062d6877d2e45b112c0bbade9a17aac507445fd638922b1a5434df34aed02"}, + {file = "debugpy-1.8.2-cp38-cp38-win32.whl", hash = "sha256:c78ba1680f1015c0ca7115671fe347b28b446081dada3fedf54138f44e4ba031"}, + {file = "debugpy-1.8.2-cp38-cp38-win_amd64.whl", hash = "sha256:cf327316ae0c0e7dd81eb92d24ba8b5e88bb4d1b585b5c0d32929274a66a5210"}, + {file = "debugpy-1.8.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:1523bc551e28e15147815d1397afc150ac99dbd3a8e64641d53425dba57b0ff9"}, + {file = "debugpy-1.8.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e24ccb0cd6f8bfaec68d577cb49e9c680621c336f347479b3fce060ba7c09ec1"}, + {file = "debugpy-1.8.2-cp39-cp39-win32.whl", hash = "sha256:7f8d57a98c5a486c5c7824bc0b9f2f11189d08d73635c326abef268f83950326"}, + {file = "debugpy-1.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:16c8dcab02617b75697a0a925a62943e26a0330da076e2a10437edd9f0bf3755"}, + {file = "debugpy-1.8.2-py2.py3-none-any.whl", hash = "sha256:16e16df3a98a35c63c3ab1e4d19be4cbc7fdda92d9ddc059294f18910928e0ca"}, + {file = "debugpy-1.8.2.zip", hash = "sha256:95378ed08ed2089221896b9b3a8d021e642c24edc8fef20e5d4342ca8be65c00"}, +] + +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +optional = false +python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] + +[[package]] +name = "deprecation" +version = "2.1.0" +description = "A library to handle automated deprecations" +optional = false +python-versions = "*" +files = [ + {file = "deprecation-2.1.0-py2.py3-none-any.whl", hash = "sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a"}, + {file = "deprecation-2.1.0.tar.gz", hash = "sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff"}, +] + +[package.dependencies] +packaging = "*" + +[[package]] +name = "devtools" +version = "0.12.2" +description = "Python's missing debug print command, and more." +optional = false +python-versions = ">=3.7" +files = [ + {file = "devtools-0.12.2-py3-none-any.whl", hash = "sha256:c366e3de1df4cdd635f1ad8cbcd3af01a384d7abda71900e68d43b04eb6aaca7"}, + {file = "devtools-0.12.2.tar.gz", hash = "sha256:efceab184cb35e3a11fa8e602cc4fadacaa2e859e920fc6f87bf130b69885507"}, +] + +[package.dependencies] +asttokens = ">=2.0.0,<3.0.0" +executing = ">=1.1.1" +pygments = ">=2.15.0" + +[[package]] +name = "diskcache" +version = "5.6.3" +description = "Disk Cache -- Disk and file backed persistent cache." +optional = false +python-versions = ">=3" +files = [ + {file = "diskcache-5.6.3-py3-none-any.whl", hash = "sha256:5e31b2d5fbad117cc363ebaf6b689474db18a1f6438bc82358b024abd4c2ca19"}, + {file = "diskcache-5.6.3.tar.gz", hash = "sha256:2c3a3fa2743d8535d832ec61c2054a1641f41775aa7c556758a109941e33e4fc"}, +] + +[[package]] +name = "distro" +version = "1.9.0" +description = "Distro - an OS platform information API" +optional = false +python-versions = ">=3.6" +files = [ + {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, + {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, +] + +[[package]] +name = "environs" +version = "11.0.0" +description = "simplified environment variable parsing" +optional = false +python-versions = ">=3.8" +files = [ + {file = "environs-11.0.0-py3-none-any.whl", hash = "sha256:e0bcfd41c718c07a7db422f9109e490746450da38793fe4ee197f397b9343435"}, + {file = "environs-11.0.0.tar.gz", hash = "sha256:069727a8f73d8ba8d033d3cd95c0da231d44f38f1da773bf076cef168d312ee8"}, +] + +[package.dependencies] +marshmallow = ">=3.13.0" +python-dotenv = "*" + +[package.extras] +dev = ["environs[tests]", "pre-commit (>=3.5,<4.0)", "tox"] +django = ["dj-database-url", "dj-email-url", "django-cache-url"] +tests = ["environs[django]", "pytest"] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "executing" +version = "2.0.1" +description = "Get the currently executing AST node of a frame, and other information" +optional = false +python-versions = ">=3.5" +files = [ + {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, + {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, +] + +[package.extras] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] + +[[package]] +name = "fastjsonschema" +version = "2.20.0" +description = "Fastest Python implementation of JSON schema" +optional = false +python-versions = "*" +files = [ + {file = "fastjsonschema-2.20.0-py3-none-any.whl", hash = "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a"}, + {file = "fastjsonschema-2.20.0.tar.gz", hash = "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23"}, +] + +[package.extras] +devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] + +[[package]] +name = "fastparquet" +version = "2024.5.0" +description = "Python support for Parquet file format" +optional = false +python-versions = ">=3.9" +files = [ + {file = "fastparquet-2024.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9dfbed87b4b58b0794b2cb3aa4abcb43fc01480a10c7779a323d2dd1599f6acd"}, + {file = "fastparquet-2024.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07fc5a45450a39cd07c6ef0e0219ac4b1879f8b27c825ee4ba5d87a3ae505f11"}, + {file = "fastparquet-2024.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a2045c21f90358541286f26f0735bfb2265b075413fbced3b876fc8848eda52"}, + {file = "fastparquet-2024.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f411056152b5d3cc82b6624d9da80535d10d9277d921fdb2e9516e93c8c227e8"}, + {file = "fastparquet-2024.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc99d7c0f1816394d53aadd47919bba70bb81355259d8788d28e35913816aee0"}, + {file = "fastparquet-2024.5.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:42149929b71d9122bd501aa695681f40a04a9fa3f5b802cf0fb6aa4e95ccf2dd"}, + {file = "fastparquet-2024.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e5b1ed889f4ac7ea059ff95f4a01f5c07c825c50c2e1bc9e2b64c814df94c243"}, + {file = "fastparquet-2024.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:f5c3cabcfa2f534e4b23343c1ab84c37d336da73770005e608d1894ab1084600"}, + {file = "fastparquet-2024.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:56d03b0a291d6a575ab365516c53b4da8e040347f8d43af79be25893c591b38c"}, + {file = "fastparquet-2024.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:784989ee2c251960b8f00dc38c6c730f784712c8e3d08cc7e0ce842055476af1"}, + {file = "fastparquet-2024.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d20bba5c39139a88d8d6931764b830ba14042742d802238d9edf86d4d765ad7a"}, + {file = "fastparquet-2024.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08358d99278c5d3fb523d819fff5c74d572d8f67ebbe2215a2c7bfca7e3664cf"}, + {file = "fastparquet-2024.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e9de270e17a6ae2f02c716421d60e18d35d4718037f561b3e359989db19f700a"}, + {file = "fastparquet-2024.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba251231b005c0f3f7e56f6e9cd1939be99b2d810ab5b05039271e260c0196c6"}, + {file = "fastparquet-2024.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1496d83d7a77c19abae796e3b582539884fc893d75a3ad4f90df12f8f23a902a"}, + {file = "fastparquet-2024.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:ea3796c4a38ef8b372a3056b5cef52ca8182fa554fa51c7637c2421e69ee56e5"}, + {file = "fastparquet-2024.5.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e1fa068ef1826bff6d4a9106a6f9e9d6fd20b8b516da4b82d87840cb5fd3947c"}, + {file = "fastparquet-2024.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3a60f7b0b308d6b9f12c642cf5237a05d754926fb31ce865ff7072bceab19fbb"}, + {file = "fastparquet-2024.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e6ac308a2f391ce589c99b8376e7cdfe4241ef5770ac4cf4c1c93f940bda83c"}, + {file = "fastparquet-2024.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b3cf7b4eb1b06e87b97a3a5c9124e4b1c08a8903ba017052c5fe2c482414a3d"}, + {file = "fastparquet-2024.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5626fc72204001b7e82fedb4b02174ecb4e2d4143b38b4ea8d2f9eb65f6b000e"}, + {file = "fastparquet-2024.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c8b2e86fe6488cce0e3d41263bb0296ef9bbb875a2fca09d67d7685640017a66"}, + {file = "fastparquet-2024.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2a951106782d51e5ab110beaad29c4aa0537f045711bb0bf146f65aeaed14174"}, + {file = "fastparquet-2024.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:47695037fdc534ef4247f25ccf17dcbd8825be6ecb70c54ca54d588a794f4a6d"}, + {file = "fastparquet-2024.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc3d35ff8341cd65baecac71062e9d73393d7afda207b3421709c1d3f4baa194"}, + {file = "fastparquet-2024.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:691348cc85890663dd3c0bb02544d38d4c07a0c3d68837324dc01007301150b5"}, + {file = "fastparquet-2024.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfdc8aaec67edd30814c2c2f0e291eb3c3044525d18c87e835ef8793d6e2ea2d"}, + {file = "fastparquet-2024.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0034d1b5af3a71cc2fb29c590f442c0b514f710d6d6996794ae375dcfe050c05"}, + {file = "fastparquet-2024.5.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:b562be0f43a007493014512602ab6b0207d13ea4ae85e0d94d61febf08efa1ee"}, + {file = "fastparquet-2024.5.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:611da9043f9dab1c63e6c90a6b124e3d2789c34fefa00d45356517f1e8a09c83"}, + {file = "fastparquet-2024.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:cb93e8951f46943c8567c9a555cb3d24d2c78efdf78e95fd72177d80da73a10f"}, + {file = "fastparquet-2024.5.0.tar.gz", hash = "sha256:dffd1d0ac6e89e31c5b6dacf67a8d299d4afbbcf0bf8b797373904c819c48f51"}, +] + +[package.dependencies] +cramjam = ">=2.3" +fsspec = "*" +numpy = "*" +packaging = "*" +pandas = ">=1.5.0" + +[package.extras] +lzo = ["python-lzo"] + +[[package]] +name = "fonttools" +version = "4.53.1" +description = "Tools to manipulate font files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, + {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, + {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, + {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, + {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, + {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, + {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, + {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, + {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, + {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, + {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, + {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, + {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, +] + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres", "pycairo", "scipy"] +lxml = ["lxml (>=4.0)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr"] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=15.1.0)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] + +[[package]] +name = "fqdn" +version = "1.5.1" +description = "Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers" +optional = false +python-versions = ">=2.7, !=3.0, !=3.1, !=3.2, !=3.3, !=3.4, <4" +files = [ + {file = "fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014"}, + {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"}, +] + +[[package]] +name = "fsspec" +version = "2024.6.1" +description = "File-system specification" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fsspec-2024.6.1-py3-none-any.whl", hash = "sha256:3cb443f8bcd2efb31295a5b9fdb02aee81d8452c80d28f97a6d0959e6cee101e"}, + {file = "fsspec-2024.6.1.tar.gz", hash = "sha256:fad7d7e209dd4c1208e3bbfda706620e0da5142bebbd9c384afb95b07e798e49"}, +] + +[package.extras] +abfs = ["adlfs"] +adl = ["adlfs"] +arrow = ["pyarrow (>=1)"] +dask = ["dask", "distributed"] +dev = ["pre-commit", "ruff"] +doc = ["numpydoc", "sphinx", "sphinx-design", "sphinx-rtd-theme", "yarl"] +dropbox = ["dropbox", "dropboxdrivefs", "requests"] +full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] +fuse = ["fusepy"] +gcs = ["gcsfs"] +git = ["pygit2"] +github = ["requests"] +gs = ["gcsfs"] +gui = ["panel"] +hdfs = ["pyarrow (>=1)"] +http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)"] +libarchive = ["libarchive-c"] +oci = ["ocifs"] +s3 = ["s3fs"] +sftp = ["paramiko"] +smb = ["smbprotocol"] +ssh = ["paramiko"] +test = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "numpy", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "requests"] +test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask-expr", "dask[dataframe,test]", "moto[server] (>4,<5)", "pytest-timeout", "xarray"] +test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard"] +tqdm = ["tqdm"] + +[[package]] +name = "future" +version = "1.0.0" +description = "Clean single-source support for Python 3 and 2" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216"}, + {file = "future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05"}, +] + +[[package]] +name = "gensim" +version = "4.3.2" +description = "Python framework for fast Vector Space Modelling" +optional = false +python-versions = ">=3.8" +files = [ + {file = "gensim-4.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:31b3cb313939b6940ee21660177f6405e71b920da462dbf065b2458a24ab33e1"}, + {file = "gensim-4.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:67c41b15e19e4950f57124f633c45839b5c84268ffa58079c5b0c0f04d2a9cb9"}, + {file = "gensim-4.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9bf1a8ee2e8214499c517008a0fd175ce5c649954a88569358cfae6bfca42dc"}, + {file = "gensim-4.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e34ee6f8a318fbf0b65e6d39a985ecf9e9051febfd1221ae6255fff1972c547"}, + {file = "gensim-4.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c46b7395dc57c83329932f3febed9660891fdcc75327d56f55000e3e08898983"}, + {file = "gensim-4.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a919493339cfad39d5e76768c1bc546cd507f715c5fca93165cc174a97657457"}, + {file = "gensim-4.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8dcd1419266bd563c371d25530f4dce3505fe78059b2c0c08724e4f9e5479b38"}, + {file = "gensim-4.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3e8035ac3f54dca3a8ca56bec526ddfe5b23006e0134b7375ca5f5dbfaef70a"}, + {file = "gensim-4.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c3b537c1fd4699c8e6d59c3ffa2fdd9918cd4e5555bf5ee7c1fbedd89b2d643"}, + {file = "gensim-4.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:5a52001226f9e89f7833503f99c9b4fd028fdf837002f24cdc1bc3cf901a4003"}, + {file = "gensim-4.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e8d62604efb8281a25254e5a6c14227034c267ed56635e590c9cae2635196dca"}, + {file = "gensim-4.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bf7a9dc37c2ca465c7834863a7b264369c1373bb474135df225cee654b8adfab"}, + {file = "gensim-4.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a33ff0d4cf3e50e7ddd7353fb38ed2d4af2e48a6ef58d622809862c30c8b8a2"}, + {file = "gensim-4.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99876be00b73c7cef01f427d241b07eb1c1b298fb411580cc1067d22c43a13be"}, + {file = "gensim-4.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:f785b3caf376a1f2989e0f3c890642e5b1566393fd3831dab03fc6670d672814"}, + {file = "gensim-4.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c86915cf0e0b86658a40a070bd7e04db0814065963657e92910303070275865d"}, + {file = "gensim-4.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:548c7bf983e619d6b8d78b6a5321dcbcba5b39f68779a0d36e38a5a971416276"}, + {file = "gensim-4.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:226690ea081b92a2289661a25e8a89069ae09b1ed4137b67a0d6ec211e0371d3"}, + {file = "gensim-4.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4715eafcd309c2f7e030829eddba72fe47bbe9bb466811fce3158127d29c8979"}, + {file = "gensim-4.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b3f26299ac241ff54329a54c37c22eac1bf4c4a337068adf2637259ee0d8484a"}, + {file = "gensim-4.3.2.tar.gz", hash = "sha256:99ac6af6ffd40682e70155ed9f92ecbf4384d59fb50af120d343ea5ee1b308ab"}, +] + +[package.dependencies] +numpy = ">=1.18.5" +scipy = ">=1.7.0" +smart-open = ">=1.8.1" + +[package.extras] +distributed = ["Pyro4 (>=4.27)"] +docs = ["POT", "Pyro4", "Pyro4 (>=4.27)", "annoy", "matplotlib", "memory-profiler", "mock", "nltk", "pandas", "pytest", "pytest-cov", "scikit-learn", "sphinx (==5.1.1)", "sphinx-gallery (==0.11.1)", "sphinxcontrib-napoleon (==0.7)", "sphinxcontrib.programoutput (==0.17)", "statsmodels", "testfixtures", "visdom (>=0.1.8,!=0.1.8.7)"] +test = ["POT", "mock", "pytest", "pytest-cov", "testfixtures", "visdom (>=0.1.8,!=0.1.8.7)"] +test-win = ["POT", "mock", "pytest", "pytest-cov", "testfixtures"] + +[[package]] +name = "graspologic" +version = "3.4.1" +description = "A set of Python modules for graph statistics" +optional = false +python-versions = "<3.13,>=3.9" +files = [ + {file = "graspologic-3.4.1-py3-none-any.whl", hash = "sha256:c6563e087eda599bad1de831d4b7321c0daa7a82f4e85a7d7737ff67e07cdda2"}, + {file = "graspologic-3.4.1.tar.gz", hash = "sha256:7561f0b852a2bccd351bff77e8db07d9892f9dfa35a420fdec01690e4fdc8075"}, +] + +[package.dependencies] +anytree = ">=2.12.1,<3.0.0" +beartype = ">=0.18.5,<0.19.0" +gensim = ">=4.3.2,<5.0.0" +graspologic-native = ">=1.2.1,<2.0.0" +hyppo = ">=0.4.0,<0.5.0" +joblib = ">=1.4.2,<2.0.0" +matplotlib = ">=3.8.4,<4.0.0" +networkx = ">=3,<4" +numpy = ">=1.26.4,<2.0.0" +POT = ">=0.9,<0.10" +scikit-learn = ">=1.4.2,<2.0.0" +scipy = "1.12.0" +seaborn = ">=0.13.2,<0.14.0" +statsmodels = ">=0.14.2,<0.15.0" +typing-extensions = ">=4.4.0,<5.0.0" +umap-learn = ">=0.5.6,<0.6.0" + +[[package]] +name = "graspologic-native" +version = "1.2.1" +description = "Python native companion module to the graspologic library" +optional = false +python-versions = ">=3.6, <3.13" +files = [ + {file = "graspologic_native-1.2.1-cp36-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:eccb2fa475b604375e34b4ae1d5497a428c34ed65f27888495239f8e120acea1"}, + {file = "graspologic_native-1.2.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a44cfdee11718c01c0f6c544750b3ae64e28cc03432a620fe0295704bd0d618d"}, + {file = "graspologic_native-1.2.1-cp36-abi3-win_amd64.whl", hash = "sha256:56b5e66ba003fd38efc0919ce90fa22d379456e177dca65e26626498d2b9b96b"}, + {file = "graspologic_native-1.2.1.tar.gz", hash = "sha256:72b7586028a91e9fef9af0ef314d368f0240c18dca99e6e6c546334359a8610a"}, +] + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.5" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"}, + {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.26.0)"] + +[[package]] +name = "httpx" +version = "0.27.0" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, + {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" +sniffio = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] + +[[package]] +name = "hyppo" +version = "0.4.0" +description = "A comprehensive independence testing package" +optional = false +python-versions = "*" +files = [ + {file = "hyppo-0.4.0-py3-none-any.whl", hash = "sha256:4e75565b8deb601485cd7bc1b5c3f44e6ddf329136fc81e65d011f9b4e95132f"}, +] + +[package.dependencies] +autograd = ">=1.3" +numba = ">=0.46" +numpy = ">=1.17" +scikit-learn = ">=0.19.1" +scipy = ">=1.4.0" + +[[package]] +name = "idna" +version = "3.7" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, +] + +[[package]] +name = "importlib-metadata" +version = "8.0.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, + {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "ipykernel" +version = "6.29.5" +description = "IPython Kernel for Jupyter" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5"}, + {file = "ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215"}, +] + +[package.dependencies] +appnope = {version = "*", markers = "platform_system == \"Darwin\""} +comm = ">=0.1.1" +debugpy = ">=1.6.5" +ipython = ">=7.23.1" +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +matplotlib-inline = ">=0.1" +nest-asyncio = "*" +packaging = "*" +psutil = "*" +pyzmq = ">=24" +tornado = ">=6.1" +traitlets = ">=5.4.0" + +[package.extras] +cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] +pyqt5 = ["pyqt5"] +pyside6 = ["pyside6"] +test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.23.5)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "ipython" +version = "8.26.0" +description = "IPython: Productive Interactive Computing" +optional = false +python-versions = ">=3.10" +files = [ + {file = "ipython-8.26.0-py3-none-any.whl", hash = "sha256:e6b347c27bdf9c32ee9d31ae85defc525755a1869f14057e900675b9e8d6e6ff"}, + {file = "ipython-8.26.0.tar.gz", hash = "sha256:1cec0fbba8404af13facebe83d04436a7434c7400e59f47acf467c64abd0956c"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""} +prompt-toolkit = ">=3.0.41,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5.13.0" +typing-extensions = {version = ">=4.6", markers = "python_version < \"3.12\""} + +[package.extras] +all = ["ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]", "ipython[test,test-extra]"] +black = ["black"] +doc = ["docrepr", "exceptiongroup", "intersphinx-registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinxcontrib-jquery", "tomli", "typing-extensions"] +kernel = ["ipykernel"] +matplotlib = ["matplotlib"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["packaging", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "ipython[test]", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "trio"] + +[[package]] +name = "ipywidgets" +version = "8.1.3" +description = "Jupyter interactive widgets" +optional = false +python-versions = ">=3.7" +files = [ + {file = "ipywidgets-8.1.3-py3-none-any.whl", hash = "sha256:efafd18f7a142248f7cb0ba890a68b96abd4d6e88ddbda483c9130d12667eaf2"}, + {file = "ipywidgets-8.1.3.tar.gz", hash = "sha256:f5f9eeaae082b1823ce9eac2575272952f40d748893972956dc09700a6392d9c"}, +] + +[package.dependencies] +comm = ">=0.1.3" +ipython = ">=6.1.0" +jupyterlab-widgets = ">=3.0.11,<3.1.0" +traitlets = ">=4.3.1" +widgetsnbextension = ">=4.0.11,<4.1.0" + +[package.extras] +test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] + +[[package]] +name = "isodate" +version = "0.6.1" +description = "An ISO 8601 date/time/duration parser and formatter" +optional = false +python-versions = "*" +files = [ + {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, + {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "isoduration" +version = "20.11.0" +description = "Operations with ISO 8601 durations" +optional = false +python-versions = ">=3.7" +files = [ + {file = "isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042"}, + {file = "isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9"}, +] + +[package.dependencies] +arrow = ">=0.15.0" + +[[package]] +name = "jedi" +version = "0.19.1" +description = "An autocompletion tool for Python that can be used for text editors." +optional = false +python-versions = ">=3.6" +files = [ + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, +] + +[package.dependencies] +parso = ">=0.8.3,<0.9.0" + +[package.extras] +docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] + +[[package]] +name = "jinja2" +version = "3.1.4" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "joblib" +version = "1.4.2" +description = "Lightweight pipelining with Python functions" +optional = false +python-versions = ">=3.8" +files = [ + {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, + {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, +] + +[[package]] +name = "json5" +version = "0.9.25" +description = "A Python implementation of the JSON5 data format." +optional = false +python-versions = ">=3.8" +files = [ + {file = "json5-0.9.25-py3-none-any.whl", hash = "sha256:34ed7d834b1341a86987ed52f3f76cd8ee184394906b6e22a1e0deb9ab294e8f"}, + {file = "json5-0.9.25.tar.gz", hash = "sha256:548e41b9be043f9426776f05df8635a00fe06104ea51ed24b67f908856e151ae"}, +] + +[[package]] +name = "jsonpointer" +version = "3.0.0" +description = "Identify specific nodes in a JSON document (RFC 6901)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, +] + +[[package]] +name = "jsonschema" +version = "4.23.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +fqdn = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +idna = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +isoduration = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format-nongpl\""} +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} +rpds-py = ">=0.7.1" +uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +webcolors = {version = ">=24.6.0", optional = true, markers = "extra == \"format-nongpl\""} + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] + +[[package]] +name = "jsonschema-specifications" +version = "2023.12.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + +[[package]] +name = "jupyter" +version = "1.0.0" +description = "Jupyter metapackage. Install all the Jupyter components in one go." +optional = false +python-versions = "*" +files = [ + {file = "jupyter-1.0.0-py2.py3-none-any.whl", hash = "sha256:5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78"}, + {file = "jupyter-1.0.0.tar.gz", hash = "sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f"}, + {file = "jupyter-1.0.0.zip", hash = "sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7"}, +] + +[package.dependencies] +ipykernel = "*" +ipywidgets = "*" +jupyter-console = "*" +nbconvert = "*" +notebook = "*" +qtconsole = "*" + +[[package]] +name = "jupyter-client" +version = "8.6.2" +description = "Jupyter protocol implementation and client libraries" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_client-8.6.2-py3-none-any.whl", hash = "sha256:50cbc5c66fd1b8f65ecb66bc490ab73217993632809b6e505687de18e9dea39f"}, + {file = "jupyter_client-8.6.2.tar.gz", hash = "sha256:2bda14d55ee5ba58552a8c53ae43d215ad9868853489213f37da060ced54d8df"}, +] + +[package.dependencies] +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +python-dateutil = ">=2.8.2" +pyzmq = ">=23.0" +tornado = ">=6.2" +traitlets = ">=5.3" + +[package.extras] +docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] + +[[package]] +name = "jupyter-console" +version = "6.6.3" +description = "Jupyter terminal console" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jupyter_console-6.6.3-py3-none-any.whl", hash = "sha256:309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485"}, + {file = "jupyter_console-6.6.3.tar.gz", hash = "sha256:566a4bf31c87adbfadf22cdf846e3069b59a71ed5da71d6ba4d8aaad14a53539"}, +] + +[package.dependencies] +ipykernel = ">=6.14" +ipython = "*" +jupyter-client = ">=7.0.0" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +prompt-toolkit = ">=3.0.30" +pygments = "*" +pyzmq = ">=17" +traitlets = ">=5.4" + +[package.extras] +test = ["flaky", "pexpect", "pytest"] + +[[package]] +name = "jupyter-core" +version = "5.7.2" +description = "Jupyter core package. A base package on which Jupyter projects rely." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409"}, + {file = "jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9"}, +] + +[package.dependencies] +platformdirs = ">=2.5" +pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} +traitlets = ">=5.3" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] +test = ["ipykernel", "pre-commit", "pytest (<8)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "jupyter-events" +version = "0.10.0" +description = "Jupyter Event System library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_events-0.10.0-py3-none-any.whl", hash = "sha256:4b72130875e59d57716d327ea70d3ebc3af1944d3717e5a498b8a06c6c159960"}, + {file = "jupyter_events-0.10.0.tar.gz", hash = "sha256:670b8229d3cc882ec782144ed22e0d29e1c2d639263f92ca8383e66682845e22"}, +] + +[package.dependencies] +jsonschema = {version = ">=4.18.0", extras = ["format-nongpl"]} +python-json-logger = ">=2.0.4" +pyyaml = ">=5.3" +referencing = "*" +rfc3339-validator = "*" +rfc3986-validator = ">=0.1.1" +traitlets = ">=5.3" + +[package.extras] +cli = ["click", "rich"] +docs = ["jupyterlite-sphinx", "myst-parser", "pydata-sphinx-theme", "sphinxcontrib-spelling"] +test = ["click", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "pytest-console-scripts", "rich"] + +[[package]] +name = "jupyter-lsp" +version = "2.2.5" +description = "Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter-lsp-2.2.5.tar.gz", hash = "sha256:793147a05ad446f809fd53ef1cd19a9f5256fd0a2d6b7ce943a982cb4f545001"}, + {file = "jupyter_lsp-2.2.5-py3-none-any.whl", hash = "sha256:45fbddbd505f3fbfb0b6cb2f1bc5e15e83ab7c79cd6e89416b248cb3c00c11da"}, +] + +[package.dependencies] +jupyter-server = ">=1.1.2" + +[[package]] +name = "jupyter-server" +version = "2.14.2" +description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_server-2.14.2-py3-none-any.whl", hash = "sha256:47ff506127c2f7851a17bf4713434208fc490955d0e8632e95014a9a9afbeefd"}, + {file = "jupyter_server-2.14.2.tar.gz", hash = "sha256:66095021aa9638ced276c248b1d81862e4c50f292d575920bbe960de1c56b12b"}, +] + +[package.dependencies] +anyio = ">=3.1.0" +argon2-cffi = ">=21.1" +jinja2 = ">=3.0.3" +jupyter-client = ">=7.4.4" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +jupyter-events = ">=0.9.0" +jupyter-server-terminals = ">=0.4.4" +nbconvert = ">=6.4.4" +nbformat = ">=5.3.0" +overrides = ">=5.0" +packaging = ">=22.0" +prometheus-client = ">=0.9" +pywinpty = {version = ">=2.0.1", markers = "os_name == \"nt\""} +pyzmq = ">=24" +send2trash = ">=1.8.2" +terminado = ">=0.8.3" +tornado = ">=6.2.0" +traitlets = ">=5.6.0" +websocket-client = ">=1.7" + +[package.extras] +docs = ["ipykernel", "jinja2", "jupyter-client", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] +test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0,<9)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.7)", "pytest-timeout", "requests"] + +[[package]] +name = "jupyter-server-terminals" +version = "0.5.3" +description = "A Jupyter Server Extension Providing Terminals." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_server_terminals-0.5.3-py3-none-any.whl", hash = "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa"}, + {file = "jupyter_server_terminals-0.5.3.tar.gz", hash = "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269"}, +] + +[package.dependencies] +pywinpty = {version = ">=2.0.3", markers = "os_name == \"nt\""} +terminado = ">=0.8.3" + +[package.extras] +docs = ["jinja2", "jupyter-server", "mistune (<4.0)", "myst-parser", "nbformat", "packaging", "pydata-sphinx-theme", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] +test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (>=0.5.3)", "pytest-timeout"] + +[[package]] +name = "jupyterlab" +version = "4.2.3" +description = "JupyterLab computational environment" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab-4.2.3-py3-none-any.whl", hash = "sha256:0b59d11808e84bb84105c73364edfa867dd475492429ab34ea388a52f2e2e596"}, + {file = "jupyterlab-4.2.3.tar.gz", hash = "sha256:df6e46969ea51d66815167f23d92f105423b7f1f06fa604d4f44aeb018c82c7b"}, +] + +[package.dependencies] +async-lru = ">=1.0.0" +httpx = ">=0.25.0" +ipykernel = ">=6.5.0" +jinja2 = ">=3.0.3" +jupyter-core = "*" +jupyter-lsp = ">=2.0.0" +jupyter-server = ">=2.4.0,<3" +jupyterlab-server = ">=2.27.1,<3" +notebook-shim = ">=0.2" +packaging = "*" +setuptools = ">=40.1.0" +tomli = {version = ">=1.2.2", markers = "python_version < \"3.11\""} +tornado = ">=6.2.0" +traitlets = "*" + +[package.extras] +dev = ["build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.3.5)"] +docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-jupyter", "sphinx (>=1.8,<7.3.0)", "sphinx-copybutton"] +docs-screenshots = ["altair (==5.3.0)", "ipython (==8.16.1)", "ipywidgets (==8.1.2)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.1.post2)", "matplotlib (==3.8.3)", "nbconvert (>=7.0.0)", "pandas (==2.2.1)", "scipy (==1.12.0)", "vega-datasets (==0.9.0)"] +test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] +upgrade-extension = ["copier (>=8,<10)", "jinja2-time (<0.3)", "pydantic (<2.0)", "pyyaml-include (<2.0)", "tomli-w (<2.0)"] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +description = "Pygments theme using JupyterLab CSS variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780"}, + {file = "jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d"}, +] + +[[package]] +name = "jupyterlab-server" +version = "2.27.3" +description = "A set of server components for JupyterLab and JupyterLab like applications." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab_server-2.27.3-py3-none-any.whl", hash = "sha256:e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4"}, + {file = "jupyterlab_server-2.27.3.tar.gz", hash = "sha256:eb36caca59e74471988f0ae25c77945610b887f777255aa21f8065def9e51ed4"}, +] + +[package.dependencies] +babel = ">=2.10" +jinja2 = ">=3.0.3" +json5 = ">=0.9.0" +jsonschema = ">=4.18.0" +jupyter-server = ">=1.21,<3" +packaging = ">=21.3" +requests = ">=2.31" + +[package.extras] +docs = ["autodoc-traits", "jinja2 (<3.2.0)", "mistune (<4)", "myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinxcontrib-openapi (>0.8)"] +openapi = ["openapi-core (>=0.18.0,<0.19.0)", "ruamel-yaml"] +test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-validator (>=0.6.0,<0.8.0)", "pytest (>=7.0,<8)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "ruamel-yaml", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] + +[[package]] +name = "jupyterlab-widgets" +version = "3.0.11" +description = "Jupyter interactive widgets for JupyterLab" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jupyterlab_widgets-3.0.11-py3-none-any.whl", hash = "sha256:78287fd86d20744ace330a61625024cf5521e1c012a352ddc0a3cdc2348becd0"}, + {file = "jupyterlab_widgets-3.0.11.tar.gz", hash = "sha256:dd5ac679593c969af29c9bed054c24f26842baa51352114736756bc035deee27"}, +] + +[[package]] +name = "kiwisolver" +version = "1.4.5" +description = "A fast implementation of the Cassowary constraint solver" +optional = false +python-versions = ">=3.7" +files = [ + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, + {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, +] + +[[package]] +name = "lancedb" +version = "0.10.0" +description = "lancedb" +optional = false +python-versions = ">=3.8" +files = [ + {file = "lancedb-0.10.0-cp38-abi3-macosx_10_15_x86_64.whl", hash = "sha256:e7b922db07d3186867c622af8bbd6fd0306e11fcdec57bdd56d0da303a51a7ad"}, + {file = "lancedb-0.10.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:f390ebe0f145612503f50d6158a7543c7eed8ad9d7a4d560aff1f1c572c3b4ea"}, + {file = "lancedb-0.10.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfa5b19ef009fd96e16417363af52a80fd53b9fa62c322e7020c6a2e154714b7"}, + {file = "lancedb-0.10.0-cp38-abi3-manylinux_2_24_aarch64.whl", hash = "sha256:e1eb075528f1a9dccb37d490b6bf745ed3afa2decb28c3846490c04bc80dc958"}, + {file = "lancedb-0.10.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:828ff34ed3d81387516e4c8356c5f960ad2c6132a1d5e2cee152f359ec9a40c9"}, + {file = "lancedb-0.10.0-cp38-abi3-win_amd64.whl", hash = "sha256:c0f7eec52938ea00ffad80bdeaa7ad398d90e0b47691c86bc9baaa604493e1f0"}, +] + +[package.dependencies] +attrs = ">=21.3.0" +cachetools = "*" +deprecation = "*" +overrides = ">=0.7" +packaging = "*" +pydantic = ">=1.10" +pylance = "0.14.1" +ratelimiter = ">=1.0,<2.0" +requests = ">=2.31.0" +retry = ">=0.9.2" +tqdm = ">=4.27.0" + +[package.extras] +azure = ["adlfs (>=2024.2.0)"] +clip = ["open-clip", "pillow", "torch"] +dev = ["pre-commit", "ruff"] +docs = ["mkdocs", "mkdocs-jupyter", "mkdocs-material", "mkdocstrings[python]"] +embeddings = ["awscli (>=1.29.57)", "boto3 (>=1.28.57)", "botocore (>=1.31.57)", "cohere", "google-generativeai", "huggingface-hub", "instructorembedding", "ollama", "open-clip-torch", "openai (>=1.6.1)", "pillow", "sentence-transformers", "torch"] +tests = ["aiohttp", "boto3", "duckdb", "pandas (>=1.4)", "polars (>=0.19)", "pytest", "pytest-asyncio", "pytest-mock", "pytz", "tantivy"] + +[[package]] +name = "linkify-it-py" +version = "2.0.3" +description = "Links recognition library with FULL unicode support." +optional = false +python-versions = ">=3.7" +files = [ + {file = "linkify-it-py-2.0.3.tar.gz", hash = "sha256:68cda27e162e9215c17d786649d1da0021a451bdc436ef9e0fa0ba5234b9b048"}, + {file = "linkify_it_py-2.0.3-py3-none-any.whl", hash = "sha256:6bcbc417b0ac14323382aef5c5192c0075bf8a9d6b41820a2b66371eac6b6d79"}, +] + +[package.dependencies] +uc-micro-py = "*" + +[package.extras] +benchmark = ["pytest", "pytest-benchmark"] +dev = ["black", "flake8", "isort", "pre-commit", "pyproject-flake8"] +doc = ["myst-parser", "sphinx", "sphinx-book-theme"] +test = ["coverage", "pytest", "pytest-cov"] + +[[package]] +name = "llvmlite" +version = "0.43.0" +description = "lightweight wrapper around basic LLVM functionality" +optional = false +python-versions = ">=3.9" +files = [ + {file = "llvmlite-0.43.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a289af9a1687c6cf463478f0fa8e8aa3b6fb813317b0d70bf1ed0759eab6f761"}, + {file = "llvmlite-0.43.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d4fd101f571a31acb1559ae1af30f30b1dc4b3186669f92ad780e17c81e91bc"}, + {file = "llvmlite-0.43.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d434ec7e2ce3cc8f452d1cd9a28591745de022f931d67be688a737320dfcead"}, + {file = "llvmlite-0.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6912a87782acdff6eb8bf01675ed01d60ca1f2551f8176a300a886f09e836a6a"}, + {file = "llvmlite-0.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:14f0e4bf2fd2d9a75a3534111e8ebeb08eda2f33e9bdd6dfa13282afacdde0ed"}, + {file = "llvmlite-0.43.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e8d0618cb9bfe40ac38a9633f2493d4d4e9fcc2f438d39a4e854f39cc0f5f98"}, + {file = "llvmlite-0.43.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0a9a1a39d4bf3517f2af9d23d479b4175ead205c592ceeb8b89af48a327ea57"}, + {file = "llvmlite-0.43.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1da416ab53e4f7f3bc8d4eeba36d801cc1894b9fbfbf2022b29b6bad34a7df2"}, + {file = "llvmlite-0.43.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977525a1e5f4059316b183fb4fd34fa858c9eade31f165427a3977c95e3ee749"}, + {file = "llvmlite-0.43.0-cp311-cp311-win_amd64.whl", hash = "sha256:d5bd550001d26450bd90777736c69d68c487d17bf371438f975229b2b8241a91"}, + {file = "llvmlite-0.43.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f99b600aa7f65235a5a05d0b9a9f31150c390f31261f2a0ba678e26823ec38f7"}, + {file = "llvmlite-0.43.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:35d80d61d0cda2d767f72de99450766250560399edc309da16937b93d3b676e7"}, + {file = "llvmlite-0.43.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eccce86bba940bae0d8d48ed925f21dbb813519169246e2ab292b5092aba121f"}, + {file = "llvmlite-0.43.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df6509e1507ca0760787a199d19439cc887bfd82226f5af746d6977bd9f66844"}, + {file = "llvmlite-0.43.0-cp312-cp312-win_amd64.whl", hash = "sha256:7a2872ee80dcf6b5dbdc838763d26554c2a18aa833d31a2635bff16aafefb9c9"}, + {file = "llvmlite-0.43.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9cd2a7376f7b3367019b664c21f0c61766219faa3b03731113ead75107f3b66c"}, + {file = "llvmlite-0.43.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18e9953c748b105668487b7c81a3e97b046d8abf95c4ddc0cd3c94f4e4651ae8"}, + {file = "llvmlite-0.43.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74937acd22dc11b33946b67dca7680e6d103d6e90eeaaaf932603bec6fe7b03a"}, + {file = "llvmlite-0.43.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc9efc739cc6ed760f795806f67889923f7274276f0eb45092a1473e40d9b867"}, + {file = "llvmlite-0.43.0-cp39-cp39-win_amd64.whl", hash = "sha256:47e147cdda9037f94b399bf03bfd8a6b6b1f2f90be94a454e3386f006455a9b4"}, + {file = "llvmlite-0.43.0.tar.gz", hash = "sha256:ae2b5b5c3ef67354824fb75517c8db5fbe93bc02cd9671f3c62271626bc041d5"}, +] + +[[package]] +name = "locket" +version = "1.0.0" +description = "File-based locks for Python on Linux and Windows" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "locket-1.0.0-py2.py3-none-any.whl", hash = "sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3"}, + {file = "locket-1.0.0.tar.gz", hash = "sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632"}, +] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +linkify-it-py = {version = ">=1,<3", optional = true, markers = "extra == \"linkify\""} +mdit-py-plugins = {version = "*", optional = true, markers = "extra == \"plugins\""} +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + +[[package]] +name = "marshmallow" +version = "3.21.3" +description = "A lightweight library for converting complex datatypes to and from native Python datatypes." +optional = false +python-versions = ">=3.8" +files = [ + {file = "marshmallow-3.21.3-py3-none-any.whl", hash = "sha256:86ce7fb914aa865001a4b2092c4c2872d13bc347f3d42673272cabfdbad386f1"}, + {file = "marshmallow-3.21.3.tar.gz", hash = "sha256:4f57c5e050a54d66361e826f94fba213eb10b67b2fdb02c3e0343ce207ba1662"}, +] + +[package.dependencies] +packaging = ">=17.0" + +[package.extras] +dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] +docs = ["alabaster (==0.7.16)", "autodocsumm (==0.2.12)", "sphinx (==7.3.7)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] +tests = ["pytest", "pytz", "simplejson"] + +[[package]] +name = "matplotlib" +version = "3.9.1" +description = "Python plotting package" +optional = false +python-versions = ">=3.9" +files = [ + {file = "matplotlib-3.9.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7ccd6270066feb9a9d8e0705aa027f1ff39f354c72a87efe8fa07632f30fc6bb"}, + {file = "matplotlib-3.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:591d3a88903a30a6d23b040c1e44d1afdd0d778758d07110eb7596f811f31842"}, + {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd2a59ff4b83d33bca3b5ec58203cc65985367812cb8c257f3e101632be86d92"}, + {file = "matplotlib-3.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fc001516ffcf1a221beb51198b194d9230199d6842c540108e4ce109ac05cc0"}, + {file = "matplotlib-3.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:83c6a792f1465d174c86d06f3ae85a8fe36e6f5964633ae8106312ec0921fdf5"}, + {file = "matplotlib-3.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:421851f4f57350bcf0811edd754a708d2275533e84f52f6760b740766c6747a7"}, + {file = "matplotlib-3.9.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b3fce58971b465e01b5c538f9d44915640c20ec5ff31346e963c9e1cd66fa812"}, + {file = "matplotlib-3.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a973c53ad0668c53e0ed76b27d2eeeae8799836fd0d0caaa4ecc66bf4e6676c0"}, + {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cd5acf8f3ef43f7532c2f230249720f5dc5dd40ecafaf1c60ac8200d46d7eb"}, + {file = "matplotlib-3.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab38a4f3772523179b2f772103d8030215b318fef6360cb40558f585bf3d017f"}, + {file = "matplotlib-3.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2315837485ca6188a4b632c5199900e28d33b481eb083663f6a44cfc8987ded3"}, + {file = "matplotlib-3.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:a0c977c5c382f6696caf0bd277ef4f936da7e2aa202ff66cad5f0ac1428ee15b"}, + {file = "matplotlib-3.9.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:565d572efea2b94f264dd86ef27919515aa6d629252a169b42ce5f570db7f37b"}, + {file = "matplotlib-3.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d397fd8ccc64af2ec0af1f0efc3bacd745ebfb9d507f3f552e8adb689ed730a"}, + {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26040c8f5121cd1ad712abffcd4b5222a8aec3a0fe40bc8542c94331deb8780d"}, + {file = "matplotlib-3.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12cb1837cffaac087ad6b44399d5e22b78c729de3cdae4629e252067b705e2b"}, + {file = "matplotlib-3.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0e835c6988edc3d2d08794f73c323cc62483e13df0194719ecb0723b564e0b5c"}, + {file = "matplotlib-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:44a21d922f78ce40435cb35b43dd7d573cf2a30138d5c4b709d19f00e3907fd7"}, + {file = "matplotlib-3.9.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0c584210c755ae921283d21d01f03a49ef46d1afa184134dd0f95b0202ee6f03"}, + {file = "matplotlib-3.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11fed08f34fa682c2b792942f8902e7aefeed400da71f9e5816bea40a7ce28fe"}, + {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0000354e32efcfd86bda75729716b92f5c2edd5b947200be9881f0a671565c33"}, + {file = "matplotlib-3.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4db17fea0ae3aceb8e9ac69c7e3051bae0b3d083bfec932240f9bf5d0197a049"}, + {file = "matplotlib-3.9.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:208cbce658b72bf6a8e675058fbbf59f67814057ae78165d8a2f87c45b48d0ff"}, + {file = "matplotlib-3.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:dc23f48ab630474264276be156d0d7710ac6c5a09648ccdf49fef9200d8cbe80"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3fda72d4d472e2ccd1be0e9ccb6bf0d2eaf635e7f8f51d737ed7e465ac020cb3"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:84b3ba8429935a444f1fdc80ed930babbe06725bcf09fbeb5c8757a2cd74af04"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b918770bf3e07845408716e5bbda17eadfc3fcbd9307dc67f37d6cf834bb3d98"}, + {file = "matplotlib-3.9.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f1f2e5d29e9435c97ad4c36fb6668e89aee13d48c75893e25cef064675038ac9"}, + {file = "matplotlib-3.9.1.tar.gz", hash = "sha256:de06b19b8db95dd33d0dc17c926c7c9ebed9f572074b6fac4f65068a6814d010"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.3.1" +numpy = ">=1.23" +packaging = ">=20.0" +pillow = ">=8" +pyparsing = ">=2.3.1" +python-dateutil = ">=2.7" + +[package.extras] +dev = ["meson-python (>=0.13.1)", "numpy (>=1.25)", "pybind11 (>=2.6)", "setuptools (>=64)", "setuptools_scm (>=7)"] + +[[package]] +name = "matplotlib-inline" +version = "0.1.7" +description = "Inline Matplotlib backend for Jupyter" +optional = false +python-versions = ">=3.8" +files = [ + {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, + {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, +] + +[package.dependencies] +traitlets = "*" + +[[package]] +name = "mdit-py-plugins" +version = "0.4.1" +description = "Collection of plugins for markdown-it-py" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mdit_py_plugins-0.4.1-py3-none-any.whl", hash = "sha256:1020dfe4e6bfc2c79fb49ae4e3f5b297f5ccd20f010187acc52af2921e27dc6a"}, + {file = "mdit_py_plugins-0.4.1.tar.gz", hash = "sha256:834b8ac23d1cd60cec703646ffd22ae97b7955a6d596eb1d304be1e251ae499c"}, +] + +[package.dependencies] +markdown-it-py = ">=1.0.0,<4.0.0" + +[package.extras] +code-style = ["pre-commit"] +rtd = ["myst-parser", "sphinx-book-theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "mistune" +version = "3.0.2" +description = "A sane and fast Markdown parser with useful plugins and renderers" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mistune-3.0.2-py3-none-any.whl", hash = "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205"}, + {file = "mistune-3.0.2.tar.gz", hash = "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8"}, +] + +[[package]] +name = "msal" +version = "1.29.0" +description = "The Microsoft Authentication Library (MSAL) for Python library enables your app to access the Microsoft Cloud by supporting authentication of users with Microsoft Azure Active Directory accounts (AAD) and Microsoft Accounts (MSA) using industry standard OAuth2 and OpenID Connect." +optional = false +python-versions = ">=3.7" +files = [ + {file = "msal-1.29.0-py3-none-any.whl", hash = "sha256:6b301e63f967481f0cc1a3a3bac0cf322b276855bc1b0955468d9deb3f33d511"}, + {file = "msal-1.29.0.tar.gz", hash = "sha256:8f6725f099752553f9b2fe84125e2a5ebe47b49f92eacca33ebedd3a9ebaae25"}, +] + +[package.dependencies] +cryptography = ">=2.5,<45" +PyJWT = {version = ">=1.0.0,<3", extras = ["crypto"]} +requests = ">=2.0.0,<3" + +[package.extras] +broker = ["pymsalruntime (>=0.13.2,<0.17)"] + +[[package]] +name = "msal-extensions" +version = "1.2.0" +description = "Microsoft Authentication Library extensions (MSAL EX) provides a persistence API that can save your data on disk, encrypted on Windows, macOS and Linux. Concurrent data access will be coordinated by a file lock mechanism." +optional = false +python-versions = ">=3.7" +files = [ + {file = "msal_extensions-1.2.0-py3-none-any.whl", hash = "sha256:cf5ba83a2113fa6dc011a254a72f1c223c88d7dfad74cc30617c4679a417704d"}, + {file = "msal_extensions-1.2.0.tar.gz", hash = "sha256:6f41b320bfd2933d631a215c91ca0dd3e67d84bd1a2f50ce917d5874ec646bef"}, +] + +[package.dependencies] +msal = ">=1.29,<2" +portalocker = ">=1.4,<3" + +[[package]] +name = "nbclient" +version = "0.10.0" +description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "nbclient-0.10.0-py3-none-any.whl", hash = "sha256:f13e3529332a1f1f81d82a53210322476a168bb7090a0289c795fe9cc11c9d3f"}, + {file = "nbclient-0.10.0.tar.gz", hash = "sha256:4b3f1b7dba531e498449c4db4f53da339c91d449dc11e9af3a43b4eb5c5abb09"}, +] + +[package.dependencies] +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +nbformat = ">=5.1" +traitlets = ">=5.4" + +[package.extras] +dev = ["pre-commit"] +docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] +test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0,<8)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] + +[[package]] +name = "nbconvert" +version = "7.16.4" +description = "Converting Jupyter Notebooks (.ipynb files) to other formats. Output formats include asciidoc, html, latex, markdown, pdf, py, rst, script. nbconvert can be used both as a Python library (`import nbconvert`) or as a command line tool (invoked as `jupyter nbconvert ...`)." +optional = false +python-versions = ">=3.8" +files = [ + {file = "nbconvert-7.16.4-py3-none-any.whl", hash = "sha256:05873c620fe520b6322bf8a5ad562692343fe3452abda5765c7a34b7d1aa3eb3"}, + {file = "nbconvert-7.16.4.tar.gz", hash = "sha256:86ca91ba266b0a448dc96fa6c5b9d98affabde2867b363258703536807f9f7f4"}, +] + +[package.dependencies] +beautifulsoup4 = "*" +bleach = "!=5.0.0" +defusedxml = "*" +jinja2 = ">=3.0" +jupyter-core = ">=4.7" +jupyterlab-pygments = "*" +markupsafe = ">=2.0" +mistune = ">=2.0.3,<4" +nbclient = ">=0.5.0" +nbformat = ">=5.7" +packaging = "*" +pandocfilters = ">=1.4.1" +pygments = ">=2.4.1" +tinycss2 = "*" +traitlets = ">=5.1" + +[package.extras] +all = ["flaky", "ipykernel", "ipython", "ipywidgets (>=7.5)", "myst-parser", "nbsphinx (>=0.2.12)", "playwright", "pydata-sphinx-theme", "pyqtwebengine (>=5.15)", "pytest (>=7)", "sphinx (==5.0.2)", "sphinxcontrib-spelling", "tornado (>=6.1)"] +docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] +qtpdf = ["pyqtwebengine (>=5.15)"] +qtpng = ["pyqtwebengine (>=5.15)"] +serve = ["tornado (>=6.1)"] +test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest (>=7)"] +webpdf = ["playwright"] + +[[package]] +name = "nbformat" +version = "5.10.4" +description = "The Jupyter Notebook format" +optional = false +python-versions = ">=3.8" +files = [ + {file = "nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b"}, + {file = "nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a"}, +] + +[package.dependencies] +fastjsonschema = ">=2.15" +jsonschema = ">=2.6" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +traitlets = ">=5.1" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["pep440", "pre-commit", "pytest", "testpath"] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +description = "Patch asyncio to allow nested event loops" +optional = false +python-versions = ">=3.5" +files = [ + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, +] + +[[package]] +name = "networkx" +version = "3.3" +description = "Python package for creating and manipulating graphs and networks" +optional = false +python-versions = ">=3.10" +files = [ + {file = "networkx-3.3-py3-none-any.whl", hash = "sha256:28575580c6ebdaf4505b22c6256a2b9de86b316dc63ba9e93abde3d78dfdbcf2"}, + {file = "networkx-3.3.tar.gz", hash = "sha256:0c127d8b2f4865f59ae9cb8aafcd60b5c70f3241ebd66f7defad7c4ab90126c9"}, +] + +[package.extras] +default = ["matplotlib (>=3.6)", "numpy (>=1.23)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] +developer = ["changelist (==0.5)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] +doc = ["myst-nb (>=1.0)", "numpydoc (>=1.7)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] +extra = ["lxml (>=4.6)", "pydot (>=2.0)", "pygraphviz (>=1.12)", "sympy (>=1.10)"] +test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] + +[[package]] +name = "nltk" +version = "3.8.1" +description = "Natural Language Toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "nltk-3.8.1-py3-none-any.whl", hash = "sha256:fd5c9109f976fa86bcadba8f91e47f5e9293bd034474752e92a520f81c93dda5"}, + {file = "nltk-3.8.1.zip", hash = "sha256:1834da3d0682cba4f2cede2f9aad6b0fafb6461ba451db0efb6f9c39798d64d3"}, +] + +[package.dependencies] +click = "*" +joblib = "*" +regex = ">=2021.8.3" +tqdm = "*" + +[package.extras] +all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"] +corenlp = ["requests"] +machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"] +plot = ["matplotlib"] +tgrep = ["pyparsing"] +twitter = ["twython"] + +[[package]] +name = "nodeenv" +version = "1.9.1" +description = "Node.js virtual environment builder" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, + {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, +] + +[[package]] +name = "notebook" +version = "7.2.1" +description = "Jupyter Notebook - A web-based notebook environment for interactive computing" +optional = false +python-versions = ">=3.8" +files = [ + {file = "notebook-7.2.1-py3-none-any.whl", hash = "sha256:f45489a3995746f2195a137e0773e2130960b51c9ac3ce257dbc2705aab3a6ca"}, + {file = "notebook-7.2.1.tar.gz", hash = "sha256:4287b6da59740b32173d01d641f763d292f49c30e7a51b89c46ba8473126341e"}, +] + +[package.dependencies] +jupyter-server = ">=2.4.0,<3" +jupyterlab = ">=4.2.0,<4.3" +jupyterlab-server = ">=2.27.1,<3" +notebook-shim = ">=0.2,<0.3" +tornado = ">=6.2.0" + +[package.extras] +dev = ["hatch", "pre-commit"] +docs = ["myst-parser", "nbsphinx", "pydata-sphinx-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["importlib-resources (>=5.0)", "ipykernel", "jupyter-server[test] (>=2.4.0,<3)", "jupyterlab-server[test] (>=2.27.1,<3)", "nbval", "pytest (>=7.0)", "pytest-console-scripts", "pytest-timeout", "pytest-tornasync", "requests"] + +[[package]] +name = "notebook-shim" +version = "0.2.4" +description = "A shim layer for notebook traits and config" +optional = false +python-versions = ">=3.7" +files = [ + {file = "notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef"}, + {file = "notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb"}, +] + +[package.dependencies] +jupyter-server = ">=1.8,<3" + +[package.extras] +test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync"] + +[[package]] +name = "numba" +version = "0.60.0" +description = "compiling Python code using LLVM" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numba-0.60.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d761de835cd38fb400d2c26bb103a2726f548dc30368853121d66201672e651"}, + {file = "numba-0.60.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:159e618ef213fba758837f9837fb402bbe65326e60ba0633dbe6c7f274d42c1b"}, + {file = "numba-0.60.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1527dc578b95c7c4ff248792ec33d097ba6bef9eda466c948b68dfc995c25781"}, + {file = "numba-0.60.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe0b28abb8d70f8160798f4de9d486143200f34458d34c4a214114e445d7124e"}, + {file = "numba-0.60.0-cp310-cp310-win_amd64.whl", hash = "sha256:19407ced081d7e2e4b8d8c36aa57b7452e0283871c296e12d798852bc7d7f198"}, + {file = "numba-0.60.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a17b70fc9e380ee29c42717e8cc0bfaa5556c416d94f9aa96ba13acb41bdece8"}, + {file = "numba-0.60.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3fb02b344a2a80efa6f677aa5c40cd5dd452e1b35f8d1c2af0dfd9ada9978e4b"}, + {file = "numba-0.60.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5f4fde652ea604ea3c86508a3fb31556a6157b2c76c8b51b1d45eb40c8598703"}, + {file = "numba-0.60.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4142d7ac0210cc86432b818338a2bc368dc773a2f5cf1e32ff7c5b378bd63ee8"}, + {file = "numba-0.60.0-cp311-cp311-win_amd64.whl", hash = "sha256:cac02c041e9b5bc8cf8f2034ff6f0dbafccd1ae9590dc146b3a02a45e53af4e2"}, + {file = "numba-0.60.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7da4098db31182fc5ffe4bc42c6f24cd7d1cb8a14b59fd755bfee32e34b8404"}, + {file = "numba-0.60.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38d6ea4c1f56417076ecf8fc327c831ae793282e0ff51080c5094cb726507b1c"}, + {file = "numba-0.60.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:62908d29fb6a3229c242e981ca27e32a6e606cc253fc9e8faeb0e48760de241e"}, + {file = "numba-0.60.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0ebaa91538e996f708f1ab30ef4d3ddc344b64b5227b67a57aa74f401bb68b9d"}, + {file = "numba-0.60.0-cp312-cp312-win_amd64.whl", hash = "sha256:f75262e8fe7fa96db1dca93d53a194a38c46da28b112b8a4aca168f0df860347"}, + {file = "numba-0.60.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:01ef4cd7d83abe087d644eaa3d95831b777aa21d441a23703d649e06b8e06b74"}, + {file = "numba-0.60.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:819a3dfd4630d95fd574036f99e47212a1af41cbcb019bf8afac63ff56834449"}, + {file = "numba-0.60.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0b983bd6ad82fe868493012487f34eae8bf7dd94654951404114f23c3466d34b"}, + {file = "numba-0.60.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c151748cd269ddeab66334bd754817ffc0cabd9433acb0f551697e5151917d25"}, + {file = "numba-0.60.0-cp39-cp39-win_amd64.whl", hash = "sha256:3031547a015710140e8c87226b4cfe927cac199835e5bf7d4fe5cb64e814e3ab"}, + {file = "numba-0.60.0.tar.gz", hash = "sha256:5df6158e5584eece5fc83294b949fd30b9f1125df7708862205217e068aabf16"}, +] + +[package.dependencies] +llvmlite = "==0.43.*" +numpy = ">=1.22,<2.1" + +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + +[[package]] +name = "openai" +version = "1.35.14" +description = "The official Python library for the openai API" +optional = false +python-versions = ">=3.7.1" +files = [ + {file = "openai-1.35.14-py3-none-any.whl", hash = "sha256:adadf8c176e0b8c47ad782ed45dc20ef46438ee1f02c7103c4155cff79c8f68b"}, + {file = "openai-1.35.14.tar.gz", hash = "sha256:394ba1dfd12ecec1d634c50e512d24ff1858bbc2674ffcce309b822785a058de"}, +] + +[package.dependencies] +anyio = ">=3.5.0,<5" +distro = ">=1.7.0,<2" +httpx = ">=0.23.0,<1" +pydantic = ">=1.9.0,<3" +sniffio = "*" +tqdm = ">4" +typing-extensions = ">=4.7,<5" + +[package.extras] +datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] + +[[package]] +name = "overrides" +version = "7.7.0" +description = "A decorator to automatically detect mismatch when overriding a method." +optional = false +python-versions = ">=3.6" +files = [ + {file = "overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49"}, + {file = "overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a"}, +] + +[[package]] +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] + +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + +[[package]] +name = "pandocfilters" +version = "1.5.1" +description = "Utilities for writing pandoc filters in python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc"}, + {file = "pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e"}, +] + +[[package]] +name = "parso" +version = "0.8.4" +description = "A Python Parser" +optional = false +python-versions = ">=3.6" +files = [ + {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, + {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, +] + +[package.extras] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["docopt", "pytest"] + +[[package]] +name = "partd" +version = "1.4.2" +description = "Appendable key-value storage" +optional = false +python-versions = ">=3.9" +files = [ + {file = "partd-1.4.2-py3-none-any.whl", hash = "sha256:978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f"}, + {file = "partd-1.4.2.tar.gz", hash = "sha256:d022c33afbdc8405c226621b015e8067888173d85f7f5ecebb3cafed9a20f02c"}, +] + +[package.dependencies] +locket = "*" +toolz = "*" + +[package.extras] +complete = ["blosc", "numpy (>=1.20.0)", "pandas (>=1.3)", "pyzmq"] + +[[package]] +name = "pastel" +version = "0.2.1" +description = "Bring colors to your terminal." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"}, + {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, +] + +[[package]] +name = "patsy" +version = "0.5.6" +description = "A Python package for describing statistical models and for building design matrices." +optional = false +python-versions = "*" +files = [ + {file = "patsy-0.5.6-py2.py3-none-any.whl", hash = "sha256:19056886fd8fa71863fa32f0eb090267f21fb74be00f19f5c70b2e9d76c883c6"}, + {file = "patsy-0.5.6.tar.gz", hash = "sha256:95c6d47a7222535f84bff7f63d7303f2e297747a598db89cf5c67f0c0c7d2cdb"}, +] + +[package.dependencies] +numpy = ">=1.4" +six = "*" + +[package.extras] +test = ["pytest", "pytest-cov", "scipy"] + +[[package]] +name = "pexpect" +version = "4.9.0" +description = "Pexpect allows easy control of interactive console applications." +optional = false +python-versions = "*" +files = [ + {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, + {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pillow" +version = "10.4.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, + {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, + {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, + {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, + {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, + {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, + {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, + {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, + {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, + {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, + {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, + {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, + {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, + {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, + {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, + {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, + {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, + {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, + {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions"] +xmp = ["defusedxml"] + +[[package]] +name = "platformdirs" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "poethepoet" +version = "0.26.1" +description = "A task runner that works well with poetry." +optional = false +python-versions = ">=3.8" +files = [ + {file = "poethepoet-0.26.1-py3-none-any.whl", hash = "sha256:aa43b443fec5d17d7e76771cccd484e5285805301721a74f059c483ad3276edd"}, + {file = "poethepoet-0.26.1.tar.gz", hash = "sha256:aaad8541f6072617a60bcff2562d00779b58b353bd0f1847b06d8d0f2b6dc192"}, +] + +[package.dependencies] +pastel = ">=0.2.1,<0.3.0" +tomli = ">=1.2.2" + +[package.extras] +poetry-plugin = ["poetry (>=1.0,<2.0)"] + +[[package]] +name = "portalocker" +version = "2.10.1" +description = "Wraps the portalocker recipe for easy usage" +optional = false +python-versions = ">=3.8" +files = [ + {file = "portalocker-2.10.1-py3-none-any.whl", hash = "sha256:53a5984ebc86a025552264b459b46a2086e269b21823cb572f8f28ee759e45bf"}, + {file = "portalocker-2.10.1.tar.gz", hash = "sha256:ef1bf844e878ab08aee7e40184156e1151f228f103aa5c6bd0724cc330960f8f"}, +] + +[package.dependencies] +pywin32 = {version = ">=226", markers = "platform_system == \"Windows\""} + +[package.extras] +docs = ["sphinx (>=1.7.1)"] +redis = ["redis"] +tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "pytest-timeout (>=2.1.0)", "redis", "sphinx (>=6.0.0)", "types-redis"] + +[[package]] +name = "pot" +version = "0.9.4" +description = "Python Optimal Transport Library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "POT-0.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8418ab9c24f549290fdc452caebb58ded05b986a024063fe3354cfd2e704b378"}, + {file = "POT-0.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:096cd3b454f87ff9c8f48d8e221bc26509d8f9355ce99d9fefe83560f82278b5"}, + {file = "POT-0.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6e67d420a479ed66f4549c785e157bb3dce2c5489bf81a44ac922a6e9471fe69"}, + {file = "POT-0.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:107bc7225906a3fa3aafdb441e1d24c55eaf1ee3badd1c93ab6199865f689221"}, + {file = "POT-0.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfee044f744b1722912654c8b905bc289ce160524db5ca0e853f1aa442ffea55"}, + {file = "POT-0.9.4-cp310-cp310-win32.whl", hash = "sha256:421c3efb8da2f1ce9605f9f2068047ea629b95de87baa15b8786b3e664de9dbd"}, + {file = "POT-0.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:6e76194a62f29ddadc975e18cf7f07d22060735bd3fb9a023781e0e126a05822"}, + {file = "POT-0.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:148040b89063790ab784458d5d200ba4a7f36c54fdb62ea0842f8d5d4c5c6ccb"}, + {file = "POT-0.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1109fc77989834a1467be731ff957d90c2b558e772cff6c06fb90f7cbe58b014"}, + {file = "POT-0.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9f8218cd419e8457b37fe2b8060b5bf9bd07d4671d5f5fa4d5ac98c58b5be8c0"}, + {file = "POT-0.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ea0055f18e26917ff326f39dd5e5fd43bcc9eccaab4b09a4f8d7785c8921250"}, + {file = "POT-0.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f03b4af3f56234787d2a34e0637dac9c1e1de4cb3f7386ca4f91331f0c4af187"}, + {file = "POT-0.9.4-cp311-cp311-win32.whl", hash = "sha256:a69f6d554df1de47dd312fc065d9171bdbedf48c90c8409889485945ffaaeacf"}, + {file = "POT-0.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:8791c8f09a852901e03e2dc1c6aec4f374b58b3ee905a90349713587aa16e26a"}, + {file = "POT-0.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1a7a55b3fd528e6808f99de0165dcacf185eb86ae3aff4d358b850479b76a8ba"}, + {file = "POT-0.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a9bbd2507605be6eae4f0f0d6f6f0ff91ce3eeb5b7c8eeb350e4eb76bcc6940a"}, + {file = "POT-0.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5594ab0e78329307ce4cd293f2de409513876695d60fb4c1013b5dd46069f256"}, + {file = "POT-0.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0ca658105d129b752c8d20751ff2cb965d1bdcaecec319ae489b135c58d9da9"}, + {file = "POT-0.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6732f1acd94959b8fa13a4fa250ad49c1e6894ece488a81f4427dbf13df4776"}, + {file = "POT-0.9.4-cp312-cp312-win32.whl", hash = "sha256:bf7f5253fee6ba7df5dd854b739540f701153cabab80dd25332dfac93d84bec1"}, + {file = "POT-0.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:597ff64b06a157871feb84e6e82b3f5dfbfff57161c14660ab2ddbcc93c940e6"}, + {file = "POT-0.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:385b41606943fbc73f1ab96fd994117d79c4ad782c91bbb7ba74c0359e9de887"}, + {file = "POT-0.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3f697e084243b9fe0a975331e471fd09610343c6aa28172232958e39100ede6"}, + {file = "POT-0.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b967fb9cafc6ad30a6d51b21d6307b384491a106d6dc75f37bee52a3f63575c3"}, + {file = "POT-0.9.4-cp37-cp37m-win32.whl", hash = "sha256:35926c2f4d2ee49309dce340f7f6646fe451ca1e0d11b2d017a851d482bf4468"}, + {file = "POT-0.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:f29fa1fcd591d1940e2279dc1422ff46c0c273f6be4ecbcaa819d91dd196573e"}, + {file = "POT-0.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:63f8b50f448e32a4ae274dd1e68e22b1a2bc291c53c5c6ec5afadfb930b6a809"}, + {file = "POT-0.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cabd13a728d2db40b3989ad57810769dfba8972b686ae7f4881dbd315252e5d9"}, + {file = "POT-0.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5984157d5a819bd6c55db3b0d8fe631ff398c243e80a9e9e933cbd1ee7c7588c"}, + {file = "POT-0.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b8da4e3268eeee40dff96364f0a9f0326979d565d970ec74a1688b8ad338022"}, + {file = "POT-0.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ede957083299e4904627621f4d2c8a6b56af108fef9b486330f65519a395f10a"}, + {file = "POT-0.9.4-cp38-cp38-win32.whl", hash = "sha256:79716079d7970c6c0bf909f986c65d7103135e36b364ba5fa5caed97d7aa6464"}, + {file = "POT-0.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:3246493745bcf2b353312183b9ab547466cae711936f991a6754b62f55ff1dec"}, + {file = "POT-0.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:223c4ca199b679e4c2b8a79fb49d31f2c7fab2975c2c37d1e68a0a7fbe2bc55d"}, + {file = "POT-0.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c30d77994d02984ad32665f5975e272e8c02e8d5288c4edfbec08617c5c38f91"}, + {file = "POT-0.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5b0fe5be45112c12cc0f6ab61fb85ed9161ca540b24a4037e5d53ab86f390a49"}, + {file = "POT-0.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab68bdfeae54719d202e923f18ec29869c09b105e42f94568221fc92996f0f4d"}, + {file = "POT-0.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2847015e3bb65171eb70eca786f8cebe806960af40625ebc17c858b6314a9e0b"}, + {file = "POT-0.9.4-cp39-cp39-win32.whl", hash = "sha256:2e35d68c6e676108d6eeb7e6b119c4c19dca364992bca57f3f513660bfb1810c"}, + {file = "POT-0.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:e7d029f024ed58f8d10b3e4d517df551bb9758ac12d0503be793f44258f2dffc"}, + {file = "pot-0.9.4.tar.gz", hash = "sha256:4cf8b46bf4992c37529161c32dd5e3334e0c089399142f08ed6d455b57015edd"}, +] + +[package.dependencies] +numpy = ">=1.16" +scipy = ">=1.6" + +[package.extras] +all = ["autograd", "cvxopt", "jax", "jaxlib", "matplotlib", "pymanopt", "scikit-learn", "tensorflow", "torch", "torch-geometric"] +backend-jax = ["jax", "jaxlib"] +backend-tf = ["tensorflow"] +backend-torch = ["torch"] +cvxopt = ["cvxopt"] +dr = ["autograd", "pymanopt", "scikit-learn"] +gnn = ["torch", "torch-geometric"] +plot = ["matplotlib"] + +[[package]] +name = "prometheus-client" +version = "0.20.0" +description = "Python client for the Prometheus monitoring system." +optional = false +python-versions = ">=3.8" +files = [ + {file = "prometheus_client-0.20.0-py3-none-any.whl", hash = "sha256:cde524a85bce83ca359cc837f28b8c0db5cac7aa653a588fd7e84ba061c329e7"}, + {file = "prometheus_client-0.20.0.tar.gz", hash = "sha256:287629d00b147a32dcb2be0b9df905da599b2d82f80377083ec8463309a4bb89"}, +] + +[package.extras] +twisted = ["twisted"] + +[[package]] +name = "prompt-toolkit" +version = "3.0.47" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.47-py3-none-any.whl", hash = "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10"}, + {file = "prompt_toolkit-3.0.47.tar.gz", hash = "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360"}, +] + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "psutil" +version = "6.0.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, + {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, + {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, + {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, + {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, + {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, + {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, + {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, + {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, + {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, +] + +[package.extras] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = false +python-versions = "*" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "pure-eval" +version = "0.2.2" +description = "Safely evaluate AST nodes without side effects" +optional = false +python-versions = "*" +files = [ + {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, + {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, +] + +[package.extras] +tests = ["pytest"] + +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] + +[[package]] +name = "pyaml-env" +version = "1.2.1" +description = "Provides yaml file parsing with environment variable resolution" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyaml_env-1.2.1-py3-none-any.whl", hash = "sha256:2e7da2d4bba0629711ade1a41864e5e200c84ded896a3d27e9f560fae7311c36"}, + {file = "pyaml_env-1.2.1.tar.gz", hash = "sha256:6d5dc98c8c82df743a132c196e79963050c9feb05b0a6f25f3ad77771d3d95b0"}, +] + +[package.dependencies] +PyYAML = ">=5.0,<=7.0" + +[package.extras] +test = ["pytest"] + +[[package]] +name = "pyarrow" +version = "15.0.0" +description = "Python library for Apache Arrow" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyarrow-15.0.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:0a524532fd6dd482edaa563b686d754c70417c2f72742a8c990b322d4c03a15d"}, + {file = "pyarrow-15.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:60a6bdb314affa9c2e0d5dddf3d9cbb9ef4a8dddaa68669975287d47ece67642"}, + {file = "pyarrow-15.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66958fd1771a4d4b754cd385835e66a3ef6b12611e001d4e5edfcef5f30391e2"}, + {file = "pyarrow-15.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f500956a49aadd907eaa21d4fff75f73954605eaa41f61cb94fb008cf2e00c6"}, + {file = "pyarrow-15.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6f87d9c4f09e049c2cade559643424da84c43a35068f2a1c4653dc5b1408a929"}, + {file = "pyarrow-15.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85239b9f93278e130d86c0e6bb455dcb66fc3fd891398b9d45ace8799a871a1e"}, + {file = "pyarrow-15.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:5b8d43e31ca16aa6e12402fcb1e14352d0d809de70edd185c7650fe80e0769e3"}, + {file = "pyarrow-15.0.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:fa7cd198280dbd0c988df525e50e35b5d16873e2cdae2aaaa6363cdb64e3eec5"}, + {file = "pyarrow-15.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8780b1a29d3c8b21ba6b191305a2a607de2e30dab399776ff0aa09131e266340"}, + {file = "pyarrow-15.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe0ec198ccc680f6c92723fadcb97b74f07c45ff3fdec9dd765deb04955ccf19"}, + {file = "pyarrow-15.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:036a7209c235588c2f07477fe75c07e6caced9b7b61bb897c8d4e52c4b5f9555"}, + {file = "pyarrow-15.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:2bd8a0e5296797faf9a3294e9fa2dc67aa7f10ae2207920dbebb785c77e9dbe5"}, + {file = "pyarrow-15.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:e8ebed6053dbe76883a822d4e8da36860f479d55a762bd9e70d8494aed87113e"}, + {file = "pyarrow-15.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:17d53a9d1b2b5bd7d5e4cd84d018e2a45bc9baaa68f7e6e3ebed45649900ba99"}, + {file = "pyarrow-15.0.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:9950a9c9df24090d3d558b43b97753b8f5867fb8e521f29876aa021c52fda351"}, + {file = "pyarrow-15.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:003d680b5e422d0204e7287bb3fa775b332b3fce2996aa69e9adea23f5c8f970"}, + {file = "pyarrow-15.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f75fce89dad10c95f4bf590b765e3ae98bcc5ba9f6ce75adb828a334e26a3d40"}, + {file = "pyarrow-15.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca9cb0039923bec49b4fe23803807e4ef39576a2bec59c32b11296464623dc2"}, + {file = "pyarrow-15.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:9ed5a78ed29d171d0acc26a305a4b7f83c122d54ff5270810ac23c75813585e4"}, + {file = "pyarrow-15.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:6eda9e117f0402dfcd3cd6ec9bfee89ac5071c48fc83a84f3075b60efa96747f"}, + {file = "pyarrow-15.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9a3a6180c0e8f2727e6f1b1c87c72d3254cac909e609f35f22532e4115461177"}, + {file = "pyarrow-15.0.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:19a8918045993349b207de72d4576af0191beef03ea655d8bdb13762f0cd6eac"}, + {file = "pyarrow-15.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0ec076b32bacb6666e8813a22e6e5a7ef1314c8069d4ff345efa6246bc38593"}, + {file = "pyarrow-15.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5db1769e5d0a77eb92344c7382d6543bea1164cca3704f84aa44e26c67e320fb"}, + {file = "pyarrow-15.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2617e3bf9df2a00020dd1c1c6dce5cc343d979efe10bc401c0632b0eef6ef5b"}, + {file = "pyarrow-15.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:d31c1d45060180131caf10f0f698e3a782db333a422038bf7fe01dace18b3a31"}, + {file = "pyarrow-15.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:c8c287d1d479de8269398b34282e206844abb3208224dbdd7166d580804674b7"}, + {file = "pyarrow-15.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:07eb7f07dc9ecbb8dace0f58f009d3a29ee58682fcdc91337dfeb51ea618a75b"}, + {file = "pyarrow-15.0.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:47af7036f64fce990bb8a5948c04722e4e3ea3e13b1007ef52dfe0aa8f23cf7f"}, + {file = "pyarrow-15.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93768ccfff85cf044c418bfeeafce9a8bb0cee091bd8fd19011aff91e58de540"}, + {file = "pyarrow-15.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6ee87fd6892700960d90abb7b17a72a5abb3b64ee0fe8db6c782bcc2d0dc0b4"}, + {file = "pyarrow-15.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:001fca027738c5f6be0b7a3159cc7ba16a5c52486db18160909a0831b063c4e4"}, + {file = "pyarrow-15.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:d1c48648f64aec09accf44140dccb92f4f94394b8d79976c426a5b79b11d4fa7"}, + {file = "pyarrow-15.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:972a0141be402bb18e3201448c8ae62958c9c7923dfaa3b3d4530c835ac81aed"}, + {file = "pyarrow-15.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:f01fc5cf49081426429127aa2d427d9d98e1cb94a32cb961d583a70b7c4504e6"}, + {file = "pyarrow-15.0.0.tar.gz", hash = "sha256:876858f549d540898f927eba4ef77cd549ad8d24baa3207cf1b72e5788b50e83"}, +] + +[package.dependencies] +numpy = ">=1.16.6,<2" + +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pydantic" +version = "2.8.2" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, + {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, +] + +[package.dependencies] +annotated-types = ">=0.4.0" +pydantic-core = "2.20.1" +typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} + +[package.extras] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.20.1" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, + {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, + {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, + {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, + {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, + {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, + {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, + {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, + {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, + {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, + {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, + {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, + {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, + {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "pygments" +version = "2.18.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pyjwt" +version = "2.8.0" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "PyJWT-2.8.0-py3-none-any.whl", hash = "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320"}, + {file = "PyJWT-2.8.0.tar.gz", hash = "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"}, +] + +[package.dependencies] +cryptography = {version = ">=3.4.0", optional = true, markers = "extra == \"crypto\""} + +[package.extras] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] + +[[package]] +name = "pylance" +version = "0.14.1" +description = "python wrapper for Lance columnar format" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pylance-0.14.1-cp39-abi3-macosx_10_15_x86_64.whl", hash = "sha256:893f4d95bda9f676cacca91e51e5bd2e9c3714a01145f42091b1820027a47401"}, + {file = "pylance-0.14.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:f5ed83cbe258dcd3c7595e87c88cbb69eb793b2ae8989afa3787719f33c99ecb"}, + {file = "pylance-0.14.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2362925d117ea5a8759ace481818f31c782c1ad9915bfd93d868615a393c4f9"}, + {file = "pylance-0.14.1-cp39-abi3-manylinux_2_24_aarch64.whl", hash = "sha256:da64d1f8bbc1ea581c2fb7e44b9712608422e78e6bd620eaf0ffa0929ce7a131"}, + {file = "pylance-0.14.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:e9307e27249262e3a95e6ec52021c9179025b24fc9d146af6a5810f1d35de8ec"}, + {file = "pylance-0.14.1-cp39-abi3-win_amd64.whl", hash = "sha256:a64ab20b0ec8e602bc7ef8e73b2dd14e4969900f237c1ea804c41b2216e2db1a"}, +] + +[package.dependencies] +numpy = ">=1.22" +pyarrow = ">=12,<15.0.1" + +[package.extras] +benchmarks = ["pytest-benchmark"] +dev = ["ruff (==0.4.1)"] +ray = ["ray[data]"] +tests = ["boto3", "datasets", "duckdb", "h5py (<3.11)", "ml-dtypes", "pandas", "pillow", "polars[pandas,pyarrow]", "pytest", "tensorflow", "tqdm"] +torch = ["torch"] + +[[package]] +name = "pynndescent" +version = "0.5.13" +description = "Nearest Neighbor Descent" +optional = false +python-versions = "*" +files = [ + {file = "pynndescent-0.5.13-py3-none-any.whl", hash = "sha256:69aabb8f394bc631b6ac475a1c7f3994c54adf3f51cd63b2730fefba5771b949"}, + {file = "pynndescent-0.5.13.tar.gz", hash = "sha256:d74254c0ee0a1eeec84597d5fe89fedcf778593eeabe32c2f97412934a9800fb"}, +] + +[package.dependencies] +joblib = ">=0.11" +llvmlite = ">=0.30" +numba = ">=0.51.2" +scikit-learn = ">=0.18" +scipy = ">=1.0" + +[[package]] +name = "pyparsing" +version = "3.1.2" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, + {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pyright" +version = "1.1.371" +description = "Command line wrapper for pyright" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyright-1.1.371-py3-none-any.whl", hash = "sha256:cce52e42ff73943243e7e5e24f2a59dee81b97d99f4e3cf97370b27e8a1858cd"}, + {file = "pyright-1.1.371.tar.gz", hash = "sha256:777b508b92dda2db476214c400ce043aad8d8f3dd0e10d284c96e79f298308b5"}, +] + +[package.dependencies] +nodeenv = ">=1.6.0" + +[package.extras] +all = ["twine (>=3.4.1)"] +dev = ["twine (>=3.4.1)"] + +[[package]] +name = "pytest" +version = "8.2.2" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, + {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2.0" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-asyncio" +version = "0.23.7" +description = "Pytest support for asyncio" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest_asyncio-0.23.7-py3-none-any.whl", hash = "sha256:009b48127fbe44518a547bddd25611551b0e43ccdbf1e67d12479f569832c20b"}, + {file = "pytest_asyncio-0.23.7.tar.gz", hash = "sha256:5f5c72948f4c49e7db4f29f2521d4031f1c27f86e57b046126654083d4770268"}, +] + +[package.dependencies] +pytest = ">=7.0.0,<9" + +[package.extras] +docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] +testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] + +[[package]] +name = "pytest-timeout" +version = "2.3.1" +description = "pytest plugin to abort hanging tests" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-timeout-2.3.1.tar.gz", hash = "sha256:12397729125c6ecbdaca01035b9e5239d4db97352320af155b3f5de1ba5165d9"}, + {file = "pytest_timeout-2.3.1-py3-none-any.whl", hash = "sha256:68188cb703edfc6a18fad98dc25a3c61e9f24d644b0b70f33af545219fc7813e"}, +] + +[package.dependencies] +pytest = ">=7.0.0" + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-dotenv" +version = "1.0.1" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, + {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + +[[package]] +name = "python-json-logger" +version = "2.0.7" +description = "A python library adding a json log formatter" +optional = false +python-versions = ">=3.6" +files = [ + {file = "python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c"}, + {file = "python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd"}, +] + +[[package]] +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, +] + +[[package]] +name = "pywin32" +version = "306" +description = "Python for Window Extensions" +optional = false +python-versions = "*" +files = [ + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, +] + +[[package]] +name = "pywinpty" +version = "2.0.13" +description = "Pseudo terminal support for Windows from Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pywinpty-2.0.13-cp310-none-win_amd64.whl", hash = "sha256:697bff211fb5a6508fee2dc6ff174ce03f34a9a233df9d8b5fe9c8ce4d5eaf56"}, + {file = "pywinpty-2.0.13-cp311-none-win_amd64.whl", hash = "sha256:b96fb14698db1284db84ca38c79f15b4cfdc3172065b5137383910567591fa99"}, + {file = "pywinpty-2.0.13-cp312-none-win_amd64.whl", hash = "sha256:2fd876b82ca750bb1333236ce98488c1be96b08f4f7647cfdf4129dfad83c2d4"}, + {file = "pywinpty-2.0.13-cp38-none-win_amd64.whl", hash = "sha256:61d420c2116c0212808d31625611b51caf621fe67f8a6377e2e8b617ea1c1f7d"}, + {file = "pywinpty-2.0.13-cp39-none-win_amd64.whl", hash = "sha256:71cb613a9ee24174730ac7ae439fd179ca34ccb8c5349e8d7b72ab5dea2c6f4b"}, + {file = "pywinpty-2.0.13.tar.gz", hash = "sha256:c34e32351a3313ddd0d7da23d27f835c860d32fe4ac814d372a3ea9594f41dde"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "pyzmq" +version = "26.0.3" +description = "Python bindings for 0MQ" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyzmq-26.0.3-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:44dd6fc3034f1eaa72ece33588867df9e006a7303725a12d64c3dff92330f625"}, + {file = "pyzmq-26.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:acb704195a71ac5ea5ecf2811c9ee19ecdc62b91878528302dd0be1b9451cc90"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dbb9c997932473a27afa93954bb77a9f9b786b4ccf718d903f35da3232317de"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6bcb34f869d431799c3ee7d516554797f7760cb2198ecaa89c3f176f72d062be"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ece17ec5f20d7d9b442e5174ae9f020365d01ba7c112205a4d59cf19dc38ee"}, + {file = "pyzmq-26.0.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:ba6e5e6588e49139a0979d03a7deb9c734bde647b9a8808f26acf9c547cab1bf"}, + {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3bf8b000a4e2967e6dfdd8656cd0757d18c7e5ce3d16339e550bd462f4857e59"}, + {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2136f64fbb86451dbbf70223635a468272dd20075f988a102bf8a3f194a411dc"}, + {file = "pyzmq-26.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e8918973fbd34e7814f59143c5f600ecd38b8038161239fd1a3d33d5817a38b8"}, + {file = "pyzmq-26.0.3-cp310-cp310-win32.whl", hash = "sha256:0aaf982e68a7ac284377d051c742610220fd06d330dcd4c4dbb4cdd77c22a537"}, + {file = "pyzmq-26.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:f1a9b7d00fdf60b4039f4455afd031fe85ee8305b019334b72dcf73c567edc47"}, + {file = "pyzmq-26.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:80b12f25d805a919d53efc0a5ad7c0c0326f13b4eae981a5d7b7cc343318ebb7"}, + {file = "pyzmq-26.0.3-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:a72a84570f84c374b4c287183debc776dc319d3e8ce6b6a0041ce2e400de3f32"}, + {file = "pyzmq-26.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ca684ee649b55fd8f378127ac8462fb6c85f251c2fb027eb3c887e8ee347bcd"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e222562dc0f38571c8b1ffdae9d7adb866363134299264a1958d077800b193b7"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f17cde1db0754c35a91ac00b22b25c11da6eec5746431d6e5092f0cd31a3fea9"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b7c0c0b3244bb2275abe255d4a30c050d541c6cb18b870975553f1fb6f37527"}, + {file = "pyzmq-26.0.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:ac97a21de3712afe6a6c071abfad40a6224fd14fa6ff0ff8d0c6e6cd4e2f807a"}, + {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:88b88282e55fa39dd556d7fc04160bcf39dea015f78e0cecec8ff4f06c1fc2b5"}, + {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:72b67f966b57dbd18dcc7efbc1c7fc9f5f983e572db1877081f075004614fcdd"}, + {file = "pyzmq-26.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4b6cecbbf3b7380f3b61de3a7b93cb721125dc125c854c14ddc91225ba52f83"}, + {file = "pyzmq-26.0.3-cp311-cp311-win32.whl", hash = "sha256:eed56b6a39216d31ff8cd2f1d048b5bf1700e4b32a01b14379c3b6dde9ce3aa3"}, + {file = "pyzmq-26.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:3191d312c73e3cfd0f0afdf51df8405aafeb0bad71e7ed8f68b24b63c4f36500"}, + {file = "pyzmq-26.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:b6907da3017ef55139cf0e417c5123a84c7332520e73a6902ff1f79046cd3b94"}, + {file = "pyzmq-26.0.3-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:068ca17214038ae986d68f4a7021f97e187ed278ab6dccb79f837d765a54d753"}, + {file = "pyzmq-26.0.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7821d44fe07335bea256b9f1f41474a642ca55fa671dfd9f00af8d68a920c2d4"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eeb438a26d87c123bb318e5f2b3d86a36060b01f22fbdffd8cf247d52f7c9a2b"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69ea9d6d9baa25a4dc9cef5e2b77b8537827b122214f210dd925132e34ae9b12"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7daa3e1369355766dea11f1d8ef829905c3b9da886ea3152788dc25ee6079e02"}, + {file = "pyzmq-26.0.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:6ca7a9a06b52d0e38ccf6bca1aeff7be178917893f3883f37b75589d42c4ac20"}, + {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1b7d0e124948daa4d9686d421ef5087c0516bc6179fdcf8828b8444f8e461a77"}, + {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e746524418b70f38550f2190eeee834db8850088c834d4c8406fbb9bc1ae10b2"}, + {file = "pyzmq-26.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:6b3146f9ae6af82c47a5282ac8803523d381b3b21caeae0327ed2f7ecb718798"}, + {file = "pyzmq-26.0.3-cp312-cp312-win32.whl", hash = "sha256:2b291d1230845871c00c8462c50565a9cd6026fe1228e77ca934470bb7d70ea0"}, + {file = "pyzmq-26.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:926838a535c2c1ea21c903f909a9a54e675c2126728c21381a94ddf37c3cbddf"}, + {file = "pyzmq-26.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:5bf6c237f8c681dfb91b17f8435b2735951f0d1fad10cc5dfd96db110243370b"}, + {file = "pyzmq-26.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c0991f5a96a8e620f7691e61178cd8f457b49e17b7d9cfa2067e2a0a89fc1d5"}, + {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:dbf012d8fcb9f2cf0643b65df3b355fdd74fc0035d70bb5c845e9e30a3a4654b"}, + {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:01fbfbeb8249a68d257f601deb50c70c929dc2dfe683b754659569e502fbd3aa"}, + {file = "pyzmq-26.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c8eb19abe87029c18f226d42b8a2c9efdd139d08f8bf6e085dd9075446db450"}, + {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5344b896e79800af86ad643408ca9aa303a017f6ebff8cee5a3163c1e9aec987"}, + {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:204e0f176fd1d067671157d049466869b3ae1fc51e354708b0dc41cf94e23a3a"}, + {file = "pyzmq-26.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a42db008d58530efa3b881eeee4991146de0b790e095f7ae43ba5cc612decbc5"}, + {file = "pyzmq-26.0.3-cp37-cp37m-win32.whl", hash = "sha256:8d7a498671ca87e32b54cb47c82a92b40130a26c5197d392720a1bce1b3c77cf"}, + {file = "pyzmq-26.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:3b4032a96410bdc760061b14ed6a33613ffb7f702181ba999df5d16fb96ba16a"}, + {file = "pyzmq-26.0.3-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:2cc4e280098c1b192c42a849de8de2c8e0f3a84086a76ec5b07bfee29bda7d18"}, + {file = "pyzmq-26.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5bde86a2ed3ce587fa2b207424ce15b9a83a9fa14422dcc1c5356a13aed3df9d"}, + {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:34106f68e20e6ff253c9f596ea50397dbd8699828d55e8fa18bd4323d8d966e6"}, + {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ebbbd0e728af5db9b04e56389e2299a57ea8b9dd15c9759153ee2455b32be6ad"}, + {file = "pyzmq-26.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6b1d1c631e5940cac5a0b22c5379c86e8df6a4ec277c7a856b714021ab6cfad"}, + {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e891ce81edd463b3b4c3b885c5603c00141151dd9c6936d98a680c8c72fe5c67"}, + {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9b273ecfbc590a1b98f014ae41e5cf723932f3b53ba9367cfb676f838038b32c"}, + {file = "pyzmq-26.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b32bff85fb02a75ea0b68f21e2412255b5731f3f389ed9aecc13a6752f58ac97"}, + {file = "pyzmq-26.0.3-cp38-cp38-win32.whl", hash = "sha256:f6c21c00478a7bea93caaaef9e7629145d4153b15a8653e8bb4609d4bc70dbfc"}, + {file = "pyzmq-26.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:3401613148d93ef0fd9aabdbddb212de3db7a4475367f49f590c837355343972"}, + {file = "pyzmq-26.0.3-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:2ed8357f4c6e0daa4f3baf31832df8a33334e0fe5b020a61bc8b345a3db7a606"}, + {file = "pyzmq-26.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c1c8f2a2ca45292084c75bb6d3a25545cff0ed931ed228d3a1810ae3758f975f"}, + {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b63731993cdddcc8e087c64e9cf003f909262b359110070183d7f3025d1c56b5"}, + {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b3cd31f859b662ac5d7f4226ec7d8bd60384fa037fc02aee6ff0b53ba29a3ba8"}, + {file = "pyzmq-26.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:115f8359402fa527cf47708d6f8a0f8234f0e9ca0cab7c18c9c189c194dbf620"}, + {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:715bdf952b9533ba13dfcf1f431a8f49e63cecc31d91d007bc1deb914f47d0e4"}, + {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e1258c639e00bf5e8a522fec6c3eaa3e30cf1c23a2f21a586be7e04d50c9acab"}, + {file = "pyzmq-26.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:15c59e780be8f30a60816a9adab900c12a58d79c1ac742b4a8df044ab2a6d920"}, + {file = "pyzmq-26.0.3-cp39-cp39-win32.whl", hash = "sha256:d0cdde3c78d8ab5b46595054e5def32a755fc028685add5ddc7403e9f6de9879"}, + {file = "pyzmq-26.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:ce828058d482ef860746bf532822842e0ff484e27f540ef5c813d516dd8896d2"}, + {file = "pyzmq-26.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:788f15721c64109cf720791714dc14afd0f449d63f3a5487724f024345067381"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c18645ef6294d99b256806e34653e86236eb266278c8ec8112622b61db255de"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e6bc96ebe49604df3ec2c6389cc3876cabe475e6bfc84ced1bf4e630662cb35"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:971e8990c5cc4ddcff26e149398fc7b0f6a042306e82500f5e8db3b10ce69f84"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8416c23161abd94cc7da80c734ad7c9f5dbebdadfdaa77dad78244457448223"}, + {file = "pyzmq-26.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:082a2988364b60bb5de809373098361cf1dbb239623e39e46cb18bc035ed9c0c"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d57dfbf9737763b3a60d26e6800e02e04284926329aee8fb01049635e957fe81"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:77a85dca4c2430ac04dc2a2185c2deb3858a34fe7f403d0a946fa56970cf60a1"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4c82a6d952a1d555bf4be42b6532927d2a5686dd3c3e280e5f63225ab47ac1f5"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4496b1282c70c442809fc1b151977c3d967bfb33e4e17cedbf226d97de18f709"}, + {file = "pyzmq-26.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:e4946d6bdb7ba972dfda282f9127e5756d4f299028b1566d1245fa0d438847e6"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:03c0ae165e700364b266876d712acb1ac02693acd920afa67da2ebb91a0b3c09"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:3e3070e680f79887d60feeda051a58d0ac36622e1759f305a41059eff62c6da7"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6ca08b840fe95d1c2bd9ab92dac5685f949fc6f9ae820ec16193e5ddf603c3b2"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e76654e9dbfb835b3518f9938e565c7806976c07b37c33526b574cc1a1050480"}, + {file = "pyzmq-26.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:871587bdadd1075b112e697173e946a07d722459d20716ceb3d1bd6c64bd08ce"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d0a2d1bd63a4ad79483049b26514e70fa618ce6115220da9efdff63688808b17"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0270b49b6847f0d106d64b5086e9ad5dc8a902413b5dbbb15d12b60f9c1747a4"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:703c60b9910488d3d0954ca585c34f541e506a091a41930e663a098d3b794c67"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74423631b6be371edfbf7eabb02ab995c2563fee60a80a30829176842e71722a"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4adfbb5451196842a88fda3612e2c0414134874bffb1c2ce83ab4242ec9e027d"}, + {file = "pyzmq-26.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3516119f4f9b8671083a70b6afaa0a070f5683e431ab3dc26e9215620d7ca1ad"}, + {file = "pyzmq-26.0.3.tar.gz", hash = "sha256:dba7d9f2e047dfa2bca3b01f4f84aa5246725203d6284e3790f2ca15fba6b40a"}, +] + +[package.dependencies] +cffi = {version = "*", markers = "implementation_name == \"pypy\""} + +[[package]] +name = "qtconsole" +version = "5.5.2" +description = "Jupyter Qt console" +optional = false +python-versions = ">=3.8" +files = [ + {file = "qtconsole-5.5.2-py3-none-any.whl", hash = "sha256:42d745f3d05d36240244a04e1e1ec2a86d5d9b6edb16dbdef582ccb629e87e0b"}, + {file = "qtconsole-5.5.2.tar.gz", hash = "sha256:6b5fb11274b297463706af84dcbbd5c92273b1f619e6d25d08874b0a88516989"}, +] + +[package.dependencies] +ipykernel = ">=4.1" +jupyter-client = ">=4.1" +jupyter-core = "*" +packaging = "*" +pygments = "*" +pyzmq = ">=17.1" +qtpy = ">=2.4.0" +traitlets = "<5.2.1 || >5.2.1,<5.2.2 || >5.2.2" + +[package.extras] +doc = ["Sphinx (>=1.3)"] +test = ["flaky", "pytest", "pytest-qt"] + +[[package]] +name = "qtpy" +version = "2.4.1" +description = "Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6)." +optional = false +python-versions = ">=3.7" +files = [ + {file = "QtPy-2.4.1-py3-none-any.whl", hash = "sha256:1c1d8c4fa2c884ae742b069151b0abe15b3f70491f3972698c683b8e38de839b"}, + {file = "QtPy-2.4.1.tar.gz", hash = "sha256:a5a15ffd519550a1361bdc56ffc07fda56a6af7292f17c7b395d4083af632987"}, +] + +[package.dependencies] +packaging = "*" + +[package.extras] +test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"] + +[[package]] +name = "ratelimiter" +version = "1.2.0.post0" +description = "Simple python rate limiting object" +optional = false +python-versions = "*" +files = [ + {file = "ratelimiter-1.2.0.post0-py3-none-any.whl", hash = "sha256:a52be07bc0bb0b3674b4b304550f10c769bbb00fead3072e035904474259809f"}, + {file = "ratelimiter-1.2.0.post0.tar.gz", hash = "sha256:5c395dcabdbbde2e5178ef3f89b568a3066454a6ddc223b76473dac22f89b4f7"}, +] + +[package.extras] +test = ["pytest (>=3.0)", "pytest-asyncio"] + +[[package]] +name = "referencing" +version = "0.35.1" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, + {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + +[[package]] +name = "regex" +version = "2024.5.15" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.8" +files = [ + {file = "regex-2024.5.15-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a81e3cfbae20378d75185171587cbf756015ccb14840702944f014e0d93ea09f"}, + {file = "regex-2024.5.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b59138b219ffa8979013be7bc85bb60c6f7b7575df3d56dc1e403a438c7a3f6"}, + {file = "regex-2024.5.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0bd000c6e266927cb7a1bc39d55be95c4b4f65c5be53e659537537e019232b1"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eaa7ddaf517aa095fa8da0b5015c44d03da83f5bd49c87961e3c997daed0de7"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba68168daedb2c0bab7fd7e00ced5ba90aebf91024dea3c88ad5063c2a562cca"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6e8d717bca3a6e2064fc3a08df5cbe366369f4b052dcd21b7416e6d71620dca1"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1337b7dbef9b2f71121cdbf1e97e40de33ff114801263b275aafd75303bd62b5"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9ebd0a36102fcad2f03696e8af4ae682793a5d30b46c647eaf280d6cfb32796"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9efa1a32ad3a3ea112224897cdaeb6aa00381627f567179c0314f7b65d354c62"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1595f2d10dff3d805e054ebdc41c124753631b6a471b976963c7b28543cf13b0"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b802512f3e1f480f41ab5f2cfc0e2f761f08a1f41092d6718868082fc0d27143"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a0981022dccabca811e8171f913de05720590c915b033b7e601f35ce4ea7019f"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:19068a6a79cf99a19ccefa44610491e9ca02c2be3305c7760d3831d38a467a6f"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1b5269484f6126eee5e687785e83c6b60aad7663dafe842b34691157e5083e53"}, + {file = "regex-2024.5.15-cp310-cp310-win32.whl", hash = "sha256:ada150c5adfa8fbcbf321c30c751dc67d2f12f15bd183ffe4ec7cde351d945b3"}, + {file = "regex-2024.5.15-cp310-cp310-win_amd64.whl", hash = "sha256:ac394ff680fc46b97487941f5e6ae49a9f30ea41c6c6804832063f14b2a5a145"}, + {file = "regex-2024.5.15-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f5b1dff3ad008dccf18e652283f5e5339d70bf8ba7c98bf848ac33db10f7bc7a"}, + {file = "regex-2024.5.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c6a2b494a76983df8e3d3feea9b9ffdd558b247e60b92f877f93a1ff43d26656"}, + {file = "regex-2024.5.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a32b96f15c8ab2e7d27655969a23895eb799de3665fa94349f3b2fbfd547236f"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10002e86e6068d9e1c91eae8295ef690f02f913c57db120b58fdd35a6bb1af35"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec54d5afa89c19c6dd8541a133be51ee1017a38b412b1321ccb8d6ddbeb4cf7d"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10e4ce0dca9ae7a66e6089bb29355d4432caed736acae36fef0fdd7879f0b0cb"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e507ff1e74373c4d3038195fdd2af30d297b4f0950eeda6f515ae3d84a1770f"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1f059a4d795e646e1c37665b9d06062c62d0e8cc3c511fe01315973a6542e40"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0721931ad5fe0dda45d07f9820b90b2148ccdd8e45bb9e9b42a146cb4f695649"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:833616ddc75ad595dee848ad984d067f2f31be645d603e4d158bba656bbf516c"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:287eb7f54fc81546346207c533ad3c2c51a8d61075127d7f6d79aaf96cdee890"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:19dfb1c504781a136a80ecd1fff9f16dddf5bb43cec6871778c8a907a085bb3d"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:119af6e56dce35e8dfb5222573b50c89e5508d94d55713c75126b753f834de68"}, + {file = "regex-2024.5.15-cp311-cp311-win32.whl", hash = "sha256:1c1c174d6ec38d6c8a7504087358ce9213d4332f6293a94fbf5249992ba54efa"}, + {file = "regex-2024.5.15-cp311-cp311-win_amd64.whl", hash = "sha256:9e717956dcfd656f5055cc70996ee2cc82ac5149517fc8e1b60261b907740201"}, + {file = "regex-2024.5.15-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:632b01153e5248c134007209b5c6348a544ce96c46005d8456de1d552455b014"}, + {file = "regex-2024.5.15-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e64198f6b856d48192bf921421fdd8ad8eb35e179086e99e99f711957ffedd6e"}, + {file = "regex-2024.5.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68811ab14087b2f6e0fc0c2bae9ad689ea3584cad6917fc57be6a48bbd012c49"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ec0c2fea1e886a19c3bee0cd19d862b3aa75dcdfb42ebe8ed30708df64687a"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d0c0c0003c10f54a591d220997dd27d953cd9ccc1a7294b40a4be5312be8797b"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2431b9e263af1953c55abbd3e2efca67ca80a3de8a0437cb58e2421f8184717a"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a605586358893b483976cffc1723fb0f83e526e8f14c6e6614e75919d9862cf"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:391d7f7f1e409d192dba8bcd42d3e4cf9e598f3979cdaed6ab11288da88cb9f2"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9ff11639a8d98969c863d4617595eb5425fd12f7c5ef6621a4b74b71ed8726d5"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4eee78a04e6c67e8391edd4dad3279828dd66ac4b79570ec998e2155d2e59fd5"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8fe45aa3f4aa57faabbc9cb46a93363edd6197cbc43523daea044e9ff2fea83e"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:d0a3d8d6acf0c78a1fff0e210d224b821081330b8524e3e2bc5a68ef6ab5803d"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c486b4106066d502495b3025a0a7251bf37ea9540433940a23419461ab9f2a80"}, + {file = "regex-2024.5.15-cp312-cp312-win32.whl", hash = "sha256:c49e15eac7c149f3670b3e27f1f28a2c1ddeccd3a2812cba953e01be2ab9b5fe"}, + {file = "regex-2024.5.15-cp312-cp312-win_amd64.whl", hash = "sha256:673b5a6da4557b975c6c90198588181029c60793835ce02f497ea817ff647cb2"}, + {file = "regex-2024.5.15-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:87e2a9c29e672fc65523fb47a90d429b70ef72b901b4e4b1bd42387caf0d6835"}, + {file = "regex-2024.5.15-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c3bea0ba8b73b71b37ac833a7f3fd53825924165da6a924aec78c13032f20850"}, + {file = "regex-2024.5.15-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bfc4f82cabe54f1e7f206fd3d30fda143f84a63fe7d64a81558d6e5f2e5aaba9"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5bb9425fe881d578aeca0b2b4b3d314ec88738706f66f219c194d67179337cb"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64c65783e96e563103d641760664125e91bd85d8e49566ee560ded4da0d3e704"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf2430df4148b08fb4324b848672514b1385ae3807651f3567871f130a728cc3"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5397de3219a8b08ae9540c48f602996aa6b0b65d5a61683e233af8605c42b0f2"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:455705d34b4154a80ead722f4f185b04c4237e8e8e33f265cd0798d0e44825fa"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2b6f1b3bb6f640c1a92be3bbfbcb18657b125b99ecf141fb3310b5282c7d4ed"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3ad070b823ca5890cab606c940522d05d3d22395d432f4aaaf9d5b1653e47ced"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5b5467acbfc153847d5adb21e21e29847bcb5870e65c94c9206d20eb4e99a384"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:e6662686aeb633ad65be2a42b4cb00178b3fbf7b91878f9446075c404ada552f"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:2b4c884767504c0e2401babe8b5b7aea9148680d2e157fa28f01529d1f7fcf67"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3cd7874d57f13bf70078f1ff02b8b0aa48d5b9ed25fc48547516c6aba36f5741"}, + {file = "regex-2024.5.15-cp38-cp38-win32.whl", hash = "sha256:e4682f5ba31f475d58884045c1a97a860a007d44938c4c0895f41d64481edbc9"}, + {file = "regex-2024.5.15-cp38-cp38-win_amd64.whl", hash = "sha256:d99ceffa25ac45d150e30bd9ed14ec6039f2aad0ffa6bb87a5936f5782fc1569"}, + {file = "regex-2024.5.15-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13cdaf31bed30a1e1c2453ef6015aa0983e1366fad2667657dbcac7b02f67133"}, + {file = "regex-2024.5.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cac27dcaa821ca271855a32188aa61d12decb6fe45ffe3e722401fe61e323cd1"}, + {file = "regex-2024.5.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7dbe2467273b875ea2de38ded4eba86cbcbc9a1a6d0aa11dcf7bd2e67859c435"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64f18a9a3513a99c4bef0e3efd4c4a5b11228b48aa80743be822b71e132ae4f5"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d347a741ea871c2e278fde6c48f85136c96b8659b632fb57a7d1ce1872547600"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1878b8301ed011704aea4c806a3cadbd76f84dece1ec09cc9e4dc934cfa5d4da"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4babf07ad476aaf7830d77000874d7611704a7fcf68c9c2ad151f5d94ae4bfc4"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35cb514e137cb3488bce23352af3e12fb0dbedd1ee6e60da053c69fb1b29cc6c"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cdd09d47c0b2efee9378679f8510ee6955d329424c659ab3c5e3a6edea696294"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:72d7a99cd6b8f958e85fc6ca5b37c4303294954eac1376535b03c2a43eb72629"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a094801d379ab20c2135529948cb84d417a2169b9bdceda2a36f5f10977ebc16"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c0c18345010870e58238790a6779a1219b4d97bd2e77e1140e8ee5d14df071aa"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:16093f563098448ff6b1fa68170e4acbef94e6b6a4e25e10eae8598bb1694b5d"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e38a7d4e8f633a33b4c7350fbd8bad3b70bf81439ac67ac38916c4a86b465456"}, + {file = "regex-2024.5.15-cp39-cp39-win32.whl", hash = "sha256:71a455a3c584a88f654b64feccc1e25876066c4f5ef26cd6dd711308aa538694"}, + {file = "regex-2024.5.15-cp39-cp39-win_amd64.whl", hash = "sha256:cab12877a9bdafde5500206d1020a584355a97884dfd388af3699e9137bf7388"}, + {file = "regex-2024.5.15.tar.gz", hash = "sha256:d3ee02d9e5f482cc8309134a91eeaacbdd2261ba111b0fef3748eeb4913e6a2c"}, +] + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "retry" +version = "0.9.2" +description = "Easy to use retry decorator." +optional = false +python-versions = "*" +files = [ + {file = "retry-0.9.2-py2.py3-none-any.whl", hash = "sha256:ccddf89761fa2c726ab29391837d4327f819ea14d244c232a1d24c67a2f98606"}, + {file = "retry-0.9.2.tar.gz", hash = "sha256:f8bfa8b99b69c4506d6f5bd3b0aabf77f98cdb17f3c9fc3f5ca820033336fba4"}, +] + +[package.dependencies] +decorator = ">=3.4.2" +py = ">=1.4.26,<2.0.0" + +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +description = "A pure python RFC3339 validator" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"}, + {file = "rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +description = "Pure python rfc3986 validator" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9"}, + {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"}, +] + +[[package]] +name = "rich" +version = "13.7.1" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, + {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + +[[package]] +name = "rpds-py" +version = "0.19.0" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.19.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:fb37bd599f031f1a6fb9e58ec62864ccf3ad549cf14bac527dbfa97123edcca4"}, + {file = "rpds_py-0.19.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3384d278df99ec2c6acf701d067147320b864ef6727405d6470838476e44d9e8"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54548e0be3ac117595408fd4ca0ac9278fde89829b0b518be92863b17ff67a2"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8eb488ef928cdbc05a27245e52de73c0d7c72a34240ef4d9893fdf65a8c1a955"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5da93debdfe27b2bfc69eefb592e1831d957b9535e0943a0ee8b97996de21b5"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79e205c70afddd41f6ee79a8656aec738492a550247a7af697d5bd1aee14f766"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:959179efb3e4a27610e8d54d667c02a9feaa86bbabaf63efa7faa4dfa780d4f1"}, + {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a6e605bb9edcf010f54f8b6a590dd23a4b40a8cb141255eec2a03db249bc915b"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9133d75dc119a61d1a0ded38fb9ba40a00ef41697cc07adb6ae098c875195a3f"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd36b712d35e757e28bf2f40a71e8f8a2d43c8b026d881aa0c617b450d6865c9"}, + {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:354f3a91718489912f2e0fc331c24eaaf6a4565c080e00fbedb6015857c00582"}, + {file = "rpds_py-0.19.0-cp310-none-win32.whl", hash = "sha256:ebcbf356bf5c51afc3290e491d3722b26aaf5b6af3c1c7f6a1b757828a46e336"}, + {file = "rpds_py-0.19.0-cp310-none-win_amd64.whl", hash = "sha256:75a6076289b2df6c8ecb9d13ff79ae0cad1d5fb40af377a5021016d58cd691ec"}, + {file = "rpds_py-0.19.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6d45080095e585f8c5097897313def60caa2046da202cdb17a01f147fb263b81"}, + {file = "rpds_py-0.19.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5c9581019c96f865483d031691a5ff1cc455feb4d84fc6920a5ffc48a794d8a"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1540d807364c84516417115c38f0119dfec5ea5c0dd9a25332dea60b1d26fc4d"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e65489222b410f79711dc3d2d5003d2757e30874096b2008d50329ea4d0f88c"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9da6f400eeb8c36f72ef6646ea530d6d175a4f77ff2ed8dfd6352842274c1d8b"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37f46bb11858717e0efa7893c0f7055c43b44c103e40e69442db5061cb26ed34"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:071d4adc734de562bd11d43bd134330fb6249769b2f66b9310dab7460f4bf714"}, + {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9625367c8955e4319049113ea4f8fee0c6c1145192d57946c6ffcd8fe8bf48dd"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e19509145275d46bc4d1e16af0b57a12d227c8253655a46bbd5ec317e941279d"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d438e4c020d8c39961deaf58f6913b1bf8832d9b6f62ec35bd93e97807e9cbc"}, + {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90bf55d9d139e5d127193170f38c584ed3c79e16638890d2e36f23aa1630b952"}, + {file = "rpds_py-0.19.0-cp311-none-win32.whl", hash = "sha256:8d6ad132b1bc13d05ffe5b85e7a01a3998bf3a6302ba594b28d61b8c2cf13aaf"}, + {file = "rpds_py-0.19.0-cp311-none-win_amd64.whl", hash = "sha256:7ec72df7354e6b7f6eb2a17fa6901350018c3a9ad78e48d7b2b54d0412539a67"}, + {file = "rpds_py-0.19.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:5095a7c838a8647c32aa37c3a460d2c48debff7fc26e1136aee60100a8cd8f68"}, + {file = "rpds_py-0.19.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f2f78ef14077e08856e788fa482107aa602636c16c25bdf59c22ea525a785e9"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7cc6cb44f8636fbf4a934ca72f3e786ba3c9f9ba4f4d74611e7da80684e48d2"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf902878b4af334a09de7a45badbff0389e7cf8dc2e4dcf5f07125d0b7c2656d"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:688aa6b8aa724db1596514751ffb767766e02e5c4a87486ab36b8e1ebc1aedac"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57dbc9167d48e355e2569346b5aa4077f29bf86389c924df25c0a8b9124461fb"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4cf5a9497874822341c2ebe0d5850fed392034caadc0bad134ab6822c0925b"}, + {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8a790d235b9d39c70a466200d506bb33a98e2ee374a9b4eec7a8ac64c2c261fa"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1d16089dfa58719c98a1c06f2daceba6d8e3fb9b5d7931af4a990a3c486241cb"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bc9128e74fe94650367fe23f37074f121b9f796cabbd2f928f13e9661837296d"}, + {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c8f77e661ffd96ff104bebf7d0f3255b02aa5d5b28326f5408d6284c4a8b3248"}, + {file = "rpds_py-0.19.0-cp312-none-win32.whl", hash = "sha256:5f83689a38e76969327e9b682be5521d87a0c9e5a2e187d2bc6be4765f0d4600"}, + {file = "rpds_py-0.19.0-cp312-none-win_amd64.whl", hash = "sha256:06925c50f86da0596b9c3c64c3837b2481337b83ef3519e5db2701df695453a4"}, + {file = "rpds_py-0.19.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:52e466bea6f8f3a44b1234570244b1cff45150f59a4acae3fcc5fd700c2993ca"}, + {file = "rpds_py-0.19.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e21cc693045fda7f745c790cb687958161ce172ffe3c5719ca1764e752237d16"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b31f059878eb1f5da8b2fd82480cc18bed8dcd7fb8fe68370e2e6285fa86da6"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dd46f309e953927dd018567d6a9e2fb84783963650171f6c5fe7e5c41fd5666"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34a01a4490e170376cd79258b7f755fa13b1a6c3667e872c8e35051ae857a92b"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcf426a8c38eb57f7bf28932e68425ba86def6e756a5b8cb4731d8e62e4e0223"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f68eea5df6347d3f1378ce992d86b2af16ad7ff4dcb4a19ccdc23dea901b87fb"}, + {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dab8d921b55a28287733263c0e4c7db11b3ee22aee158a4de09f13c93283c62d"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6fe87efd7f47266dfc42fe76dae89060038f1d9cb911f89ae7e5084148d1cc08"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:535d4b52524a961d220875688159277f0e9eeeda0ac45e766092bfb54437543f"}, + {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:8b1a94b8afc154fbe36978a511a1f155f9bd97664e4f1f7a374d72e180ceb0ae"}, + {file = "rpds_py-0.19.0-cp38-none-win32.whl", hash = "sha256:7c98298a15d6b90c8f6e3caa6457f4f022423caa5fa1a1ca7a5e9e512bdb77a4"}, + {file = "rpds_py-0.19.0-cp38-none-win_amd64.whl", hash = "sha256:b0da31853ab6e58a11db3205729133ce0df26e6804e93079dee095be3d681dc1"}, + {file = "rpds_py-0.19.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5039e3cef7b3e7a060de468a4a60a60a1f31786da94c6cb054e7a3c75906111c"}, + {file = "rpds_py-0.19.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab1932ca6cb8c7499a4d87cb21ccc0d3326f172cfb6a64021a889b591bb3045c"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2afd2164a1e85226fcb6a1da77a5c8896c18bfe08e82e8ceced5181c42d2179"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1c30841f5040de47a0046c243fc1b44ddc87d1b12435a43b8edff7e7cb1e0d0"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f757f359f30ec7dcebca662a6bd46d1098f8b9fb1fcd661a9e13f2e8ce343ba1"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15e65395a59d2e0e96caf8ee5389ffb4604e980479c32742936ddd7ade914b22"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb0f6eb3a320f24b94d177e62f4074ff438f2ad9d27e75a46221904ef21a7b05"}, + {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b228e693a2559888790936e20f5f88b6e9f8162c681830eda303bad7517b4d5a"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2575efaa5d949c9f4e2cdbe7d805d02122c16065bfb8d95c129372d65a291a0b"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5c872814b77a4e84afa293a1bee08c14daed1068b2bb1cc312edbf020bbbca2b"}, + {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:850720e1b383df199b8433a20e02b25b72f0fded28bc03c5bd79e2ce7ef050be"}, + {file = "rpds_py-0.19.0-cp39-none-win32.whl", hash = "sha256:ce84a7efa5af9f54c0aa7692c45861c1667080814286cacb9958c07fc50294fb"}, + {file = "rpds_py-0.19.0-cp39-none-win_amd64.whl", hash = "sha256:1c26da90b8d06227d7769f34915913911222d24ce08c0ab2d60b354e2d9c7aff"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:75969cf900d7be665ccb1622a9aba225cf386bbc9c3bcfeeab9f62b5048f4a07"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8445f23f13339da640d1be8e44e5baf4af97e396882ebbf1692aecd67f67c479"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5a7c1062ef8aea3eda149f08120f10795835fc1c8bc6ad948fb9652a113ca55"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:462b0c18fbb48fdbf980914a02ee38c423a25fcc4cf40f66bacc95a2d2d73bc8"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3208f9aea18991ac7f2b39721e947bbd752a1abbe79ad90d9b6a84a74d44409b"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3444fe52b82f122d8a99bf66777aed6b858d392b12f4c317da19f8234db4533"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88cb4bac7185a9f0168d38c01d7a00addece9822a52870eee26b8d5b61409213"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6b130bd4163c93798a6b9bb96be64a7c43e1cec81126ffa7ffaa106e1fc5cef5"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:a707b158b4410aefb6b054715545bbb21aaa5d5d0080217290131c49c2124a6e"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dc9ac4659456bde7c567107556ab065801622396b435a3ff213daef27b495388"}, + {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:81ea573aa46d3b6b3d890cd3c0ad82105985e6058a4baed03cf92518081eec8c"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3f148c3f47f7f29a79c38cc5d020edcb5ca780020fab94dbc21f9af95c463581"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0906357f90784a66e89ae3eadc2654f36c580a7d65cf63e6a616e4aec3a81be"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f629ecc2db6a4736b5ba95a8347b0089240d69ad14ac364f557d52ad68cf94b0"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c6feacd1d178c30e5bc37184526e56740342fd2aa6371a28367bad7908d454fc"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae8b6068ee374fdfab63689be0963333aa83b0815ead5d8648389a8ded593378"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d57546bad81e0da13263e4c9ce30e96dcbe720dbff5ada08d2600a3502e526"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b6683a37338818646af718c9ca2a07f89787551057fae57c4ec0446dc6224b"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e8481b946792415adc07410420d6fc65a352b45d347b78fec45d8f8f0d7496f0"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bec35eb20792ea64c3c57891bc3ca0bedb2884fbac2c8249d9b731447ecde4fa"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:aa5476c3e3a402c37779e95f7b4048db2cb5b0ed0b9d006983965e93f40fe05a"}, + {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:19d02c45f2507b489fd4df7b827940f1420480b3e2e471e952af4d44a1ea8e34"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a3e2fd14c5d49ee1da322672375963f19f32b3d5953f0615b175ff7b9d38daed"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:93a91c2640645303e874eada51f4f33351b84b351a689d470f8108d0e0694210"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b9fc03bf76a94065299d4a2ecd8dfbae4ae8e2e8098bbfa6ab6413ca267709"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a4b07cdf3f84310c08c1de2c12ddadbb7a77568bcb16e95489f9c81074322ed"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba0ed0dc6763d8bd6e5de5cf0d746d28e706a10b615ea382ac0ab17bb7388633"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:474bc83233abdcf2124ed3f66230a1c8435896046caa4b0b5ab6013c640803cc"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:329c719d31362355a96b435f4653e3b4b061fcc9eba9f91dd40804ca637d914e"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef9101f3f7b59043a34f1dccbb385ca760467590951952d6701df0da9893ca0c"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:0121803b0f424ee2109d6e1f27db45b166ebaa4b32ff47d6aa225642636cd834"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8344127403dea42f5970adccf6c5957a71a47f522171fafaf4c6ddb41b61703a"}, + {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:443cec402ddd650bb2b885113e1dcedb22b1175c6be223b14246a714b61cd521"}, + {file = "rpds_py-0.19.0.tar.gz", hash = "sha256:4fdc9afadbeb393b4bbbad75481e0ea78e4469f2e1d713a90811700830b553a9"}, +] + +[[package]] +name = "ruff" +version = "0.5.2" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.5.2-py3-none-linux_armv6l.whl", hash = "sha256:7bab8345df60f9368d5f4594bfb8b71157496b44c30ff035d1d01972e764d3be"}, + {file = "ruff-0.5.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:1aa7acad382ada0189dbe76095cf0a36cd0036779607c397ffdea16517f535b1"}, + {file = "ruff-0.5.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:aec618d5a0cdba5592c60c2dee7d9c865180627f1a4a691257dea14ac1aa264d"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b62adc5ce81780ff04077e88bac0986363e4a3260ad3ef11ae9c14aa0e67ef"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dc42ebf56ede83cb080a50eba35a06e636775649a1ffd03dc986533f878702a3"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c15c6e9f88c67ffa442681365d11df38afb11059fc44238e71a9d9f1fd51de70"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d3de9a5960f72c335ef00763d861fc5005ef0644cb260ba1b5a115a102157251"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe5a968ae933e8f7627a7b2fc8893336ac2be0eb0aace762d3421f6e8f7b7f83"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a04f54a9018f75615ae52f36ea1c5515e356e5d5e214b22609ddb546baef7132"}, + {file = "ruff-0.5.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed02fb52e3741f0738db5f93e10ae0fb5c71eb33a4f2ba87c9a2fa97462a649"}, + {file = "ruff-0.5.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3cf8fe659f6362530435d97d738eb413e9f090e7e993f88711b0377fbdc99f60"}, + {file = "ruff-0.5.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:237a37e673e9f3cbfff0d2243e797c4862a44c93d2f52a52021c1a1b0899f846"}, + {file = "ruff-0.5.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2a2949ce7c1cbd8317432ada80fe32156df825b2fd611688814c8557824ef060"}, + {file = "ruff-0.5.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:481af57c8e99da92ad168924fd82220266043c8255942a1cb87958b108ac9335"}, + {file = "ruff-0.5.2-py3-none-win32.whl", hash = "sha256:f1aea290c56d913e363066d83d3fc26848814a1fed3d72144ff9c930e8c7c718"}, + {file = "ruff-0.5.2-py3-none-win_amd64.whl", hash = "sha256:8532660b72b5d94d2a0a7a27ae7b9b40053662d00357bb2a6864dd7e38819084"}, + {file = "ruff-0.5.2-py3-none-win_arm64.whl", hash = "sha256:73439805c5cb68f364d826a5c5c4b6c798ded6b7ebaa4011f01ce6c94e4d5583"}, + {file = "ruff-0.5.2.tar.gz", hash = "sha256:2c0df2d2de685433794a14d8d2e240df619b748fbe3367346baa519d8e6f1ca2"}, +] + +[[package]] +name = "scikit-learn" +version = "1.5.1" +description = "A set of python modules for machine learning and data mining" +optional = false +python-versions = ">=3.9" +files = [ + {file = "scikit_learn-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:781586c414f8cc58e71da4f3d7af311e0505a683e112f2f62919e3019abd3745"}, + {file = "scikit_learn-1.5.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:f5b213bc29cc30a89a3130393b0e39c847a15d769d6e59539cd86b75d276b1a7"}, + {file = "scikit_learn-1.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ff4ba34c2abff5ec59c803ed1d97d61b036f659a17f55be102679e88f926fac"}, + {file = "scikit_learn-1.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:161808750c267b77b4a9603cf9c93579c7a74ba8486b1336034c2f1579546d21"}, + {file = "scikit_learn-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:10e49170691514a94bb2e03787aa921b82dbc507a4ea1f20fd95557862c98dc1"}, + {file = "scikit_learn-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:154297ee43c0b83af12464adeab378dee2d0a700ccd03979e2b821e7dd7cc1c2"}, + {file = "scikit_learn-1.5.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:b5e865e9bd59396220de49cb4a57b17016256637c61b4c5cc81aaf16bc123bbe"}, + {file = "scikit_learn-1.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:909144d50f367a513cee6090873ae582dba019cb3fca063b38054fa42704c3a4"}, + {file = "scikit_learn-1.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:689b6f74b2c880276e365fe84fe4f1befd6a774f016339c65655eaff12e10cbf"}, + {file = "scikit_learn-1.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:9a07f90846313a7639af6a019d849ff72baadfa4c74c778821ae0fad07b7275b"}, + {file = "scikit_learn-1.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5944ce1faada31c55fb2ba20a5346b88e36811aab504ccafb9f0339e9f780395"}, + {file = "scikit_learn-1.5.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:0828673c5b520e879f2af6a9e99eee0eefea69a2188be1ca68a6121b809055c1"}, + {file = "scikit_learn-1.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:508907e5f81390e16d754e8815f7497e52139162fd69c4fdbd2dfa5d6cc88915"}, + {file = "scikit_learn-1.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97625f217c5c0c5d0505fa2af28ae424bd37949bb2f16ace3ff5f2f81fb4498b"}, + {file = "scikit_learn-1.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:da3f404e9e284d2b0a157e1b56b6566a34eb2798205cba35a211df3296ab7a74"}, + {file = "scikit_learn-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:88e0672c7ac21eb149d409c74cc29f1d611d5158175846e7a9c2427bd12b3956"}, + {file = "scikit_learn-1.5.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:7b073a27797a283187a4ef4ee149959defc350b46cbf63a84d8514fe16b69855"}, + {file = "scikit_learn-1.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b59e3e62d2be870e5c74af4e793293753565c7383ae82943b83383fdcf5cc5c1"}, + {file = "scikit_learn-1.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bd8d3a19d4bd6dc5a7d4f358c8c3a60934dc058f363c34c0ac1e9e12a31421d"}, + {file = "scikit_learn-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:5f57428de0c900a98389c4a433d4a3cf89de979b3aa24d1c1d251802aa15e44d"}, + {file = "scikit_learn-1.5.1.tar.gz", hash = "sha256:0ea5d40c0e3951df445721927448755d3fe1d80833b0b7308ebff5d2a45e6414"}, +] + +[package.dependencies] +joblib = ">=1.2.0" +numpy = ">=1.19.5" +scipy = ">=1.6.0" +threadpoolctl = ">=3.1.0" + +[package.extras] +benchmark = ["matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "pandas (>=1.1.5)"] +build = ["cython (>=3.0.10)", "meson-python (>=0.16.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "polars (>=0.20.23)", "pooch (>=1.6.0)", "pydata-sphinx-theme (>=0.15.3)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)", "sphinx (>=7.3.7)", "sphinx-copybutton (>=0.5.2)", "sphinx-design (>=0.5.0)", "sphinx-gallery (>=0.16.0)", "sphinx-prompt (>=1.4.0)", "sphinx-remove-toctrees (>=1.0.0.post1)", "sphinxcontrib-sass (>=0.3.4)", "sphinxext-opengraph (>=0.9.1)"] +examples = ["matplotlib (>=3.3.4)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)"] +install = ["joblib (>=1.2.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)", "threadpoolctl (>=3.1.0)"] +maintenance = ["conda-lock (==2.5.6)"] +tests = ["black (>=24.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.9)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "polars (>=0.20.23)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pyarrow (>=12.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.2.1)", "scikit-image (>=0.17.2)"] + +[[package]] +name = "scipy" +version = "1.12.0" +description = "Fundamental algorithms for scientific computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "scipy-1.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:78e4402e140879387187f7f25d91cc592b3501a2e51dfb320f48dfb73565f10b"}, + {file = "scipy-1.12.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:f5f00ebaf8de24d14b8449981a2842d404152774c1a1d880c901bf454cb8e2a1"}, + {file = "scipy-1.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e53958531a7c695ff66c2e7bb7b79560ffdc562e2051644c5576c39ff8efb563"}, + {file = "scipy-1.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e32847e08da8d895ce09d108a494d9eb78974cf6de23063f93306a3e419960c"}, + {file = "scipy-1.12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4c1020cad92772bf44b8e4cdabc1df5d87376cb219742549ef69fc9fd86282dd"}, + {file = "scipy-1.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:75ea2a144096b5e39402e2ff53a36fecfd3b960d786b7efd3c180e29c39e53f2"}, + {file = "scipy-1.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:408c68423f9de16cb9e602528be4ce0d6312b05001f3de61fe9ec8b1263cad08"}, + {file = "scipy-1.12.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:5adfad5dbf0163397beb4aca679187d24aec085343755fcdbdeb32b3679f254c"}, + {file = "scipy-1.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3003652496f6e7c387b1cf63f4bb720951cfa18907e998ea551e6de51a04467"}, + {file = "scipy-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b8066bce124ee5531d12a74b617d9ac0ea59245246410e19bca549656d9a40a"}, + {file = "scipy-1.12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8bee4993817e204d761dba10dbab0774ba5a8612e57e81319ea04d84945375ba"}, + {file = "scipy-1.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:a24024d45ce9a675c1fb8494e8e5244efea1c7a09c60beb1eeb80373d0fecc70"}, + {file = "scipy-1.12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e7e76cc48638228212c747ada851ef355c2bb5e7f939e10952bc504c11f4e372"}, + {file = "scipy-1.12.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:f7ce148dffcd64ade37b2df9315541f9adad6efcaa86866ee7dd5db0c8f041c3"}, + {file = "scipy-1.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c39f92041f490422924dfdb782527a4abddf4707616e07b021de33467f917bc"}, + {file = "scipy-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7ebda398f86e56178c2fa94cad15bf457a218a54a35c2a7b4490b9f9cb2676c"}, + {file = "scipy-1.12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:95e5c750d55cf518c398a8240571b0e0782c2d5a703250872f36eaf737751338"}, + {file = "scipy-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:e646d8571804a304e1da01040d21577685ce8e2db08ac58e543eaca063453e1c"}, + {file = "scipy-1.12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:913d6e7956c3a671de3b05ccb66b11bc293f56bfdef040583a7221d9e22a2e35"}, + {file = "scipy-1.12.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba1b0c7256ad75401c73e4b3cf09d1f176e9bd4248f0d3112170fb2ec4db067"}, + {file = "scipy-1.12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:730badef9b827b368f351eacae2e82da414e13cf8bd5051b4bdfd720271a5371"}, + {file = "scipy-1.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6546dc2c11a9df6926afcbdd8a3edec28566e4e785b915e849348c6dd9f3f490"}, + {file = "scipy-1.12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:196ebad3a4882081f62a5bf4aeb7326aa34b110e533aab23e4374fcccb0890dc"}, + {file = "scipy-1.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:b360f1b6b2f742781299514e99ff560d1fe9bd1bff2712894b52abe528d1fd1e"}, + {file = "scipy-1.12.0.tar.gz", hash = "sha256:4bf5abab8a36d20193c698b0f1fc282c1d083c94723902c447e5d2f1780936a3"}, +] + +[package.dependencies] +numpy = ">=1.22.4,<1.29.0" + +[package.extras] +dev = ["click", "cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] +doc = ["jupytext", "matplotlib (>2)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] +test = ["asv", "gmpy2", "hypothesis", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + +[[package]] +name = "seaborn" +version = "0.13.2" +description = "Statistical data visualization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "seaborn-0.13.2-py3-none-any.whl", hash = "sha256:636f8336facf092165e27924f223d3c62ca560b1f2bb5dff7ab7fad265361987"}, + {file = "seaborn-0.13.2.tar.gz", hash = "sha256:93e60a40988f4d65e9f4885df477e2fdaff6b73a9ded434c1ab356dd57eefff7"}, +] + +[package.dependencies] +matplotlib = ">=3.4,<3.6.1 || >3.6.1" +numpy = ">=1.20,<1.24.0 || >1.24.0" +pandas = ">=1.2" + +[package.extras] +dev = ["flake8", "flit", "mypy", "pandas-stubs", "pre-commit", "pytest", "pytest-cov", "pytest-xdist"] +docs = ["ipykernel", "nbconvert", "numpydoc", "pydata_sphinx_theme (==0.10.0rc2)", "pyyaml", "sphinx (<6.0.0)", "sphinx-copybutton", "sphinx-design", "sphinx-issues"] +stats = ["scipy (>=1.7)", "statsmodels (>=0.12)"] + +[[package]] +name = "semversioner" +version = "2.0.5" +description = "Manage properly semver in your repository" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "semversioner-2.0.5-py2.py3-none-any.whl", hash = "sha256:c5134188592764eab72fea081f8696b3ab9e12fa132a6b4c5cc008285b06f45e"}, + {file = "semversioner-2.0.5.tar.gz", hash = "sha256:84b307e95eb7eab2e299935fe5acfb91f23a2e493526d3f42cfe1d5adcfc3641"}, +] + +[package.dependencies] +click = ">=8.0.0" +jinja2 = ">=3.0.0" +packaging = ">=21.0" + +[[package]] +name = "send2trash" +version = "1.8.3" +description = "Send file to trash natively under Mac OS X, Windows and Linux" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "Send2Trash-1.8.3-py3-none-any.whl", hash = "sha256:0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9"}, + {file = "Send2Trash-1.8.3.tar.gz", hash = "sha256:b18e7a3966d99871aefeb00cfbcfdced55ce4871194810fc71f4aa484b953abf"}, +] + +[package.extras] +nativelib = ["pyobjc-framework-Cocoa", "pywin32"] +objc = ["pyobjc-framework-Cocoa"] +win32 = ["pywin32"] + +[[package]] +name = "setuptools" +version = "70.3.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-70.3.0-py3-none-any.whl", hash = "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc"}, + {file = "setuptools-70.3.0.tar.gz", hash = "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5"}, +] + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "smart-open" +version = "7.0.4" +description = "Utils for streaming large files (S3, HDFS, GCS, Azure Blob Storage, gzip, bz2...)" +optional = false +python-versions = "<4.0,>=3.7" +files = [ + {file = "smart_open-7.0.4-py3-none-any.whl", hash = "sha256:4e98489932b3372595cddc075e6033194775165702887216b65eba760dfd8d47"}, + {file = "smart_open-7.0.4.tar.gz", hash = "sha256:62b65852bdd1d1d516839fcb1f6bc50cd0f16e05b4ec44b52f43d38bcb838524"}, +] + +[package.dependencies] +wrapt = "*" + +[package.extras] +all = ["azure-common", "azure-core", "azure-storage-blob", "boto3", "google-cloud-storage (>=2.6.0)", "paramiko", "requests", "zstandard"] +azure = ["azure-common", "azure-core", "azure-storage-blob"] +gcs = ["google-cloud-storage (>=2.6.0)"] +http = ["requests"] +s3 = ["boto3"] +ssh = ["paramiko"] +test = ["azure-common", "azure-core", "azure-storage-blob", "boto3", "google-cloud-storage (>=2.6.0)", "moto[server]", "paramiko", "pytest", "pytest-rerunfailures", "requests", "responses", "zstandard"] +webhdfs = ["requests"] +zst = ["zstandard"] + +[[package]] +name = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + +[[package]] +name = "soupsieve" +version = "2.5" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.8" +files = [ + {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, + {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +description = "Extract data from python stack frames and tracebacks for informative displays" +optional = false +python-versions = "*" +files = [ + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, +] + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + +[[package]] +name = "statsmodels" +version = "0.14.2" +description = "Statistical computations and models for Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "statsmodels-0.14.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df5d6f95c46f0341da6c79ee7617e025bf2b371e190a8e60af1ae9cabbdb7a97"}, + {file = "statsmodels-0.14.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a87ef21fadb445b650f327340dde703f13aec1540f3d497afb66324499dea97a"}, + {file = "statsmodels-0.14.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5827a12e3ede2b98a784476d61d6bec43011fedb64aa815f2098e0573bece257"}, + {file = "statsmodels-0.14.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f2b7611a61adb7d596a6d239abdf1a4d5492b931b00d5ed23d32844d40e48e"}, + {file = "statsmodels-0.14.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c254c66142f1167b4c7d031cf8db55294cc62ff3280e090fc45bd10a7f5fd029"}, + {file = "statsmodels-0.14.2-cp310-cp310-win_amd64.whl", hash = "sha256:0e46e9d59293c1af4cc1f4e5248f17e7e7bc596bfce44d327c789ac27f09111b"}, + {file = "statsmodels-0.14.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:50fcb633987779e795142f51ba49fb27648d46e8a1382b32ebe8e503aaabaa9e"}, + {file = "statsmodels-0.14.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:876794068abfaeed41df71b7887000031ecf44fbfa6b50d53ccb12ebb4ab747a"}, + {file = "statsmodels-0.14.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a91f6c4943de13e3ce2e20ee3b5d26d02bd42300616a421becd53756f5deb37"}, + {file = "statsmodels-0.14.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4864a1c4615c5ea5f2e3b078a75bdedc90dd9da210a37e0738e064b419eccee2"}, + {file = "statsmodels-0.14.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:afbd92410e0df06f3d8c4e7c0e2e71f63f4969531f280fb66059e2ecdb6e0415"}, + {file = "statsmodels-0.14.2-cp311-cp311-win_amd64.whl", hash = "sha256:8e004cfad0e46ce73fe3f3812010c746f0d4cfd48e307b45c14e9e360f3d2510"}, + {file = "statsmodels-0.14.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:eb0ba1ad3627705f5ae20af6b2982f500546d43892543b36c7bca3e2f87105e7"}, + {file = "statsmodels-0.14.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:90fd2f0110b73fc3fa5a2f21c3ca99b0e22285cccf38e56b5b8fd8ce28791b0f"}, + {file = "statsmodels-0.14.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac780ad9ff552773798829a0b9c46820b0faa10e6454891f5e49a845123758ab"}, + {file = "statsmodels-0.14.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55d1742778400ae67acb04b50a2c7f5804182f8a874bd09ca397d69ed159a751"}, + {file = "statsmodels-0.14.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f870d14a587ea58a3b596aa994c2ed889cc051f9e450e887d2c83656fc6a64bf"}, + {file = "statsmodels-0.14.2-cp312-cp312-win_amd64.whl", hash = "sha256:f450fcbae214aae66bd9d2b9af48e0f8ba1cb0e8596c6ebb34e6e3f0fec6542c"}, + {file = "statsmodels-0.14.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:201c3d00929c4a67cda1fe05b098c8dcf1b1eeefa88e80a8f963a844801ed59f"}, + {file = "statsmodels-0.14.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9edefa4ce08e40bc1d67d2f79bc686ee5e238e801312b5a029ee7786448c389a"}, + {file = "statsmodels-0.14.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c78a7601fdae1aa32104c5ebff2e0b72c26f33e870e2f94ab1bcfd927ece9b"}, + {file = "statsmodels-0.14.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f36494df7c03d63168fccee5038a62f469469ed6a4dd6eaeb9338abedcd0d5f5"}, + {file = "statsmodels-0.14.2-cp39-cp39-win_amd64.whl", hash = "sha256:8875823bdd41806dc853333cc4e1b7ef9481bad2380a999e66ea42382cf2178d"}, + {file = "statsmodels-0.14.2.tar.gz", hash = "sha256:890550147ad3a81cda24f0ba1a5c4021adc1601080bd00e191ae7cd6feecd6ad"}, +] + +[package.dependencies] +numpy = ">=1.22.3" +packaging = ">=21.3" +pandas = ">=1.4,<2.1.0 || >2.1.0" +patsy = ">=0.5.6" +scipy = ">=1.8,<1.9.2 || >1.9.2" + +[package.extras] +build = ["cython (>=0.29.33)"] +develop = ["colorama", "cython (>=0.29.33)", "cython (>=3.0.10,<4)", "flake8", "isort", "joblib", "matplotlib (>=3)", "pytest (>=7.3.0,<8)", "pytest-cov", "pytest-randomly", "pytest-xdist", "pywinpty", "setuptools-scm[toml] (>=8.0,<9.0)"] +docs = ["ipykernel", "jupyter-client", "matplotlib", "nbconvert", "nbformat", "numpydoc", "pandas-datareader", "sphinx"] + +[[package]] +name = "swifter" +version = "1.4.0" +description = "A package which efficiently applies any function to a pandas dataframe or series in the fastest available manner" +optional = false +python-versions = "*" +files = [ + {file = "swifter-1.4.0.tar.gz", hash = "sha256:e1bb74476a21b3f07a17aa18c97fdcba8599726bd17da732f09dabcc50e26ba0"}, +] + +[package.dependencies] +dask = {version = ">=2.10.0", extras = ["dataframe"]} +pandas = ">=1.0.0" +psutil = ">=5.6.6" +tqdm = ">=4.33.0" + +[package.extras] +groupby = ["ray (>=1.0.0)"] +notebook = ["ipywidgets (>=7.0.0)"] + +[[package]] +name = "tenacity" +version = "8.5.0" +description = "Retry code until it succeeds" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, + {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, +] + +[package.extras] +doc = ["reno", "sphinx"] +test = ["pytest", "tornado (>=4.5)", "typeguard"] + +[[package]] +name = "terminado" +version = "0.18.1" +description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0"}, + {file = "terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e"}, +] + +[package.dependencies] +ptyprocess = {version = "*", markers = "os_name != \"nt\""} +pywinpty = {version = ">=1.1.0", markers = "os_name == \"nt\""} +tornado = ">=6.1.0" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] +typing = ["mypy (>=1.6,<2.0)", "traitlets (>=5.11.1)"] + +[[package]] +name = "textual" +version = "0.72.0" +description = "Modern Text User Interface framework" +optional = false +python-versions = "<4.0,>=3.8" +files = [ + {file = "textual-0.72.0-py3-none-any.whl", hash = "sha256:a9886eb96bd6391b8795244d2b8fe592204556c42264ea7513a1211584e17366"}, + {file = "textual-0.72.0.tar.gz", hash = "sha256:14174ce8d49016a85aa6c0669d0881b5419e98cf46d429f263314295409ed262"}, +] + +[package.dependencies] +markdown-it-py = {version = ">=2.1.0", extras = ["linkify", "plugins"]} +rich = ">=13.3.3" +typing-extensions = ">=4.4.0,<5.0.0" + +[package.extras] +syntax = ["tree-sitter (>=0.20.1,<0.21.0)", "tree-sitter-languages (==1.10.2)"] + +[[package]] +name = "threadpoolctl" +version = "3.5.0" +description = "threadpoolctl" +optional = false +python-versions = ">=3.8" +files = [ + {file = "threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467"}, + {file = "threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107"}, +] + +[[package]] +name = "tiktoken" +version = "0.7.0" +description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tiktoken-0.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485f3cc6aba7c6b6ce388ba634fbba656d9ee27f766216f45146beb4ac18b25f"}, + {file = "tiktoken-0.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e54be9a2cd2f6d6ffa3517b064983fb695c9a9d8aa7d574d1ef3c3f931a99225"}, + {file = "tiktoken-0.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79383a6e2c654c6040e5f8506f3750db9ddd71b550c724e673203b4f6b4b4590"}, + {file = "tiktoken-0.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d4511c52caacf3c4981d1ae2df85908bd31853f33d30b345c8b6830763f769c"}, + {file = "tiktoken-0.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:13c94efacdd3de9aff824a788353aa5749c0faee1fbe3816df365ea450b82311"}, + {file = "tiktoken-0.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8e58c7eb29d2ab35a7a8929cbeea60216a4ccdf42efa8974d8e176d50c9a3df5"}, + {file = "tiktoken-0.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:21a20c3bd1dd3e55b91c1331bf25f4af522c525e771691adbc9a69336fa7f702"}, + {file = "tiktoken-0.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:10c7674f81e6e350fcbed7c09a65bca9356eaab27fb2dac65a1e440f2bcfe30f"}, + {file = "tiktoken-0.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:084cec29713bc9d4189a937f8a35dbdfa785bd1235a34c1124fe2323821ee93f"}, + {file = "tiktoken-0.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:811229fde1652fedcca7c6dfe76724d0908775b353556d8a71ed74d866f73f7b"}, + {file = "tiktoken-0.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86b6e7dc2e7ad1b3757e8a24597415bafcfb454cebf9a33a01f2e6ba2e663992"}, + {file = "tiktoken-0.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1063c5748be36344c7e18c7913c53e2cca116764c2080177e57d62c7ad4576d1"}, + {file = "tiktoken-0.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:20295d21419bfcca092644f7e2f2138ff947a6eb8cfc732c09cc7d76988d4a89"}, + {file = "tiktoken-0.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:959d993749b083acc57a317cbc643fb85c014d055b2119b739487288f4e5d1cb"}, + {file = "tiktoken-0.7.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:71c55d066388c55a9c00f61d2c456a6086673ab7dec22dd739c23f77195b1908"}, + {file = "tiktoken-0.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:09ed925bccaa8043e34c519fbb2f99110bd07c6fd67714793c21ac298e449410"}, + {file = "tiktoken-0.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03c6c40ff1db0f48a7b4d2dafeae73a5607aacb472fa11f125e7baf9dce73704"}, + {file = "tiktoken-0.7.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d20b5c6af30e621b4aca094ee61777a44118f52d886dbe4f02b70dfe05c15350"}, + {file = "tiktoken-0.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d427614c3e074004efa2f2411e16c826f9df427d3c70a54725cae860f09e4bf4"}, + {file = "tiktoken-0.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8c46d7af7b8c6987fac9b9f61041b452afe92eb087d29c9ce54951280f899a97"}, + {file = "tiktoken-0.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:0bc603c30b9e371e7c4c7935aba02af5994a909fc3c0fe66e7004070858d3f8f"}, + {file = "tiktoken-0.7.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2398fecd38c921bcd68418675a6d155fad5f5e14c2e92fcf5fe566fa5485a858"}, + {file = "tiktoken-0.7.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f5f6afb52fb8a7ea1c811e435e4188f2bef81b5e0f7a8635cc79b0eef0193d6"}, + {file = "tiktoken-0.7.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:861f9ee616766d736be4147abac500732b505bf7013cfaf019b85892637f235e"}, + {file = "tiktoken-0.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54031f95c6939f6b78122c0aa03a93273a96365103793a22e1793ee86da31685"}, + {file = "tiktoken-0.7.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:fffdcb319b614cf14f04d02a52e26b1d1ae14a570f90e9b55461a72672f7b13d"}, + {file = "tiktoken-0.7.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c72baaeaefa03ff9ba9688624143c858d1f6b755bb85d456d59e529e17234769"}, + {file = "tiktoken-0.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:131b8aeb043a8f112aad9f46011dced25d62629091e51d9dc1adbf4a1cc6aa98"}, + {file = "tiktoken-0.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cabc6dc77460df44ec5b879e68692c63551ae4fae7460dd4ff17181df75f1db7"}, + {file = "tiktoken-0.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8d57f29171255f74c0aeacd0651e29aa47dff6f070cb9f35ebc14c82278f3b25"}, + {file = "tiktoken-0.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ee92776fdbb3efa02a83f968c19d4997a55c8e9ce7be821ceee04a1d1ee149c"}, + {file = "tiktoken-0.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e215292e99cb41fbc96988ef62ea63bb0ce1e15f2c147a61acc319f8b4cbe5bf"}, + {file = "tiktoken-0.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8a81bac94769cab437dd3ab0b8a4bc4e0f9cf6835bcaa88de71f39af1791727a"}, + {file = "tiktoken-0.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d6d73ea93e91d5ca771256dfc9d1d29f5a554b83821a1dc0891987636e0ae226"}, + {file = "tiktoken-0.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:2bcb28ddf79ffa424f171dfeef9a4daff61a94c631ca6813f43967cb263b83b9"}, + {file = "tiktoken-0.7.0.tar.gz", hash = "sha256:1077266e949c24e0291f6c350433c6f0971365ece2b173a23bc3b9f9defef6b6"}, +] + +[package.dependencies] +regex = ">=2022.1.18" +requests = ">=2.26.0" + +[package.extras] +blobfile = ["blobfile (>=2)"] + +[[package]] +name = "tinycss2" +version = "1.3.0" +description = "A tiny CSS parser" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tinycss2-1.3.0-py3-none-any.whl", hash = "sha256:54a8dbdffb334d536851be0226030e9505965bb2f30f21a4a82c55fb2a80fae7"}, + {file = "tinycss2-1.3.0.tar.gz", hash = "sha256:152f9acabd296a8375fbca5b84c961ff95971fcfc32e79550c8df8e29118c54d"}, +] + +[package.dependencies] +webencodings = ">=0.4" + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["pytest", "ruff"] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "tomlkit" +version = "0.12.5" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, + {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, +] + +[[package]] +name = "toolz" +version = "0.12.1" +description = "List processing tools and functional utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "toolz-0.12.1-py3-none-any.whl", hash = "sha256:d22731364c07d72eea0a0ad45bafb2c2937ab6fd38a3507bf55eae8744aa7d85"}, + {file = "toolz-0.12.1.tar.gz", hash = "sha256:ecca342664893f177a13dac0e6b41cbd8ac25a358e5f215316d43e2100224f4d"}, +] + +[[package]] +name = "tornado" +version = "6.4.1" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +optional = false +python-versions = ">=3.8" +files = [ + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8"}, + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6d5ce3437e18a2b66fbadb183c1d3364fb03f2be71299e7d10dbeeb69f4b2a14"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ae50a504a740365267b2a8d1a90c9fbc86b780a39170feca9bcc1787ff80842"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:613bf4ddf5c7a95509218b149b555621497a6cc0d46ac341b30bd9ec19eac7f3"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25486eb223babe3eed4b8aecbac33b37e3dd6d776bc730ca14e1bf93888b979f"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:454db8a7ecfcf2ff6042dde58404164d969b6f5d58b926da15e6b23817950fc4"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a02a08cc7a9314b006f653ce40483b9b3c12cda222d6a46d4ac63bb6c9057698"}, + {file = "tornado-6.4.1-cp38-abi3-win32.whl", hash = "sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d"}, + {file = "tornado-6.4.1-cp38-abi3-win_amd64.whl", hash = "sha256:b24b8982ed444378d7f21d563f4180a2de31ced9d8d84443907a0a64da2072e7"}, + {file = "tornado-6.4.1.tar.gz", hash = "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9"}, +] + +[[package]] +name = "tqdm" +version = "4.66.4" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.66.4-py3-none-any.whl", hash = "sha256:b75ca56b413b030bc3f00af51fd2c1a1a5eac6a0c1cca83cbb37a5c52abce644"}, + {file = "tqdm-4.66.4.tar.gz", hash = "sha256:e4d936c9de8727928f3be6079590e97d9abfe8d39a590be678eb5919ffc186bb"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "traitlets" +version = "5.14.3" +description = "Traitlets Python configuration system" +optional = false +python-versions = ">=3.8" +files = [ + {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, + {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, +] + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] + +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20240316" +description = "Typing stubs for python-dateutil" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, + {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + +[[package]] +name = "uc-micro-py" +version = "1.0.3" +description = "Micro subset of unicode data files for linkify-it-py projects." +optional = false +python-versions = ">=3.7" +files = [ + {file = "uc-micro-py-1.0.3.tar.gz", hash = "sha256:d321b92cff673ec58027c04015fcaa8bb1e005478643ff4a500882eaab88c48a"}, + {file = "uc_micro_py-1.0.3-py3-none-any.whl", hash = "sha256:db1dffff340817673d7b466ec86114a9dc0e9d4d9b5ba229d9d60e5c12600cd5"}, +] + +[package.extras] +test = ["coverage", "pytest", "pytest-cov"] + +[[package]] +name = "umap-learn" +version = "0.5.6" +description = "Uniform Manifold Approximation and Projection" +optional = false +python-versions = "*" +files = [ + {file = "umap-learn-0.5.6.tar.gz", hash = "sha256:5b3917a862c23ba0fc83bfcd67a7b719dec85b3d9c01fdc7d894cce455df4e03"}, + {file = "umap_learn-0.5.6-py3-none-any.whl", hash = "sha256:881cc0c2ee845b790bf0455aa1664f9f68b838d9d0fe12a1291b85c5a559c913"}, +] + +[package.dependencies] +numba = ">=0.51.2" +numpy = ">=1.17" +pynndescent = ">=0.5" +scikit-learn = ">=0.22" +scipy = ">=1.3.1" +tqdm = "*" + +[package.extras] +parametric-umap = ["tensorflow (>=2.1)"] +plot = ["bokeh", "colorcet", "datashader", "holoviews", "matplotlib", "pandas", "scikit-image", "seaborn"] +tbb = ["tbb (>=2019.0)"] + +[[package]] +name = "update-toml" +version = "0.2.1" +description = "Update a toml value from a CLI" +optional = false +python-versions = ">=3.8" +files = [ + {file = "update_toml-0.2.1-py3-none-any.whl", hash = "sha256:90d5d9d2efbe2f273328ec78394912c33c0f741dc3b0ae744cfc4ddbe27051f7"}, + {file = "update_toml-0.2.1.tar.gz", hash = "sha256:92870b2ef8591eeffa32df674d9b4c4fce59a428f65063e138dee253bdb5d372"}, +] + +[package.dependencies] +tomlkit = ">=0.12.5,<0.13.0" + +[[package]] +name = "uri-template" +version = "1.3.0" +description = "RFC 6570 URI Template Processor" +optional = false +python-versions = ">=3.7" +files = [ + {file = "uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7"}, + {file = "uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363"}, +] + +[package.extras] +dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake8-commas", "flake8-comprehensions", "flake8-continuation", "flake8-datetimez", "flake8-docstrings", "flake8-import-order", "flake8-literal", "flake8-modern-annotations", "flake8-noqa", "flake8-pyproject", "flake8-requirements", "flake8-typechecking-import", "flake8-use-fstring", "mypy", "pep8-naming", "types-PyYAML"] + +[[package]] +name = "urllib3" +version = "2.2.2" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "uvloop" +version = "0.19.0" +description = "Fast implementation of asyncio event loop on top of libuv" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e"}, + {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428"}, + {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8"}, + {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849"}, + {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957"}, + {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd"}, + {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef"}, + {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2"}, + {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1"}, + {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24"}, + {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533"}, + {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12"}, + {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650"}, + {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec"}, + {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc"}, + {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6"}, + {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593"}, + {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3"}, + {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd"}, + {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd"}, + {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be"}, + {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797"}, + {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d"}, + {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7"}, + {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b"}, + {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67"}, + {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7"}, + {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256"}, + {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17"}, + {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5"}, + {file = "uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd"}, +] + +[package.extras] +docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] +test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)", "flake8 (>=5.0,<6.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=23.0.0,<23.1.0)", "pycodestyle (>=2.9.0,<2.10.0)"] + +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + +[[package]] +name = "webcolors" +version = "24.6.0" +description = "A library for working with the color formats defined by HTML and CSS." +optional = false +python-versions = ">=3.8" +files = [ + {file = "webcolors-24.6.0-py3-none-any.whl", hash = "sha256:8cf5bc7e28defd1d48b9e83d5fc30741328305a8195c29a8e668fa45586568a1"}, + {file = "webcolors-24.6.0.tar.gz", hash = "sha256:1d160d1de46b3e81e58d0a280d0c78b467dc80f47294b91b1ad8029d2cedb55b"}, +] + +[package.extras] +docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"] +tests = ["coverage[toml]"] + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +optional = false +python-versions = "*" +files = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] + +[[package]] +name = "websocket-client" +version = "1.8.0" +description = "WebSocket client for Python with low level API options" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526"}, + {file = "websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da"}, +] + +[package.extras] +docs = ["Sphinx (>=6.0)", "myst-parser (>=2.0.0)", "sphinx-rtd-theme (>=1.1.0)"] +optional = ["python-socks", "wsaccel"] +test = ["websockets"] + +[[package]] +name = "widgetsnbextension" +version = "4.0.11" +description = "Jupyter interactive widgets for Jupyter Notebook" +optional = false +python-versions = ">=3.7" +files = [ + {file = "widgetsnbextension-4.0.11-py3-none-any.whl", hash = "sha256:55d4d6949d100e0d08b94948a42efc3ed6dfdc0e9468b2c4b128c9a2ce3a7a36"}, + {file = "widgetsnbextension-4.0.11.tar.gz", hash = "sha256:8b22a8f1910bfd188e596fe7fc05dcbd87e810c8a4ba010bdb3da86637398474"}, +] + +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + +[[package]] +name = "zipp" +version = "3.19.2" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, + {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, +] + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] + +[metadata] +lock-version = "2.0" +python-versions = ">=3.10,<3.13" +content-hash = "01ee5a94c60b640ad124c27244a21cf97ddbd7effdd7aaf89ff8c896af3a0887" diff --git a/graphrag/pyproject.toml b/graphrag/pyproject.toml new file mode 100644 index 0000000000000000000000000000000000000000..fb3ff7fbd2610b87fcdc6a46e77bc14b952e7736 --- /dev/null +++ b/graphrag/pyproject.toml @@ -0,0 +1,254 @@ +[tool.poetry] +name = "graphrag" +# Maintainers: do not change the version here manually, use ./scripts/release.sh +version = "0.1.1" +description = "" +authors = [ + "Alonso Guevara Fernández ", + "Andrés Morales Esquivel ", + "Chris Trevino ", + "David Tittsworth ", + "Dayenne de Souza ", + "Gaudy Blanco Meneses ", + "Ha Trinh ", + "Jonathan Larson ", + "Kate Lytvynets ", + "Mónica Carvajal", + "Nathan Evans ", + "Rodrigo Racanicci ", + "Sarah Smith ", +] +license = "MIT" +readme = "README.md" +packages = [{ include = "graphrag" }] + +[tool.poetry-dynamic-versioning] +enable = true +style = "pep440" +vcs = "git" +bump = true +format-jinja = """ + {%- if distance == 0 -%} + {{ serialize_pep440(base, stage, revision) }} + {%- else -%} + {{ serialize_pep440(base, stage, revision, dev=distance) }} + {%- endif -%} +""" + +[tool.poetry.dependencies] +python = ">=3.10,<3.13" +environs = "^11.0.0" +datashaper = "^0.0.49" + +# Vector Stores +azure-search-documents = "^11.4.0" +lancedb = "^0.10.0" + +# Event Loops +uvloop = { version = "^0.19.0", markers = "platform_system != 'Windows'" } +nest-asyncio = { version = "^1.6.0", markers = "platform_system == 'Windows'" } + +# Async IO +aiolimiter = "^1.1.0" +aiofiles = "^24.1.0" + +# LLM +openai = "^1.35.7" +nltk = "3.8.1" +tiktoken = "^0.7.0" + +# Data-Sci +numba = "0.60.0" +numpy = "^1.25.2" +graspologic = "^3.4.1" +networkx = "^3" +fastparquet = "^2024.2.0" +# 1.13.0 was a footgun +scipy = "1.12.0" + +# Configuration +pyyaml = "^6.0.1" +pyaml-env = "^1.2.1" +python-dotenv = "^1.0.0" + +# Network +tenacity = "^8.5.0" + +swifter = "^1.4.0" +pydantic = "^2" +rich = "^13.6.0" +textual = "^0.72.0" +devtools = "^0.12.2" + +typing-extensions = "^4.12.2" + +#Azure +azure-storage-blob = "^12.19.0" +azure-identity = "^1.17.1" + +[tool.poetry.group.dev.dependencies] +coverage = "^7.6.0" +ipykernel = "^6.29.4" +jupyter = "^1.0.0" +nbconvert = "^7.16.3" +poethepoet = "^0.26.0" +pyright = "^1.1.371" +pytest = "^8.2.0" +pytest-asyncio = "^0.23.4" +pytest-timeout = "^2.3.1" +ruff = "^0.5.2" +semversioner = "^2.0.3" + +update-toml = "^0.2.1" + +[build-system] +requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning>=1.0.0,<2.0.0"] +build-backend = "poetry_dynamic_versioning.backend" + +[tool.poe.tasks] +_sort_imports = "ruff check --select I --fix . --preview" +_format_code = "ruff format . --preview" +_ruff_check = 'ruff check . --preview' +_pyright = "pyright" +_convert_local_search_nb = 'jupyter nbconvert --output-dir=docsite/posts/query/notebooks/ --output="{notebook_name}_nb" --template=docsite/nbdocsite_template --to markdown examples_notebooks/local_search.ipynb' +_convert_global_search_nb = 'jupyter nbconvert --output-dir=docsite/posts/query/notebooks/ --output="{notebook_name}_nb" --template=docsite/nbdocsite_template --to markdown examples_notebooks/global_search.ipynb' +_semversioner_release = "semversioner release" +_semversioner_changelog = "semversioner changelog > CHANGELOG.md" +_semversioner_update_toml_version = "update-toml --path tool.poetry.version --value \"$(semversioner current-version)\" pyproject.toml" +coverage_report = 'coverage report --omit "**/tests/**" --show-missing' +check_format = 'ruff format . --check --preview' +fix = "ruff --preview check --fix ." +fix_unsafe = "ruff check --preview --fix --unsafe-fixes ." + +_test_all = "coverage run -m pytest ./tests" +test_unit = "pytest ./tests/unit" +test_integration = "pytest ./tests/integration" +test_smoke = "pytest ./tests/smoke" +index = "python -m graphrag.index" +query = "python -m graphrag.query" +prompt_tune = "python -m graphrag.prompt_tune" +# Pass in a test pattern +test_only = "pytest -s -k" + +[[tool.poe.tasks.release]] +sequence = [ + '_semversioner_release', + '_semversioner_changelog', + '_semversioner_update_toml_version', +] +ignore_fail = 'return_non_zero' + +[[tool.poe.tasks.convert_docsite_notebooks]] +sequence = ['_convert_local_search_nb', '_convert_global_search_nb'] +ignore_fail = 'return_non_zero' + +[[tool.poe.tasks.format]] +sequence = ['_sort_imports', '_format_code'] +ignore_fail = 'return_non_zero' + +[[tool.poe.tasks.check]] +sequence = ['check_format', '_ruff_check', '_pyright'] +ignore_fail = 'return_non_zero' + +[[tool.poe.tasks.test]] +sequence = ['_test_all', 'coverage_report'] +ignore_fail = 'return_non_zero' + +[tool.ruff] +target-version = "py310" +extend-include = ["*.ipynb"] + +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = 20 + +[tool.ruff.lint] +select = [ + "E4", + "E7", + "E9", + "W291", + "YTT", + "T10", + "ICN", + "INP", + "Q", + "RSE", + "SLOT", + "INT", + "FLY", + "LOG", + "C90", + "T20", + "D", + "RET", + "PD", + "N", + "PIE", + "SIM", + "S", + "G", + "ERA", + "ASYNC", + "TID", + "UP", + "SLF", + "BLE", + "C4", + "I", + "F", + "A", + "ARG", + "PTH", + "RUF", + "B", + "TCH", + "DTZ", + "PYI", + "PT", + "EM", + "TRY", + "PERF", + "CPY", + # "FBT", # use named arguments for boolean flags + # "TD", # todos + # "FIX", # fixme + # "FURB" # preview rules + # ANN # Type annotations, re-enable when we get bandwidth +] +ignore = [ + # Deprecated Rules + "ANN101", + "ANN102", + # Conflicts with interface argument checking + "ARG002", + "ANN204", + # TODO: Inspect these pandas rules for validity + "PD002", # prevents inplace=True + # TODO RE-Enable when we get bandwidth + "PERF203", # Needs restructuring of errors, we should bail-out on first error + "C901", # needs refactoring to remove cyclomatic complexity +] + +[tool.ruff.lint.per-file-ignores] +"tests/*" = ["S", "D", "ANN", "T201", "ASYNC", "ARG", "PTH", "TRY"] +"examples/*" = ["S", "D", "ANN", "T201", "PTH", "TRY", "PERF"] +"graphrag/index/config/*" = ["TCH"] +"*.ipynb" = ["T201"] + +[tool.ruff.lint.flake8-builtins] +builtins-ignorelist = ["input", "id", "bytes"] + +[tool.ruff.lint.pydocstyle] +convention = "numpy" + +# https://github.com/microsoft/pyright/blob/9f81564a4685ff5c55edd3959f9b39030f590b2f/docs/configuration.md#sample-pyprojecttoml-file +[tool.pyright] +include = ["graphrag", "tests", "examples", "examples_notebooks"] +exclude = ["**/node_modules", "**/__pycache__"] + +[tool.pytest.ini_options] +asyncio_mode = "auto" +timeout = 600 +# log_cli = true +# log_cli_level = "INFO" diff --git a/graphrag/scripts/e2e-test.sh b/graphrag/scripts/e2e-test.sh new file mode 100644 index 0000000000000000000000000000000000000000..5c260a148bc62df9de7529b4c35e7d8b07aa3292 --- /dev/null +++ b/graphrag/scripts/e2e-test.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Use CLI Form +poetry run python -m graphrag.index --config ./examples/single_verb/pipeline.yml \ No newline at end of file diff --git a/graphrag/scripts/semver-check.sh b/graphrag/scripts/semver-check.sh new file mode 100644 index 0000000000000000000000000000000000000000..26d69f9baa5ed78cce8067c5f4738aa1282f78b0 --- /dev/null +++ b/graphrag/scripts/semver-check.sh @@ -0,0 +1,10 @@ +#!/bin/sh +changes=$(git diff --name-only origin/main) +has_change_doc=$(echo $changes | grep .semversioner/next-release) +has_impacting_changes=$(echo $changes | grep graphrag) + +if [ "$has_impacting_changes" ] && [ -z "$has_change_doc" ]; then + echo "Check failed. Run 'poetry run semversioner add-change' to update the next release version" + exit 1 +fi +echo "OK" diff --git a/graphrag/scripts/spellcheck.sh b/graphrag/scripts/spellcheck.sh new file mode 100644 index 0000000000000000000000000000000000000000..7c1b50e9317ea201cffe0aba712722d64bdb02b6 --- /dev/null +++ b/graphrag/scripts/spellcheck.sh @@ -0,0 +1,2 @@ +#!/bin/sh +npx --yes cspell -c cspell.config.yaml --no-progress lint . \ No newline at end of file diff --git a/graphrag/scripts/start-azurite.sh b/graphrag/scripts/start-azurite.sh new file mode 100644 index 0000000000000000000000000000000000000000..345f500f3b2236ac18c47917f2ffd389a075cbf7 --- /dev/null +++ b/graphrag/scripts/start-azurite.sh @@ -0,0 +1,2 @@ +#!/bin/sh +npx --yes azurite -L -l ./temp_azurite -d ./temp_azurite/debug.log \ No newline at end of file diff --git a/graphrag/tests/__init__.py b/graphrag/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/conftest.py b/graphrag/tests/conftest.py new file mode 100644 index 0000000000000000000000000000000000000000..c6536014b82d889abce355340c448e5191b490e2 --- /dev/null +++ b/graphrag/tests/conftest.py @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +def pytest_addoption(parser): + parser.addoption( + "--run_slow", action="store_true", default=False, help="run slow tests" + ) diff --git a/graphrag/tests/fixtures/azure/config.json b/graphrag/tests/fixtures/azure/config.json new file mode 100644 index 0000000000000000000000000000000000000000..8adced2c08a7e21c53ad2621949a786e005e6c11 --- /dev/null +++ b/graphrag/tests/fixtures/azure/config.json @@ -0,0 +1,13 @@ +{ + "input_path": "./tests/fixtures/azure", + "input_file_type": "text", + "workflow_config": { + "skip_assert": true, + "azure": { + "input_container": "azurefixture", + "input_base_dir": "input" + } + }, + "query_config": [], + "slow": false +} \ No newline at end of file diff --git a/graphrag/tests/fixtures/azure/input/ABOUT.md b/graphrag/tests/fixtures/azure/input/ABOUT.md new file mode 100644 index 0000000000000000000000000000000000000000..42c316108ec0893e6b1df44f8f42e5a50a8edb43 --- /dev/null +++ b/graphrag/tests/fixtures/azure/input/ABOUT.md @@ -0,0 +1,3 @@ +# About + +This document (Operation Dulce) in an AI-generated science fiction novella, included here for the purposes of integration testing. \ No newline at end of file diff --git a/graphrag/tests/fixtures/azure/input/dulce.txt b/graphrag/tests/fixtures/azure/input/dulce.txt new file mode 100644 index 0000000000000000000000000000000000000000..95c9e3cd3af76b570f0550d69b2025d7cd6fafbb --- /dev/null +++ b/graphrag/tests/fixtures/azure/input/dulce.txt @@ -0,0 +1,970 @@ +# Operation: Dulce + +## Chapter 1 + +The thrumming of monitors cast a stark contrast to the rigid silence enveloping the group. Agent Alex Mercer, unfailingly determined on paper, seemed dwarfed by the enormity of the sterile briefing room where Paranormal Military Squad's elite convened. With dulled eyes, he scanned the projectors outlining their impending odyssey into Operation: Dulce. + +“I assume, Agent Mercer, you’re not having second thoughts?” It was Taylor Cruz’s voice, laced with an edge that demanded attention. + +Alex flickered a strained smile, still thumbing his folder's corner. "Of course not, Agent Cruz. Just trying to soak in all the details." The compliance in his tone was unsettling, even to himself. + +Jordan Hayes, perched on the opposite side of the table, narrowed their eyes but offered a supportive nod. "Details are imperative. We’ll need your clear-headedness down there, Mercer." + +A comfortable silence, the kind that threaded between veterans of shared secrets, lingered briefly before Sam Rivera, never one to submit to quiet, added, "I’ve combed through the last transmission logs. If anyone can make sense of the anomalies, it’s going to be the two of you." + +Taylor snorted dismissively. “Focus, people. We have protocols for a reason. Speculation is counter-productive.” The words 'counter-productive' seemed to hang in the air, a tacit reprimand directed at Alex. + +Feeling the weight of his compliance conflicting with his natural inclination to leave no stone unturned, Alex straightened in his seat. "I agree, Agent Cruz. Protocol is paramount," he said, meeting Taylor's steely gaze. It was an affirmation, but beneath it lay layers of unspoken complexities that would undoubtedly unwind with time. + +Alex's submission, though seemingly complete, didn't escape Jordan, who tilted their head ever so slightly, their eyes revealing a spark of understanding. They knew well enough the struggle of aligning personal convictions with overarching missions. As everyone began to collect their binders and prepare for departure, a quiet resolve took form within Alex, galvanized by the groundwork laid by their interactions. He may have spoken in compliance, but his determination had merely taken a subtler form — one that wouldn't surrender so easily to the forthcoming shadows. + +\* + +Dr. Jordan Hayes shuffled a stack of papers, their eyes revealing a tinge of skepticism at Taylor Cruz's authoritarian performance. _Protocols_, Jordan thought, _are just the framework, the true challenges we're about to face lie well beyond the boundaries of any protocol._ They cleared their throat before speaking, tone cautious yet firm, "Let's remember, the unknown variables exceed the known. We should remain adaptive." + +A murmur of agreement echoed from Sam Rivera, who leaned forward, lacing their fingers together as if weaving a digital framework in the air before them, "Exactly, adaptability could be the key to interpreting the signal distortions and system malfunctions. We shouldn't discount the… erratic." + +Their words hung like an electric charge in the room, challenging Taylor's position with an inherent truth. Cruz’s jaw tightened almost imperceptibly, but the agent masked it with a small nod, conceding to the omnipresent threat of the unpredictable. + +Alex glanced at Jordan, who never looked back, their gaze fixed instead on a distant point, as if envisioning the immense dark corridors they were soon to navigate in Dulce. Jordan was not one to embrace fantastical theories, but the air of cautious calculation betrayed a mind bracing for confrontation with the inexplicable, an internal battle between the evidence of their research and the calculating skepticism that kept them alive in their field. + +The meeting adjourned with no further comments, the team members quietly retreading the paths to their personal preparations. Alex, trailing slightly behind, observed the others. _The cautious reserve Jordan wears like armor doesn't fool me_, he thought, _their analytical mind sees the patterns I do. And that's worth more than protocol. That's the connection we need to survive this._ + +As the agents dispersed into the labyrinth of the facility, lost in their thoughts and preparations, the base's halogen lights flickered, a brief and unnoticed harbingers of the darkness to come. + +\* + +A deserted corridor inside the facility stretched before Taylor Cruz, each footstep rhythmic and precise. Cruz, ambitious and meticulous, eyed the troops passing by with a sardonic tilt of the lips. Obedience—it was as much a tool as any weapon in the arsenal, and Cruz wielded it masterfully. To them, it was another step toward unfettered power within the dark bowels of the military complex. + +Inside a secluded equipment bay, Cruz began checking over gear with mechanical efficiency. They traced fingers over the sleek surface of an encrypted radio transmitter. "If protocols are maintained," said Cruz aloud, rehearsing the speech for their subordinates, "not only will we re-establish a line of communication with Dulce, but we shall also illuminate the darkest secrets it conceals." + +Agent Hayes appeared in the doorway, arms crossed and a knowing glint in their eyes. "You do understand," Jordan began, the words measured and probing, "that once we're in the depths, rank gives way to survival instincts. It's not about commands—it's empowerment through trust." + +The sentiment snagged on Cruz's armor of confidence, probing at the insecurities festering beneath. Taylor offered a brief nod, perhaps too curt, but enough to acknowledge Jordan's point without yielding ground. "Trust," Cruz mused, "or the illusion thereof, is just as potent." + +Silence claimed the space between them, steeped in the reality of the unknown dangers lurking in the shadows of the mission. Cruz diligently returned to the equipment, the act a clear dismissal. + +Not much later, Cruz stood alone, the hollow echo of the bay a stark reminder of the isolation that power often wrought. With each checked box, their resolve steeled further, a silent vow to usher their team through the abyss—whatever it might hold—and emerge enshrined in the respect they so deeply craved. + +## Chapter 2 + +Sam Rivera sat alone in a cramped office, the hum of a dozen servers murmuring a digital lullaby in the background. Surrounded by the glow of multiple screens, their eyes danced across lines of code and intercepted comm signals from Dulce — a kaleidoscope of data that their curious and isolated mind hungered to decrypt. + +To an outsider, it might have looked like obsession, this fervent quest for answers. But to Sam, it was a dance — a give and take with the mysteries of the universe. Their fingers paused over the keyboard as they leaned back in the chair, whispering to thin air, "What secrets are you hiding from us?" + +The stillness of the room broke with the unexpected arrival of Alex Mercer, whose encroaching shadow loomed over Sam's workspace. The cybersecurity expert craned their neck upwards, met by the ever-so-slight furrow in Alex's brow. "Got a minute, Rivera?" + +"Always," Sam said, a smile surfacing as they swiveled to face their mentor more directly. _He has that look — like something's not sitting right with him,_ they noted inwardly. + +Alex hesitated, weighing his words carefully. "Our tech is top-tier, but the silence from Dulce... It's not just technology that will see us through, it's intuition and... trust." His gaze pierced through the digital haze, trying to instill something more profound than advice. + +Sam regarded Alex for a moment, the sincerity in his voice resonating with their own unspoken desire to prove their worth. "Intuition," they mirrored thoughtfully. "I guess sometimes the numbers don't have all the answers." + +Their shared silence held a newfound understanding, a recognition that between the ones and zeros, it was their combined human insights that might prevail against the impossible. As Alex turned to leave, Sam's eyes drifted back to the screens, now seeing them not as barriers to isolate behind, but as windows into the vast and enigmatic challenge that awaited their team. + +Outside the office, the persistent buzz of activity in the facility belied the unease that gripped its inhabitants. A restlessness that nibbled on the edges of reality, as though forewarning of the threshold they were soon to cross — from the known into the realm of cosmic secrets and silent threats. + +\* + +Shadows played against the walls of the cramped underground meeting room, where Alex Mercer stood gazing at the concealed elevator that would deliver them into the bowels of Dulce base. The air was thick, every breath laced with the weight of impending confrontation, the kind one feels when stepping into a legend. Though armed with an array of advanced weaponry and gear, there was an unshakeable sense that they were delving into a conflict where the physical might be of little consequence. + +"I know what you're thinking," Jordan Hayes remarked, approaching Mercer. Their voice was low, a blend of confidence and hidden apprehension. "This feels like more than a rescue or reconnaissance mission, doesn't it?" + +Alex turned, his features a mask of uneasy resolve. "It's like we're being pulled into someone else’s game. Not just observers or participants, but... pawns." + +Jordan gave a short nod, their analytical mind colliding with the uncertain dynamics of this operation. "I've felt that way since the briefing. Like there's a layer we’re not seeing. And yet, we have no choice but to play along." Their eyes locked with Alex's, silently exchanging a vow to remain vigilant. + +"You two need to cut the philosophical chatter. We have positions to secure," Taylor Cruz interjected sharply, stepping into their exchange. The authority in Taylor's voice brooked no argument; it was their way of pulling everyone back to the now. + +Alex's response was measured, more assertive than moments ago. "Acknowledged, Agent Cruz," he replied, his voice steadier, mirroring the transformation brewing within. He gripped his rifle with a newfound firmness. "Let's proceed." + +As they congregated at the elevator, a tension palpable, Sam Rivera piped in with a tone of balanced levity, "Hope everyone’s brought their good luck charms. Something tells me we’re going to need all the help we can get." + +Their laughter served as a brief respite from the gravity of their mission, a shared moment that reinforced their common humanity amidst the unknowable. Then, as one, they stepped into the elevator. The doors closed with a silent hiss, and they descended into the darkness together, aware that when they returned, if they returned, none of them would be the same. + +\* + +The sense of foreboding hung heavier than the darkness that the artificial lights of the elevator shaft failed to fully penetrate. The team was descending into the earth, carrying with them not only the weight of their equipment but also the silent pressure of the invisible war they were about to fight—a war that seemed to edge away from physicality and into the unnervingly psychological. + +As they descended, Dr. Jordan Hayes couldn't help but muse over the layers of data that could wait below, now almost longing for the comfort of empirical evidence. _To think that this reluctance to accept other possibilities may have been my biggest blind spot,_ Jordan contemplated, feeling the hard shell of skepticism begin to crack. + +Alex caught Jordan's reflective gaze and leaned in, his voice barely a murmur over the hum of the elevator. "Once we're down there, keep that analytical edge sharp. You see through the mazes of the unexplained better than anyone." + +The compliment was unexpected and weighed differently than praise from others. This was an acknowledgment from someone who stood on the front lines of the unknown with eyes wide open. "Thank you, Alex," Jordan said, the words carrying a trace of newfound assertiveness. "You can count on me." + +The exchange was cut short by a shudder that ran through the elevator, subtle, but enough to make them instinctively hold their breaths. It wasn't the mechanical stutter of old gears but a vibration that seemed to emanate from the very walls of the shaft—a whisper of something that defied natural explanation. + +Cruz was the first to react, all business despite the shadow that crossed their expression. "Systems check. Now," they barked out, masking the moment of disquiet with swift command. + +Every agent checked their gear, sending confirmation signals through their comms, creating a chorus of electronic beeps that promised readiness. But there was an unspoken question among them: was their technology, their weaponry, their protocols sufficient for what awaited them or merely a fragile comfort? + +Against the gravity of the silence that was once again closing in, Sam's voice crackled through, only half-jest. "I'd laugh if we run into Martians playing poker down there—just to lighten the mood, you know?" + +Despite—or perhaps because of—the oddity of the moment, this elicited a round of chuckles, an audible release of tension that ran counterpoint to the undercurrent of anxiety coursing through the team. + +As the elevator came to a halting, eerie calm at the sub-level, the group stepped off, finding themselves at the threshold of Dulce's mysterious halls. They stood in a tight pack, sharing a cautious glance before fanning out into the unknown, each one acutely aware that the truth was inevitably intertwined with danger. + +Into the depths of Dulce, the team advanced, their silence now a shared testament to the camaraderie born of facing the abyss together—and the steel resolve to uncover whatever horrors lay hidden in its shadows. + +\* + +The weight of the thick metal door closing behind them reverberated through the concrete hallway, marking the final threshold between the familiar world above and the strangeness that lay beneath. Dulce base, a name that had been whispered in the wind-blown deserts above and in the shadowed corners of conspiracy forums, now a tangible cold reality that they could touch — and that touched them back with a chill. + +Like lambs led to an altar of alien deities, so did Agents Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera proceed, their movements measured, their senses heightened. The air was still, almost respectful of the gravity of their presence. Their torch beams sliced through the darkness, uncovering steel doors with warnings that spoke of top secrets and mortal dangers. + +Taylor Cruz, stepping firmly into the role of de facto leader, set a brisk pace. "Eyes sharp, people. Comms check, every thirty seconds," Taylor ordered, their voice echoing slightly before being swallowed by the surrounding silence. + +Sam, fiddling with a handheld device aimed at detecting electronic anomalies, offered a murmured "Copy that," their usual buoyancy dimmed by the oppressive atmosphere. + +It was Jordan Hayes who paused at an innocuous looking panel, nondescript amongst the gauntlet of secured doorways. "Mercer, Rivera, come see this," Jordan’s voice was marked with a rare hint of urgency. + +Alex joined Jordan's side, examining the panel which, at a mere glance, seemed just another part of the base's infrastructure. Yet, to the trained eye, it appeared out of place—a facade. + +Jordan explained their reasoning as Sam approached, instinctively understanding the significance of what lay beneath, "This panel is a recent addition — covering something they didn't want found." + +Before Alex could respond, the soft whir of an approaching drone cut through their muffled exchange. Taylor had looped back upon hearing the commotion. "Explanations later. We can't afford to attract..." Cruz’s voice trailed off as the small airborne device came into view, its sensors locked onto the group. + +Sam was the first to react, their tech-savvy mind already steps ahead. "I've got this," they declared, fingers flying over the controls of their own gadgetry to ward off the impending threat. + +The drone lingered, its scan seeming more curious than hostile. But within moments, courtesy of Sam's interference, the little sentinel drifted away, retreating into the shadows as if accepting a silent truce. The crew exhaled, a moment of collective relief palpable in the air. + +Cruz squared their shoulders, clearly ruffled but not conceding any ground. "Move out," they directed, a hint more forceful than before. "And Rivera, keep that trick handy." + +The team pressed onward, the quiet now filled with the soft beeps of regular comms checks, their pace undeterred by the confrontation. Yet, every agent held a renewed sense of wariness, their trust in one another deepening with the knowledge that the base—its technology, its secrets—was alive in a way they hadn't fully anticipated. + +As they converged upon a central hub, the imposing doors to the mainframe room stood ajar — an invitation or a trap, neither option comforting. Without a word, they fortified their resolve and stepped through the threshold, where the dim glow of operational LED lights and the distant hum of machinery hinted at Dulce’s still-beating heart. + +Solemnly, yet unmistakably together, they moved deeper into the heart of the enigma, ready to unmask the lifeforce of Dulce base or confront whatever existential threat lay in wait. It was in that unwavering march towards the unknown that their destinies were forever cemented to the legacy of Operation: Dulce. + +## Chapter 3 + +The thrumming of monitors cast a stark contrast to the rigid silence enveloping the group. Agent Alex Mercer, unfailingly determined on paper, seemed dwarfed by the enormity of the sterile briefing room where Paranormal Military Squad's elite convened. With dulled eyes, he scanned the projectors outlining their impending odyssey into Operation: Dulce. + +\* + +The cooling vents hummed in a monotonous drone, but it was the crackle of the comms system coming to life that cut through the lab’s tension. Dr. Jordan Hayes hovered over a table arrayed with alien technology, their fingers delicately probing the enigmatic circuitry retrieved from the crash site. Agent Alex Mercer watched, admiration blooming in silent solidarity for Jordan's deft touch and unspoken drive. + +Jordan, always composed, only allowed the faintest furrow of concentration to mar their brow. "What we understand about physics..." they muttered, trailing off as they realigned a translucent component. The device emitted a low pulse, causing Jordan to still. "Could be fundamentally changed by this." + +A calculated risk—that's what this was. And for a person of science, a gamble was worth the potential paradigm shift. + +"I’ve been thinking," Alex started, his eyes still fixed on the immediately tangible mystery before them. "About what’s at stake here. Not the mission parameters, but what this means for us—humanity." + +Jordan glanced up, meeting his eyes just long enough to convey the shared enormity of their situation; the career-defining glory and existential dread entwined. "The quest for understanding always comes at a price. We're standing on the precipice of knowledge that could either elevate us or condemn us." + +The charged air between them spiked as Taylor Cruz’s brusque tones sliced through their reverie. "Hayes, Mercer, this isn't philosophy hour. Focus on the task. We need actionable intel, not daydreams." + +With a sound of restrained acknowledgment, Jordan returned their gaze to the device, while Alex clenched his jaw, the buzz of frustration dull against the backdrop of Taylor's authoritarian certainty. It was this competitive undercurrent that kept him alert, the sense that his and Jordan's shared commitment to discovery was an unspoken rebellion against Cruz's narrowing vision of control and order. + +Then Taylor did something unexpected. They paused beside Jordan and, for a moment, observed the device with something akin to reverence. “If this tech can be understood..." Taylor said, their voice quieter, "It could change the game for us. For all of us.” + +The underlying dismissal earlier seemed to falter, replaced by a glimpse of reluctant respect for the gravity of what lay in their hands. Jordan looked up, and for a fleeting heartbeat, their eyes locked with Taylor's, a wordless clash of wills softening into an uneasy truce. + +It was a small transformation, barely perceptible, but one that Alex noted with an inward nod. They had all been brought here by different paths and for different reasons. Yet, beneath the veneer of duty, the enticement of the vast unknown pulled them inexorably together, coalescing their distinct desires into a shared pulse of anticipation. + +Marshaled back to the moment by the blink of lights and whir of machinery, they refocused their efforts, each movement sharpened by the knowledge that beyond understanding the unearthly artifacts, they might be piecing together the future of their species. + +\* + +Amidst the sterility of the briefing room, the liminal space between the facts laid out and the hidden truths, sat Sam Rivera, his demeanor an artful balance of focus and a casual disguise of his razor-sharp talent with technology. Across from him, Alex Mercer lingered in thought, the mental cogs turning as each file on Dulce stirred more than curiosity—it beckoned to a past both honored and burdensome. + +"You've been quiet, Sam," Alex noted, catching the younger man's contemplative gaze. "Your take on these signal inconsistencies?" + +There was a respect in Alex's tone, though a respectful distance remained—a gulf of experience and a hint of protective mentorship that stood between them. Sam nodded, recognizing the space afforded to him, and he couldn't help but feel the weight of expectation pressing upon his shoulders. It wasn't just the mission that was immense, it was the trust being placed in him. + +"The patterns are... off," Sam admitted, hesitant but driven. "If I'm right, what we're looking at isn't random—it's a structured anomaly. We need to be ready for anything." + +Alex's eyes brightened with a subtle approval that crossed the distance like a silent nod. "Good. Keen eyes will keep us ahead—or at least not blindsided," he said, affirming the belief that inscribed Sam's role as more than the tech personnel—he was to be a guiding intellect in the heart of uncertainty. + +Their exchange was cut short by Taylor Cruz's abrupt arrival, his gait brimming with a robust confidence that veiled the sharp undercurrents of his striving nature. "Time to gear up. Dulce waits for no one," Taylor announced, his voice carrying an iron resolve that knew the costs of hesitation—though whether the cost was calculated in human or career terms was an ambiguity he wore like a badge of honor. + +As Sam and Alex nodded in unison, the icy chasm of hierarchy and cryptic protocols seemed momentarily to bridge over with an understanding—this mission was convergence, a nexus point that would challenge each of their motives and strength. + +They filed out of the briefing room, their footsteps synchronized, a rhythm that spoke volumes of the unknown cadence they would soon march to within the base's veins. For Alex Mercer, the link with Sam Rivera, though distant, was now poised with a mutuality ready to be tested; for Taylor Cruz, the initiative pulsed like a heartbeat, anticipation thinly veiled behind a mask of duty. + +In the midst of the descent, they were each alone yet irrevocably joined, stepping closer towards the volatile embrace of Operation: Dulce. + +## Chapter 4 + +The corridors of the Dulce military base were as silent as a tomb and twice as chilling. Alex Mercer walked with a surety that belied his bubbling undercurrents of doubt. The briefing had been definitive, sturdy pillars of facts and protocols, yet as he ventured deeper, the ominous atmosphere gnawed at him—a stark reminder of how much remained unknown. + +Jordan Hayes trailed a few steps behind, their detached exterior breaking for a moment as they caught up to Alex. "What's on your mind?" Jordan asked, their astuteness cutting through the unspoken tension. + +Alex glanced back at them. This place was a puzzle, a treacherous labyrinth where the walls whispered secrets, and among them, he sensed a call to question, to challenge the narrative they'd been sold. "The silence here... It's almost as if the base is waiting for something—or someone." + +"Just stay sharp, Mercer," Jordan cautioned, yet their eyes lingered on the quietude around them, conceiving the same shadow of doubt that unsettled Alex. + +Before they could delve into further discussion, the distinctive click of a safety catch echoed in the hollow space. Both agents turned to find Taylor Cruz standing resolute, primed for combat. Taylor's gaze was scrutinizing and cold, a stark contrast to the growing unease that smoldered silently amongst the rest. + +"Chatter is a liability," Taylor snapped, with a commanding flair that bordered on tyrannical. "We move forward, eyes open, mouths shut." + +Alex felt the tight grip of compliance strangle his gut, a lesson learned under the hard tutelage of rank and order. But here, in the bowels of Dulce, those instincts began to wane, the imperative to adhere now conflicting with the pressing urgency to confront the shadows they were enmeshed in. + +Then, unexpectedly, the lights flickered, a power fluctuation—or a sign? Alex's hand instinctively went to his sidearm, his mindset shifting from soldier to skeptic. The base, with its unyielding coldness, had just given them their first nudge into the realm of the speculative, an invitation to peel back the veneer of reality. + +"We should consider all possibilities," Alex murmured, more to himself than the others, his voice a barely audible breath against the sterile air of the complex. + +Taylor's posture stiffened at the challenge, yet their response was uncharacteristically reserved, notable in its lack of rebuke. "Agreed. For now, keep moving. But stay vigilant." + +A surprise—an echo of agreement from the last person Alex expected it from. And there it was, the glimpse of a wrinkle in the unyielding fabric of command, a hint that perhaps they were all starting to sense the strangeness that permeated this place. + +Progressing with determined steps, the trio moved deeper, silently acknowledging the evolution of their predicament. It was a small yet transformative concession to the unknown forces at play, an acknowledgment from each agent that, despite their disparate goals and ideals, the true nature of the Dulce base was an enigma that would forge new paths through their convictions. + +As they reached the central communications hub, the truth that awaited them lurked in the shadows, its eyes unseen but felt by all. The walls didn't just whisper now; they spoke in tones only the brave—or the foolish—would dare to listen to. + +\* + +The subterranean silence of Dulce was an oppressive entity of its own, wrapping the team in a cloak of uneasiness as they pressed on through the dimly lit corridor. Jordan Hayes found themselves contemplating the ramifications of each step taken into this suspended world, where the sterile air seemed to mock the gravity of their predicament. The closer they got to the communication hub, the more Jordan's mind wandered toward the realm of the inexplicable. + +Beside Jordan, Alex Mercer moved forward with deliberation, his gaze scanning the heavy utility doors they passed—one of which was partially ajar, beckoning them with its darkness. "After you, Dr. Hayes," Alex said, gesturing toward the mysterious opening. A hint of shared understanding passed between them; knowledge was the guiding star of this mission as much as confrontation or recovery. + +Jordan peered inside, the beam from their flashlight slicing through the obscurity. The room beyond was a chaotic cascade of papers, overturned furniture, and the particular kind of disorder born from hasty evacuation—or something far more sinister. + +"It's like they vanished in the middle of something urgent," Alex murmured, his voice tight with a mix of concern and anticipation. He began to sift through the scattered reports, each page a potential clue to the enigmatic silence that shrouded Dulce. + +Behind them, Taylor watched with a disciplined patience, their authority the foundation upon which the operation was built. Their voice cut into the stillness, a reminder of their presence, "Time is not our ally here." + +Drawing back from momentary distraction, Jordan acknowledged the wisdom in Taylor's words, yet could feel the shift in their stance—from skeptical, reserved analyst, to a proactive agent within the narrative. "You're right; these documents may hold critical insights. Let's collect what we can and analyze them properly." + +From the darkened hollows of the room, shadows seemed to cast subtle judgment as Alex and Jordan worked together with heightened urgency. Taylor, for once, didn't intervene but instead surveyed the entrance, their mind anticipating the unknown variables that lay ahead. + +Unexpectedly, a soft hiss emanated from a neglected terminal on the desk. Jordan's head snapped up, their heart rate accelerating at the potential ramifications. Without a word, they moved to the machine, hands driven by the newfound conviction that knowledge was more than power—it was survival. + +As Jordan began to extract what data they could from the terminal, the first comprehensible communication from the depths of Dulce in far too long crackled through: an automated distress marker, looping endlessly without further context. It was a revelation, one that reverberated through the group, confirming their fears and igniting an even greater need to press on. + +Watching Jordan's dogged determination, Alex witnessed the minor transformation in his colleague unfold—a shift from doubt to action, a sliver of belief in the possibilities beyond their rational understanding. This forge of resolve amidst the alien echoes of Dulce not only bonded them closer as a team but compelled them forward with a sharpened edge of responsibility to the truth, wherever it would lead. + +As they collected their findings and regrouped, the base around them imperceptibly changed, the air charged with the vibration of secrets poised on the brink of revelation. And in that charged silence, the group moved on, each now carrying pieces of a puzzle that would soon converge into a picture of galactic significance. + +\* + +In the chill of the cramped server room, the hum of machinery was the backbone to a symphony of data streams coursing through the air. Dr. Jordan Hayes, nerves alight with the mission's mounting unknowns, patched into the last known coordinates of the unsent distress broadcast they had uncovered. They were so close to the core now – to the truth behind the blackout – it was almost tangible. + +Beside them stood Agent Alex Mercer, ever the soldier, yet with eyes that betrayed an intellect craving to understand the murk beneath the surface. "Any progress, Dr. Hayes?" Alex queried, his voice betraying a subtle urgency. + +"Getting there," Jordan replied, fingers dancing across the keyboard. "Whoever sent this was cut off mid-transmission. It's as if Dulce itself swallowed the message whole." + +Taylor Cruz closed in, their frame casting a long shadow over the duo, evoking an almost palpable wall between them and the forward momentum of their mission. "Time is against us," Taylor intoned, more statement than threat. "What we uncover here determines our next course of action." + +Alex acknowledged Taylor with a brisk nod, his stance firm. Yet inwardly, the tightening grip he felt from Taylor's words couldn't throttle the swell of his own investigative instinct. His soldier's obedience had begun to war with the advocate's zeal for unveiling the dark heart of Dulce's secrets. + +And then, the unexpected occurred. The screens flashed in unison, spilling a discordant stream of symbols and images that defied immediate analysis. Jordan's breath caught – this was the response they had been fishing for, an alien communication protocol resonating just at the edge of human comprehension. + +Each member of the team felt it: a shift in the room’s very atmosphere, like a veil being drawn from their perception. Alex and Jordan stood still, absorbed in the bewilderment of contact, while Taylor, despite their authority, hesitated – a minor betrayal that unease was creeping into even their disciplined heart. + +"Thoughts, Rivera?" Taylor rallied, seeking the counsel of Sam Rivera, whose eyes were wide with exhilaration. + +Sam stepped forward, breaking the spell of stillness. "It's like nothing I've ever seen before, but I think I can bridge our systems to communicate," they declared, a wisp of optimism braiding their voice. They set about adapting their gear to transmute the foreign signals into something the team could dissect, their actions a testament to the mentorship and belief instilled in them by Mercer and the team. + +Taylor observed them, a cold calculation behind their facade, as they weighed the worth of this anomaly. It was a crossroad that potentially led to either monumental breakthrough or unprecedented catastrophe. "Once you've established a line, document everything. We can't afford to miss any detail," Taylor ordered, the words sharper than intended. + +The connection was made, and with trembling anticipation, the team listened as the first garbled outputs began to emerge, their very essence promising insights that could alter the course of history. It was an enigmatic dance with the unknown, the pulse of Dulce no longer just a place, but a herald to an alien register the team had yet to decipher. + +Together, they stood at the precipice of understanding, where the faint glow of their monitors cast more than just light – it cast the shadow of burgeoning transformation. It was in this moment, in the grasp of an extraterrestrial tongue, that the team, bound by a hunger for knowledge and the raw edge of survival, found their mission reframed from a search for answers to the articulation of a question humankind had yet to fully ask. + +Silent in their commune with the inexplicable frequency, they realized they were not merely investigators; they had become liaisons on behalf of Earth, interpreters of a cosmic message that could redefine their very existence. The implications loomed large, but now, they would not face them alone – they would face them as a united front, wrought together by the very mysteries that once drove them apart. + +## Chapter 5 + +Dr. Jordan Hayes clutched the edge of the briefing room table, their fingers white-knuckled against the laminate surface, as an array of constellations rotated on the projector—charts and graphs bleeding across the stars. In the dim room, nebulas and dark matter seemed within arm's reach, tangible yet unfathomable. + +Sam Rivera leaned back against the wall, arms crossed, gaze darting between the swirling cosmos and the faces of their companions. A taut line of concentration etched their young features, a mingling of fervent curiosity with the nascent understanding of the high stakes for which they played. + +Jordan's voice broke the profound silence. "The patterns in the signal disruptions sync with none other than zenithal star alignments. It's as if... as if these 'meet and greets' were scheduled, predestined by celestial mechanics." + +The statement hung heavy, daring the occupants of the room to unravel its implications. Alex Mercer, his prior military resolve momentarily suspended, absorbed the hypothesis with a visible hunger. "It's like we're adhering to an appointment we never knew we had," he murmured, his heart a drumbeat in his chest. + +Taylor Cruz snorted—a sound that clattered against the high concepts like a tumbledown shack in a futurist cityscape. Folding their arms, they glanced between the agents, their apprehension clad in the contempt of practicality. "What we need are facts, not mystic conjecture." + +Alex pivoted on his heel, facing Taylor squarely, and his voice found its edge of steel. "This isn't mysticism, Cruz. It's a hypothesis based on observed phenomena as unpredictable as the place we're standing in." + +Taylor's gaze never wavered, yet the slight twitch at the corner of their mouth belied their taut composure. "If there's a semblance of truth to it, then it's critical intel. But remember, we're not astrologers—we're soldiers and scientists." + +Jordan met Taylor’s gaze with a curt nod, accepting the caution even as the crucible of their intellect smoldered with the fervor of cosmic discovery. Their eyes flicked to Sam, whose steady presence and ready tech affirmed a burgeoning dynamic—the makings of a sentinel, standing guard over the threshold of human understanding and cosmic reality. + +With the projector casting pallid light over their features, each agent became a silhouette of purpose, shadows pillared against the backdrop of an endless universe. The story they were embroiled in would soon demand they plunge into darkness to retrieve the light of knowledge—a light that could very well redraw the shape of their world. + +They left the briefing room with a shared silence, each pondering the vast weave of celestial intent and terrestrial response, sensing that the galactic appointment to which they'd unwittingly RSVP’d was more insistent—and more threatening—than any operation they’d faced before. + +\* + +As the Paranormal Military Squad team convened in the heart of the Dulce military complex, an air of bristling expectation clung to the walls of the underground sanctum. Alex Mercer’s brow furrowed while watching his companions—Jordan Hayes, diligently setting up their makeshift lab station, and Sam Rivera meticulously checking the communication relays they had restored. Taylor Cruz observed with hawk-like focus, yet to betray the strain that their command posed on them. + +The gravity of the mission had shifted, deepened; each member of the team felt its pull, tethered to the understanding that they were now part of a larger narrative—a cosmic play with Earth as a stage and the human race unwitting actors. + +Jordan paused, a tension creeping across their shoulders as they aligned the satellite data with the alien message that had been decoded. "The instructions in this message," Jordan started, the timbre of their voice betraying their usual composure. "They're coordinates and... a warning." + +Sam leaned in, their eyes widening behind the glow of their laptop screen. "A warning? Like, ‘stay away from’, or ‘beware of’...?" Their words trailed off, uncertainty a new companion in their lexicon. + +Alex exhaled slowly, his mind racing to connect the dots. "It doesn't matter which," he said, decisive yet contemplative. "What matters is we understand intent. Are we being warned out of concern, or are we stumbling upon a threat?" + +Cruz’s iron-clad facade momentarily cracked, a fleeting glimpse of vulnerability flashing through their eyes. "We need to know if this entails additional risk to the operation," they said, directing their gaze specifically at Alex. "Mercer, I rely on you to keep the team grounded. No one goes off-course." + +Their reminder seemed both a command and a plea—rooted in an understanding that each member of the team now faced the duality of their roles, protectors of earthly secrets and heralds of potentially devastating revelations. + +Sam's fingers stilled mid-type, their task forgotten as they absorbed the weight of the unfolding reality. "We're the first line of defense... or detection," they mused half to themselves, a growing sense of agency within the larger play they were cast into. + +Jordan returned to the data, more resolute in their actions. The warning, whether cautionary or dire, was a beacon they no longer could ignore; its light casting aside shadows of doubt and igniting a collective purpose within the team. + +Alex watched Jordan and Sam, feeling a brotherhood in their shared quest. As Cruz paced, poised on the cusp of decisions that would mark their career and perhaps the fate of many, Alex knew the narrative had changed. They were no longer mere operatives; they had become guardians of a threshold, keepers of a message from a realm beyond stars and stripes. This elevation in their mission could not be shackled by regulations and established protocols—it demanded a new perspective, a new resolve. + +Tension threaded through the dialogue of beeps and static as communications with Washington buzzed in the background. The team stood, a portentous air enveloping them. It was clear that the decisions they made in the ensuing hours could redefine humanity's place in the cosmos or condemn them to ignorance and potential peril. + +Their connection to the stars solidified, the group moved to address the crystallizing warning, shifting from passive recipients to active participants. Mercer’s latter instincts gained precedence— the team’s mandate had evolved, no longer solely to observe and report but to interact and prepare. A metamorphosis had begun, and Operation: Dulce hummed with the newfound frequency of their daring, a tone set not by the earthly hierarchies but by the pulsing symphony of the universe itself. + +\* + +The desert night loomed eerily still as echoes of hidden activity reverberated deep beneath the bleak sands of New Mexico. Diverting his gaze from the array of sensors before him, Jordan Hayes allowed a rare breath, deep and anxious. Turning to Alex Mercer's focused silhouette, the nocturnal landscape illuminated softly by makeshift floodlights, Jordan felt the syncopated tempo of apprehension and exhilaration jockey for primacy within. + +"The closer we get to unlocking these messages, the more I feel like we're peeling back layers of reality itself," Jordan confided, eyes not leaving the monitors that presented a constellation of data points. + +"Yes," Alex replied, his voice steady as he considered the implications of their discovery. "And we have to be ready for whatever we find beneath those layers. Whether it's a breakthrough or a Pandora's Box." + +Silence settled between them, broken only by the occasional buzz of communications equipment attempting to bridge terrestrial and extraterrestrial intelligences. Tense moments drifted by, laden with the expectant weight of near breakthrough, when a soft chime signaled an incoming transmission -- a rare sound that set every agent on high alert. + +Absent was the voice of Washington or Paranormal Military Squad command. Instead, a rhythmic series of pulses and tones filled the air, deliberately patterned, unmistakably non-human. + +Sam Rivera adjusted the sensitivity of the decoding equipment, their hands shaking with anticipation as much as focus. "I have it!" they announced, the signal transforming under their expertise into a sequence of visual symbols on the screen before them. + +Their shared excitement was palpable, a kinetic force resonating between the team members as they crowded around the display. + +"What does it say?" Taylor Cruz demanded, the urgency in his tone scraping against the newfound wonderment. + +Interpreting the alien syntax required not only decoding but intuition and empathy. The words that emerged upon the screen were at once coherent and enigmatic: "*Voyage. Convergence. Peril.*" + +The stark simplicity of the message struck them collectively, a chill breeze wafting through their resolve. + +Alex stepped forward, piecing together the cryptic communication with a growing sense of obligation. "It’s a call to action," he deduced, "or possibly a summons." + +Jordan's gaze met Alex’s, both understanding that this was no longer an investigation or mere extraction of hidden truths. This was humanity's unwitting enlistment into a galactic dialogue that defied boundaries of nation, creed, or protocol. + +Sam's eyes were aglow, not with fear, but with the profound acceptance of inevitability that comes with groundbreaking revelation. Moreover, within Taylor's stern exterior churned the seed of reluctant admiration for the unclassified, the uncharted realms they were approaching. + +Together, they accepted the pivot in their mission, readjusting their objectives from exploration to engagement, and from isolation to a communal outreach beyond the stars. As dawn's first light threatened the horizon, it became clear that they were no longer merely operatives of a clandestine governmental faction—they were delegates on behalf of Earth, embarking on a voyage orchestrated by destinies unrelated to the mere geopolitics of their world. + +Turning to each other, their silhouettes sketched against the coming dawn, the agents recognized the transformation within and amongst them. They were bound by more than duty—they were intricately woven into the fabric of an unfolding cosmic opera, one in which they had been granted an undeniable role. And as they set course for the coordinates that beckoned them like a distant siren's call, it was with a solemn dedication to not only uncover the mysteries ahead but to navigate the convergence, and the peril, as unified emissaries of a world on the cusp of a broader understanding. + +\* + +Beneath the hum of the fluorescent lights and the vigilance of silent monitors, Alex Mercer stood with his team in the threshold of the base's command center, their faces etched with the fatigue of hours spent unraveling galactic mysteries. Jordan Hayes broke the stillness with a delicate fusion of disbelief and resolve. "The signal..." they began, their tone deliberate, "it’s evolving. It’s not just sending a message—it’s responding to us." + +Taylor Cruz leaned over the console, their eyes narrowing with intrigue and a flicker of unease, studying the alternating patterns on the screen. "Responding? Like it’s alive?" Taylor asked, a question that bordered on the edge of wonder and alarm. + +Sam Rivera’s gaze was locked onto their interface, a digital orchestra at their fingertips. "It could be some form of advanced AI. Or something else entirely," they contributed, a note of exhilaration betraying the gravity of the situation. + +Alex paced before the terminal, absorbing the enormity of their predicament. Their mission—once rooted in the solid ground of military discipline and covert operations—had transcended into an encounter of unprecedented import. "We need to be cautious," he advised, his voice a low rumble of cautious strategy. "If this signal is intelligent, how we interact with it could dictate the outcome of this entire operation." + +Jordan met Alex's gaze with a nod, the weight of the responsibility shared and accepted. "We have protocols for first contact, but nothing for... this," Jordan admitted. The room was gripped with tension, each breath seemingly louder than the last. + +Then, with a sudden burst that filled the command center, the signal coalesced into a clear and distinct pattern which replicated and expanded, its complexity revealing the hand—or mind—of an intelligent architect. + +Taylor's instinct for command surged forth. "Prepare to record and analyze. Whatever it is, we need to understand it—" But their words were cut short as the signal surged, enveloping the room in a brief, blinding cascade of light. + +In that pulse of brilliance, a shared revelation coursed through the team. The signal had become a bridge, an extension of unknown consciousness reaching towards them, testing, communicating, searching. + +Alex stepped back from the light, feeling a profound change unravelling within him. The path forward would not be one of confrontation or conquest, but of connection and comprehension. + +Jordan turned to Alex and Taylor, seeing in their faces a reflection of the same metamorphosis taking place within themselves—a movement from observers to participants, from agents to ambassadors. + +With a collective breath, the team faced the kaleidoscope of lights. The alien signal, once a harbinger of enigma, was now a catalyst for transformation—a symphony of light and sound that echoed the beginnings of a new relationship between humanity and the alien unknown. + +And so, with deliberate steps, Alex Mercer led his team into the luminous fray. Science, protocol, and survival instinct harmonized within them, each member poised on the cusp of a new chapter in human history. + +They were no longer merely the instruments of Paranormal Military Squad's will—they were the vanguard of humankind’s first definitive leap into the cosmic community. + +With the last echoes of the signal resonating in the control room, they each embraced the sequencing of the transmission, the dance of extraterrestrial light that now wrote itself into their story. The chapter of Operation: Dulce drew to a close, but the narrative of their destiny had only just begun. + +## Chapter 6 + +\* + +The cool darkness of the command center at Dulce base was a stark contrast to the brewing storm outside, where the unforgiving New Mexico desert winds whispered of the hidden truths that lay buried deep beneath its surface. Dr. Jordan Hayes sat, their eyes fixed on the readout, the frenetic dance of symbols and numbers reflecting off their determined face. They were on the cusp of an epiphany, teetering between the widely accepted laws of physics and the promise of a new cosmic paradigm. + +Alex Mercer watched from across the room, noting the subtle shifts in Jordan’s posture that belied a developing readiness to embrace the unbelievable. “Find something?” Alex’s question, asked with a blend of curiosity and solidarity, bridged the gap between a command and a genuine query among equals. + +Jordan's response was slow, measured against the magnitude of their analysis. “This isn’t random static. It’s a pattern - a repeated sequence phasing in and out but distinctly artificial.” Jordan turned away from the screen, locking eyes with Alex. “This could change everything.” + +Sam Rivera leaned in, their eyes alight with the fires of revelation and a quenchless thirst for understanding. “A pattern means intention. Could it be a message?” + +A figure emerged from the doorway, casting a long shadow into the room - Taylor Cruz. “Intentions can be friendly, or hostile. We shouldn’t forget that,” said Taylor, bringing a dose of their usual pragmatism into the heart of discovery. + +Alex acknowledged Taylor’s caution with a nod, understanding the need to keep their feet grounded even as their spirits soared toward the unknown. “Then let’s be the first to find out which it is." + +The team gathered around the monitors, the soft tapping of Jordan's keystrokes now punctuated by the occasional crackle of Sam's radio equipment. The sound was almost ritualistic, a prelude to humanity’s potential first, knowing foray into a larger universe. + +Jordan’s fingers paused, suspended in mid-air. The signal had evolved, becoming a beacon that somehow felt less alien and more familiar. It was as if the complexities of their message were unfolding into something more accessible, more terrestrial. + +A hushed excitement swept through the room. The transformation suggested an awareness on the part of the unknown senders; a finesse that spoke volumes about their capabilities and perhaps their intentions. + +With the growing realization that they were engaging with an intelligence far exceeding their previous understanding, the team prepared to reach back across the cosmic divide. Prepared or not, they were no longer bystanders in this galactic narrative. They were active correspondents in an exchange that transcended galaxies and welcomed them into an expansive, possibly fraught, interstellar conversation. + +\* + +Inside the cavernous central hub of Dulce military base, Dr. Jordan Hayes stood in near-darkness, surrounded by a nest of cables and monitors that buzzed with silent, cryptic life. Jordan's eyes narrowed to focus on the sequences that danced across the screen—patterns that could unravel the cosmic enigma surrounding them. + +Alex Mercer approached with his characteristic stride, a signal of reliability in the chaos. "Status report, Dr. Hayes?" he inquired, his voice low, almost blending into the soundscape of beeping consoles and swirling fans. + +"We're on the brink of unravelling the signal's origin," Jordan replied, the weight of implications heavy in their tone. "There's intelligence behind it, a thought process alien to our own." + +As if summoned by their analysis, Taylor Cruz approached with authority radiating from every pore. "Understand this, we need to know if it's friend or foe. Don't get wrapped up in the existential—our lives may depend on the answers you provide." + +Sam Rivera, their hands adroitly adjusting a device to fine-tune the signal, chimed in with optimism undercut by anxious anticipation. "We're deciphering the comm encryption. Soon, we'll have a channel open—not just listening in, but speaking back." + +Alex nodded his understanding, his strategic mind processing the tactical implications while grappling with the more profound humanistic impact. "When we do, we'll tread carefully, communicate with purpose," he reassured the team. + +The operation had evolved rapidly, from a stealthy incursion into a clandestine labyrinth to an exchange with an extraterrestrial intellect. Their earlier trepidation transformed into determined focus, as they prepared to extend humanity’s hand into the vast unknown. + +An alert on one of the monitor stations snapped the team into alarm. The signal had not simply been waiting—it had been calculating. Now, it reached its crescendo, demanding their attention with a provocative urgency. + +Jordan's fingers raced over the keyboard, their eyes simultaneously interpreting data and sharing directives. "It’s a linguistic lock, a test of comprehension. We crack this, we establish dialogue." + +Taylor's presence was a beacon of steely resolve. "Then let’s solve it. This is what we trained for—the unknown." + +Alex and Sam exchanged a look that telegraphed their shared determination—this was not only the mission they had trained for; it was the mission they had been destined for. + +Together, the Paranormal Military Squad team leaned into the challenge, their minds honing in on the complex patterns with a singular goal: to unlock the conversation with an intelligence that had already begun to shift the foundations of what they knew, or thought they knew, about the universe. + +In a symphony of clicks and murmurs, they worked, knowing they were about to make a giant leap not just for themselves or Paranormal Military Squad, but for all of humanity. As the final pieces fell into place, Dulce's militaristic silence was shattered by the sound of intergalactic contact—by the sound of history being made. + +## Chapter 7 + +In the enclosed space of Dulce’s command center, the air was thick with anticipation, each team member poised to tread the razor's edge between scientific breakthrough and galactic peril. Dr. Jordan Hayes focused intently on the screen, their fingers tapping a staccato rhythm against the keyboard as lines of alien code cascaded down the monitor. + +Alex Mercer's steely gaze surveyed the room, stopping on each member of his team. "Thoughts?" he asked, echoing the unspoken tension. His question, while directed at the group, lingered on Jordan—acknowledging their expertise and inviting collaboration rather than dictating orders. + +Jordan’s brow furrowed, an indicator of the mental gymnastics being performed. "It's unprecedented," they finally said, their voice a testament to the gravity of the moment. "Behavioral algorithms... if we're right, this code could reveal extraterrestrial thought patterns." + +Before anyone could react, Taylor Cruz interjected with the assertiveness of someone accustomed to commandeering the discourse. "Then let’s ensure we’re deciphering it correctly," Taylor stated, their tone suggesting they were still battling to maintain control over an increasingly alien situation. + +Sam Rivera hovered near the mainframe, youthful energy barely contained under the surface. "What if it’s more than just a message? What if they’re trying to extend consciousness across the stars?" + +The room fell into a contemplative silence, broken only by the hum of electronic equipment and the distant thud of secured doors locking in rhythm. The weight of responsibility rested on each agent's shoulders—a heaviness palpable in the air they shared. + +Alex stepped forward, reaching a subtle decision, one dictated by foresight and the humanity nestled at the core of their mission. "We approach with the aim to understand, not to confront," he said, softening his military bearing into a more diplomatic stance. + +Jordan nodded, appreciating the leadership that Alex displayed in the face of the unknown, and turned back to the cryptic data. Here, before them all, was a tangible piece of evidence—proof of an extraterrestrial sentience that had outreached the bounds of their expectations. + +Taylor took a breath, simultaneously exuding a sense of preparedness and venturing into the unknown alongside their peers. "Then let’s do what Paranormal Military Squad does best—investigate and adapt," Taylor added, finding comfort in the familiar even as they stood on the cusp of an unprecedented alchemy of science and mystery. + +The team leaned into their respective roles, driven by the urgency of the assignment and the pull of an insatiable curiosity. Sam offered a grin that belied the tension, a youthfulness that reminded them all of the profound excitement nested within the terror of the unknown. + +Quietly but resolutely, they turned back to their instruments, each of them a sentinel on the threshold of a new reality. The once implicit lines of command were now woven into a shared tapestry of hierarchy and camaraderie. As they danced with the unknown, they were beacons of sentient endeavor, casting the light of human consciousness into the vast darkness that called to them. + +\* + +\* + +Dulce Base's cavernous darkness was pierced by the sharp luminescence of monitors, casting an electric glow onto the faces of those who dared to unearth its secrets. Dr. Jordan Hayes stood motionless, eyes glazed in concentration, their mind a nexus where terrestrial science battled with celestial unknowns. + +Alex Mercer watched from a slight distance, the weight of command tangible upon his shoulders, though lightened by the shared burden now held amongst them. "We could be on the frontier of a new kind of diplomacy," he mused aloud, giving voice to the moment's gravity. + +At those words, Jordan's trance broke. "If that's the case, then these communications," Jordan motioned to the stream of data, "are our olive branch across the cosmos." + +Taylor Cruz, who paced with restless energy, halted and faced the team—his stoicism marred by the erratic dance of lights reflected in his eyes. "An olive branch, or an invitation to a battlefield?" he posed, ever the strategist, his words laced with a hint of cynicism. + +Sam Rivera, nestled amongst an array of equipment, licked their lips—a mixture of nerves and anticipation palpable. "We're mapping out something incredible here. Whether it's peace or war, we're the cartographers." + +Silence enveloped them like the expanse of space itself, each member contemplating the chasms they might bridge—or the abysses into which they might unwittingly descend. + +Alex's demeanor assumed a quiet resolve—the profound knowledge that this mission was as much about navigating uncharted philosophical territories as it was about ensuring survival. "Whichever it proves to be, we'll face it. Prepared, unified." + +A nod passed between Jordan and Alex, a silent exchange of mutual respect and shared mission. Sam, buoyed by the weighty encounters of the mind and machinery, entered keystrokes with a fervor that seemed to bring them ever closer to the alien mind. + +They stood there, the Paranormal Military Squad team, not just as guardians of homeworld secrets or as soldiers of clandestine wars, but as humankind's chosen few at the fulcrum of history—a history that was now unfolding to the rhythm of otherworldly codes. + +Each revelation, each parsed symbol, inched them toward the line between the earthly and otherworldly. And as they stood on this precipice of cosmic negotiations, it was clear the ensuing dialogue would not just shape the future of Paranormal Military Squad—it could very well redefine the parameters of human existence. + +\* + +The hum of advanced computational systems tingling with cryptic transmissions framed the ambiance of Dulce's mainframe chamber. Jordan Hayes, fingers hovering over a console dense with blinking lights, furrowed their brow as sequences of alien data streamed across the screen. + +Alex materialized behind them, his presence a stable beacon amidst the technological whirlwind. "Look for patterns, anomalies. Anything that might resemble a handshake protocol in their communications," he directed, his voice a low thrum, reverberating with cautious optimism. + +Jordan cast a glance over their shoulder, acknowledging Alex's contribution with the shared understanding of colleagues who had transcended mere professional acquaintance. "I’m isolating sequences that seem to recur with more intention than static. If these are their ‘handshakes,’ then we might just be making first contact," they remarked, their focus returning to the screen with renewed vigor. + +From the other end of the room, where shadows married the artificial light, Sam's voice crackled through the static of nearby speakers, "Don't forget the anomalies we detected earlier. Each one could be a word, a sentence, or even a concept untranslatable to our current understandings." + +Resolute, Taylor Cruz stood at Jordan's other side, a stoic figure wrestling with the implications of their mission. "Keep pursuing this line," Taylor instructed, an undercurrent of intensity carried forth in their otherwise composed demeanor. "And remember, this isn't just about making contact; it's about securing knowledge for humanity." + +Alex offered a nod that spoke volumes, conveying his understanding of the stakes at play. Here, in this chamber of possibility, the team's actions would determine if humanity stood at the brink of a new age of understanding or the onset of an unprecedented threat. + +Every second thrummed with significance as Jordan and Sam worked in tandem, each keystroke a foray into the unknown. Taylor observed with a commander's scrutiny, the gravity of their role sustaining them against the waves of ambiguity breaking against their resolve. + +Pivotal moments come rarely in the course of human events but here, amidst the electronic symphony of a stalwart command center, lay the incepting notes of a cosmic overture. The harmony between human and alien, between Paranormal Military Squad and the vast reaches of space, began its first tentative measures, with each member of the team a vital instrument in a celestial ensemble yet to be fully heard. + +\* + +The crisp air within the mainframe room of Dulce base seemed to hum with unspoken possibilities. Jordan Hayes was the centerpiece of focus, their hands dancing methodically over the console as streams of otherworldly code cascaded down monitors, each flicker a potential key to the cosmic doors they were inching open. + +Alex Mercer watched, posture relaxed but eyes sharp. "Remember, this could be our first introduction, maybe even our first impression," he said, mindful of the gravity carried by each action they made henceforth. + +A hint of a smile touched Jordan's face, a small acknowledgment of the monumental task at hand. "Understood. I'm balancing the signal's syntax with our algorithms. If we're interpreting this correctly, it could be... well, an invitation." + +Into the electric tension of the chamber walked Taylor Cruz, their silhouette a sharp contrast against the cool lighting, radiating a presence that spoke of command and chilly tenacity. "An invitation, or a challenge?” Taylor questioned, the weight of their suspicion casting a different tint on the cascading data. + +Sam Rivera, in a corner arrayed with sophisticated equipment, piped up, their voice a buoyant note amidst the tentative atmosphere. "Either way, it's a connection. One that we're uniquely positioned to navigate," they remarked with an air of optimism threading through the uncertainty. + +Alex channeled the strengths of his team into the core of their approach, his leadership adapting to the contours of an unprecedented scenario. "Cautious and curious," he reflected aloud, shaping a strategy that balanced their thirst for comprehension with the prudence required in addressing the unknown. + +Jordan, hands momentarily at rest, looked up. The signal was more than a sequence of bits and commands—it was a riddle wrapped in the depths of space-time, and they were on the cusp of parsing its meaning. + +Taylor, hardly a step away, nodded in silent agreement. The implications of their findings might very well direct the course of human destiny from this point onward. + +Finding a tempo among themselves, the Dulce team was a confluence of ambition and acumen, each member intuitive to the beats of discovery. The chamber around them held untold stories, secrets coaxed from the stars, that now, led by Paranormal Military Squad's finest, began to unravel. + +The future in those moments was unwritten, a narrative scribed not in the dust of desert confines, but in the potential for interstellar diplomacy and understanding. As they prepared to script humanity's next chapter, the room seemed to pulse with the heartbeat of a story far greater than the sum of its parts. + +## Chapter 8 + +The grit of an earthbound dust storm contrasted sharply with the pristine sterility of the underground command center. Alex Mercer, eyes set with fervent determination, stood over Jordan Hayes, whose fingers danced across the keyboard with rapid purpose. Monitoring the progression of alien code unraveling before them, Mercer spoke with a tempered urgency, "Keep it steady, Jordan. We might be initiating the first true interspecies communication bridge here. It's all about finesse now." + +Taylor Cruz, the embodiment of military precision, surveyed the room with a calculated gaze from their vigil beside an array of glimmering screens. "Remember, these could be delicate negotiations -- or coded threats. Stay sharp," Cruz added, their voice cool as polished steel. + +Jordan, with a silent nod, recognized the gravity of both stances. Gravitating between scientific acuity and diplomatic caution, they replied, "The sequence is aligning—syncing with our comms. It's looking more and more like direct engagement." + +Amid the banks of electronic machinery, the thrumming pulse of an impending interspecies signal exchange, Sam Rivera interjected with a youthful zeal that cut through the weighty atmosphere, "It's not just an exchange. It's a... symphony. It's as if they're teaching us their language through modulation." + +A moment of profound silence swept over the team. The isolation of their location, deep within the top-secret labyrinth of Dulce, became suffused with an almost palpable sense of historical significance. + +"Then our response needs to be equally symphonic," Alex uttered, contemplating the awe-inspiring transmutation of their task from a simple recovery mission to a full-blown cosmic concerto. + +With a renewed sense of wonder tempered by caution, the Paranormal Military Squad team found themselves harmonizing a delicate balance between envoys and interpreters. The long shadow cast by their duty was now illuminated by the brilliant glow of otherworldly dialogue. + +In this carefully orchestrated march towards the unknown, each individual's expertise became critical notes in a larger melody. The narrative of human achievement, so often defined by solitary pursuits, now emerged as a collaborative opus, each member of the team a maestro in their right. + +The protocols of encounters, the mathematics of languages, and the poetics of connection all fused into a singular moment of convergence. The echo of their efforts reverberated back to them, not through the cavernous base's concrete walls, but from light-years away, in the form of a reply, intangible yet infinitely profound. + +\* + +Amidst the hum of the supercomputers and the faint static from the scrambled transmissions, Alex Mercer cast a thoughtful glance across the dimly lit room toward where Dr. Jordan Hayes was methodically adjusting the archaic dials of the decryption machine. "Any progress?" he asked, his tone conveying both impatience and the deep-seated respect born from countless shared challenges. + +Jordan did not look up, their gaze remained locked on the flickering lights that represented a dialogue suspended between worlds. Their fingers ceased their dance, hovering meditatively over the controls. "We might be on the cusp of a breakthrough," Jordan suggested. "The signal... it's evolved. It's reflexive now, responsive in a way that suggests sentience." + +Taylor Cruz's familiar sharp strides approached the two, breaking the rhythm of soft beeps. "Responsive is good, if it means understanding," Taylor said, head tilted as they peered at the encryption data scrolling by. "But remember, comprehension can bring revelation or conflict." + +Sam Rivera’s youthful voice permeated the tension, brimming with an excitement edged by the enormity of what they faced. "If it's truly sentient, we're not just cracking a code; we're learning how to converse with an entirely new form of consciousness," they chimed in, the weight of history not lost on the zealous astrotechnician. + +Alex nodded, his thoughts alighting on potential strategies for navigating the conversation they were cultivating with the unfathomable. "We need to keep that conversation going, echo its patterns, and speak its language," he resolved, knowing the delicate nature of their work merited every ounce of their collective acumen. + +The chamber now was a crucible, forging within it the future narrative of human contact with the unknown. Every signal pulse they sent out was an invitation for understanding, and every echo back a step closer to bridging the cosmic divide. And so, together, they stood - agents in Paranormal Military Squad's clandestine ranks, united by purpose, sculpting humanity’s first sonnets into the void. + +\* + +#### Knowledge graph updates + +- (Jordan Hayes, Interprets, Communications as cosmic diplomacy, Moderate) + +- (Taylor Cruz, Questions, Potential aggressiveness of alien intent, Minor) + +- (Sam Rivera, Expresses, Optimism about forming a connection, Minor) + +- (Alex Mercer, Adopts, Balanced strategy for contact, Moderate) + +- (Paranormal Military Squad team, Navigates, Beats of cosmic discovery, Moderate) + +- (Paranormal Military Squad team, Prepares, To script humanity's interstellar narrative, Major) + +## Chapter 9 + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +Dr. Jordan Hayes, whose hands had been steadfastly working the decryption algorithms, paused and looked up at Alex. "We're through the next layer of encryption," Jordan announced, a mixture of pride and gravitas in their tone. "It's communicating. It's... aware." + +A shadow momentarily clouded Alex's determined features—awareness implied so much more than mere intelligence. "Aware and reactive or aware and proactive?" he queried, his experience anticipating the pivotal importance of intention. + +"Unknown at this stage," Taylor Cruz interjected, looking up from a datasheet. "But I urge caution. We tread the line between breakthrough and disaster with each keystroke." + +Sam Rivera, ever the source of technological acumen, added their voice to the conversation. "The signal's adapting every time we interact with it. Like a conversation where both parties are learning each other's language in real time." + +Alex leaned in, rested a hand on Jordan's shoulder—a sign of companionship and an affirmation of trust. "Keep the communication channels open. But let no message, no pulse go unchecked. This could be our Rosetta Stone or our Tower of Babel." + +Silence fell over them, a momentary lull as each member of the team contemplated the historic weight of their task. Yet, it was impregnated with a tangible sense of excitement—a collective energy that thrummed through the air just as palpably as the electric current through the banks of machines surrounding them. + +They continued their work, squaring shoulders against the magnitude of their undertaking. The agents were standing not just at the precipice of a new chapter for Paranormal Military Squad but for all of humanity. For now, they communicated with powerful unknowns, but with each exchange, they were etching the first words of a dialogue that might forever alter humanity's place in the cosmos. + +\* + +\* + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +Dr. Jordan Hayes, whose hands had been steadfastly working the decryption algorithms, paused and looked up at Alex. "We're through the next layer of encryption," Jordan announced, a mixture of pride and gravitas in their tone. "It's communicating. It's... aware." + +A shadow momentarily clouded Alex's determined features—awareness implied so much more than mere intelligence. "Aware and reactive or aware and proactive?" he queried, his experience anticipating the pivotal importance of intention. + +"Unknown at this stage," Taylor Cruz interjected, looking up from a datasheet. "But I urge caution. We tread the line between breakthrough and disaster with each keystroke." + +Sam Rivera, ever the source of technological acumen, added their voice to the conversation. "The signal's adapting every time we interact with it. Like a conversation where both parties are learning each other's language in real time." + +Alex leaned in, rested a hand on Jordan's shoulder—a sign of companionship and an affirmation of trust. "Keep the communication channels open. But let no message, no pulse go unchecked. This could be our Rosetta Stone or our Tower of Babel." + +Silence fell over them, a momentary lull as each member of the team contemplated the historic weight of their task. Yet, it was impregnated with a tangible sense of excitement—a collective energy that thrummed through the air just as palpably as the electric current through the banks of machines surrounding them. + +They continued their work, squaring shoulders against the magnitude of their undertaking. The agents were standing not just at the precipice of a new chapter for Paranormal Military Squad but for all of humanity. For now, they communicated with powerful unknowns, but with each exchange, they were etching the first words of a dialogue that might forever alter humanity's place in the cosmos. + +\* + +Alex Mercer's eyes were fixed on the monitors, the reflected light casting an ethereal glow across his stoic face. The room buzzed with tension, a cacophony of low hums and electronic beeps that underscored the historic nature of their actions. He moved to where Dr. Jordan Hayes was immersed in their work, scrutinizing the alien code streaming rapidly down the terminal. + +"Find anything that might look like an entry point or a... digital handshake?" Alex asked, his voice steady, betraying none of the tension gripping his chest. + +Jordan looked up briefly, their expression weary yet intense, "Potentially. It's as if the code is anticipating our input, modifying itself in real-time. I've never seen anything like it." + +From across the room, Taylor Cruz's sharp voice cut through the hum. "Then it's learning or, possibly worse, baiting us. Proceed with extreme caution," they commanded, their firm stance reinforcing the gravity of the situation. + +Sam Rivera, surrounded by a cascade of screens and interfaces, added, "It's almost organic in its complexity. Any minute now, and I might have a way in." + +A slight nod was Alex's immediate response, his mind racing through the potential scenarios. "Everyone, stay alert. This could be the beginning of something profound." His seasoned eyes never left the unfolding drama on the monitors. + +The room fell silent, the air heavy with unspoken questions. Were they mere moments away from unlocking an otherworldly dialogue? Or was it a Pandora's box that, once opened, could not be closed? + +Alex moved closer to the main console, his fingers hovering over the command keys. With the precision of a maestro orchestrating a symphony, he communicated silently with Jordan – respectful of their expertise, aware that the next move could alter the course of human history. + +Jordan met his gaze, nodding sharply, and refocused on the task. The signal seemed to pulse with sentient curiosity, drawing them further into its intricate web. + +A sudden flurry of alerts and the intensifying glow of monitors heralded that they had bridged a technological chasm. The alien intelligence on the other end was no longer a distant enigma – it was an active participant, responding to their digital overtures with an unknown agenda. + +The team's meticulous efforts had led them to a momentous threshold. Beyond lay unprecedented contact – a nexus of curiosity and potential peril. Within the confines of the base, against the backdrop of a silent desert night, the Paranormal Military Squad operatives became mediators of Earth's bid for cosmic relevance, their every action now a gesture in the grand dance of intergalactic relations. + +## Chapter 10 + +The corridors of the Dulce military base, now silent, echoed with a history of whispered conspiracies and furtive movements. But in the command center, a delicate tapestry of light and sound was being woven as the echoes of cosmic dialogue resonated through the high-tech enclave. Dr. Jordan Hayes, now leading the efforts, called out from their workstation, "I’ve isolated the signal's harmonics. It's more than a call; it's a song, an interstellar siren’s call." + +Alex Mercer, steady and resilient in the face of the incomprehensible, acknowledged with a quiet nod, "A song that we need to learn—quickly." His eyes, heavy with responsibility, scanned the room, watching his team work tirelessly at the intersection of science and speculation. + +Sam Rivera, dulled by fatigue yet driven by unshakeable resolve, manipulated a complex array of audio interfaces. "There's a pattern, a repeating motif. It's structured, intentional," they muttered, their revelation a bridge between the known and the unimaginable. + +Taylor Cruz, a figure of central authority, paced the length of the room, their usual unflappable demeanor betraying a rare flicker of apprehension. "We should be wary of the sirens’ call," Taylor interjected, invoking myths of old as a cautionary metaphor. "We don't want to crash upon unseen shores." + +Undeterred, Jordan cast a determined glance at the team. "We navigate by starlight now, not by the limited light of our previous understanding." Their voice was a beacon, charting a course through unchartered realities. + +Every individual was acutely aware that each moment in that room was a conduit to an epochal shift for civilization. The mysterious signals, once distant and alien, had coalesced into complex and harmonious oscillations—beacons of an extraterrestrial intellect inviting Earth to join in a cosmic consortium. + +Silently, Alex approached the mainframe, his trained fingers aligning with the console’s mechanisms. The room watched in collective breathlessness as he set the frequency in motion, an introductory phrase to an otherworldly melody—a symphony that could bind worlds or spell devastation for all they knew. + +In the control room of Dulce, amongst whispered legends and the quiet hum of machines, humanity's ambassadors now stood, stretching their hands into the void, reaching for the hand that would either pull them into the light of new stars or into the maw of darkness between them. + +\* + +Underground, the Dulce facility's command center was awash with frenetic energy, a stark juxtaposition against the silent, decrepit corridors that enveloped them. The air hummed with anticipation as Dr. Jordan Hayes and Alex Mercer hunched over a console. The sterile light from the monitors cast an otherworldly glow upon their faces, now reflecting a mosaic of alien characters rapidly translating across the screen. + +"The patterns are evolving," Jordan murmured, concentration etched into their every feature. "It’s as if our attempts to decrypt have accelerated its learning. It’s adapting to us." + +Alex, who stood steadfast behind Jordan, felt a tinge of uncharted fear quickly quelled by the fire of discovery raging within him. "Keep it up," he urged. "But whatever this is becoming, we need to ensure it remains within our control." + +Taylor Cruz interjected, their voice slicing through the buzz of activity. "Control may be an illusion when facing an intelligence that literally writes its own rules," they stated stoically, casting a watchful eye over the flurry of data. + +"It's like it's learning to communicate," offered Sam Rivera from a nearby interface, their youthful energy boding a mix of awe and anxiety. "This gives ‘talking to strangers’ a whole new meaning." + +Alex surveyed his team—each face a study in concentration, determination, and not a small measure of trepidation. "This might well be our first contact," he acknowledged, "And we need to be ready for whatever answers back." + +Together, they stood on the edge of the unknown, forging humanity’s response to a message from the heavens. The ensuing silence was palpable—a collective introspection about their role in this grand cosmic play, one that could rewrite human history. + +The encrypted dialogue continued to unfold, its intricate patterns showing an almost uncanny anticipation of their investigative strategies. The air turned heavy with the scent of electricity and ambition as they closed in on a pivotal response. + +As the signal’s intelligence—whether artificial or biological—grew more profound, so too did the realization that their mission had morphed from passive observation to active engagement. There was no turning back now. Each agent embraced their part in the delicate dance of an interstellar exchange that could change everything they thought they knew about life, intelligence, and the dark void beyond Earth's atmosphere. + +\* + +The underground halls of Dulce Base, usually buzzing with covert operations, now thrummed with a different kind of energy, an electric mix of fear and fascination. At the heart of the base, in a room shielded from the world’s eyes, Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera huddled around a bank of monitors. Each screen flickered erratically with the alien script that had become the center of their lives—and perhaps the pivot on which humanity’s future would turn. + +Jordan's eyes never wavered from the displays, their expression was one of rapt concentration, interspersed with flashes of revelation. "We're conversing with the stars," they whispered, almost to themselves. The words hung in the air, a testament to the awe-inspiring strangeness of the situation. + +"The language is morphing; changing its structure with every exchange we have," Sam chimed in, enthusiasm tinged with the solemnity of the occasion. "It's like witnessing the birth of a new form of dialogue—one that spans galaxies." + +Taylor, despite the situation's precariousness, maintained an appearance of ironclad composure. "Keep the communication stream secured and monitored. We don't know what we're dealing with yet," they reminded the team, a bastion of protocol amidst uncertainty. + +Alex watched his team expand the parameters of human achievement; their work here would possibly define an era. "This is untrodden territory," he acknowledged, "and in every word we script, in every response we decode, we're drawing a map that others will follow." + +Jordan turned to Alex, a nod acknowledging the shared responsibility of this moment. They had embarked on a new voyage, an odyssey not of the body, but of the intellect and spirit. No longer explorers of the Earthly realm, they had been promoted by circumstance to ambassadors of humanity in a silent and boundless ocean. + +A sudden pulse of energy from the monitors signaled a breakthrough; the language had not only adapted but it seemed to resonate, to harmonize with their attempts at making contact. The alien script now sprawled across the screens didn't just ask to be understood—it invited interpretation, collaboration, maybe even companionship across the cold distances of space. + +As they stood before the precipice of first contact, Paranormal Military Squad's finest became the architects of a symphony meant to echo through the cosmos. But more than architects, they were the first to play the notes of this cosmic composition, daring to believe that on the other end, someone—or something—might be listening, ready to join the chorus. + +\* + +The underground command center of Dulce Base, once pulsing with clandestine operations, now resonated with the charge of an impending cosmic threshold. Encircled by banks of whirring machinery, each monitor flickered erratically with alien script that had occupied center stage in the lives of Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera. + +Jordan's gaze didn’t flit for even a moment from the screens, where indiscernible alien messages ebbed and flowed like the tide. The ciphers and symbols cascaded down as they tweaked the algorithmic sliders. "This sequence here," Jordan began, voice both hushed and heavy, "it’s not just transmitting; it resonates—it's designed to be felt." + +The room took a collective breath, the remarkable implication hanging in the air like a careful revelation. Sam Rivera was the first to respond, their voice alive with ingenuity: "It's a form of communication stretching well beyond words. We need to respond in kind—the whole array of human expression might be at play here." + +Taylor's eyes remained fixed on the figures playing across the data sheets. "If that's the case," Taylor intoned pragmatically, "we must tread carefully. This is no longer just about being heard—it's about being understood." + +Alex watched his team, each a fulcrum of insight and expertise, and felt the solemnity of the role they were about to assume. "Then we'll ensure our message is clear and full. Our humanity is our strength in this dialogue," he declared, the depths of his experience fueling a commanding reassurance. + +The anticipation was palpable as the agents contemplated the vastness of their endeavor. They were not merely probing at the secrets of the planar cosmos—they were negotiating across the starry expanse, extending to distant intelligences the full spectrum of human curiosity and compassion. + +A symphony of beeping consoles orchestrated their next steps as they prepared to articulate their interplanetary overture. The rhythmic tapping of Jordan's keystrokes set the tempo for an undertaking that traversed beyond algorithms and encryption. + +The base withstood time and whispered secrets of its own, but none so grand as this moment of creation—an invitation to the universe that promised to echo through both the echoes of space and the annals of human history. + +## Chapter 11 + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +\* + +The thrum of the colossal machinery vibrated through the subterranean facility as Alex Mercer stood amidst the whispers of technology, each carrying voices from worlds apart. He watched as Sam Rivera adjusted a complex array of cosmic translators, their expression a mixture of anticipation and awe. + +"Are we ready, Mercer?" Taylor Cruz asked, the soft glow of the command center consoles reflecting upon their stern face. + +Alex turned towards Taylor, his eyes holding a depth that betrayed the enormity of the threshold they were about to cross. "This is it," he said. "Initiate the protocol. It's time we answer the cosmos." + +Jordan Hayes, stationed at the mainframe, typed rhythmically, a blue hue painting their focused features. The eerie silence that had settled over the team was interrupted by a visceral sound—humankind's response to the alien dialogue, now streaming into the abyss. + +The control room, once a fortress of solitude, erupted into an oasis of life. Lights flickered in tandem, echoing the symphony of interstellar communication. They stood together at the edge of discovery, facing the symmetry and discord of a universe unknown. + +"If we're right, we've just become Earth's first emissaries to a celestial congress we're only beginning to comprehend," Jordan's voice was somber, resonating with a mix of trepidation and honor. + +The room filled with the resonance of human and alien minds converging, creating a new narrative within the fathomless expanse of existence. Paranormal Military Squad, once protectors of Earth's clandestine secrets, had now become the tether linking humanity to the cosmic fold. + +\* + +The underground command center of Dulce Base, once pulsing with covert operations, now resonated with the charge of an impending cosmic threshold. Encircled by banks of whirring machinery, each monitor flickered erratically with alien script that had occupied center stage in the lives of Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera. + +Jordan's gaze didn’t flit for even a moment from the screens, where indiscernible alien messages ebbed and flowed like the tide. The ciphers and symbols cascaded down as they tweaked the algorithmic sliders. "This sequence here," Jordan began, voice both hushed and heavy, "it’s not just transmitting; it resonates—it's designed to be felt." + +The room took a collective breath, the remarkable implication hanging in the air like a careful revelation. Sam Rivera was the first to respond, their voice alive with ingenuity: "It's a form of communication stretching well beyond words. We need to respond in kind—the whole array of human expression might be at play here." + +Taylor's eyes remained fixed on the figures playing across the data sheets. "If that's the case," Taylor intoned pragmatically, "we must tread carefully. This is no longer just about being heard—it's about being understood." + +Alex watched his team, each a fulcrum of insight and expertise, and felt the solemnity of the role they were about to assume. "Then we'll ensure our message is clear and full. Our humanity is our strength in this dialogue," he declared, the depths of his experience fueling a commanding reassurance. + +The anticipation was palpable as the agents contemplated the vastness of their endeavor. They were not merely probing at the secrets of the planar cosmos—they were negotiating across the starry expanse, extending to distant intelligences the full spectrum of human curiosity and compassion. + +A symphony of beeping consoles orchestrated their next steps as they prepared to articulate their interplanetary overture. The rhythmic tapping of Jordan's keystrokes set the tempo for an undertaking that traversed beyond algorithms and encryption. + +The base withstood time and whispered secrets of its own, but none so grand as this moment of creation—an invitation to the universe that promised to echo through both the echoes of space and the annals of human history. + +## Chapter 12 + +The underground facility of Dulce Base, once shrouded in silence and operational secrecy, now hummed with an energy that cradled the promise of cosmic revelation. Alex Mercer stood pensively by the central terminal, flanked by Dr. Jordan Hayes, Taylor Cruz, and Sam Rivera, each poised at the edge of a history-defining moment. + +Jordan's fingers ghosted across the console, tracing patterns of otherworldly origin. "The signal’s architecture is becoming more complex, resembling aspects of human cognition—recognition, learning, even... empathy?" they postulated with furrowed concern. + +Alex turned his gaze upon Jordan, his voice quiet but resolute, "Empathy could bridge galaxies. Let's harness this connection and proceed with cautious optimism." + +Taylor, ever the sober sentinel, projected a more pragmatic standpoint. "Empathy or not, we are duty-bound to assess the risk to humanity. Every new discovery warrants a measured response." + +The static hiss of communications equipment filled the air, its purpose now transformed into a dialogue with an intelligence beyond the stars. It was Sam, wide-eyed amid the myriad lights and switches, who broke the silence, "We have provisional confirmation of the signal’s intent—initiation. We’re being brought into a broader spectrum of cognizance." + +The chamber lay still for a heartbeat, the Paranormal Military Squad agents steeped in contemplation of the path unfurling before them—a path paved with possibilities of diplomacy or disruption, each step a venture further into the cosmic unknown. + +Alex stepped closer to the viewing monitors, each depicting alien symbols seemingly reaching out from the void. "Initiate the broadcast," he spoke with quiet command. "Our response will mark humanity’s readiness to partake in the wider conversation of conscious beings." + +Amidst the crackling air of expectation, the team wordlessly returned to their stations. They had transcended their roles as protectors of Earth's clandestine lore to become the harbingers of an interstellar parley that could change the existential course of life on their pale blue dot. + +The deep hum of the terminal emitted a signal—a testament to the uncanny reality that Earth was now actively partaking in an exchange not bound by gravity nor the limits of the solar wind. + +Here, in the depths of Dulce, a message from humanity woven from understanding and uncertainty was cast into the firmament, an epitheg of their desire to join the universal dialogue and discover their place among the constellations. + +\* + +The somber depths of the Dulce Base command center stood in stark counterpoint to the animated flurry of activity around the central comms array. Alex Mercer's silhouette loomed behind Dr. Jordan Hayes, who sat with a posture indicating laser focus on the decryption process. A quiet murmur of digital soundscape filled the space, subtly heightened by the anticipation of contact with an intelligence beyond the Earth. + +Jordan's voice was steady, betraying none of the extraordinary nature of their work, "Looking through the signal's pattern, it's evident we’re dealing with a form of intelligence—calculating, mirroring, possibly even understanding." + +Alex's reflection bounced off the darkened screens, his head nodding in silent affirmation. "We’re walking a delicate line. Our response should be thoughtful, measured. We’re ambassadors, not merely explorers." + +Taylor Cruz approached, arms folded, their words slicing through the din of careful keystrokes and soft whirrs, "If there’s even the slightest chance it understands, we can’t afford missteps. The language of the stars might be more absolute than ours." + +From another terminal, Sam Rivera brought youthful vigor to the conversation, "There’s rhythm in these patterns. If this is their way of reaching out, our reply should encapsulate all that we are—all that humanity stands for." + +Looking around at his team, Alex saw resolve etched on every face. The chamber, usually somber and echoing with the quiet steps of covert agents, now felt alive with the heartbeat of discovery. They were not just professionals operating in the gloom; they were a collective standing at the helm of a momentous journey. + +"Let’s begin," he said, returned by the resolve in his voice. "Every second counts." With that, they pressed forward, setting in motion a reply to a conversation billions of years in the making. + +The dance with an unseen partner commenced, each pulse they sent out a step taken with caution and hope. And as those digital pulses journeyed through the black sea of infinity, Earth, for perhaps the first time, joined a pan-galactic dialogue that whispered secrets of the cosmos—secrets that, until now, had been lost in the silent vastness of space. + +\* + +As the team stood in the centralized nerve center of Dulce's underground fortress, the solemn atmosphere was reverent, overseeing systems that engaged with an intelligence from the void. Alex's stance was contemplative as he gazed at Jordan Hayes, who presided over the console, the tension of the moment reaching a tactile fervor. Each rhythmic tap of Hayes's fingers on the keys was a foray into uncharted symphonies of contact. + +Observing Hayes unravel the dense alien encryption, Alex spoke, a diplomatic tenor underpinning his words, "Keep focused on the syntax, dissect its nuances. We're not just decoding signals; we're translating intentions." + +Without diverting from their task, Jordan acknowledged the insight. "Indeed, if their understanding of us is as deep as we hope, we're paving the way for dialogue far beyond our current realm." + +Taylor Cruz, near the rear of the room, provided a steady oversight. "As horizonless as our prospects may seem," Taylor intoned, "remain diligent. Complacency before alien cognition could spell catastrophe." + +Sam's youthful voice resonated with optimism, "Imagine—forming a rapport with a consciousness separate from our reality; we're drafting the bridge to stars alive with minds!" + +The sentiment hung for a moment before Alex gathered his conviction. "Dialogue is our vessel. We are not just agents of enigma; we are the threads that may weave a new cosmic relationship." His words seemed to reflect off the walls, reaching beyond the room's confines, a quiet yet resilient vow. + +Their task was titanic, stepping stones laid delicately into new territories of existence. The signal, once an esoteric strand in the echo of the universe, beckoned now with a clarity rocketing the complexity of thoughts from a distant order. + +Action by action, the Paranormal Military Squad team bridged the vast interstellar distances, their expertise and empathy casting a beacon of unity into frontiers of intelligence and knowledge. Their work, a partnership struck with an unseen cosmic congregation, each pulse sent and received a line in Earth's novitiate envoi to the cosmic shores. + +\* + +Under the stark, unforgiving lights of Dulce Base's underground command center, tension buzzed harder than the banks of supercomputers that lined the walls. Agent Alex Mercer leaned over the shoulder of Jordan Hayes, whose eyes were locked onto the display screen, where an incomprehensible series of alien symbols streamed past incessantly. + +“Any progress on the decryption?” Alex's voice was steady, a controlled presence necessary in the gravity of their undertaking. + +Jordan tapped a key, pausing the flow of code, and leaned back with a deep sigh. "We've broken through another subset of the cipher. It's revealing... well, indications of a complex society, not unlike our own." His eyes met Alex's with an unspoken question that hung heavily between them—were they truly prepared for what they might find? + +Taylor Cruz strode into the room, a tightly coiled spring of ambition and authority, and peered at the screen. "Understand their society, and we may predict behavior. Remain expedient—we don't know how much time we have before the situation shifts." There was an edge of stark realism to Taylor's words, the underlying message clear: every revelation bore its own set of risks. + +Alex nodded thoughtfully, recognizing the validity of Cruz's caution. Turning to Sam, who was tinkering with a device that buzzed quietly on the table, he asked, “Sam, can your contraption get us any further?” + +Sam looked up with a smirk, a twinkle of mischief in their eye. “It’s not just any contraption, it’s potentially a direct line to their thoughts. Give me a moment more, and I'll have something for you.” + +The air ticked with electronic beeps and the rustling sound of the Paranormal Military Squad team at work. They were so close to peering into the intelligence of an alien race—a reality on the brink of dramatically expanding their understanding of the universe. + +The machinery whirred in response to Sam’s precise touches, and suddenly, the room filled with a low hum—something had changed, a signal had been successfully sent. The team held their breath as they listened. The sound that filled the room was unmistakable: a response, an alien voice filtered through the static of space and time. + +Alex exchanged a look of quiet triumph with Jordan. The breakthrough was monumental; they were no longer casting messages into the void but engaged in a dialogue—an exchange that marked the beginning of Operation: Dulce’s true unfolding. This was it, the first steps into an interstellar odyssey that demanded every ounce of their courage and wit. + +## Chapter 13 + +Dr. Jordan Hayes shuffled a stack of papers, their eyes revealing a tinge of skepticism at Taylor Cruz's authoritarian performance. _Protocols_, Jordan thought, _are just the framework, the true challenges we're about to face lie well beyond the boundaries of any protocol._ They cleared their throat before speaking, tone cautious yet firm, "Let's remember, the unknown variables exceed the known. We should remain adaptive." + +A murmur of agreement echoed from Sam Rivera, who leaned forward, lacing their fingers together as if weaving a digital framework in the air before them, "Exactly, adaptability could be the key to interpreting the signal distortions and system malfunctions. We shouldn't discount the… erratic." + +Their words hung like an electric charge in the room, challenging Taylor's position with an inherent truth. Cruz’s jaw tightened almost imperceptibly, but the agent masked it with a small nod, conceding to the omnipresent threat of the unpredictable. + +Alex glanced at Jordan, who never looked back, their gaze fixed instead on a distant point, as if envisioning the immense dark corridors they were soon to navigate in Dulce. Jordan was not one to embrace fantastical theories, but the air of cautious calculation betrayed a mind bracing for confrontation with the inexplicable, an internal battle between the evidence of their research and the calculating skepticism that kept them alive in their field. + +The meeting adjourned with no further comments, the team members quietly retreading the paths to their personal preparations. Alex, trailing slightly behind, observed the others. _The cautious reserve Jordan wears like armor doesn't fool me_, he thought, _their analytical mind sees the patterns I do. And that's worth more than protocol. That's the connection we need to survive this._ + +As the agents dispersed into the labyrinth of the facility, lost in their thoughts and preparations, the base's halogen lights flickered, a brief and unnoticed harbingers of the darkness to come. + +\* + +The gritty, wind-tossed surface of New Mexico, just above the cavernous domain of Dulce Base, offered no shelter from the burgeoning storm—the scouring sands an earthly reminder of chaos theories in motion. Far beneath, a similar maelstrom brewed within the confines of the command center, as Paranormal Military Squad's handpicked squad stood poised for potential enormities of contact. + +Ruffling through printed transmission logs, Jordan Hayes dialed the focus of their analytical prowess onto the emerging pattern of signals crisscrossing between Earth and the unfathomable. "Our responses so far have echoed their complexity, but the real divergence is yet to come," Jordan remarked stoically, the calm belying the mounting surge of adrenaline for the revelation ahead. + +Alex Mercer's figure, a silhouette sharpened by the purpose, loomed at the periphery of the monitors' sickly glow. "Indeed," he assented, "The echoes are the easy part. It will be the introduction of our own, human variable that truly begins our dialogue." + +Taylor Cruz, windowless command center notwithstanding, appeared as though they could feel the tempest above. Their eyes never left the monitors as they unspooled their hard wisdom. "For all our advances, we find ourselves deciphering the swings and nuances of an interstellar pendulum. Predict its arc, and we may preempt the gravity of its message." + +Amidst a chorus of bleeps and static, Sam Rivera's tech-clad hands moved rhythmically, their spirited approach to unruly streams of data bordering an intimate dance with entropy. "Entropy that leads to discovery," Sam mused, responding to Taylor's metaphor. "Each step into the unknown is a step away from precedent." + +Alex, drawing near Jordan, spoke again, his voice now a thread woven through the very fabric of their operations. "Let's be the cartographers of this new territory. Our initial shades of understanding could color the cosmos for generations to come." + +Their gazes fell upon a screen as the latest transmission painted its digital blooms of alien script across the black. This time, the pattern wavered in an almost imperceptible fashion, a modification that whispered of active, alien thought awaiting their next move. A hush enveloped the Paranormal Military Squad ensemble, the gravity of the pathogen undeniable. They were about to issue a reply, one poised to reshape the very concept of humanity's outreach into the cosmos. + +The New Mexico desert's secrets were infamous, its storms a mere prelude to the revelations that the team—united in purpose—would unleash upon the world. The howling winds outside found their counterpart in the newfound resolve within, as Dulce's stalwart guardians readied themselves to send forth humanity's retort to the echoes from beyond. + +\* + +The cavernous control room, deeply entrenched beneath the desolate New Mexico terrain, held the Paranormal Military Squad team in intense focus; an island of calm amid the storm of cosmic dialectics. Dr. Jordan Hayes worked methodically, every keystroke an intricate step in their tenuous cosmic ballet. Suddenly, they paused, a signal pattern resonating from the screen. "This is new; it's...inviting. It’s as if the signal is not just calling to us but weaving its intelligence through ours." + +Alex Mercer scrutinized the shift in data. "A confluence of minds, then. If we're to meet them halfway, Jordan, our reply must be both innovative and discerning," he proposed, a glimmer of profound curiosity behind his authoritative demeanor. + +Taylor Cruz, whose sharp eyes missed nothing, nodded from beside a secondary panel. "Innovative, yes, but also defensive. This interaction is a razor’s edge, and we cannot afford to bleed before the unknown," Taylor reminded them, the metaphor a stark warning of potential dangers. + +Against the backdrop of their conversation, Sam Rivera’s youthful optimism cut through the tension. "If they’re weaving through our intellect, then we've achieved something beyond first contact—we're at the genesis of interstellar symbiosis," they posited with a mix of reverence and excitement. + +Alex returned Sam’s smile with his own, tempered and faint, as he turned back to the task at hand. The magnitude of their mission extended beyond the fabric of the universe, an exploration into the threads that connected sentient beings across the vast expanse. “Let’s reply with our own woven tapestry of thought—delicate, but deliberate.” + +With renewed determination, the room came alive with an undercurrent of anticipation, its occupants charged with the potential of forging an alliance with the cosmos. Paranormal Military Squad's finest were no longer merely soldiers and scientists; they had become pioneers on the vanguard of humanity’s greatest odyssey. + +The New Mexican sands above, impassive to the change brewing underneath, stood as silent sentinels as Earth's emissaries crafted their response. A response that, composed with care and imbued with humanity's essence, reached into the void, connecting with an otherworldly intelligence that awaited their harmony in the cosmic conversation. + +## Chapter 14 + +The command center of Dulce Base lay shrouded in shadows that seemed to claw at the edges of the dimly lit array of screens and consoles. Alex Mercer, focused and unwavering, watched as Dr. Jordan Hayes parsed the latest string of alien signals—a symphony of otherworldly communications that threatened to either enlighten or confound. + +"We’re encountering a paradigm shift with every transmission," Jordan Hayes murmured, the pulsing glow of the monitor painting their features with an almost spectral hue. "This signal... it’s evolving, becoming denser, more sophisticated. As if it's growing alongside us—tandem evolution." + +The air was electric, charged with the raw potential of uncharted discovery and laden with the gravity of existential risk. Taylor Cruz, who always seemed here to mold such gravity into actionable strategies, stepped forward. "We must contain this evolution within parameters we can manage. We cannot be bystanders to an uncontrolled ascent of intelligence." + +Sam Rivera, the youngest of the cohort, worked feverishly at their station. "It's not just intelligence—these signals have rhythm, a kind of music suggesting not just evolution, but a dance! We're being invited to partake in the cosmos's ballet!" they exclaimed, a touch of youthful exuberance breaking through the solemnity. + +Alex turned, facing his team, the stoic mask of command tempered by the perceptible flicker of awe in his gaze. "Let this dance then be our dialogue. We will match their steps with prudent but daring measures—our humanity as our guide." + +In the ensuing hours, the Paranormal Military Squad team forged a rhythm of their own, their collective expertise a beacon piercing through the fog of the unknown. The signal, increasingly intricate and seemingly conscious, now demanded not just observation but participation, an interstellar pas de deux that hummed with the promise and peril of first contact. + +Before them, the communications interface flickered to life with a received transmission—a resonant hum that seemed to vibrate through the very foundations of the base. They had successfully established a back-and-forth with whatever intelligence lay hidden among the stars. Every subsequent note they struck within the cosmic ether would come to define humanity's place within the galactic community—heralds of Earth's grand entrance into a universe far less silent than once perceived. + +\* + +In the concrete belly of Dulce Base, dimly lit by the jagged dance of fluorescent lights above, Sam Rivera perched on the edge of their seat, their eager fingers fluttering across an ancient keyboard. The stark, cold room—reminiscent of a time when covert operations and unspoken dread ruled supreme—now housed a peculiar blend of old-world machinery and sleek, modern interfaces. + +Alex Mercer, standing steadfast like a bridge between the enigmatic past and the unfathomable present, watched on. In his eyes flashed the foreboding excitement of change. "Sam," he started, his voice steadfast, "the patterns in these signals, what do they tell us about the nature of our... guest?" + +Sam's eyes glimmered with something akin to thrill—or was it trepidation? "It's like we're mirroring each other, evolving together through this.. dialogue. Like it knows us, understands us, and it's… learning." + +Jordan Hayes, preoccupied at a nearby console, chimed in without lifting their gaze. "It's a dialogue that transcends mere words, Alex. We're being woven into a narrative far grander than the sum of our known sciences." + +Taylor Cruz, arms crossed, wore the heavy mantle of their skepticism comfortably. "Keep theorizing," they interjected crisply, "but remember the grounding reality of what we are part of here. This contact is a blade that cuts both ways." + +In this cavern of history, voices both human and inhuman whispered secrets to those brave enough to listen. Each member present understood the gravity that pulled at their feet; no longer were they mere mortals shackled to their terrestrial plane. The digital pings and encrypted calls resonated with an implication of a cosmic agenda that would not be ignored. + +Jordan's fingers paused, hovering in hesitation. What ripple might the next keystroke send through the fabric of known existence? It was a step into the ballet of the infinite, where the Paranormal Military Squad team played their part in the waltz of wonders with an audience of stars. + +\* + +## Chapter 15 + +In the clandestine hush of Dulce Base's subterranean command center, the Paranormal Military Squad team had become a crucible for interstellar communication. Dr. Jordan Hayes' gaze lingered on the screen as they navigated through the convolution of alien code. Each character held the potential to unravel a new dimension of contact, and with Sam Rivera's keen interjection, they were crafting humanity's inaugural cosmological discourse. + +Alex Mercer peered over Jordan's shoulder, calculating the implications of every visual nuance that cascaded across the monitor. "Look for consistency—any repeating motifs could signal a willingness to engage. We're drafting history with each exchange," he remarked, aware of the delicate balance between forging a bond and exposing vulnerabilities. + +Taylor Cruz, stoic and enigmatic, observed the interplay from the threshold, a silhouette against the machinery's luminescence. "Remember, while we seek common ground, the foundation we stand upon remains Terra firma. Caution must temper our curiosity," they stated, their voice an anchor amidst the current of excitement. + +The command center buzzed with energy, rivaled only by the tempest overhead that concealed their operation. Sam, with swift dexterity, navigated the communications relay. "Their signals resonate almost musically. It's as if they're composing a symphony, and we've been handed the baton to conduct the next movement," they offered, imbuing the scenario with a blend of scientific adventurism and poetic license. + +Amidst the whirring servers and the occasional flicker of emergency lighting, the essence of their mission transcended mere reconnaissance. They were humanity's elected envoys at the brink of a celestial alliance—or confrontation—with an audience as vast as the universe itself. + +Alex stepped back, his profile etched by the chamber's artificial day. "Then let's ensure our contribution to this symphony harmonizes with theirs. It's time for humanity's voice to rise and be counted among the cosmic ensemble." + +Under his directive, the Paranormal Military Squad team initiated their calculated response, weaving thoughts and theories into a digital overture aimed at the heart of alien intellect. As the digital stream punctured the endless night, each member of this clandestine group was acutely aware of the irrevocable step they undertook—bringing Earth into the pantheon of galactic entities designed to converse among the stars. + +\* + +Clusters of high-tech equipment bathed the Dulce underground command center in an eerie blue light. Sam Rivera's fingers flew across the keyboard, navigating an elaborate network of alien patterns. The very air seemed to pulse with the ebb and flow of cryptic communications reaching across the stars. "I've got something!" Sam's announcement tore through the focus in the room, drawing every pair of eyes to the torrent of symbols unraveling on the screen. + +With the pacing of a seasoned officer gauging the moment before action, Alex Mercer approached, his calm demeanor belying an acute awareness of the precipice on which they now stood. "Define 'something," Alex prompted, reinforcing the need for clarity amidst the extraordinary. + +"It's repeating—a sequence that’s evolved with each interaction, almost as if it's... singing," Sam theorized, the awe in their voice reflecting the potential magnitude of their discovery. + +Jordan Hayes interjected from across the console, their eyes not leaving the display as they absorbed the new data. "A cosmic vocalization, then," they mused, intrigued. "A singularity in the signal that might represent a point of reference for both parties." + +Taylor Cruz, hands clasped behind their back, regarded the unfolding scene, their own calculations etching lines of concern onto their stern visage. "Or a beacon—a homing tune, calling out to something we might not be ready to greet," Taylor offered, voicing the group's unspoken apprehension. + +Alex's eyes locked on the screen, taking in the scope of what they were attempting to interpret. Drawing a deep breath, Alex gave a slight nod. "If this is their song, then let us respond with ours. We've come this far by mirroring their signals, now let's engage in an interstellar duet, and see where the music leads us." + +With the expectation of the significant achieving a crescendo, the members of Paranormal Military Squad huddled over their equipment—sages at the threshold of a potentially world-altering communion. The strange harmonies that reverberated through the command center suggested that their interlocutors were poised, waiting, perhaps even eager, for Earth's chorus to join the symphony. + +As the team initiated their reply, weaving humanity's own intricate melody into the vast cosmic dialogue, they each felt a profound change within—an evolution of purpose. They were not just messengers or investigators; they had become co-composers in a galactic orchestra, with the universe itself as their witness and concert hall. + +With the exchange of harmonious signals crawling through the vacuum of space, the Paranormal Military Squad operatives found themselves part of a bridging of minds—a realization that out there, among the vast arrays of stars and planets, harmony was the true universal language. + +\* + +The dim glow of monitors cast an otherworldly ambiance upon Dulce Base's command center, where Paranormal Military Squad's chosen stood huddled over their instruments, suspended at history's threshold. Codes—alien in origin and nature—were being deciphered by Dr. Jordan Hayes, whose countenance bore the marks of deep concentration. + +Alex Mercer, the bedrock upon which their team's resolve was founded, leaned in with an eagerness tempered by his chain of command. "Jordan, we've invested our expertise into comprehending their patterns, but now we must also endeavor to understand their intent," he urged, his voice bearing the gravitas of their mission's potential consequences. + +At another console, Sam Rivera's youth did not betray their crucial role in the operation. With eyes alight, they mirrored the rapid computing before them. "There's emotion here—complex, profound even. This isn't just the output of a cold machine; it's...sentience," Sam whispered, nearly drowned by the mechanical chorus around them. + +Jordan, without shifting focus from their work, replied, "It's a sentience that—should we succeed here—ushers us into a new era of existence. The cadence of these signals," they tapped the screen with a flourish, "could well be the heartbeat of this new dawn." + +Taylor Cruz paused beside Mercer, their expression unreadable beneath the sterile light. "And as it beats, we must gauge whether its rhythm bodes well for us, or spells our missteps. Courage must not blind us to the hazards intrinsic to such contact," Taylor cautioned, the sentinel within them ever alert. + +Alex nodded, a gesture that carried the weight of responsibility and a silent command: proceed, but with circumspection. They were not merely decoding a message; they were interpreting a dialogue across the celestial divide. + +The room fell into a rhythm akin to a well-conducted ensemble. Each member's expertise proved a critical note in the unfolding symphony. Their actions were now more than mere research or defense; they were the tentative overtures of humankind reaching out to grasp the vast unknown. + +Textures of sound meshed with the light from countless computations, the palpable anticipation of the agents at the edge of discovery cresting with an awareness that their work would reshape future chronicles. And when the response finally came—a signal piercing the deafening silence of uncertainty—all within Dulce's confines understood: the dawn of an interstellar continuum had just begun to break. + +\* + +In the sterile hum and flickering lights of Dulce Base's command center, the Paranormal Military Squad team stood as humanity's vanguard, verging on the brim of an intergalactic abyss. Dr. Jordan Hayes, analytical edges sharp, deciphered extraterrestrial patterns that bled across screens in enigmatic cascades—a daunting mosaic of potential threats and untapped wisdom. + +Agent Alex Mercer, the embodiment of focus and a steadfast nerve, observed the unfolding digital drama with the gravitas due a historic first contact. "Let the data weave its narrative, Jordan," he instructed, a moderate undertone of exhilaration within his command. "It's encoding more than information—it's outlining civilization." + +Jordan absorbed the directive, their gaze unflinching from the screens, feeling the weight of their next move. "The nuances here are extraordinary," they acknowledged. "It paints a picture of a culture steeped in complexities we're only starting to fathom.” + +Taylor Cruz, stoicism personified yet not immune to the situation's gravity, chimed in. "Understand it, but guard against it," they cautioned, bringing a sober prudence to the room. "This culture, however advanced, remains an unknown quantity—an ocean of wonders and darkness with uncertain tides." + +Sam Rivera, a visual contrast with wide eyes and restless hands, represented the other side of the room — intrigue and optimism against the drawn swords of precaution. “Think of it,” they proposed, voice bouncing with a rebellious upbeat timbre, “as the first act of a play written in constellations. We're setting the stage for a galactic narrative.” + +Each team member, in their way, was both actor and scribe in this moment of tense pageantry. Heavy with the presence of risk, the command center had become not just a room of computers and glass panels but a theater for performing the elaborate choreography of contact. + +Bound by resolve and curiosity, they proceeded, each data entry a trembling step onto the cosmic stage. And like all cautious pioneers edging into fertile but unnavigated lands, they understood: as they mapped the heavens, they were simultaneously mapping the furthest reaches of their own existential horizons. + diff --git a/graphrag/tests/fixtures/azure/settings.yml b/graphrag/tests/fixtures/azure/settings.yml new file mode 100644 index 0000000000000000000000000000000000000000..2ebe953fe0493b6921be98085fef52ef8faca4c0 --- /dev/null +++ b/graphrag/tests/fixtures/azure/settings.yml @@ -0,0 +1,38 @@ +claim_extraction: + enabled: true + +embeddings: + vector_store: + type: "azure_ai_search" + url: ${AZURE_AI_SEARCH_URL_ENDPOINT} + api_key: ${AZURE_AI_SEARCH_API_KEY} + collection_name: "azure_ci" + query_collection_name: "azure_ci_query" + + entity_name_description: + title_column: "name" + +input: + type: blob + file_type: text + connection_string: ${LOCAL_BLOB_STORAGE_CONNECTION_STRING} + container_name: azurefixture + base_dir: input + +cache: + type: blob + connection_string: ${BLOB_STORAGE_CONNECTION_STRING} + container_name: cicache + base_dir: cache_azure_ai + +storage: + type: blob + connection_string: ${LOCAL_BLOB_STORAGE_CONNECTION_STRING} + container_name: azurefixture + base_dir: output + +reporting: + type: blob + connection_string: ${LOCAL_BLOB_STORAGE_CONNECTION_STRING} + container_name: azurefixture + base_dir: reports diff --git a/graphrag/tests/fixtures/min-csv/config.json b/graphrag/tests/fixtures/min-csv/config.json new file mode 100644 index 0000000000000000000000000000000000000000..fb15f5d4c8c3e581f10240e9cf0f5ae5f91488e3 --- /dev/null +++ b/graphrag/tests/fixtures/min-csv/config.json @@ -0,0 +1,155 @@ +{ + "input_path": "./tests/fixtures/min-csv", + "input_file_type": "text", + "workflow_config": { + "create_base_text_units": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 11, + "max_runtime": 10 + }, + "create_base_extracted_entities": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 2, + "max_runtime": 300 + }, + "create_summarized_entities": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 1, + "max_runtime": 300 + }, + "create_base_entity_graph": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 2, + "max_runtime": 10 + }, + "create_final_entities": { + "row_range": [ + 1, + 2000 + ], + "nan_allowed_columns": [ + "type", + "description", + "graph_embedding" + ], + "subworkflows": 11, + "max_runtime": 300 + }, + "create_final_relationships": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 8, + "max_runtime": 100 + }, + "create_final_nodes": { + "row_range": [ + 1, + 2000 + ], + "nan_allowed_columns": [ + "entity_type", + "description", + "graph_embedding", + "community", + "level" + ], + "subworkflows": 10, + "max_runtime": 10 + }, + "create_final_communities": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 14, + "max_runtime": 10 + }, + "create_final_community_reports": { + "row_range": [ + 1, + 2000 + ], + "nan_allowed_columns": [ + "community_id", + "title", + "summary", + "full_content", + "full_content_json", + "rank", + "rank_explanation", + "findings" + ], + "subworkflows": 6, + "max_runtime": 300 + }, + "join_text_units_to_entity_ids": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 3, + "max_runtime": 10 + }, + "join_text_units_to_relationship_ids": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 4, + "max_runtime": 10 + }, + "create_final_text_units": { + "row_range": [ + 1, + 2000 + ], + "nan_allowed_columns": [ + "relationship_ids", + "entity_ids" + ], + "subworkflows": 6, + "max_runtime": 100 + }, + "create_base_documents": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 8, + "max_runtime": 10 + }, + "create_final_documents": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 1, + "max_runtime": 100 + } + }, + "query_config": [ + { + "query": "Who is Agent Alex Mercer and what are his goals?", + "method": "local" + }, + { + "query": "What is the major conflict in this story and who are the protagonist and antagonist?", + "method": "global" + } + ], + "slow": false +} \ No newline at end of file diff --git a/graphrag/tests/fixtures/min-csv/input/ABOUT.md b/graphrag/tests/fixtures/min-csv/input/ABOUT.md new file mode 100644 index 0000000000000000000000000000000000000000..42c316108ec0893e6b1df44f8f42e5a50a8edb43 --- /dev/null +++ b/graphrag/tests/fixtures/min-csv/input/ABOUT.md @@ -0,0 +1,3 @@ +# About + +This document (Operation Dulce) in an AI-generated science fiction novella, included here for the purposes of integration testing. \ No newline at end of file diff --git a/graphrag/tests/fixtures/min-csv/input/dulce.csv b/graphrag/tests/fixtures/min-csv/input/dulce.csv new file mode 100644 index 0000000000000000000000000000000000000000..227b406f0a696c4f933f5d744f0c9078606f99f9 --- /dev/null +++ b/graphrag/tests/fixtures/min-csv/input/dulce.csv @@ -0,0 +1,959 @@ +text +"## Chapter 1 + +The thrumming of monitors cast a stark contrast to the rigid silence enveloping the group. Agent Alex Mercer, unfailingly determined on paper, seemed dwarfed by the enormity of the sterile briefing room where Paranormal Military Squad's elite convened. With dulled eyes, he scanned the projectors outlining their impending odyssey into Operation: Dulce. + +“I assume, Agent Mercer, you’re not having second thoughts?” It was Taylor Cruz’s voice, laced with an edge that demanded attention. + +Alex flickered a strained smile, still thumbing his folder's corner. ""Of course not, Agent Cruz. Just trying to soak in all the details."" The compliance in his tone was unsettling, even to himself. + +Jordan Hayes, perched on the opposite side of the table, narrowed their eyes but offered a supportive nod. ""Details are imperative. We’ll need your clear-headedness down there, Mercer."" + +A comfortable silence, the kind that threaded between veterans of shared secrets, lingered briefly before Sam Rivera, never one to submit to quiet, added, ""I’ve combed through the last transmission logs. If anyone can make sense of the anomalies, it’s going to be the two of you."" + +Taylor snorted dismissively. “Focus, people. We have protocols for a reason. Speculation is counter-productive.” The words 'counter-productive' seemed to hang in the air, a tacit reprimand directed at Alex. + +Feeling the weight of his compliance conflicting with his natural inclination to leave no stone unturned, Alex straightened in his seat. ""I agree, Agent Cruz. Protocol is paramount,"" he said, meeting Taylor's steely gaze. It was an affirmation, but beneath it lay layers of unspoken complexities that would undoubtedly unwind with time. + +Alex's submission, though seemingly complete, didn't escape Jordan, who tilted their head ever so slightly, their eyes revealing a spark of understanding. They knew well enough the struggle of aligning personal convictions with overarching missions. As everyone began to collect their binders and prepare for departure, a quiet resolve took form within Alex, galvanized by the groundwork laid by their interactions. He may have spoken in compliance, but his determination had merely taken a subtler form — one that wouldn't surrender so easily to the forthcoming shadows. + +\* + +Dr. Jordan Hayes shuffled a stack of papers, their eyes revealing a tinge of skepticism at Taylor Cruz's authoritarian performance. _Protocols_, Jordan thought, _are just the framework, the true challenges we're about to face lie well beyond the boundaries of any protocol._ They cleared their throat before speaking, tone cautious yet firm, ""Let's remember, the unknown variables exceed the known. We should remain adaptive."" + +A murmur of agreement echoed from Sam Rivera, who leaned forward, lacing their fingers together as if weaving a digital framework in the air before them, ""Exactly, adaptability could be the key to interpreting the signal distortions and system malfunctions. We shouldn't discount the… erratic."" + +Their words hung like an electric charge in the room, challenging Taylor's position with an inherent truth. Cruz’s jaw tightened almost imperceptibly, but the agent masked it with a small nod, conceding to the omnipresent threat of the unpredictable. + +Alex glanced at Jordan, who never looked back, their gaze fixed instead on a distant point, as if envisioning the immense dark corridors they were soon to navigate in Dulce. Jordan was not one to embrace fantastical theories, but the air of cautious calculation betrayed a mind bracing for confrontation with the inexplicable, an internal battle between the evidence of their research and the calculating skepticism that kept them alive in their field. + +The meeting adjourned with no further comments, the team members quietly retreading the paths to their personal preparations. Alex, trailing slightly behind, observed the others. _The cautious reserve Jordan wears like armor doesn't fool me_, he thought, _their analytical mind sees the patterns I do. And that's worth more than protocol. That's the connection we need to survive this._ + +As the agents dispersed into the labyrinth of the facility, lost in their thoughts and preparations, the base's halogen lights flickered, a brief and unnoticed harbingers of the darkness to come. + +\* + +A deserted corridor inside the facility stretched before Taylor Cruz, each footstep rhythmic and precise. Cruz, ambitious and meticulous, eyed the troops passing by with a sardonic tilt of the lips. Obedience—it was as much a tool as any weapon in the arsenal, and Cruz wielded it masterfully. To them, it was another step toward unfettered power within the dark bowels of the military complex. + +Inside a secluded equipment bay, Cruz began checking over gear with mechanical efficiency. They traced fingers over the sleek surface of an encrypted radio transmitter. ""If protocols are maintained,"" said Cruz aloud, rehearsing the speech for their subordinates, ""not only will we re-establish a line of communication with Dulce, but we shall also illuminate the darkest secrets it conceals."" + +Agent Hayes appeared in the doorway, arms crossed and a knowing glint in their eyes. ""You do understand,"" Jordan began, the words measured and probing, ""that once we're in the depths, rank gives way to survival instincts. It's not about commands—it's empowerment through trust."" + +The sentiment snagged on Cruz's armor of confidence, probing at the insecurities festering beneath. Taylor offered a brief nod, perhaps too curt, but enough to acknowledge Jordan's point without yielding ground. ""Trust,"" Cruz mused, ""or the illusion thereof, is just as potent."" + +Silence claimed the space between them, steeped in the reality of the unknown dangers lurking in the shadows of the mission. Cruz diligently returned to the equipment, the act a clear dismissal. + +Not much later, Cruz stood alone, the hollow echo of the bay a stark reminder of the isolation that power often wrought. With each checked box, their resolve steeled further, a silent vow to usher their team through the abyss—whatever it might hold—and emerge enshrined in the respect they so deeply craved." +"## Chapter 2 + +Sam Rivera sat alone in a cramped office, the hum of a dozen servers murmuring a digital lullaby in the background. Surrounded by the glow of multiple screens, their eyes danced across lines of code and intercepted comm signals from Dulce — a kaleidoscope of data that their curious and isolated mind hungered to decrypt. + +To an outsider, it might have looked like obsession, this fervent quest for answers. But to Sam, it was a dance — a give and take with the mysteries of the universe. Their fingers paused over the keyboard as they leaned back in the chair, whispering to thin air, ""What secrets are you hiding from us?"" + +The stillness of the room broke with the unexpected arrival of Alex Mercer, whose encroaching shadow loomed over Sam's workspace. The cybersecurity expert craned their neck upwards, met by the ever-so-slight furrow in Alex's brow. ""Got a minute, Rivera?"" + +""Always,"" Sam said, a smile surfacing as they swiveled to face their mentor more directly. _He has that look — like something's not sitting right with him,_ they noted inwardly. + +Alex hesitated, weighing his words carefully. ""Our tech is top-tier, but the silence from Dulce... It's not just technology that will see us through, it's intuition and... trust."" His gaze pierced through the digital haze, trying to instill something more profound than advice. + +Sam regarded Alex for a moment, the sincerity in his voice resonating with their own unspoken desire to prove their worth. ""Intuition,"" they mirrored thoughtfully. ""I guess sometimes the numbers don't have all the answers."" + +Their shared silence held a newfound understanding, a recognition that between the ones and zeros, it was their combined human insights that might prevail against the impossible. As Alex turned to leave, Sam's eyes drifted back to the screens, now seeing them not as barriers to isolate behind, but as windows into the vast and enigmatic challenge that awaited their team. + +Outside the office, the persistent buzz of activity in the facility belied the unease that gripped its inhabitants. A restlessness that nibbled on the edges of reality, as though forewarning of the threshold they were soon to cross — from the known into the realm of cosmic secrets and silent threats. + +\* + +Shadows played against the walls of the cramped underground meeting room, where Alex Mercer stood gazing at the concealed elevator that would deliver them into the bowels of Dulce base. The air was thick, every breath laced with the weight of impending confrontation, the kind one feels when stepping into a legend. Though armed with an array of advanced weaponry and gear, there was an unshakeable sense that they were delving into a conflict where the physical might be of little consequence. + +""I know what you're thinking,"" Jordan Hayes remarked, approaching Mercer. Their voice was low, a blend of confidence and hidden apprehension. ""This feels like more than a rescue or reconnaissance mission, doesn't it?"" + +Alex turned, his features a mask of uneasy resolve. ""It's like we're being pulled into someone else’s game. Not just observers or participants, but... pawns."" + +Jordan gave a short nod, their analytical mind colliding with the uncertain dynamics of this operation. ""I've felt that way since the briefing. Like there's a layer we’re not seeing. And yet, we have no choice but to play along."" Their eyes locked with Alex's, silently exchanging a vow to remain vigilant. + +""You two need to cut the philosophical chatter. We have positions to secure,"" Taylor Cruz interjected sharply, stepping into their exchange. The authority in Taylor's voice brooked no argument; it was their way of pulling everyone back to the now. + +Alex's response was measured, more assertive than moments ago. ""Acknowledged, Agent Cruz,"" he replied, his voice steadier, mirroring the transformation brewing within. He gripped his rifle with a newfound firmness. ""Let's proceed."" + +As they congregated at the elevator, a tension palpable, Sam Rivera piped in with a tone of balanced levity, ""Hope everyone’s brought their good luck charms. Something tells me we’re going to need all the help we can get."" + +Their laughter served as a brief respite from the gravity of their mission, a shared moment that reinforced their common humanity amidst the unknowable. Then, as one, they stepped into the elevator. The doors closed with a silent hiss, and they descended into the darkness together, aware that when they returned, if they returned, none of them would be the same. + +\* + +The sense of foreboding hung heavier than the darkness that the artificial lights of the elevator shaft failed to fully penetrate. The team was descending into the earth, carrying with them not only the weight of their equipment but also the silent pressure of the invisible war they were about to fight—a war that seemed to edge away from physicality and into the unnervingly psychological. + +As they descended, Dr. Jordan Hayes couldn't help but muse over the layers of data that could wait below, now almost longing for the comfort of empirical evidence. _To think that this reluctance to accept other possibilities may have been my biggest blind spot,_ Jordan contemplated, feeling the hard shell of skepticism begin to crack. + +Alex caught Jordan's reflective gaze and leaned in, his voice barely a murmur over the hum of the elevator. ""Once we're down there, keep that analytical edge sharp. You see through the mazes of the unexplained better than anyone."" + +The compliment was unexpected and weighed differently than praise from others. This was an acknowledgment from someone who stood on the front lines of the unknown with eyes wide open. ""Thank you, Alex,"" Jordan said, the words carrying a trace of newfound assertiveness. ""You can count on me."" + +The exchange was cut short by a shudder that ran through the elevator, subtle, but enough to make them instinctively hold their breaths. It wasn't the mechanical stutter of old gears but a vibration that seemed to emanate from the very walls of the shaft—a whisper of something that defied natural explanation. + +Cruz was the first to react, all business despite the shadow that crossed their expression. ""Systems check. Now,"" they barked out, masking the moment of disquiet with swift command. + +Every agent checked their gear, sending confirmation signals through their comms, creating a chorus of electronic beeps that promised readiness. But there was an unspoken question among them: was their technology, their weaponry, their protocols sufficient for what awaited them or merely a fragile comfort? + +Against the gravity of the silence that was once again closing in, Sam's voice crackled through, only half-jest. ""I'd laugh if we run into Martians playing poker down there—just to lighten the mood, you know?"" + +Despite—or perhaps because of—the oddity of the moment, this elicited a round of chuckles, an audible release of tension that ran counterpoint to the undercurrent of anxiety coursing through the team. + +As the elevator came to a halting, eerie calm at the sub-level, the group stepped off, finding themselves at the threshold of Dulce's mysterious halls. They stood in a tight pack, sharing a cautious glance before fanning out into the unknown, each one acutely aware that the truth was inevitably intertwined with danger. + +Into the depths of Dulce, the team advanced, their silence now a shared testament to the camaraderie born of facing the abyss together—and the steel resolve to uncover whatever horrors lay hidden in its shadows. + +\* + +The weight of the thick metal door closing behind them reverberated through the concrete hallway, marking the final threshold between the familiar world above and the strangeness that lay beneath. Dulce base, a name that had been whispered in the wind-blown deserts above and in the shadowed corners of conspiracy forums, now a tangible cold reality that they could touch — and that touched them back with a chill. + +Like lambs led to an altar of alien deities, so did Agents Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera proceed, their movements measured, their senses heightened. The air was still, almost respectful of the gravity of their presence. Their torch beams sliced through the darkness, uncovering steel doors with warnings that spoke of top secrets and mortal dangers. + +Taylor Cruz, stepping firmly into the role of de facto leader, set a brisk pace. ""Eyes sharp, people. Comms check, every thirty seconds,"" Taylor ordered, their voice echoing slightly before being swallowed by the surrounding silence. + +Sam, fiddling with a handheld device aimed at detecting electronic anomalies, offered a murmured ""Copy that,"" their usual buoyancy dimmed by the oppressive atmosphere. + +It was Jordan Hayes who paused at an innocuous looking panel, nondescript amongst the gauntlet of secured doorways. ""Mercer, Rivera, come see this,"" Jordan’s voice was marked with a rare hint of urgency. + +Alex joined Jordan's side, examining the panel which, at a mere glance, seemed just another part of the base's infrastructure. Yet, to the trained eye, it appeared out of place—a facade. + +Jordan explained their reasoning as Sam approached, instinctively understanding the significance of what lay beneath, ""This panel is a recent addition — covering something they didn't want found."" + +Before Alex could respond, the soft whir of an approaching drone cut through their muffled exchange. Taylor had looped back upon hearing the commotion. ""Explanations later. We can't afford to attract..."" Cruz’s voice trailed off as the small airborne device came into view, its sensors locked onto the group. + +Sam was the first to react, their tech-savvy mind already steps ahead. ""I've got this,"" they declared, fingers flying over the controls of their own gadgetry to ward off the impending threat. + +The drone lingered, its scan seeming more curious than hostile. But within moments, courtesy of Sam's interference, the little sentinel drifted away, retreating into the shadows as if accepting a silent truce. The crew exhaled, a moment of collective relief palpable in the air. + +Cruz squared their shoulders, clearly ruffled but not conceding any ground. ""Move out,"" they directed, a hint more forceful than before. ""And Rivera, keep that trick handy."" + +The team pressed onward, the quiet now filled with the soft beeps of regular comms checks, their pace undeterred by the confrontation. Yet, every agent held a renewed sense of wariness, their trust in one another deepening with the knowledge that the base—its technology, its secrets—was alive in a way they hadn't fully anticipated. + +As they converged upon a central hub, the imposing doors to the mainframe room stood ajar — an invitation or a trap, neither option comforting. Without a word, they fortified their resolve and stepped through the threshold, where the dim glow of operational LED lights and the distant hum of machinery hinted at Dulce’s still-beating heart. + +Solemnly, yet unmistakably together, they moved deeper into the heart of the enigma, ready to unmask the lifeforce of Dulce base or confront whatever existential threat lay in wait. It was in that unwavering march towards the unknown that their destinies were forever cemented to the legacy of Operation: Dulce." +"## Chapter 3 + +The thrumming of monitors cast a stark contrast to the rigid silence enveloping the group. Agent Alex Mercer, unfailingly determined on paper, seemed dwarfed by the enormity of the sterile briefing room where Paranormal Military Squad's elite convened. With dulled eyes, he scanned the projectors outlining their impending odyssey into Operation: Dulce. + +\* + +The cooling vents hummed in a monotonous drone, but it was the crackle of the comms system coming to life that cut through the lab’s tension. Dr. Jordan Hayes hovered over a table arrayed with alien technology, their fingers delicately probing the enigmatic circuitry retrieved from the crash site. Agent Alex Mercer watched, admiration blooming in silent solidarity for Jordan's deft touch and unspoken drive. + +Jordan, always composed, only allowed the faintest furrow of concentration to mar their brow. ""What we understand about physics..."" they muttered, trailing off as they realigned a translucent component. The device emitted a low pulse, causing Jordan to still. ""Could be fundamentally changed by this."" + +A calculated risk—that's what this was. And for a person of science, a gamble was worth the potential paradigm shift. + +""I’ve been thinking,"" Alex started, his eyes still fixed on the immediately tangible mystery before them. ""About what’s at stake here. Not the mission parameters, but what this means for us—humanity."" + +Jordan glanced up, meeting his eyes just long enough to convey the shared enormity of their situation; the career-defining glory and existential dread entwined. ""The quest for understanding always comes at a price. We're standing on the precipice of knowledge that could either elevate us or condemn us."" + +The charged air between them spiked as Taylor Cruz’s brusque tones sliced through their reverie. ""Hayes, Mercer, this isn't philosophy hour. Focus on the task. We need actionable intel, not daydreams."" + +With a sound of restrained acknowledgment, Jordan returned their gaze to the device, while Alex clenched his jaw, the buzz of frustration dull against the backdrop of Taylor's authoritarian certainty. It was this competitive undercurrent that kept him alert, the sense that his and Jordan's shared commitment to discovery was an unspoken rebellion against Cruz's narrowing vision of control and order. + +Then Taylor did something unexpected. They paused beside Jordan and, for a moment, observed the device with something akin to reverence. “If this tech can be understood..."" Taylor said, their voice quieter, ""It could change the game for us. For all of us.” + +The underlying dismissal earlier seemed to falter, replaced by a glimpse of reluctant respect for the gravity of what lay in their hands. Jordan looked up, and for a fleeting heartbeat, their eyes locked with Taylor's, a wordless clash of wills softening into an uneasy truce. + +It was a small transformation, barely perceptible, but one that Alex noted with an inward nod. They had all been brought here by different paths and for different reasons. Yet, beneath the veneer of duty, the enticement of the vast unknown pulled them inexorably together, coalescing their distinct desires into a shared pulse of anticipation. + +Marshaled back to the moment by the blink of lights and whir of machinery, they refocused their efforts, each movement sharpened by the knowledge that beyond understanding the unearthly artifacts, they might be piecing together the future of their species. + +\* + +Amidst the sterility of the briefing room, the liminal space between the facts laid out and the hidden truths, sat Sam Rivera, his demeanor an artful balance of focus and a casual disguise of his razor-sharp talent with technology. Across from him, Alex Mercer lingered in thought, the mental cogs turning as each file on Dulce stirred more than curiosity—it beckoned to a past both honored and burdensome. + +""You've been quiet, Sam,"" Alex noted, catching the younger man's contemplative gaze. ""Your take on these signal inconsistencies?"" + +There was a respect in Alex's tone, though a respectful distance remained—a gulf of experience and a hint of protective mentorship that stood between them. Sam nodded, recognizing the space afforded to him, and he couldn't help but feel the weight of expectation pressing upon his shoulders. It wasn't just the mission that was immense, it was the trust being placed in him. + +""The patterns are... off,"" Sam admitted, hesitant but driven. ""If I'm right, what we're looking at isn't random—it's a structured anomaly. We need to be ready for anything."" + +Alex's eyes brightened with a subtle approval that crossed the distance like a silent nod. ""Good. Keen eyes will keep us ahead—or at least not blindsided,"" he said, affirming the belief that inscribed Sam's role as more than the tech personnel—he was to be a guiding intellect in the heart of uncertainty. + +Their exchange was cut short by Taylor Cruz's abrupt arrival, his gait brimming with a robust confidence that veiled the sharp undercurrents of his striving nature. ""Time to gear up. Dulce waits for no one,"" Taylor announced, his voice carrying an iron resolve that knew the costs of hesitation—though whether the cost was calculated in human or career terms was an ambiguity he wore like a badge of honor. + +As Sam and Alex nodded in unison, the icy chasm of hierarchy and cryptic protocols seemed momentarily to bridge over with an understanding—this mission was convergence, a nexus point that would challenge each of their motives and strength. + +They filed out of the briefing room, their footsteps synchronized, a rhythm that spoke volumes of the unknown cadence they would soon march to within the base's veins. For Alex Mercer, the link with Sam Rivera, though distant, was now poised with a mutuality ready to be tested; for Taylor Cruz, the initiative pulsed like a heartbeat, anticipation thinly veiled behind a mask of duty. + +In the midst of the descent, they were each alone yet irrevocably joined, stepping closer towards the volatile embrace of Operation: Dulce." +" +## Chapter 4 + +The corridors of the Dulce military base were as silent as a tomb and twice as chilling. Alex Mercer walked with a surety that belied his bubbling undercurrents of doubt. The briefing had been definitive, sturdy pillars of facts and protocols, yet as he ventured deeper, the ominous atmosphere gnawed at him—a stark reminder of how much remained unknown. + +Jordan Hayes trailed a few steps behind, their detached exterior breaking for a moment as they caught up to Alex. ""What's on your mind?"" Jordan asked, their astuteness cutting through the unspoken tension. + +Alex glanced back at them. This place was a puzzle, a treacherous labyrinth where the walls whispered secrets, and among them, he sensed a call to question, to challenge the narrative they'd been sold. ""The silence here... It's almost as if the base is waiting for something—or someone."" + +""Just stay sharp, Mercer,"" Jordan cautioned, yet their eyes lingered on the quietude around them, conceiving the same shadow of doubt that unsettled Alex. + +Before they could delve into further discussion, the distinctive click of a safety catch echoed in the hollow space. Both agents turned to find Taylor Cruz standing resolute, primed for combat. Taylor's gaze was scrutinizing and cold, a stark contrast to the growing unease that smoldered silently amongst the rest. + +""Chatter is a liability,"" Taylor snapped, with a commanding flair that bordered on tyrannical. ""We move forward, eyes open, mouths shut."" + +Alex felt the tight grip of compliance strangle his gut, a lesson learned under the hard tutelage of rank and order. But here, in the bowels of Dulce, those instincts began to wane, the imperative to adhere now conflicting with the pressing urgency to confront the shadows they were enmeshed in. + +Then, unexpectedly, the lights flickered, a power fluctuation—or a sign? Alex's hand instinctively went to his sidearm, his mindset shifting from soldier to skeptic. The base, with its unyielding coldness, had just given them their first nudge into the realm of the speculative, an invitation to peel back the veneer of reality. + +""We should consider all possibilities,"" Alex murmured, more to himself than the others, his voice a barely audible breath against the sterile air of the complex. + +Taylor's posture stiffened at the challenge, yet their response was uncharacteristically reserved, notable in its lack of rebuke. ""Agreed. For now, keep moving. But stay vigilant."" + +A surprise—an echo of agreement from the last person Alex expected it from. And there it was, the glimpse of a wrinkle in the unyielding fabric of command, a hint that perhaps they were all starting to sense the strangeness that permeated this place. + +Progressing with determined steps, the trio moved deeper, silently acknowledging the evolution of their predicament. It was a small yet transformative concession to the unknown forces at play, an acknowledgment from each agent that, despite their disparate goals and ideals, the true nature of the Dulce base was an enigma that would forge new paths through their convictions. + +As they reached the central communications hub, the truth that awaited them lurked in the shadows, its eyes unseen but felt by all. The walls didn't just whisper now; they spoke in tones only the brave—or the foolish—would dare to listen to. + +\* + +The subterranean silence of Dulce was an oppressive entity of its own, wrapping the team in a cloak of uneasiness as they pressed on through the dimly lit corridor. Jordan Hayes found themselves contemplating the ramifications of each step taken into this suspended world, where the sterile air seemed to mock the gravity of their predicament. The closer they got to the communication hub, the more Jordan's mind wandered toward the realm of the inexplicable. + +Beside Jordan, Alex Mercer moved forward with deliberation, his gaze scanning the heavy utility doors they passed—one of which was partially ajar, beckoning them with its darkness. ""After you, Dr. Hayes,"" Alex said, gesturing toward the mysterious opening. A hint of shared understanding passed between them; knowledge was the guiding star of this mission as much as confrontation or recovery. + +Jordan peered inside, the beam from their flashlight slicing through the obscurity. The room beyond was a chaotic cascade of papers, overturned furniture, and the particular kind of disorder born from hasty evacuation—or something far more sinister. + +""It's like they vanished in the middle of something urgent,"" Alex murmured, his voice tight with a mix of concern and anticipation. He began to sift through the scattered reports, each page a potential clue to the enigmatic silence that shrouded Dulce. + +Behind them, Taylor watched with a disciplined patience, their authority the foundation upon which the operation was built. Their voice cut into the stillness, a reminder of their presence, ""Time is not our ally here."" + +Drawing back from momentary distraction, Jordan acknowledged the wisdom in Taylor's words, yet could feel the shift in their stance—from skeptical, reserved analyst, to a proactive agent within the narrative. ""You're right; these documents may hold critical insights. Let's collect what we can and analyze them properly."" + +From the darkened hollows of the room, shadows seemed to cast subtle judgment as Alex and Jordan worked together with heightened urgency. Taylor, for once, didn't intervene but instead surveyed the entrance, their mind anticipating the unknown variables that lay ahead. + +Unexpectedly, a soft hiss emanated from a neglected terminal on the desk. Jordan's head snapped up, their heart rate accelerating at the potential ramifications. Without a word, they moved to the machine, hands driven by the newfound conviction that knowledge was more than power—it was survival. + +As Jordan began to extract what data they could from the terminal, the first comprehensible communication from the depths of Dulce in far too long crackled through: an automated distress marker, looping endlessly without further context. It was a revelation, one that reverberated through the group, confirming their fears and igniting an even greater need to press on. + +Watching Jordan's dogged determination, Alex witnessed the minor transformation in his colleague unfold—a shift from doubt to action, a sliver of belief in the possibilities beyond their rational understanding. This forge of resolve amidst the alien echoes of Dulce not only bonded them closer as a team but compelled them forward with a sharpened edge of responsibility to the truth, wherever it would lead. + +As they collected their findings and regrouped, the base around them imperceptibly changed, the air charged with the vibration of secrets poised on the brink of revelation. And in that charged silence, the group moved on, each now carrying pieces of a puzzle that would soon converge into a picture of galactic significance. + +\* + +In the chill of the cramped server room, the hum of machinery was the backbone to a symphony of data streams coursing through the air. Dr. Jordan Hayes, nerves alight with the mission's mounting unknowns, patched into the last known coordinates of the unsent distress broadcast they had uncovered. They were so close to the core now – to the truth behind the blackout – it was almost tangible. + +Beside them stood Agent Alex Mercer, ever the soldier, yet with eyes that betrayed an intellect craving to understand the murk beneath the surface. ""Any progress, Dr. Hayes?"" Alex queried, his voice betraying a subtle urgency. + +""Getting there,"" Jordan replied, fingers dancing across the keyboard. ""Whoever sent this was cut off mid-transmission. It's as if Dulce itself swallowed the message whole."" + +Taylor Cruz closed in, their frame casting a long shadow over the duo, evoking an almost palpable wall between them and the forward momentum of their mission. ""Time is against us,"" Taylor intoned, more statement than threat. ""What we uncover here determines our next course of action."" + +Alex acknowledged Taylor with a brisk nod, his stance firm. Yet inwardly, the tightening grip he felt from Taylor's words couldn't throttle the swell of his own investigative instinct. His soldier's obedience had begun to war with the advocate's zeal for unveiling the dark heart of Dulce's secrets. + +And then, the unexpected occurred. The screens flashed in unison, spilling a discordant stream of symbols and images that defied immediate analysis. Jordan's breath caught – this was the response they had been fishing for, an alien communication protocol resonating just at the edge of human comprehension. + +Each member of the team felt it: a shift in the room’s very atmosphere, like a veil being drawn from their perception. Alex and Jordan stood still, absorbed in the bewilderment of contact, while Taylor, despite their authority, hesitated – a minor betrayal that unease was creeping into even their disciplined heart. + +""Thoughts, Rivera?"" Taylor rallied, seeking the counsel of Sam Rivera, whose eyes were wide with exhilaration. + +Sam stepped forward, breaking the spell of stillness. ""It's like nothing I've ever seen before, but I think I can bridge our systems to communicate,"" they declared, a wisp of optimism braiding their voice. They set about adapting their gear to transmute the foreign signals into something the team could dissect, their actions a testament to the mentorship and belief instilled in them by Mercer and the team. + +Taylor observed them, a cold calculation behind their facade, as they weighed the worth of this anomaly. It was a crossroad that potentially led to either monumental breakthrough or unprecedented catastrophe. ""Once you've established a line, document everything. We can't afford to miss any detail,"" Taylor ordered, the words sharper than intended. + +The connection was made, and with trembling anticipation, the team listened as the first garbled outputs began to emerge, their very essence promising insights that could alter the course of history. It was an enigmatic dance with the unknown, the pulse of Dulce no longer just a place, but a herald to an alien register the team had yet to decipher. + +Together, they stood at the precipice of understanding, where the faint glow of their monitors cast more than just light – it cast the shadow of burgeoning transformation. It was in this moment, in the grasp of an extraterrestrial tongue, that the team, bound by a hunger for knowledge and the raw edge of survival, found their mission reframed from a search for answers to the articulation of a question humankind had yet to fully ask. + +Silent in their commune with the inexplicable frequency, they realized they were not merely investigators; they had become liaisons on behalf of Earth, interpreters of a cosmic message that could redefine their very existence. The implications loomed large, but now, they would not face them alone – they would face them as a united front, wrought together by the very mysteries that once drove them apart." +"## Chapter 5 + +Dr. Jordan Hayes clutched the edge of the briefing room table, their fingers white-knuckled against the laminate surface, as an array of constellations rotated on the projector—charts and graphs bleeding across the stars. In the dim room, nebulas and dark matter seemed within arm's reach, tangible yet unfathomable. + +Sam Rivera leaned back against the wall, arms crossed, gaze darting between the swirling cosmos and the faces of their companions. A taut line of concentration etched their young features, a mingling of fervent curiosity with the nascent understanding of the high stakes for which they played. + +Jordan's voice broke the profound silence. ""The patterns in the signal disruptions sync with none other than zenithal star alignments. It's as if... as if these 'meet and greets' were scheduled, predestined by celestial mechanics."" + +The statement hung heavy, daring the occupants of the room to unravel its implications. Alex Mercer, his prior military resolve momentarily suspended, absorbed the hypothesis with a visible hunger. ""It's like we're adhering to an appointment we never knew we had,"" he murmured, his heart a drumbeat in his chest. + +Taylor Cruz snorted—a sound that clattered against the high concepts like a tumbledown shack in a futurist cityscape. Folding their arms, they glanced between the agents, their apprehension clad in the contempt of practicality. ""What we need are facts, not mystic conjecture."" + +Alex pivoted on his heel, facing Taylor squarely, and his voice found its edge of steel. ""This isn't mysticism, Cruz. It's a hypothesis based on observed phenomena as unpredictable as the place we're standing in."" + +Taylor's gaze never wavered, yet the slight twitch at the corner of their mouth belied their taut composure. ""If there's a semblance of truth to it, then it's critical intel. But remember, we're not astrologers—we're soldiers and scientists."" + +Jordan met Taylor’s gaze with a curt nod, accepting the caution even as the crucible of their intellect smoldered with the fervor of cosmic discovery. Their eyes flicked to Sam, whose steady presence and ready tech affirmed a burgeoning dynamic—the makings of a sentinel, standing guard over the threshold of human understanding and cosmic reality. + +With the projector casting pallid light over their features, each agent became a silhouette of purpose, shadows pillared against the backdrop of an endless universe. The story they were embroiled in would soon demand they plunge into darkness to retrieve the light of knowledge—a light that could very well redraw the shape of their world. + +They left the briefing room with a shared silence, each pondering the vast weave of celestial intent and terrestrial response, sensing that the galactic appointment to which they'd unwittingly RSVP’d was more insistent—and more threatening—than any operation they’d faced before. + +\* + +As the Paranormal Military Squad team convened in the heart of the Dulce military complex, an air of bristling expectation clung to the walls of the underground sanctum. Alex Mercer’s brow furrowed while watching his companions—Jordan Hayes, diligently setting up their makeshift lab station, and Sam Rivera meticulously checking the communication relays they had restored. Taylor Cruz observed with hawk-like focus, yet to betray the strain that their command posed on them. + +The gravity of the mission had shifted, deepened; each member of the team felt its pull, tethered to the understanding that they were now part of a larger narrative—a cosmic play with Earth as a stage and the human race unwitting actors. + +Jordan paused, a tension creeping across their shoulders as they aligned the satellite data with the alien message that had been decoded. ""The instructions in this message,"" Jordan started, the timbre of their voice betraying their usual composure. ""They're coordinates and... a warning."" + +Sam leaned in, their eyes widening behind the glow of their laptop screen. ""A warning? Like, ‘stay away from’, or ‘beware of’...?"" Their words trailed off, uncertainty a new companion in their lexicon. + +Alex exhaled slowly, his mind racing to connect the dots. ""It doesn't matter which,"" he said, decisive yet contemplative. ""What matters is we understand intent. Are we being warned out of concern, or are we stumbling upon a threat?"" + +Cruz’s iron-clad facade momentarily cracked, a fleeting glimpse of vulnerability flashing through their eyes. ""We need to know if this entails additional risk to the operation,"" they said, directing their gaze specifically at Alex. ""Mercer, I rely on you to keep the team grounded. No one goes off-course."" + +Their reminder seemed both a command and a plea—rooted in an understanding that each member of the team now faced the duality of their roles, protectors of earthly secrets and heralds of potentially devastating revelations. + +Sam's fingers stilled mid-type, their task forgotten as they absorbed the weight of the unfolding reality. ""We're the first line of defense... or detection,"" they mused half to themselves, a growing sense of agency within the larger play they were cast into. + +Jordan returned to the data, more resolute in their actions. The warning, whether cautionary or dire, was a beacon they no longer could ignore; its light casting aside shadows of doubt and igniting a collective purpose within the team. + +Alex watched Jordan and Sam, feeling a brotherhood in their shared quest. As Cruz paced, poised on the cusp of decisions that would mark their career and perhaps the fate of many, Alex knew the narrative had changed. They were no longer mere operatives; they had become guardians of a threshold, keepers of a message from a realm beyond stars and stripes. This elevation in their mission could not be shackled by regulations and established protocols—it demanded a new perspective, a new resolve. + +Tension threaded through the dialogue of beeps and static as communications with Washington buzzed in the background. The team stood, a portentous air enveloping them. It was clear that the decisions they made in the ensuing hours could redefine humanity's place in the cosmos or condemn them to ignorance and potential peril. + +Their connection to the stars solidified, the group moved to address the crystallizing warning, shifting from passive recipients to active participants. Mercer’s latter instincts gained precedence— the team’s mandate had evolved, no longer solely to observe and report but to interact and prepare. A metamorphosis had begun, and Operation: Dulce hummed with the newfound frequency of their daring, a tone set not by the earthly hierarchies but by the pulsing symphony of the universe itself. + +\* + +The desert night loomed eerily still as echoes of hidden activity reverberated deep beneath the bleak sands of New Mexico. Diverting his gaze from the array of sensors before him, Jordan Hayes allowed a rare breath, deep and anxious. Turning to Alex Mercer's focused silhouette, the nocturnal landscape illuminated softly by makeshift floodlights, Jordan felt the syncopated tempo of apprehension and exhilaration jockey for primacy within. + +""The closer we get to unlocking these messages, the more I feel like we're peeling back layers of reality itself,"" Jordan confided, eyes not leaving the monitors that presented a constellation of data points. + +""Yes,"" Alex replied, his voice steady as he considered the implications of their discovery. ""And we have to be ready for whatever we find beneath those layers. Whether it's a breakthrough or a Pandora's Box."" + +Silence settled between them, broken only by the occasional buzz of communications equipment attempting to bridge terrestrial and extraterrestrial intelligences. Tense moments drifted by, laden with the expectant weight of near breakthrough, when a soft chime signaled an incoming transmission -- a rare sound that set every agent on high alert. + +Absent was the voice of Washington or Paranormal Military Squad command. Instead, a rhythmic series of pulses and tones filled the air, deliberately patterned, unmistakably non-human. + +Sam Rivera adjusted the sensitivity of the decoding equipment, their hands shaking with anticipation as much as focus. ""I have it!"" they announced, the signal transforming under their expertise into a sequence of visual symbols on the screen before them. + +Their shared excitement was palpable, a kinetic force resonating between the team members as they crowded around the display. + +""What does it say?"" Taylor Cruz demanded, the urgency in his tone scraping against the newfound wonderment. + +Interpreting the alien syntax required not only decoding but intuition and empathy. The words that emerged upon the screen were at once coherent and enigmatic: ""*Voyage. Convergence. Peril.*"" + +The stark simplicity of the message struck them collectively, a chill breeze wafting through their resolve. + +Alex stepped forward, piecing together the cryptic communication with a growing sense of obligation. ""It’s a call to action,"" he deduced, ""or possibly a summons."" + +Jordan's gaze met Alex’s, both understanding that this was no longer an investigation or mere extraction of hidden truths. This was humanity's unwitting enlistment into a galactic dialogue that defied boundaries of nation, creed, or protocol. + +Sam's eyes were aglow, not with fear, but with the profound acceptance of inevitability that comes with groundbreaking revelation. Moreover, within Taylor's stern exterior churned the seed of reluctant admiration for the unclassified, the uncharted realms they were approaching. + +Together, they accepted the pivot in their mission, readjusting their objectives from exploration to engagement, and from isolation to a communal outreach beyond the stars. As dawn's first light threatened the horizon, it became clear that they were no longer merely operatives of a clandestine governmental faction—they were delegates on behalf of Earth, embarking on a voyage orchestrated by destinies unrelated to the mere geopolitics of their world. + +Turning to each other, their silhouettes sketched against the coming dawn, the agents recognized the transformation within and amongst them. They were bound by more than duty—they were intricately woven into the fabric of an unfolding cosmic opera, one in which they had been granted an undeniable role. And as they set course for the coordinates that beckoned them like a distant siren's call, it was with a solemn dedication to not only uncover the mysteries ahead but to navigate the convergence, and the peril, as unified emissaries of a world on the cusp of a broader understanding. + +\* + +Beneath the hum of the fluorescent lights and the vigilance of silent monitors, Alex Mercer stood with his team in the threshold of the base's command center, their faces etched with the fatigue of hours spent unraveling galactic mysteries. Jordan Hayes broke the stillness with a delicate fusion of disbelief and resolve. ""The signal..."" they began, their tone deliberate, ""it’s evolving. It’s not just sending a message—it’s responding to us."" + +Taylor Cruz leaned over the console, their eyes narrowing with intrigue and a flicker of unease, studying the alternating patterns on the screen. ""Responding? Like it’s alive?"" Taylor asked, a question that bordered on the edge of wonder and alarm. + +Sam Rivera’s gaze was locked onto their interface, a digital orchestra at their fingertips. ""It could be some form of advanced AI. Or something else entirely,"" they contributed, a note of exhilaration betraying the gravity of the situation. + +Alex paced before the terminal, absorbing the enormity of their predicament. Their mission—once rooted in the solid ground of military discipline and covert operations—had transcended into an encounter of unprecedented import. ""We need to be cautious,"" he advised, his voice a low rumble of cautious strategy. ""If this signal is intelligent, how we interact with it could dictate the outcome of this entire operation."" + +Jordan met Alex's gaze with a nod, the weight of the responsibility shared and accepted. ""We have protocols for first contact, but nothing for... this,"" Jordan admitted. The room was gripped with tension, each breath seemingly louder than the last. + +Then, with a sudden burst that filled the command center, the signal coalesced into a clear and distinct pattern which replicated and expanded, its complexity revealing the hand—or mind—of an intelligent architect. + +Taylor's instinct for command surged forth. ""Prepare to record and analyze. Whatever it is, we need to understand it—"" But their words were cut short as the signal surged, enveloping the room in a brief, blinding cascade of light. + +In that pulse of brilliance, a shared revelation coursed through the team. The signal had become a bridge, an extension of unknown consciousness reaching towards them, testing, communicating, searching. + +Alex stepped back from the light, feeling a profound change unravelling within him. The path forward would not be one of confrontation or conquest, but of connection and comprehension. + +Jordan turned to Alex and Taylor, seeing in their faces a reflection of the same metamorphosis taking place within themselves—a movement from observers to participants, from agents to ambassadors. + +With a collective breath, the team faced the kaleidoscope of lights. The alien signal, once a harbinger of enigma, was now a catalyst for transformation—a symphony of light and sound that echoed the beginnings of a new relationship between humanity and the alien unknown. + +And so, with deliberate steps, Alex Mercer led his team into the luminous fray. Science, protocol, and survival instinct harmonized within them, each member poised on the cusp of a new chapter in human history. + +They were no longer merely the instruments of Paranormal Military Squad's will—they were the vanguard of humankind’s first definitive leap into the cosmic community. + +With the last echoes of the signal resonating in the control room, they each embraced the sequencing of the transmission, the dance of extraterrestrial light that now wrote itself into their story. The chapter of Operation: Dulce drew to a close, but the narrative of their destiny had only just begun." +"## Chapter 6 + +\* + +The cool darkness of the command center at Dulce base was a stark contrast to the brewing storm outside, where the unforgiving New Mexico desert winds whispered of the hidden truths that lay buried deep beneath its surface. Dr. Jordan Hayes sat, their eyes fixed on the readout, the frenetic dance of symbols and numbers reflecting off their determined face. They were on the cusp of an epiphany, teetering between the widely accepted laws of physics and the promise of a new cosmic paradigm. + +Alex Mercer watched from across the room, noting the subtle shifts in Jordan’s posture that belied a developing readiness to embrace the unbelievable. “Find something?” Alex’s question, asked with a blend of curiosity and solidarity, bridged the gap between a command and a genuine query among equals. + +Jordan's response was slow, measured against the magnitude of their analysis. “This isn’t random static. It’s a pattern - a repeated sequence phasing in and out but distinctly artificial.” Jordan turned away from the screen, locking eyes with Alex. “This could change everything.” + +Sam Rivera leaned in, their eyes alight with the fires of revelation and a quenchless thirst for understanding. “A pattern means intention. Could it be a message?” + +A figure emerged from the doorway, casting a long shadow into the room - Taylor Cruz. “Intentions can be friendly, or hostile. We shouldn’t forget that,” said Taylor, bringing a dose of their usual pragmatism into the heart of discovery. + +Alex acknowledged Taylor’s caution with a nod, understanding the need to keep their feet grounded even as their spirits soared toward the unknown. “Then let’s be the first to find out which it is."" + +The team gathered around the monitors, the soft tapping of Jordan's keystrokes now punctuated by the occasional crackle of Sam's radio equipment. The sound was almost ritualistic, a prelude to humanity’s potential first, knowing foray into a larger universe. + +Jordan’s fingers paused, suspended in mid-air. The signal had evolved, becoming a beacon that somehow felt less alien and more familiar. It was as if the complexities of their message were unfolding into something more accessible, more terrestrial. + +A hushed excitement swept through the room. The transformation suggested an awareness on the part of the unknown senders; a finesse that spoke volumes about their capabilities and perhaps their intentions. + +With the growing realization that they were engaging with an intelligence far exceeding their previous understanding, the team prepared to reach back across the cosmic divide. Prepared or not, they were no longer bystanders in this galactic narrative. They were active correspondents in an exchange that transcended galaxies and welcomed them into an expansive, possibly fraught, interstellar conversation. + +\* + +Inside the cavernous central hub of Dulce military base, Dr. Jordan Hayes stood in near-darkness, surrounded by a nest of cables and monitors that buzzed with silent, cryptic life. Jordan's eyes narrowed to focus on the sequences that danced across the screen—patterns that could unravel the cosmic enigma surrounding them. + +Alex Mercer approached with his characteristic stride, a signal of reliability in the chaos. ""Status report, Dr. Hayes?"" he inquired, his voice low, almost blending into the soundscape of beeping consoles and swirling fans. + +""We're on the brink of unravelling the signal's origin,"" Jordan replied, the weight of implications heavy in their tone. ""There's intelligence behind it, a thought process alien to our own."" + +As if summoned by their analysis, Taylor Cruz approached with authority radiating from every pore. ""Understand this, we need to know if it's friend or foe. Don't get wrapped up in the existential—our lives may depend on the answers you provide."" + +Sam Rivera, their hands adroitly adjusting a device to fine-tune the signal, chimed in with optimism undercut by anxious anticipation. ""We're deciphering the comm encryption. Soon, we'll have a channel open—not just listening in, but speaking back."" + +Alex nodded his understanding, his strategic mind processing the tactical implications while grappling with the more profound humanistic impact. ""When we do, we'll tread carefully, communicate with purpose,"" he reassured the team. + +The operation had evolved rapidly, from a stealthy incursion into a clandestine labyrinth to an exchange with an extraterrestrial intellect. Their earlier trepidation transformed into determined focus, as they prepared to extend humanity’s hand into the vast unknown. + +An alert on one of the monitor stations snapped the team into alarm. The signal had not simply been waiting—it had been calculating. Now, it reached its crescendo, demanding their attention with a provocative urgency. + +Jordan's fingers raced over the keyboard, their eyes simultaneously interpreting data and sharing directives. ""It’s a linguistic lock, a test of comprehension. We crack this, we establish dialogue."" + +Taylor's presence was a beacon of steely resolve. ""Then let’s solve it. This is what we trained for—the unknown."" + +Alex and Sam exchanged a look that telegraphed their shared determination—this was not only the mission they had trained for; it was the mission they had been destined for. + +Together, the Paranormal Military Squad team leaned into the challenge, their minds honing in on the complex patterns with a singular goal: to unlock the conversation with an intelligence that had already begun to shift the foundations of what they knew, or thought they knew, about the universe. + +In a symphony of clicks and murmurs, they worked, knowing they were about to make a giant leap not just for themselves or Paranormal Military Squad, but for all of humanity. As the final pieces fell into place, Dulce's militaristic silence was shattered by the sound of intergalactic contact—by the sound of history being made." +"## Chapter 7 + +In the enclosed space of Dulce’s command center, the air was thick with anticipation, each team member poised to tread the razor's edge between scientific breakthrough and galactic peril. Dr. Jordan Hayes focused intently on the screen, their fingers tapping a staccato rhythm against the keyboard as lines of alien code cascaded down the monitor. + +Alex Mercer's steely gaze surveyed the room, stopping on each member of his team. ""Thoughts?"" he asked, echoing the unspoken tension. His question, while directed at the group, lingered on Jordan—acknowledging their expertise and inviting collaboration rather than dictating orders. + +Jordan’s brow furrowed, an indicator of the mental gymnastics being performed. ""It's unprecedented,"" they finally said, their voice a testament to the gravity of the moment. ""Behavioral algorithms... if we're right, this code could reveal extraterrestrial thought patterns."" + +Before anyone could react, Taylor Cruz interjected with the assertiveness of someone accustomed to commandeering the discourse. ""Then let’s ensure we’re deciphering it correctly,"" Taylor stated, their tone suggesting they were still battling to maintain control over an increasingly alien situation. + +Sam Rivera hovered near the mainframe, youthful energy barely contained under the surface. ""What if it’s more than just a message? What if they’re trying to extend consciousness across the stars?"" + +The room fell into a contemplative silence, broken only by the hum of electronic equipment and the distant thud of secured doors locking in rhythm. The weight of responsibility rested on each agent's shoulders—a heaviness palpable in the air they shared. + +Alex stepped forward, reaching a subtle decision, one dictated by foresight and the humanity nestled at the core of their mission. ""We approach with the aim to understand, not to confront,"" he said, softening his military bearing into a more diplomatic stance. + +Jordan nodded, appreciating the leadership that Alex displayed in the face of the unknown, and turned back to the cryptic data. Here, before them all, was a tangible piece of evidence—proof of an extraterrestrial sentience that had outreached the bounds of their expectations. + +Taylor took a breath, simultaneously exuding a sense of preparedness and venturing into the unknown alongside their peers. ""Then let’s do what Paranormal Military Squad does best—investigate and adapt,"" Taylor added, finding comfort in the familiar even as they stood on the cusp of an unprecedented alchemy of science and mystery. + +The team leaned into their respective roles, driven by the urgency of the assignment and the pull of an insatiable curiosity. Sam offered a grin that belied the tension, a youthfulness that reminded them all of the profound excitement nested within the terror of the unknown. + +Quietly but resolutely, they turned back to their instruments, each of them a sentinel on the threshold of a new reality. The once implicit lines of command were now woven into a shared tapestry of hierarchy and camaraderie. As they danced with the unknown, they were beacons of sentient endeavor, casting the light of human consciousness into the vast darkness that called to them. + +\* + +\* + +Dulce Base's cavernous darkness was pierced by the sharp luminescence of monitors, casting an electric glow onto the faces of those who dared to unearth its secrets. Dr. Jordan Hayes stood motionless, eyes glazed in concentration, their mind a nexus where terrestrial science battled with celestial unknowns. + +Alex Mercer watched from a slight distance, the weight of command tangible upon his shoulders, though lightened by the shared burden now held amongst them. ""We could be on the frontier of a new kind of diplomacy,"" he mused aloud, giving voice to the moment's gravity. + +At those words, Jordan's trance broke. ""If that's the case, then these communications,"" Jordan motioned to the stream of data, ""are our olive branch across the cosmos."" + +Taylor Cruz, who paced with restless energy, halted and faced the team—his stoicism marred by the erratic dance of lights reflected in his eyes. ""An olive branch, or an invitation to a battlefield?"" he posed, ever the strategist, his words laced with a hint of cynicism. + +Sam Rivera, nestled amongst an array of equipment, licked their lips—a mixture of nerves and anticipation palpable. ""We're mapping out something incredible here. Whether it's peace or war, we're the cartographers."" + +Silence enveloped them like the expanse of space itself, each member contemplating the chasms they might bridge—or the abysses into which they might unwittingly descend. + +Alex's demeanor assumed a quiet resolve—the profound knowledge that this mission was as much about navigating uncharted philosophical territories as it was about ensuring survival. ""Whichever it proves to be, we'll face it. Prepared, unified."" + +A nod passed between Jordan and Alex, a silent exchange of mutual respect and shared mission. Sam, buoyed by the weighty encounters of the mind and machinery, entered keystrokes with a fervor that seemed to bring them ever closer to the alien mind. + +They stood there, the Paranormal Military Squad team, not just as guardians of homeworld secrets or as soldiers of clandestine wars, but as humankind's chosen few at the fulcrum of history—a history that was now unfolding to the rhythm of otherworldly codes. + +Each revelation, each parsed symbol, inched them toward the line between the earthly and otherworldly. And as they stood on this precipice of cosmic negotiations, it was clear the ensuing dialogue would not just shape the future of Paranormal Military Squad—it could very well redefine the parameters of human existence. + +\* + +The hum of advanced computational systems tingling with cryptic transmissions framed the ambiance of Dulce's mainframe chamber. Jordan Hayes, fingers hovering over a console dense with blinking lights, furrowed their brow as sequences of alien data streamed across the screen. + +Alex materialized behind them, his presence a stable beacon amidst the technological whirlwind. ""Look for patterns, anomalies. Anything that might resemble a handshake protocol in their communications,"" he directed, his voice a low thrum, reverberating with cautious optimism. + +Jordan cast a glance over their shoulder, acknowledging Alex's contribution with the shared understanding of colleagues who had transcended mere professional acquaintance. ""I’m isolating sequences that seem to recur with more intention than static. If these are their ‘handshakes,’ then we might just be making first contact,"" they remarked, their focus returning to the screen with renewed vigor. + +From the other end of the room, where shadows married the artificial light, Sam's voice crackled through the static of nearby speakers, ""Don't forget the anomalies we detected earlier. Each one could be a word, a sentence, or even a concept untranslatable to our current understandings."" + +Resolute, Taylor Cruz stood at Jordan's other side, a stoic figure wrestling with the implications of their mission. ""Keep pursuing this line,"" Taylor instructed, an undercurrent of intensity carried forth in their otherwise composed demeanor. ""And remember, this isn't just about making contact; it's about securing knowledge for humanity."" + +Alex offered a nod that spoke volumes, conveying his understanding of the stakes at play. Here, in this chamber of possibility, the team's actions would determine if humanity stood at the brink of a new age of understanding or the onset of an unprecedented threat. + +Every second thrummed with significance as Jordan and Sam worked in tandem, each keystroke a foray into the unknown. Taylor observed with a commander's scrutiny, the gravity of their role sustaining them against the waves of ambiguity breaking against their resolve. + +Pivotal moments come rarely in the course of human events but here, amidst the electronic symphony of a stalwart command center, lay the incepting notes of a cosmic overture. The harmony between human and alien, between Paranormal Military Squad and the vast reaches of space, began its first tentative measures, with each member of the team a vital instrument in a celestial ensemble yet to be fully heard. + +\* + +The crisp air within the mainframe room of Dulce base seemed to hum with unspoken possibilities. Jordan Hayes was the centerpiece of focus, their hands dancing methodically over the console as streams of otherworldly code cascaded down monitors, each flicker a potential key to the cosmic doors they were inching open. + +Alex Mercer watched, posture relaxed but eyes sharp. ""Remember, this could be our first introduction, maybe even our first impression,"" he said, mindful of the gravity carried by each action they made henceforth. + +A hint of a smile touched Jordan's face, a small acknowledgment of the monumental task at hand. ""Understood. I'm balancing the signal's syntax with our algorithms. If we're interpreting this correctly, it could be... well, an invitation."" + +Into the electric tension of the chamber walked Taylor Cruz, their silhouette a sharp contrast against the cool lighting, radiating a presence that spoke of command and chilly tenacity. ""An invitation, or a challenge?” Taylor questioned, the weight of their suspicion casting a different tint on the cascading data. + +Sam Rivera, in a corner arrayed with sophisticated equipment, piped up, their voice a buoyant note amidst the tentative atmosphere. ""Either way, it's a connection. One that we're uniquely positioned to navigate,"" they remarked with an air of optimism threading through the uncertainty. + +Alex channeled the strengths of his team into the core of their approach, his leadership adapting to the contours of an unprecedented scenario. ""Cautious and curious,"" he reflected aloud, shaping a strategy that balanced their thirst for comprehension with the prudence required in addressing the unknown. + +Jordan, hands momentarily at rest, looked up. The signal was more than a sequence of bits and commands—it was a riddle wrapped in the depths of space-time, and they were on the cusp of parsing its meaning. + +Taylor, hardly a step away, nodded in silent agreement. The implications of their findings might very well direct the course of human destiny from this point onward. + +Finding a tempo among themselves, the Dulce team was a confluence of ambition and acumen, each member intuitive to the beats of discovery. The chamber around them held untold stories, secrets coaxed from the stars, that now, led by Paranormal Military Squad's finest, began to unravel. + +The future in those moments was unwritten, a narrative scribed not in the dust of desert confines, but in the potential for interstellar diplomacy and understanding. As they prepared to script humanity's next chapter, the room seemed to pulse with the heartbeat of a story far greater than the sum of its parts." +"## Chapter 8 + +The grit of an earthbound dust storm contrasted sharply with the pristine sterility of the underground command center. Alex Mercer, eyes set with fervent determination, stood over Jordan Hayes, whose fingers danced across the keyboard with rapid purpose. Monitoring the progression of alien code unraveling before them, Mercer spoke with a tempered urgency, ""Keep it steady, Jordan. We might be initiating the first true interspecies communication bridge here. It's all about finesse now."" + +Taylor Cruz, the embodiment of military precision, surveyed the room with a calculated gaze from their vigil beside an array of glimmering screens. ""Remember, these could be delicate negotiations -- or coded threats. Stay sharp,"" Cruz added, their voice cool as polished steel. + +Jordan, with a silent nod, recognized the gravity of both stances. Gravitating between scientific acuity and diplomatic caution, they replied, ""The sequence is aligning—syncing with our comms. It's looking more and more like direct engagement."" + +Amid the banks of electronic machinery, the thrumming pulse of an impending interspecies signal exchange, Sam Rivera interjected with a youthful zeal that cut through the weighty atmosphere, ""It's not just an exchange. It's a... symphony. It's as if they're teaching us their language through modulation."" + +A moment of profound silence swept over the team. The isolation of their location, deep within the top-secret labyrinth of Dulce, became suffused with an almost palpable sense of historical significance. + +""Then our response needs to be equally symphonic,"" Alex uttered, contemplating the awe-inspiring transmutation of their task from a simple recovery mission to a full-blown cosmic concerto. + +With a renewed sense of wonder tempered by caution, the Paranormal Military Squad team found themselves harmonizing a delicate balance between envoys and interpreters. The long shadow cast by their duty was now illuminated by the brilliant glow of otherworldly dialogue. + +In this carefully orchestrated march towards the unknown, each individual's expertise became critical notes in a larger melody. The narrative of human achievement, so often defined by solitary pursuits, now emerged as a collaborative opus, each member of the team a maestro in their right. + +The protocols of encounters, the mathematics of languages, and the poetics of connection all fused into a singular moment of convergence. The echo of their efforts reverberated back to them, not through the cavernous base's concrete walls, but from light-years away, in the form of a reply, intangible yet infinitely profound. + +\* + +Amidst the hum of the supercomputers and the faint static from the scrambled transmissions, Alex Mercer cast a thoughtful glance across the dimly lit room toward where Dr. Jordan Hayes was methodically adjusting the archaic dials of the decryption machine. ""Any progress?"" he asked, his tone conveying both impatience and the deep-seated respect born from countless shared challenges. + +Jordan did not look up, their gaze remained locked on the flickering lights that represented a dialogue suspended between worlds. Their fingers ceased their dance, hovering meditatively over the controls. ""We might be on the cusp of a breakthrough,"" Jordan suggested. ""The signal... it's evolved. It's reflexive now, responsive in a way that suggests sentience."" + +Taylor Cruz's familiar sharp strides approached the two, breaking the rhythm of soft beeps. ""Responsive is good, if it means understanding,"" Taylor said, head tilted as they peered at the encryption data scrolling by. ""But remember, comprehension can bring revelation or conflict."" + +Sam Rivera’s youthful voice permeated the tension, brimming with an excitement edged by the enormity of what they faced. ""If it's truly sentient, we're not just cracking a code; we're learning how to converse with an entirely new form of consciousness,"" they chimed in, the weight of history not lost on the zealous astrotechnician. + +Alex nodded, his thoughts alighting on potential strategies for navigating the conversation they were cultivating with the unfathomable. ""We need to keep that conversation going, echo its patterns, and speak its language,"" he resolved, knowing the delicate nature of their work merited every ounce of their collective acumen. + +The chamber now was a crucible, forging within it the future narrative of human contact with the unknown. Every signal pulse they sent out was an invitation for understanding, and every echo back a step closer to bridging the cosmic divide. And so, together, they stood - agents in Paranormal Military Squad's clandestine ranks, united by purpose, sculpting humanity’s first sonnets into the void. + +\* + +#### Knowledge graph updates + +- (Jordan Hayes, Interprets, Communications as cosmic diplomacy, Moderate) + +- (Taylor Cruz, Questions, Potential aggressiveness of alien intent, Minor) + +- (Sam Rivera, Expresses, Optimism about forming a connection, Minor) + +- (Alex Mercer, Adopts, Balanced strategy for contact, Moderate) + +- (Paranormal Military Squad team, Navigates, Beats of cosmic discovery, Moderate) + +- (Paranormal Military Squad team, Prepares, To script humanity's interstellar narrative, Major)" +"## Chapter 9 + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +Dr. Jordan Hayes, whose hands had been steadfastly working the decryption algorithms, paused and looked up at Alex. ""We're through the next layer of encryption,"" Jordan announced, a mixture of pride and gravitas in their tone. ""It's communicating. It's... aware."" + +A shadow momentarily clouded Alex's determined features—awareness implied so much more than mere intelligence. ""Aware and reactive or aware and proactive?"" he queried, his experience anticipating the pivotal importance of intention. + +""Unknown at this stage,"" Taylor Cruz interjected, looking up from a datasheet. ""But I urge caution. We tread the line between breakthrough and disaster with each keystroke."" + +Sam Rivera, ever the source of technological acumen, added their voice to the conversation. ""The signal's adapting every time we interact with it. Like a conversation where both parties are learning each other's language in real time."" + +Alex leaned in, rested a hand on Jordan's shoulder—a sign of companionship and an affirmation of trust. ""Keep the communication channels open. But let no message, no pulse go unchecked. This could be our Rosetta Stone or our Tower of Babel."" + +Silence fell over them, a momentary lull as each member of the team contemplated the historic weight of their task. Yet, it was impregnated with a tangible sense of excitement—a collective energy that thrummed through the air just as palpably as the electric current through the banks of machines surrounding them. + +They continued their work, squaring shoulders against the magnitude of their undertaking. The agents were standing not just at the precipice of a new chapter for Paranormal Military Squad but for all of humanity. For now, they communicated with powerful unknowns, but with each exchange, they were etching the first words of a dialogue that might forever alter humanity's place in the cosmos. + +\* + +\* + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +Dr. Jordan Hayes, whose hands had been steadfastly working the decryption algorithms, paused and looked up at Alex. ""We're through the next layer of encryption,"" Jordan announced, a mixture of pride and gravitas in their tone. ""It's communicating. It's... aware."" + +A shadow momentarily clouded Alex's determined features—awareness implied so much more than mere intelligence. ""Aware and reactive or aware and proactive?"" he queried, his experience anticipating the pivotal importance of intention. + +""Unknown at this stage,"" Taylor Cruz interjected, looking up from a datasheet. ""But I urge caution. We tread the line between breakthrough and disaster with each keystroke."" + +Sam Rivera, ever the source of technological acumen, added their voice to the conversation. ""The signal's adapting every time we interact with it. Like a conversation where both parties are learning each other's language in real time."" + +Alex leaned in, rested a hand on Jordan's shoulder—a sign of companionship and an affirmation of trust. ""Keep the communication channels open. But let no message, no pulse go unchecked. This could be our Rosetta Stone or our Tower of Babel."" + +Silence fell over them, a momentary lull as each member of the team contemplated the historic weight of their task. Yet, it was impregnated with a tangible sense of excitement—a collective energy that thrummed through the air just as palpably as the electric current through the banks of machines surrounding them. + +They continued their work, squaring shoulders against the magnitude of their undertaking. The agents were standing not just at the precipice of a new chapter for Paranormal Military Squad but for all of humanity. For now, they communicated with powerful unknowns, but with each exchange, they were etching the first words of a dialogue that might forever alter humanity's place in the cosmos. + +\* + +Alex Mercer's eyes were fixed on the monitors, the reflected light casting an ethereal glow across his stoic face. The room buzzed with tension, a cacophony of low hums and electronic beeps that underscored the historic nature of their actions. He moved to where Dr. Jordan Hayes was immersed in their work, scrutinizing the alien code streaming rapidly down the terminal. + +""Find anything that might look like an entry point or a... digital handshake?"" Alex asked, his voice steady, betraying none of the tension gripping his chest. + +Jordan looked up briefly, their expression weary yet intense, ""Potentially. It's as if the code is anticipating our input, modifying itself in real-time. I've never seen anything like it."" + +From across the room, Taylor Cruz's sharp voice cut through the hum. ""Then it's learning or, possibly worse, baiting us. Proceed with extreme caution,"" they commanded, their firm stance reinforcing the gravity of the situation. + +Sam Rivera, surrounded by a cascade of screens and interfaces, added, ""It's almost organic in its complexity. Any minute now, and I might have a way in."" + +A slight nod was Alex's immediate response, his mind racing through the potential scenarios. ""Everyone, stay alert. This could be the beginning of something profound."" His seasoned eyes never left the unfolding drama on the monitors. + +The room fell silent, the air heavy with unspoken questions. Were they mere moments away from unlocking an otherworldly dialogue? Or was it a Pandora's box that, once opened, could not be closed? + +Alex moved closer to the main console, his fingers hovering over the command keys. With the precision of a maestro orchestrating a symphony, he communicated silently with Jordan – respectful of their expertise, aware that the next move could alter the course of human history. + +Jordan met his gaze, nodding sharply, and refocused on the task. The signal seemed to pulse with sentient curiosity, drawing them further into its intricate web. + +A sudden flurry of alerts and the intensifying glow of monitors heralded that they had bridged a technological chasm. The alien intelligence on the other end was no longer a distant enigma – it was an active participant, responding to their digital overtures with an unknown agenda. + +The team's meticulous efforts had led them to a momentous threshold. Beyond lay unprecedented contact – a nexus of curiosity and potential peril. Within the confines of the base, against the backdrop of a silent desert night, the Paranormal Military Squad operatives became mediators of Earth's bid for cosmic relevance, their every action now a gesture in the grand dance of intergalactic relations." +"## Chapter 10 + +The corridors of the Dulce military base, now silent, echoed with a history of whispered conspiracies and furtive movements. But in the command center, a delicate tapestry of light and sound was being woven as the echoes of cosmic dialogue resonated through the high-tech enclave. Dr. Jordan Hayes, now leading the efforts, called out from their workstation, ""I’ve isolated the signal's harmonics. It's more than a call; it's a song, an interstellar siren’s call."" + +Alex Mercer, steady and resilient in the face of the incomprehensible, acknowledged with a quiet nod, ""A song that we need to learn—quickly."" His eyes, heavy with responsibility, scanned the room, watching his team work tirelessly at the intersection of science and speculation. + +Sam Rivera, dulled by fatigue yet driven by unshakeable resolve, manipulated a complex array of audio interfaces. ""There's a pattern, a repeating motif. It's structured, intentional,"" they muttered, their revelation a bridge between the known and the unimaginable. + +Taylor Cruz, a figure of central authority, paced the length of the room, their usual unflappable demeanor betraying a rare flicker of apprehension. ""We should be wary of the sirens’ call,"" Taylor interjected, invoking myths of old as a cautionary metaphor. ""We don't want to crash upon unseen shores."" + +Undeterred, Jordan cast a determined glance at the team. ""We navigate by starlight now, not by the limited light of our previous understanding."" Their voice was a beacon, charting a course through unchartered realities. + +Every individual was acutely aware that each moment in that room was a conduit to an epochal shift for civilization. The mysterious signals, once distant and alien, had coalesced into complex and harmonious oscillations—beacons of an extraterrestrial intellect inviting Earth to join in a cosmic consortium. + +Silently, Alex approached the mainframe, his trained fingers aligning with the console’s mechanisms. The room watched in collective breathlessness as he set the frequency in motion, an introductory phrase to an otherworldly melody—a symphony that could bind worlds or spell devastation for all they knew. + +In the control room of Dulce, amongst whispered legends and the quiet hum of machines, humanity's ambassadors now stood, stretching their hands into the void, reaching for the hand that would either pull them into the light of new stars or into the maw of darkness between them. + +\* + +Underground, the Dulce facility's command center was awash with frenetic energy, a stark juxtaposition against the silent, decrepit corridors that enveloped them. The air hummed with anticipation as Dr. Jordan Hayes and Alex Mercer hunched over a console. The sterile light from the monitors cast an otherworldly glow upon their faces, now reflecting a mosaic of alien characters rapidly translating across the screen. + +""The patterns are evolving,"" Jordan murmured, concentration etched into their every feature. ""It’s as if our attempts to decrypt have accelerated its learning. It’s adapting to us."" + +Alex, who stood steadfast behind Jordan, felt a tinge of uncharted fear quickly quelled by the fire of discovery raging within him. ""Keep it up,"" he urged. ""But whatever this is becoming, we need to ensure it remains within our control."" + +Taylor Cruz interjected, their voice slicing through the buzz of activity. ""Control may be an illusion when facing an intelligence that literally writes its own rules,"" they stated stoically, casting a watchful eye over the flurry of data. + +""It's like it's learning to communicate,"" offered Sam Rivera from a nearby interface, their youthful energy boding a mix of awe and anxiety. ""This gives ‘talking to strangers’ a whole new meaning."" + +Alex surveyed his team—each face a study in concentration, determination, and not a small measure of trepidation. ""This might well be our first contact,"" he acknowledged, ""And we need to be ready for whatever answers back."" + +Together, they stood on the edge of the unknown, forging humanity’s response to a message from the heavens. The ensuing silence was palpable—a collective introspection about their role in this grand cosmic play, one that could rewrite human history. + +The encrypted dialogue continued to unfold, its intricate patterns showing an almost uncanny anticipation of their investigative strategies. The air turned heavy with the scent of electricity and ambition as they closed in on a pivotal response. + +As the signal’s intelligence—whether artificial or biological—grew more profound, so too did the realization that their mission had morphed from passive observation to active engagement. There was no turning back now. Each agent embraced their part in the delicate dance of an interstellar exchange that could change everything they thought they knew about life, intelligence, and the dark void beyond Earth's atmosphere. + +\* + +The underground halls of Dulce Base, usually buzzing with covert operations, now thrummed with a different kind of energy, an electric mix of fear and fascination. At the heart of the base, in a room shielded from the world’s eyes, Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera huddled around a bank of monitors. Each screen flickered erratically with the alien script that had become the center of their lives—and perhaps the pivot on which humanity’s future would turn. + +Jordan's eyes never wavered from the displays, their expression was one of rapt concentration, interspersed with flashes of revelation. ""We're conversing with the stars,"" they whispered, almost to themselves. The words hung in the air, a testament to the awe-inspiring strangeness of the situation. + +""The language is morphing; changing its structure with every exchange we have,"" Sam chimed in, enthusiasm tinged with the solemnity of the occasion. ""It's like witnessing the birth of a new form of dialogue—one that spans galaxies."" + +Taylor, despite the situation's precariousness, maintained an appearance of ironclad composure. ""Keep the communication stream secured and monitored. We don't know what we're dealing with yet,"" they reminded the team, a bastion of protocol amidst uncertainty. + +Alex watched his team expand the parameters of human achievement; their work here would possibly define an era. ""This is untrodden territory,"" he acknowledged, ""and in every word we script, in every response we decode, we're drawing a map that others will follow."" + +Jordan turned to Alex, a nod acknowledging the shared responsibility of this moment. They had embarked on a new voyage, an odyssey not of the body, but of the intellect and spirit. No longer explorers of the Earthly realm, they had been promoted by circumstance to ambassadors of humanity in a silent and boundless ocean. + +A sudden pulse of energy from the monitors signaled a breakthrough; the language had not only adapted but it seemed to resonate, to harmonize with their attempts at making contact. The alien script now sprawled across the screens didn't just ask to be understood—it invited interpretation, collaboration, maybe even companionship across the cold distances of space. + +As they stood before the precipice of first contact, Paranormal Military Squad's finest became the architects of a symphony meant to echo through the cosmos. But more than architects, they were the first to play the notes of this cosmic composition, daring to believe that on the other end, someone—or something—might be listening, ready to join the chorus. + +\* + +The underground command center of Dulce Base, once pulsing with clandestine operations, now resonated with the charge of an impending cosmic threshold. Encircled by banks of whirring machinery, each monitor flickered erratically with alien script that had occupied center stage in the lives of Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera. + +Jordan's gaze didn’t flit for even a moment from the screens, where indiscernible alien messages ebbed and flowed like the tide. The ciphers and symbols cascaded down as they tweaked the algorithmic sliders. ""This sequence here,"" Jordan began, voice both hushed and heavy, ""it’s not just transmitting; it resonates—it's designed to be felt."" + +The room took a collective breath, the remarkable implication hanging in the air like a careful revelation. Sam Rivera was the first to respond, their voice alive with ingenuity: ""It's a form of communication stretching well beyond words. We need to respond in kind—the whole array of human expression might be at play here."" + +Taylor's eyes remained fixed on the figures playing across the data sheets. ""If that's the case,"" Taylor intoned pragmatically, ""we must tread carefully. This is no longer just about being heard—it's about being understood."" + +Alex watched his team, each a fulcrum of insight and expertise, and felt the solemnity of the role they were about to assume. ""Then we'll ensure our message is clear and full. Our humanity is our strength in this dialogue,"" he declared, the depths of his experience fueling a commanding reassurance. + +The anticipation was palpable as the agents contemplated the vastness of their endeavor. They were not merely probing at the secrets of the planar cosmos—they were negotiating across the starry expanse, extending to distant intelligences the full spectrum of human curiosity and compassion. + +A symphony of beeping consoles orchestrated their next steps as they prepared to articulate their interplanetary overture. The rhythmic tapping of Jordan's keystrokes set the tempo for an undertaking that traversed beyond algorithms and encryption. + +The base withstood time and whispered secrets of its own, but none so grand as this moment of creation—an invitation to the universe that promised to echo through both the echoes of space and the annals of human history." +"## Chapter 11 + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +\* + +The thrum of the colossal machinery vibrated through the subterranean facility as Alex Mercer stood amidst the whispers of technology, each carrying voices from worlds apart. He watched as Sam Rivera adjusted a complex array of cosmic translators, their expression a mixture of anticipation and awe. + +""Are we ready, Mercer?"" Taylor Cruz asked, the soft glow of the command center consoles reflecting upon their stern face. + +Alex turned towards Taylor, his eyes holding a depth that betrayed the enormity of the threshold they were about to cross. ""This is it,"" he said. ""Initiate the protocol. It's time we answer the cosmos."" + +Jordan Hayes, stationed at the mainframe, typed rhythmically, a blue hue painting their focused features. The eerie silence that had settled over the team was interrupted by a visceral sound—humankind's response to the alien dialogue, now streaming into the abyss. + +The control room, once a fortress of solitude, erupted into an oasis of life. Lights flickered in tandem, echoing the symphony of interstellar communication. They stood together at the edge of discovery, facing the symmetry and discord of a universe unknown. + +""If we're right, we've just become Earth's first emissaries to a celestial congress we're only beginning to comprehend,"" Jordan's voice was somber, resonating with a mix of trepidation and honor. + +The room filled with the resonance of human and alien minds converging, creating a new narrative within the fathomless expanse of existence. Paranormal Military Squad, once protectors of Earth's clandestine secrets, had now become the tether linking humanity to the cosmic fold. + +\* + +The underground command center of Dulce Base, once pulsing with covert operations, now resonated with the charge of an impending cosmic threshold. Encircled by banks of whirring machinery, each monitor flickered erratically with alien script that had occupied center stage in the lives of Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera. + +Jordan's gaze didn’t flit for even a moment from the screens, where indiscernible alien messages ebbed and flowed like the tide. The ciphers and symbols cascaded down as they tweaked the algorithmic sliders. ""This sequence here,"" Jordan began, voice both hushed and heavy, ""it’s not just transmitting; it resonates—it's designed to be felt."" + +The room took a collective breath, the remarkable implication hanging in the air like a careful revelation. Sam Rivera was the first to respond, their voice alive with ingenuity: ""It's a form of communication stretching well beyond words. We need to respond in kind—the whole array of human expression might be at play here."" + +Taylor's eyes remained fixed on the figures playing across the data sheets. ""If that's the case,"" Taylor intoned pragmatically, ""we must tread carefully. This is no longer just about being heard—it's about being understood."" + +Alex watched his team, each a fulcrum of insight and expertise, and felt the solemnity of the role they were about to assume. ""Then we'll ensure our message is clear and full. Our humanity is our strength in this dialogue,"" he declared, the depths of his experience fueling a commanding reassurance. + +The anticipation was palpable as the agents contemplated the vastness of their endeavor. They were not merely probing at the secrets of the planar cosmos—they were negotiating across the starry expanse, extending to distant intelligences the full spectrum of human curiosity and compassion. + +A symphony of beeping consoles orchestrated their next steps as they prepared to articulate their interplanetary overture. The rhythmic tapping of Jordan's keystrokes set the tempo for an undertaking that traversed beyond algorithms and encryption. + +The base withstood time and whispered secrets of its own, but none so grand as this moment of creation—an invitation to the universe that promised to echo through both the echoes of space and the annals of human history." +"## Chapter 12 + +The underground facility of Dulce Base, once shrouded in silence and operational secrecy, now hummed with an energy that cradled the promise of cosmic revelation. Alex Mercer stood pensively by the central terminal, flanked by Dr. Jordan Hayes, Taylor Cruz, and Sam Rivera, each poised at the edge of a history-defining moment. + +Jordan's fingers ghosted across the console, tracing patterns of otherworldly origin. ""The signal’s architecture is becoming more complex, resembling aspects of human cognition—recognition, learning, even... empathy?"" they postulated with furrowed concern. + +Alex turned his gaze upon Jordan, his voice quiet but resolute, ""Empathy could bridge galaxies. Let's harness this connection and proceed with cautious optimism."" + +Taylor, ever the sober sentinel, projected a more pragmatic standpoint. ""Empathy or not, we are duty-bound to assess the risk to humanity. Every new discovery warrants a measured response."" + +The static hiss of communications equipment filled the air, its purpose now transformed into a dialogue with an intelligence beyond the stars. It was Sam, wide-eyed amid the myriad lights and switches, who broke the silence, ""We have provisional confirmation of the signal’s intent—initiation. We’re being brought into a broader spectrum of cognizance."" + +The chamber lay still for a heartbeat, the Paranormal Military Squad agents steeped in contemplation of the path unfurling before them—a path paved with possibilities of diplomacy or disruption, each step a venture further into the cosmic unknown. + +Alex stepped closer to the viewing monitors, each depicting alien symbols seemingly reaching out from the void. ""Initiate the broadcast,"" he spoke with quiet command. ""Our response will mark humanity’s readiness to partake in the wider conversation of conscious beings."" + +Amidst the crackling air of expectation, the team wordlessly returned to their stations. They had transcended their roles as protectors of Earth's clandestine lore to become the harbingers of an interstellar parley that could change the existential course of life on their pale blue dot. + +The deep hum of the terminal emitted a signal—a testament to the uncanny reality that Earth was now actively partaking in an exchange not bound by gravity nor the limits of the solar wind. + +Here, in the depths of Dulce, a message from humanity woven from understanding and uncertainty was cast into the firmament, an epitheg of their desire to join the universal dialogue and discover their place among the constellations. + +\* + +The somber depths of the Dulce Base command center stood in stark counterpoint to the animated flurry of activity around the central comms array. Alex Mercer's silhouette loomed behind Dr. Jordan Hayes, who sat with a posture indicating laser focus on the decryption process. A quiet murmur of digital soundscape filled the space, subtly heightened by the anticipation of contact with an intelligence beyond the Earth. + +Jordan's voice was steady, betraying none of the extraordinary nature of their work, ""Looking through the signal's pattern, it's evident we’re dealing with a form of intelligence—calculating, mirroring, possibly even understanding."" + +Alex's reflection bounced off the darkened screens, his head nodding in silent affirmation. ""We’re walking a delicate line. Our response should be thoughtful, measured. We’re ambassadors, not merely explorers."" + +Taylor Cruz approached, arms folded, their words slicing through the din of careful keystrokes and soft whirrs, ""If there’s even the slightest chance it understands, we can’t afford missteps. The language of the stars might be more absolute than ours."" + +From another terminal, Sam Rivera brought youthful vigor to the conversation, ""There’s rhythm in these patterns. If this is their way of reaching out, our reply should encapsulate all that we are—all that humanity stands for."" + +Looking around at his team, Alex saw resolve etched on every face. The chamber, usually somber and echoing with the quiet steps of covert agents, now felt alive with the heartbeat of discovery. They were not just professionals operating in the gloom; they were a collective standing at the helm of a momentous journey. + +""Let’s begin,"" he said, returned by the resolve in his voice. ""Every second counts."" With that, they pressed forward, setting in motion a reply to a conversation billions of years in the making. + +The dance with an unseen partner commenced, each pulse they sent out a step taken with caution and hope. And as those digital pulses journeyed through the black sea of infinity, Earth, for perhaps the first time, joined a pan-galactic dialogue that whispered secrets of the cosmos—secrets that, until now, had been lost in the silent vastness of space. + +\* + +As the team stood in the centralized nerve center of Dulce's underground fortress, the solemn atmosphere was reverent, overseeing systems that engaged with an intelligence from the void. Alex's stance was contemplative as he gazed at Jordan Hayes, who presided over the console, the tension of the moment reaching a tactile fervor. Each rhythmic tap of Hayes's fingers on the keys was a foray into uncharted symphonies of contact. + +Observing Hayes unravel the dense alien encryption, Alex spoke, a diplomatic tenor underpinning his words, ""Keep focused on the syntax, dissect its nuances. We're not just decoding signals; we're translating intentions."" + +Without diverting from their task, Jordan acknowledged the insight. ""Indeed, if their understanding of us is as deep as we hope, we're paving the way for dialogue far beyond our current realm."" + +Taylor Cruz, near the rear of the room, provided a steady oversight. ""As horizonless as our prospects may seem,"" Taylor intoned, ""remain diligent. Complacency before alien cognition could spell catastrophe."" + +Sam's youthful voice resonated with optimism, ""Imagine—forming a rapport with a consciousness separate from our reality; we're drafting the bridge to stars alive with minds!"" + +The sentiment hung for a moment before Alex gathered his conviction. ""Dialogue is our vessel. We are not just agents of enigma; we are the threads that may weave a new cosmic relationship."" His words seemed to reflect off the walls, reaching beyond the room's confines, a quiet yet resilient vow. + +Their task was titanic, stepping stones laid delicately into new territories of existence. The signal, once an esoteric strand in the echo of the universe, beckoned now with a clarity rocketing the complexity of thoughts from a distant order. + +Action by action, the Paranormal Military Squad team bridged the vast interstellar distances, their expertise and empathy casting a beacon of unity into frontiers of intelligence and knowledge. Their work, a partnership struck with an unseen cosmic congregation, each pulse sent and received a line in Earth's novitiate envoi to the cosmic shores. + +\* + +Under the stark, unforgiving lights of Dulce Base's underground command center, tension buzzed harder than the banks of supercomputers that lined the walls. Agent Alex Mercer leaned over the shoulder of Jordan Hayes, whose eyes were locked onto the display screen, where an incomprehensible series of alien symbols streamed past incessantly. + +“Any progress on the decryption?” Alex's voice was steady, a controlled presence necessary in the gravity of their undertaking. + +Jordan tapped a key, pausing the flow of code, and leaned back with a deep sigh. ""We've broken through another subset of the cipher. It's revealing... well, indications of a complex society, not unlike our own."" His eyes met Alex's with an unspoken question that hung heavily between them—were they truly prepared for what they might find? + +Taylor Cruz strode into the room, a tightly coiled spring of ambition and authority, and peered at the screen. ""Understand their society, and we may predict behavior. Remain expedient—we don't know how much time we have before the situation shifts."" There was an edge of stark realism to Taylor's words, the underlying message clear: every revelation bore its own set of risks. + +Alex nodded thoughtfully, recognizing the validity of Cruz's caution. Turning to Sam, who was tinkering with a device that buzzed quietly on the table, he asked, “Sam, can your contraption get us any further?” + +Sam looked up with a smirk, a twinkle of mischief in their eye. “It’s not just any contraption, it’s potentially a direct line to their thoughts. Give me a moment more, and I'll have something for you.” + +The air ticked with electronic beeps and the rustling sound of the Paranormal Military Squad team at work. They were so close to peering into the intelligence of an alien race—a reality on the brink of dramatically expanding their understanding of the universe. + +The machinery whirred in response to Sam’s precise touches, and suddenly, the room filled with a low hum—something had changed, a signal had been successfully sent. The team held their breath as they listened. The sound that filled the room was unmistakable: a response, an alien voice filtered through the static of space and time. + +Alex exchanged a look of quiet triumph with Jordan. The breakthrough was monumental; they were no longer casting messages into the void but engaged in a dialogue—an exchange that marked the beginning of Operation: Dulce’s true unfolding. This was it, the first steps into an interstellar odyssey that demanded every ounce of their courage and wit." +"## Chapter 13 + +Dr. Jordan Hayes shuffled a stack of papers, their eyes revealing a tinge of skepticism at Taylor Cruz's authoritarian performance. _Protocols_, Jordan thought, _are just the framework, the true challenges we're about to face lie well beyond the boundaries of any protocol._ They cleared their throat before speaking, tone cautious yet firm, ""Let's remember, the unknown variables exceed the known. We should remain adaptive."" + +A murmur of agreement echoed from Sam Rivera, who leaned forward, lacing their fingers together as if weaving a digital framework in the air before them, ""Exactly, adaptability could be the key to interpreting the signal distortions and system malfunctions. We shouldn't discount the… erratic."" + +Their words hung like an electric charge in the room, challenging Taylor's position with an inherent truth. Cruz’s jaw tightened almost imperceptibly, but the agent masked it with a small nod, conceding to the omnipresent threat of the unpredictable. + +Alex glanced at Jordan, who never looked back, their gaze fixed instead on a distant point, as if envisioning the immense dark corridors they were soon to navigate in Dulce. Jordan was not one to embrace fantastical theories, but the air of cautious calculation betrayed a mind bracing for confrontation with the inexplicable, an internal battle between the evidence of their research and the calculating skepticism that kept them alive in their field. + +The meeting adjourned with no further comments, the team members quietly retreading the paths to their personal preparations. Alex, trailing slightly behind, observed the others. _The cautious reserve Jordan wears like armor doesn't fool me_, he thought, _their analytical mind sees the patterns I do. And that's worth more than protocol. That's the connection we need to survive this._ + +As the agents dispersed into the labyrinth of the facility, lost in their thoughts and preparations, the base's halogen lights flickered, a brief and unnoticed harbingers of the darkness to come. + +\* + +The gritty, wind-tossed surface of New Mexico, just above the cavernous domain of Dulce Base, offered no shelter from the burgeoning storm—the scouring sands an earthly reminder of chaos theories in motion. Far beneath, a similar maelstrom brewed within the confines of the command center, as Paranormal Military Squad's handpicked squad stood poised for potential enormities of contact. + +Ruffling through printed transmission logs, Jordan Hayes dialed the focus of their analytical prowess onto the emerging pattern of signals crisscrossing between Earth and the unfathomable. ""Our responses so far have echoed their complexity, but the real divergence is yet to come,"" Jordan remarked stoically, the calm belying the mounting surge of adrenaline for the revelation ahead. + +Alex Mercer's figure, a silhouette sharpened by the purpose, loomed at the periphery of the monitors' sickly glow. ""Indeed,"" he assented, ""The echoes are the easy part. It will be the introduction of our own, human variable that truly begins our dialogue."" + +Taylor Cruz, windowless command center notwithstanding, appeared as though they could feel the tempest above. Their eyes never left the monitors as they unspooled their hard wisdom. ""For all our advances, we find ourselves deciphering the swings and nuances of an interstellar pendulum. Predict its arc, and we may preempt the gravity of its message."" + +Amidst a chorus of bleeps and static, Sam Rivera's tech-clad hands moved rhythmically, their spirited approach to unruly streams of data bordering an intimate dance with entropy. ""Entropy that leads to discovery,"" Sam mused, responding to Taylor's metaphor. ""Each step into the unknown is a step away from precedent."" + +Alex, drawing near Jordan, spoke again, his voice now a thread woven through the very fabric of their operations. ""Let's be the cartographers of this new territory. Our initial shades of understanding could color the cosmos for generations to come."" + +Their gazes fell upon a screen as the latest transmission painted its digital blooms of alien script across the black. This time, the pattern wavered in an almost imperceptible fashion, a modification that whispered of active, alien thought awaiting their next move. A hush enveloped the Paranormal Military Squad ensemble, the gravity of the pathogen undeniable. They were about to issue a reply, one poised to reshape the very concept of humanity's outreach into the cosmos. + +The New Mexico desert's secrets were infamous, its storms a mere prelude to the revelations that the team—united in purpose—would unleash upon the world. The howling winds outside found their counterpart in the newfound resolve within, as Dulce's stalwart guardians readied themselves to send forth humanity's retort to the echoes from beyond. + +\* + +The cavernous control room, deeply entrenched beneath the desolate New Mexico terrain, held the Paranormal Military Squad team in intense focus; an island of calm amid the storm of cosmic dialectics. Dr. Jordan Hayes worked methodically, every keystroke an intricate step in their tenuous cosmic ballet. Suddenly, they paused, a signal pattern resonating from the screen. ""This is new; it's...inviting. It’s as if the signal is not just calling to us but weaving its intelligence through ours."" + +Alex Mercer scrutinized the shift in data. ""A confluence of minds, then. If we're to meet them halfway, Jordan, our reply must be both innovative and discerning,"" he proposed, a glimmer of profound curiosity behind his authoritative demeanor. + +Taylor Cruz, whose sharp eyes missed nothing, nodded from beside a secondary panel. ""Innovative, yes, but also defensive. This interaction is a razor’s edge, and we cannot afford to bleed before the unknown,"" Taylor reminded them, the metaphor a stark warning of potential dangers. + +Against the backdrop of their conversation, Sam Rivera’s youthful optimism cut through the tension. ""If they’re weaving through our intellect, then we've achieved something beyond first contact—we're at the genesis of interstellar symbiosis,"" they posited with a mix of reverence and excitement. + +Alex returned Sam’s smile with his own, tempered and faint, as he turned back to the task at hand. The magnitude of their mission extended beyond the fabric of the universe, an exploration into the threads that connected sentient beings across the vast expanse. “Let’s reply with our own woven tapestry of thought—delicate, but deliberate.” + +With renewed determination, the room came alive with an undercurrent of anticipation, its occupants charged with the potential of forging an alliance with the cosmos. Paranormal Military Squad's finest were no longer merely soldiers and scientists; they had become pioneers on the vanguard of humanity’s greatest odyssey. + +The New Mexican sands above, impassive to the change brewing underneath, stood as silent sentinels as Earth's emissaries crafted their response. A response that, composed with care and imbued with humanity's essence, reached into the void, connecting with an otherworldly intelligence that awaited their harmony in the cosmic conversation." +" +## Chapter 14 + +The command center of Dulce Base lay shrouded in shadows that seemed to claw at the edges of the dimly lit array of screens and consoles. Alex Mercer, focused and unwavering, watched as Dr. Jordan Hayes parsed the latest string of alien signals—a symphony of otherworldly communications that threatened to either enlighten or confound. + +""We’re encountering a paradigm shift with every transmission,"" Jordan Hayes murmured, the pulsing glow of the monitor painting their features with an almost spectral hue. ""This signal... it’s evolving, becoming denser, more sophisticated. As if it's growing alongside us—tandem evolution."" + +The air was electric, charged with the raw potential of uncharted discovery and laden with the gravity of existential risk. Taylor Cruz, who always seemed here to mold such gravity into actionable strategies, stepped forward. ""We must contain this evolution within parameters we can manage. We cannot be bystanders to an uncontrolled ascent of intelligence."" + +Sam Rivera, the youngest of the cohort, worked feverishly at their station. ""It's not just intelligence—these signals have rhythm, a kind of music suggesting not just evolution, but a dance! We're being invited to partake in the cosmos's ballet!"" they exclaimed, a touch of youthful exuberance breaking through the solemnity. + +Alex turned, facing his team, the stoic mask of command tempered by the perceptible flicker of awe in his gaze. ""Let this dance then be our dialogue. We will match their steps with prudent but daring measures—our humanity as our guide."" + +In the ensuing hours, the Paranormal Military Squad team forged a rhythm of their own, their collective expertise a beacon piercing through the fog of the unknown. The signal, increasingly intricate and seemingly conscious, now demanded not just observation but participation, an interstellar pas de deux that hummed with the promise and peril of first contact. + +Before them, the communications interface flickered to life with a received transmission—a resonant hum that seemed to vibrate through the very foundations of the base. They had successfully established a back-and-forth with whatever intelligence lay hidden among the stars. Every subsequent note they struck within the cosmic ether would come to define humanity's place within the galactic community—heralds of Earth's grand entrance into a universe far less silent than once perceived. + +\* + +In the concrete belly of Dulce Base, dimly lit by the jagged dance of fluorescent lights above, Sam Rivera perched on the edge of their seat, their eager fingers fluttering across an ancient keyboard. The stark, cold room—reminiscent of a time when covert operations and unspoken dread ruled supreme—now housed a peculiar blend of old-world machinery and sleek, modern interfaces. + +Alex Mercer, standing steadfast like a bridge between the enigmatic past and the unfathomable present, watched on. In his eyes flashed the foreboding excitement of change. ""Sam,"" he started, his voice steadfast, ""the patterns in these signals, what do they tell us about the nature of our... guest?"" + +Sam's eyes glimmered with something akin to thrill—or was it trepidation? ""It's like we're mirroring each other, evolving together through this.. dialogue. Like it knows us, understands us, and it's… learning."" + +Jordan Hayes, preoccupied at a nearby console, chimed in without lifting their gaze. ""It's a dialogue that transcends mere words, Alex. We're being woven into a narrative far grander than the sum of our known sciences."" + +Taylor Cruz, arms crossed, wore the heavy mantle of their skepticism comfortably. ""Keep theorizing,"" they interjected crisply, ""but remember the grounding reality of what we are part of here. This contact is a blade that cuts both ways."" + +In this cavern of history, voices both human and inhuman whispered secrets to those brave enough to listen. Each member present understood the gravity that pulled at their feet; no longer were they mere mortals shackled to their terrestrial plane. The digital pings and encrypted calls resonated with an implication of a cosmic agenda that would not be ignored. + +Jordan's fingers paused, hovering in hesitation. What ripple might the next keystroke send through the fabric of known existence? It was a step into the ballet of the infinite, where the Paranormal Military Squad team played their part in the waltz of wonders with an audience of stars. + +\*" +" +## Chapter 15 + +In the clandestine hush of Dulce Base's subterranean command center, the Paranormal Military Squad team had become a crucible for interstellar communication. Dr. Jordan Hayes' gaze lingered on the screen as they navigated through the convolution of alien code. Each character held the potential to unravel a new dimension of contact, and with Sam Rivera's keen interjection, they were crafting humanity's inaugural cosmological discourse. + +Alex Mercer peered over Jordan's shoulder, calculating the implications of every visual nuance that cascaded across the monitor. ""Look for consistency—any repeating motifs could signal a willingness to engage. We're drafting history with each exchange,"" he remarked, aware of the delicate balance between forging a bond and exposing vulnerabilities. + +Taylor Cruz, stoic and enigmatic, observed the interplay from the threshold, a silhouette against the machinery's luminescence. ""Remember, while we seek common ground, the foundation we stand upon remains Terra firma. Caution must temper our curiosity,"" they stated, their voice an anchor amidst the current of excitement. + +The command center buzzed with energy, rivaled only by the tempest overhead that concealed their operation. Sam, with swift dexterity, navigated the communications relay. ""Their signals resonate almost musically. It's as if they're composing a symphony, and we've been handed the baton to conduct the next movement,"" they offered, imbuing the scenario with a blend of scientific adventurism and poetic license. + +Amidst the whirring servers and the occasional flicker of emergency lighting, the essence of their mission transcended mere reconnaissance. They were humanity's elected envoys at the brink of a celestial alliance—or confrontation—with an audience as vast as the universe itself. + +Alex stepped back, his profile etched by the chamber's artificial day. ""Then let's ensure our contribution to this symphony harmonizes with theirs. It's time for humanity's voice to rise and be counted among the cosmic ensemble."" + +Under his directive, the Paranormal Military Squad team initiated their calculated response, weaving thoughts and theories into a digital overture aimed at the heart of alien intellect. As the digital stream punctured the endless night, each member of this clandestine group was acutely aware of the irrevocable step they undertook—bringing Earth into the pantheon of galactic entities designed to converse among the stars. + +\* + +Clusters of high-tech equipment bathed the Dulce underground command center in an eerie blue light. Sam Rivera's fingers flew across the keyboard, navigating an elaborate network of alien patterns. The very air seemed to pulse with the ebb and flow of cryptic communications reaching across the stars. ""I've got something!"" Sam's announcement tore through the focus in the room, drawing every pair of eyes to the torrent of symbols unraveling on the screen. + +With the pacing of a seasoned officer gauging the moment before action, Alex Mercer approached, his calm demeanor belying an acute awareness of the precipice on which they now stood. ""Define 'something,"" Alex prompted, reinforcing the need for clarity amidst the extraordinary. + +""It's repeating—a sequence that’s evolved with each interaction, almost as if it's... singing,"" Sam theorized, the awe in their voice reflecting the potential magnitude of their discovery. + +Jordan Hayes interjected from across the console, their eyes not leaving the display as they absorbed the new data. ""A cosmic vocalization, then,"" they mused, intrigued. ""A singularity in the signal that might represent a point of reference for both parties."" + +Taylor Cruz, hands clasped behind their back, regarded the unfolding scene, their own calculations etching lines of concern onto their stern visage. ""Or a beacon—a homing tune, calling out to something we might not be ready to greet,"" Taylor offered, voicing the group's unspoken apprehension. + +Alex's eyes locked on the screen, taking in the scope of what they were attempting to interpret. Drawing a deep breath, Alex gave a slight nod. ""If this is their song, then let us respond with ours. We've come this far by mirroring their signals, now let's engage in an interstellar duet, and see where the music leads us."" + +With the expectation of the significant achieving a crescendo, the members of Paranormal Military Squad huddled over their equipment—sages at the threshold of a potentially world-altering communion. The strange harmonies that reverberated through the command center suggested that their interlocutors were poised, waiting, perhaps even eager, for Earth's chorus to join the symphony. + +As the team initiated their reply, weaving humanity's own intricate melody into the vast cosmic dialogue, they each felt a profound change within—an evolution of purpose. They were not just messengers or investigators; they had become co-composers in a galactic orchestra, with the universe itself as their witness and concert hall. + +With the exchange of harmonious signals crawling through the vacuum of space, the Paranormal Military Squad operatives found themselves part of a bridging of minds—a realization that out there, among the vast arrays of stars and planets, harmony was the true universal language. + +\* + +The dim glow of monitors cast an otherworldly ambiance upon Dulce Base's command center, where Paranormal Military Squad's chosen stood huddled over their instruments, suspended at history's threshold. Codes—alien in origin and nature—were being deciphered by Dr. Jordan Hayes, whose countenance bore the marks of deep concentration. + +Alex Mercer, the bedrock upon which their team's resolve was founded, leaned in with an eagerness tempered by his chain of command. ""Jordan, we've invested our expertise into comprehending their patterns, but now we must also endeavor to understand their intent,"" he urged, his voice bearing the gravitas of their mission's potential consequences. + +At another console, Sam Rivera's youth did not betray their crucial role in the operation. With eyes alight, they mirrored the rapid computing before them. ""There's emotion here—complex, profound even. This isn't just the output of a cold machine; it's...sentience,"" Sam whispered, nearly drowned by the mechanical chorus around them. + +Jordan, without shifting focus from their work, replied, ""It's a sentience that—should we succeed here—ushers us into a new era of existence. The cadence of these signals,"" they tapped the screen with a flourish, ""could well be the heartbeat of this new dawn."" + +Taylor Cruz paused beside Mercer, their expression unreadable beneath the sterile light. ""And as it beats, we must gauge whether its rhythm bodes well for us, or spells our missteps. Courage must not blind us to the hazards intrinsic to such contact,"" Taylor cautioned, the sentinel within them ever alert. + +Alex nodded, a gesture that carried the weight of responsibility and a silent command: proceed, but with circumspection. They were not merely decoding a message; they were interpreting a dialogue across the celestial divide. + +The room fell into a rhythm akin to a well-conducted ensemble. Each member's expertise proved a critical note in the unfolding symphony. Their actions were now more than mere research or defense; they were the tentative overtures of humankind reaching out to grasp the vast unknown. + +Textures of sound meshed with the light from countless computations, the palpable anticipation of the agents at the edge of discovery cresting with an awareness that their work would reshape future chronicles. And when the response finally came—a signal piercing the deafening silence of uncertainty—all within Dulce's confines understood: the dawn of an interstellar continuum had just begun to break. + +\* + +In the sterile hum and flickering lights of Dulce Base's command center, the Paranormal Military Squad team stood as humanity's vanguard, verging on the brim of an intergalactic abyss. Dr. Jordan Hayes, analytical edges sharp, deciphered extraterrestrial patterns that bled across screens in enigmatic cascades—a daunting mosaic of potential threats and untapped wisdom. + +Agent Alex Mercer, the embodiment of focus and a steadfast nerve, observed the unfolding digital drama with the gravitas due a historic first contact. ""Let the data weave its narrative, Jordan,"" he instructed, a moderate undertone of exhilaration within his command. ""It's encoding more than information—it's outlining civilization."" + +Jordan absorbed the directive, their gaze unflinching from the screens, feeling the weight of their next move. ""The nuances here are extraordinary,"" they acknowledged. ""It paints a picture of a culture steeped in complexities we're only starting to fathom.” + +Taylor Cruz, stoicism personified yet not immune to the situation's gravity, chimed in. ""Understand it, but guard against it,"" they cautioned, bringing a sober prudence to the room. ""This culture, however advanced, remains an unknown quantity—an ocean of wonders and darkness with uncertain tides."" + +Sam Rivera, a visual contrast with wide eyes and restless hands, represented the other side of the room — intrigue and optimism against the drawn swords of precaution. “Think of it,” they proposed, voice bouncing with a rebellious upbeat timbre, “as the first act of a play written in constellations. We're setting the stage for a galactic narrative.” + +Each team member, in their way, was both actor and scribe in this moment of tense pageantry. Heavy with the presence of risk, the command center had become not just a room of computers and glass panels but a theater for performing the elaborate choreography of contact. + +Bound by resolve and curiosity, they proceeded, each data entry a trembling step onto the cosmic stage. And like all cautious pioneers edging into fertile but unnavigated lands, they understood: as they mapped the heavens, they were simultaneously mapping the furthest reaches of their own existential horizons. + +" \ No newline at end of file diff --git a/graphrag/tests/fixtures/min-csv/input/dulce.txt b/graphrag/tests/fixtures/min-csv/input/dulce.txt new file mode 100644 index 0000000000000000000000000000000000000000..95c9e3cd3af76b570f0550d69b2025d7cd6fafbb --- /dev/null +++ b/graphrag/tests/fixtures/min-csv/input/dulce.txt @@ -0,0 +1,970 @@ +# Operation: Dulce + +## Chapter 1 + +The thrumming of monitors cast a stark contrast to the rigid silence enveloping the group. Agent Alex Mercer, unfailingly determined on paper, seemed dwarfed by the enormity of the sterile briefing room where Paranormal Military Squad's elite convened. With dulled eyes, he scanned the projectors outlining their impending odyssey into Operation: Dulce. + +“I assume, Agent Mercer, you’re not having second thoughts?” It was Taylor Cruz’s voice, laced with an edge that demanded attention. + +Alex flickered a strained smile, still thumbing his folder's corner. "Of course not, Agent Cruz. Just trying to soak in all the details." The compliance in his tone was unsettling, even to himself. + +Jordan Hayes, perched on the opposite side of the table, narrowed their eyes but offered a supportive nod. "Details are imperative. We’ll need your clear-headedness down there, Mercer." + +A comfortable silence, the kind that threaded between veterans of shared secrets, lingered briefly before Sam Rivera, never one to submit to quiet, added, "I’ve combed through the last transmission logs. If anyone can make sense of the anomalies, it’s going to be the two of you." + +Taylor snorted dismissively. “Focus, people. We have protocols for a reason. Speculation is counter-productive.” The words 'counter-productive' seemed to hang in the air, a tacit reprimand directed at Alex. + +Feeling the weight of his compliance conflicting with his natural inclination to leave no stone unturned, Alex straightened in his seat. "I agree, Agent Cruz. Protocol is paramount," he said, meeting Taylor's steely gaze. It was an affirmation, but beneath it lay layers of unspoken complexities that would undoubtedly unwind with time. + +Alex's submission, though seemingly complete, didn't escape Jordan, who tilted their head ever so slightly, their eyes revealing a spark of understanding. They knew well enough the struggle of aligning personal convictions with overarching missions. As everyone began to collect their binders and prepare for departure, a quiet resolve took form within Alex, galvanized by the groundwork laid by their interactions. He may have spoken in compliance, but his determination had merely taken a subtler form — one that wouldn't surrender so easily to the forthcoming shadows. + +\* + +Dr. Jordan Hayes shuffled a stack of papers, their eyes revealing a tinge of skepticism at Taylor Cruz's authoritarian performance. _Protocols_, Jordan thought, _are just the framework, the true challenges we're about to face lie well beyond the boundaries of any protocol._ They cleared their throat before speaking, tone cautious yet firm, "Let's remember, the unknown variables exceed the known. We should remain adaptive." + +A murmur of agreement echoed from Sam Rivera, who leaned forward, lacing their fingers together as if weaving a digital framework in the air before them, "Exactly, adaptability could be the key to interpreting the signal distortions and system malfunctions. We shouldn't discount the… erratic." + +Their words hung like an electric charge in the room, challenging Taylor's position with an inherent truth. Cruz’s jaw tightened almost imperceptibly, but the agent masked it with a small nod, conceding to the omnipresent threat of the unpredictable. + +Alex glanced at Jordan, who never looked back, their gaze fixed instead on a distant point, as if envisioning the immense dark corridors they were soon to navigate in Dulce. Jordan was not one to embrace fantastical theories, but the air of cautious calculation betrayed a mind bracing for confrontation with the inexplicable, an internal battle between the evidence of their research and the calculating skepticism that kept them alive in their field. + +The meeting adjourned with no further comments, the team members quietly retreading the paths to their personal preparations. Alex, trailing slightly behind, observed the others. _The cautious reserve Jordan wears like armor doesn't fool me_, he thought, _their analytical mind sees the patterns I do. And that's worth more than protocol. That's the connection we need to survive this._ + +As the agents dispersed into the labyrinth of the facility, lost in their thoughts and preparations, the base's halogen lights flickered, a brief and unnoticed harbingers of the darkness to come. + +\* + +A deserted corridor inside the facility stretched before Taylor Cruz, each footstep rhythmic and precise. Cruz, ambitious and meticulous, eyed the troops passing by with a sardonic tilt of the lips. Obedience—it was as much a tool as any weapon in the arsenal, and Cruz wielded it masterfully. To them, it was another step toward unfettered power within the dark bowels of the military complex. + +Inside a secluded equipment bay, Cruz began checking over gear with mechanical efficiency. They traced fingers over the sleek surface of an encrypted radio transmitter. "If protocols are maintained," said Cruz aloud, rehearsing the speech for their subordinates, "not only will we re-establish a line of communication with Dulce, but we shall also illuminate the darkest secrets it conceals." + +Agent Hayes appeared in the doorway, arms crossed and a knowing glint in their eyes. "You do understand," Jordan began, the words measured and probing, "that once we're in the depths, rank gives way to survival instincts. It's not about commands—it's empowerment through trust." + +The sentiment snagged on Cruz's armor of confidence, probing at the insecurities festering beneath. Taylor offered a brief nod, perhaps too curt, but enough to acknowledge Jordan's point without yielding ground. "Trust," Cruz mused, "or the illusion thereof, is just as potent." + +Silence claimed the space between them, steeped in the reality of the unknown dangers lurking in the shadows of the mission. Cruz diligently returned to the equipment, the act a clear dismissal. + +Not much later, Cruz stood alone, the hollow echo of the bay a stark reminder of the isolation that power often wrought. With each checked box, their resolve steeled further, a silent vow to usher their team through the abyss—whatever it might hold—and emerge enshrined in the respect they so deeply craved. + +## Chapter 2 + +Sam Rivera sat alone in a cramped office, the hum of a dozen servers murmuring a digital lullaby in the background. Surrounded by the glow of multiple screens, their eyes danced across lines of code and intercepted comm signals from Dulce — a kaleidoscope of data that their curious and isolated mind hungered to decrypt. + +To an outsider, it might have looked like obsession, this fervent quest for answers. But to Sam, it was a dance — a give and take with the mysteries of the universe. Their fingers paused over the keyboard as they leaned back in the chair, whispering to thin air, "What secrets are you hiding from us?" + +The stillness of the room broke with the unexpected arrival of Alex Mercer, whose encroaching shadow loomed over Sam's workspace. The cybersecurity expert craned their neck upwards, met by the ever-so-slight furrow in Alex's brow. "Got a minute, Rivera?" + +"Always," Sam said, a smile surfacing as they swiveled to face their mentor more directly. _He has that look — like something's not sitting right with him,_ they noted inwardly. + +Alex hesitated, weighing his words carefully. "Our tech is top-tier, but the silence from Dulce... It's not just technology that will see us through, it's intuition and... trust." His gaze pierced through the digital haze, trying to instill something more profound than advice. + +Sam regarded Alex for a moment, the sincerity in his voice resonating with their own unspoken desire to prove their worth. "Intuition," they mirrored thoughtfully. "I guess sometimes the numbers don't have all the answers." + +Their shared silence held a newfound understanding, a recognition that between the ones and zeros, it was their combined human insights that might prevail against the impossible. As Alex turned to leave, Sam's eyes drifted back to the screens, now seeing them not as barriers to isolate behind, but as windows into the vast and enigmatic challenge that awaited their team. + +Outside the office, the persistent buzz of activity in the facility belied the unease that gripped its inhabitants. A restlessness that nibbled on the edges of reality, as though forewarning of the threshold they were soon to cross — from the known into the realm of cosmic secrets and silent threats. + +\* + +Shadows played against the walls of the cramped underground meeting room, where Alex Mercer stood gazing at the concealed elevator that would deliver them into the bowels of Dulce base. The air was thick, every breath laced with the weight of impending confrontation, the kind one feels when stepping into a legend. Though armed with an array of advanced weaponry and gear, there was an unshakeable sense that they were delving into a conflict where the physical might be of little consequence. + +"I know what you're thinking," Jordan Hayes remarked, approaching Mercer. Their voice was low, a blend of confidence and hidden apprehension. "This feels like more than a rescue or reconnaissance mission, doesn't it?" + +Alex turned, his features a mask of uneasy resolve. "It's like we're being pulled into someone else’s game. Not just observers or participants, but... pawns." + +Jordan gave a short nod, their analytical mind colliding with the uncertain dynamics of this operation. "I've felt that way since the briefing. Like there's a layer we’re not seeing. And yet, we have no choice but to play along." Their eyes locked with Alex's, silently exchanging a vow to remain vigilant. + +"You two need to cut the philosophical chatter. We have positions to secure," Taylor Cruz interjected sharply, stepping into their exchange. The authority in Taylor's voice brooked no argument; it was their way of pulling everyone back to the now. + +Alex's response was measured, more assertive than moments ago. "Acknowledged, Agent Cruz," he replied, his voice steadier, mirroring the transformation brewing within. He gripped his rifle with a newfound firmness. "Let's proceed." + +As they congregated at the elevator, a tension palpable, Sam Rivera piped in with a tone of balanced levity, "Hope everyone’s brought their good luck charms. Something tells me we’re going to need all the help we can get." + +Their laughter served as a brief respite from the gravity of their mission, a shared moment that reinforced their common humanity amidst the unknowable. Then, as one, they stepped into the elevator. The doors closed with a silent hiss, and they descended into the darkness together, aware that when they returned, if they returned, none of them would be the same. + +\* + +The sense of foreboding hung heavier than the darkness that the artificial lights of the elevator shaft failed to fully penetrate. The team was descending into the earth, carrying with them not only the weight of their equipment but also the silent pressure of the invisible war they were about to fight—a war that seemed to edge away from physicality and into the unnervingly psychological. + +As they descended, Dr. Jordan Hayes couldn't help but muse over the layers of data that could wait below, now almost longing for the comfort of empirical evidence. _To think that this reluctance to accept other possibilities may have been my biggest blind spot,_ Jordan contemplated, feeling the hard shell of skepticism begin to crack. + +Alex caught Jordan's reflective gaze and leaned in, his voice barely a murmur over the hum of the elevator. "Once we're down there, keep that analytical edge sharp. You see through the mazes of the unexplained better than anyone." + +The compliment was unexpected and weighed differently than praise from others. This was an acknowledgment from someone who stood on the front lines of the unknown with eyes wide open. "Thank you, Alex," Jordan said, the words carrying a trace of newfound assertiveness. "You can count on me." + +The exchange was cut short by a shudder that ran through the elevator, subtle, but enough to make them instinctively hold their breaths. It wasn't the mechanical stutter of old gears but a vibration that seemed to emanate from the very walls of the shaft—a whisper of something that defied natural explanation. + +Cruz was the first to react, all business despite the shadow that crossed their expression. "Systems check. Now," they barked out, masking the moment of disquiet with swift command. + +Every agent checked their gear, sending confirmation signals through their comms, creating a chorus of electronic beeps that promised readiness. But there was an unspoken question among them: was their technology, their weaponry, their protocols sufficient for what awaited them or merely a fragile comfort? + +Against the gravity of the silence that was once again closing in, Sam's voice crackled through, only half-jest. "I'd laugh if we run into Martians playing poker down there—just to lighten the mood, you know?" + +Despite—or perhaps because of—the oddity of the moment, this elicited a round of chuckles, an audible release of tension that ran counterpoint to the undercurrent of anxiety coursing through the team. + +As the elevator came to a halting, eerie calm at the sub-level, the group stepped off, finding themselves at the threshold of Dulce's mysterious halls. They stood in a tight pack, sharing a cautious glance before fanning out into the unknown, each one acutely aware that the truth was inevitably intertwined with danger. + +Into the depths of Dulce, the team advanced, their silence now a shared testament to the camaraderie born of facing the abyss together—and the steel resolve to uncover whatever horrors lay hidden in its shadows. + +\* + +The weight of the thick metal door closing behind them reverberated through the concrete hallway, marking the final threshold between the familiar world above and the strangeness that lay beneath. Dulce base, a name that had been whispered in the wind-blown deserts above and in the shadowed corners of conspiracy forums, now a tangible cold reality that they could touch — and that touched them back with a chill. + +Like lambs led to an altar of alien deities, so did Agents Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera proceed, their movements measured, their senses heightened. The air was still, almost respectful of the gravity of their presence. Their torch beams sliced through the darkness, uncovering steel doors with warnings that spoke of top secrets and mortal dangers. + +Taylor Cruz, stepping firmly into the role of de facto leader, set a brisk pace. "Eyes sharp, people. Comms check, every thirty seconds," Taylor ordered, their voice echoing slightly before being swallowed by the surrounding silence. + +Sam, fiddling with a handheld device aimed at detecting electronic anomalies, offered a murmured "Copy that," their usual buoyancy dimmed by the oppressive atmosphere. + +It was Jordan Hayes who paused at an innocuous looking panel, nondescript amongst the gauntlet of secured doorways. "Mercer, Rivera, come see this," Jordan’s voice was marked with a rare hint of urgency. + +Alex joined Jordan's side, examining the panel which, at a mere glance, seemed just another part of the base's infrastructure. Yet, to the trained eye, it appeared out of place—a facade. + +Jordan explained their reasoning as Sam approached, instinctively understanding the significance of what lay beneath, "This panel is a recent addition — covering something they didn't want found." + +Before Alex could respond, the soft whir of an approaching drone cut through their muffled exchange. Taylor had looped back upon hearing the commotion. "Explanations later. We can't afford to attract..." Cruz’s voice trailed off as the small airborne device came into view, its sensors locked onto the group. + +Sam was the first to react, their tech-savvy mind already steps ahead. "I've got this," they declared, fingers flying over the controls of their own gadgetry to ward off the impending threat. + +The drone lingered, its scan seeming more curious than hostile. But within moments, courtesy of Sam's interference, the little sentinel drifted away, retreating into the shadows as if accepting a silent truce. The crew exhaled, a moment of collective relief palpable in the air. + +Cruz squared their shoulders, clearly ruffled but not conceding any ground. "Move out," they directed, a hint more forceful than before. "And Rivera, keep that trick handy." + +The team pressed onward, the quiet now filled with the soft beeps of regular comms checks, their pace undeterred by the confrontation. Yet, every agent held a renewed sense of wariness, their trust in one another deepening with the knowledge that the base—its technology, its secrets—was alive in a way they hadn't fully anticipated. + +As they converged upon a central hub, the imposing doors to the mainframe room stood ajar — an invitation or a trap, neither option comforting. Without a word, they fortified their resolve and stepped through the threshold, where the dim glow of operational LED lights and the distant hum of machinery hinted at Dulce’s still-beating heart. + +Solemnly, yet unmistakably together, they moved deeper into the heart of the enigma, ready to unmask the lifeforce of Dulce base or confront whatever existential threat lay in wait. It was in that unwavering march towards the unknown that their destinies were forever cemented to the legacy of Operation: Dulce. + +## Chapter 3 + +The thrumming of monitors cast a stark contrast to the rigid silence enveloping the group. Agent Alex Mercer, unfailingly determined on paper, seemed dwarfed by the enormity of the sterile briefing room where Paranormal Military Squad's elite convened. With dulled eyes, he scanned the projectors outlining their impending odyssey into Operation: Dulce. + +\* + +The cooling vents hummed in a monotonous drone, but it was the crackle of the comms system coming to life that cut through the lab’s tension. Dr. Jordan Hayes hovered over a table arrayed with alien technology, their fingers delicately probing the enigmatic circuitry retrieved from the crash site. Agent Alex Mercer watched, admiration blooming in silent solidarity for Jordan's deft touch and unspoken drive. + +Jordan, always composed, only allowed the faintest furrow of concentration to mar their brow. "What we understand about physics..." they muttered, trailing off as they realigned a translucent component. The device emitted a low pulse, causing Jordan to still. "Could be fundamentally changed by this." + +A calculated risk—that's what this was. And for a person of science, a gamble was worth the potential paradigm shift. + +"I’ve been thinking," Alex started, his eyes still fixed on the immediately tangible mystery before them. "About what’s at stake here. Not the mission parameters, but what this means for us—humanity." + +Jordan glanced up, meeting his eyes just long enough to convey the shared enormity of their situation; the career-defining glory and existential dread entwined. "The quest for understanding always comes at a price. We're standing on the precipice of knowledge that could either elevate us or condemn us." + +The charged air between them spiked as Taylor Cruz’s brusque tones sliced through their reverie. "Hayes, Mercer, this isn't philosophy hour. Focus on the task. We need actionable intel, not daydreams." + +With a sound of restrained acknowledgment, Jordan returned their gaze to the device, while Alex clenched his jaw, the buzz of frustration dull against the backdrop of Taylor's authoritarian certainty. It was this competitive undercurrent that kept him alert, the sense that his and Jordan's shared commitment to discovery was an unspoken rebellion against Cruz's narrowing vision of control and order. + +Then Taylor did something unexpected. They paused beside Jordan and, for a moment, observed the device with something akin to reverence. “If this tech can be understood..." Taylor said, their voice quieter, "It could change the game for us. For all of us.” + +The underlying dismissal earlier seemed to falter, replaced by a glimpse of reluctant respect for the gravity of what lay in their hands. Jordan looked up, and for a fleeting heartbeat, their eyes locked with Taylor's, a wordless clash of wills softening into an uneasy truce. + +It was a small transformation, barely perceptible, but one that Alex noted with an inward nod. They had all been brought here by different paths and for different reasons. Yet, beneath the veneer of duty, the enticement of the vast unknown pulled them inexorably together, coalescing their distinct desires into a shared pulse of anticipation. + +Marshaled back to the moment by the blink of lights and whir of machinery, they refocused their efforts, each movement sharpened by the knowledge that beyond understanding the unearthly artifacts, they might be piecing together the future of their species. + +\* + +Amidst the sterility of the briefing room, the liminal space between the facts laid out and the hidden truths, sat Sam Rivera, his demeanor an artful balance of focus and a casual disguise of his razor-sharp talent with technology. Across from him, Alex Mercer lingered in thought, the mental cogs turning as each file on Dulce stirred more than curiosity—it beckoned to a past both honored and burdensome. + +"You've been quiet, Sam," Alex noted, catching the younger man's contemplative gaze. "Your take on these signal inconsistencies?" + +There was a respect in Alex's tone, though a respectful distance remained—a gulf of experience and a hint of protective mentorship that stood between them. Sam nodded, recognizing the space afforded to him, and he couldn't help but feel the weight of expectation pressing upon his shoulders. It wasn't just the mission that was immense, it was the trust being placed in him. + +"The patterns are... off," Sam admitted, hesitant but driven. "If I'm right, what we're looking at isn't random—it's a structured anomaly. We need to be ready for anything." + +Alex's eyes brightened with a subtle approval that crossed the distance like a silent nod. "Good. Keen eyes will keep us ahead—or at least not blindsided," he said, affirming the belief that inscribed Sam's role as more than the tech personnel—he was to be a guiding intellect in the heart of uncertainty. + +Their exchange was cut short by Taylor Cruz's abrupt arrival, his gait brimming with a robust confidence that veiled the sharp undercurrents of his striving nature. "Time to gear up. Dulce waits for no one," Taylor announced, his voice carrying an iron resolve that knew the costs of hesitation—though whether the cost was calculated in human or career terms was an ambiguity he wore like a badge of honor. + +As Sam and Alex nodded in unison, the icy chasm of hierarchy and cryptic protocols seemed momentarily to bridge over with an understanding—this mission was convergence, a nexus point that would challenge each of their motives and strength. + +They filed out of the briefing room, their footsteps synchronized, a rhythm that spoke volumes of the unknown cadence they would soon march to within the base's veins. For Alex Mercer, the link with Sam Rivera, though distant, was now poised with a mutuality ready to be tested; for Taylor Cruz, the initiative pulsed like a heartbeat, anticipation thinly veiled behind a mask of duty. + +In the midst of the descent, they were each alone yet irrevocably joined, stepping closer towards the volatile embrace of Operation: Dulce. + +## Chapter 4 + +The corridors of the Dulce military base were as silent as a tomb and twice as chilling. Alex Mercer walked with a surety that belied his bubbling undercurrents of doubt. The briefing had been definitive, sturdy pillars of facts and protocols, yet as he ventured deeper, the ominous atmosphere gnawed at him—a stark reminder of how much remained unknown. + +Jordan Hayes trailed a few steps behind, their detached exterior breaking for a moment as they caught up to Alex. "What's on your mind?" Jordan asked, their astuteness cutting through the unspoken tension. + +Alex glanced back at them. This place was a puzzle, a treacherous labyrinth where the walls whispered secrets, and among them, he sensed a call to question, to challenge the narrative they'd been sold. "The silence here... It's almost as if the base is waiting for something—or someone." + +"Just stay sharp, Mercer," Jordan cautioned, yet their eyes lingered on the quietude around them, conceiving the same shadow of doubt that unsettled Alex. + +Before they could delve into further discussion, the distinctive click of a safety catch echoed in the hollow space. Both agents turned to find Taylor Cruz standing resolute, primed for combat. Taylor's gaze was scrutinizing and cold, a stark contrast to the growing unease that smoldered silently amongst the rest. + +"Chatter is a liability," Taylor snapped, with a commanding flair that bordered on tyrannical. "We move forward, eyes open, mouths shut." + +Alex felt the tight grip of compliance strangle his gut, a lesson learned under the hard tutelage of rank and order. But here, in the bowels of Dulce, those instincts began to wane, the imperative to adhere now conflicting with the pressing urgency to confront the shadows they were enmeshed in. + +Then, unexpectedly, the lights flickered, a power fluctuation—or a sign? Alex's hand instinctively went to his sidearm, his mindset shifting from soldier to skeptic. The base, with its unyielding coldness, had just given them their first nudge into the realm of the speculative, an invitation to peel back the veneer of reality. + +"We should consider all possibilities," Alex murmured, more to himself than the others, his voice a barely audible breath against the sterile air of the complex. + +Taylor's posture stiffened at the challenge, yet their response was uncharacteristically reserved, notable in its lack of rebuke. "Agreed. For now, keep moving. But stay vigilant." + +A surprise—an echo of agreement from the last person Alex expected it from. And there it was, the glimpse of a wrinkle in the unyielding fabric of command, a hint that perhaps they were all starting to sense the strangeness that permeated this place. + +Progressing with determined steps, the trio moved deeper, silently acknowledging the evolution of their predicament. It was a small yet transformative concession to the unknown forces at play, an acknowledgment from each agent that, despite their disparate goals and ideals, the true nature of the Dulce base was an enigma that would forge new paths through their convictions. + +As they reached the central communications hub, the truth that awaited them lurked in the shadows, its eyes unseen but felt by all. The walls didn't just whisper now; they spoke in tones only the brave—or the foolish—would dare to listen to. + +\* + +The subterranean silence of Dulce was an oppressive entity of its own, wrapping the team in a cloak of uneasiness as they pressed on through the dimly lit corridor. Jordan Hayes found themselves contemplating the ramifications of each step taken into this suspended world, where the sterile air seemed to mock the gravity of their predicament. The closer they got to the communication hub, the more Jordan's mind wandered toward the realm of the inexplicable. + +Beside Jordan, Alex Mercer moved forward with deliberation, his gaze scanning the heavy utility doors they passed—one of which was partially ajar, beckoning them with its darkness. "After you, Dr. Hayes," Alex said, gesturing toward the mysterious opening. A hint of shared understanding passed between them; knowledge was the guiding star of this mission as much as confrontation or recovery. + +Jordan peered inside, the beam from their flashlight slicing through the obscurity. The room beyond was a chaotic cascade of papers, overturned furniture, and the particular kind of disorder born from hasty evacuation—or something far more sinister. + +"It's like they vanished in the middle of something urgent," Alex murmured, his voice tight with a mix of concern and anticipation. He began to sift through the scattered reports, each page a potential clue to the enigmatic silence that shrouded Dulce. + +Behind them, Taylor watched with a disciplined patience, their authority the foundation upon which the operation was built. Their voice cut into the stillness, a reminder of their presence, "Time is not our ally here." + +Drawing back from momentary distraction, Jordan acknowledged the wisdom in Taylor's words, yet could feel the shift in their stance—from skeptical, reserved analyst, to a proactive agent within the narrative. "You're right; these documents may hold critical insights. Let's collect what we can and analyze them properly." + +From the darkened hollows of the room, shadows seemed to cast subtle judgment as Alex and Jordan worked together with heightened urgency. Taylor, for once, didn't intervene but instead surveyed the entrance, their mind anticipating the unknown variables that lay ahead. + +Unexpectedly, a soft hiss emanated from a neglected terminal on the desk. Jordan's head snapped up, their heart rate accelerating at the potential ramifications. Without a word, they moved to the machine, hands driven by the newfound conviction that knowledge was more than power—it was survival. + +As Jordan began to extract what data they could from the terminal, the first comprehensible communication from the depths of Dulce in far too long crackled through: an automated distress marker, looping endlessly without further context. It was a revelation, one that reverberated through the group, confirming their fears and igniting an even greater need to press on. + +Watching Jordan's dogged determination, Alex witnessed the minor transformation in his colleague unfold—a shift from doubt to action, a sliver of belief in the possibilities beyond their rational understanding. This forge of resolve amidst the alien echoes of Dulce not only bonded them closer as a team but compelled them forward with a sharpened edge of responsibility to the truth, wherever it would lead. + +As they collected their findings and regrouped, the base around them imperceptibly changed, the air charged with the vibration of secrets poised on the brink of revelation. And in that charged silence, the group moved on, each now carrying pieces of a puzzle that would soon converge into a picture of galactic significance. + +\* + +In the chill of the cramped server room, the hum of machinery was the backbone to a symphony of data streams coursing through the air. Dr. Jordan Hayes, nerves alight with the mission's mounting unknowns, patched into the last known coordinates of the unsent distress broadcast they had uncovered. They were so close to the core now – to the truth behind the blackout – it was almost tangible. + +Beside them stood Agent Alex Mercer, ever the soldier, yet with eyes that betrayed an intellect craving to understand the murk beneath the surface. "Any progress, Dr. Hayes?" Alex queried, his voice betraying a subtle urgency. + +"Getting there," Jordan replied, fingers dancing across the keyboard. "Whoever sent this was cut off mid-transmission. It's as if Dulce itself swallowed the message whole." + +Taylor Cruz closed in, their frame casting a long shadow over the duo, evoking an almost palpable wall between them and the forward momentum of their mission. "Time is against us," Taylor intoned, more statement than threat. "What we uncover here determines our next course of action." + +Alex acknowledged Taylor with a brisk nod, his stance firm. Yet inwardly, the tightening grip he felt from Taylor's words couldn't throttle the swell of his own investigative instinct. His soldier's obedience had begun to war with the advocate's zeal for unveiling the dark heart of Dulce's secrets. + +And then, the unexpected occurred. The screens flashed in unison, spilling a discordant stream of symbols and images that defied immediate analysis. Jordan's breath caught – this was the response they had been fishing for, an alien communication protocol resonating just at the edge of human comprehension. + +Each member of the team felt it: a shift in the room’s very atmosphere, like a veil being drawn from their perception. Alex and Jordan stood still, absorbed in the bewilderment of contact, while Taylor, despite their authority, hesitated – a minor betrayal that unease was creeping into even their disciplined heart. + +"Thoughts, Rivera?" Taylor rallied, seeking the counsel of Sam Rivera, whose eyes were wide with exhilaration. + +Sam stepped forward, breaking the spell of stillness. "It's like nothing I've ever seen before, but I think I can bridge our systems to communicate," they declared, a wisp of optimism braiding their voice. They set about adapting their gear to transmute the foreign signals into something the team could dissect, their actions a testament to the mentorship and belief instilled in them by Mercer and the team. + +Taylor observed them, a cold calculation behind their facade, as they weighed the worth of this anomaly. It was a crossroad that potentially led to either monumental breakthrough or unprecedented catastrophe. "Once you've established a line, document everything. We can't afford to miss any detail," Taylor ordered, the words sharper than intended. + +The connection was made, and with trembling anticipation, the team listened as the first garbled outputs began to emerge, their very essence promising insights that could alter the course of history. It was an enigmatic dance with the unknown, the pulse of Dulce no longer just a place, but a herald to an alien register the team had yet to decipher. + +Together, they stood at the precipice of understanding, where the faint glow of their monitors cast more than just light – it cast the shadow of burgeoning transformation. It was in this moment, in the grasp of an extraterrestrial tongue, that the team, bound by a hunger for knowledge and the raw edge of survival, found their mission reframed from a search for answers to the articulation of a question humankind had yet to fully ask. + +Silent in their commune with the inexplicable frequency, they realized they were not merely investigators; they had become liaisons on behalf of Earth, interpreters of a cosmic message that could redefine their very existence. The implications loomed large, but now, they would not face them alone – they would face them as a united front, wrought together by the very mysteries that once drove them apart. + +## Chapter 5 + +Dr. Jordan Hayes clutched the edge of the briefing room table, their fingers white-knuckled against the laminate surface, as an array of constellations rotated on the projector—charts and graphs bleeding across the stars. In the dim room, nebulas and dark matter seemed within arm's reach, tangible yet unfathomable. + +Sam Rivera leaned back against the wall, arms crossed, gaze darting between the swirling cosmos and the faces of their companions. A taut line of concentration etched their young features, a mingling of fervent curiosity with the nascent understanding of the high stakes for which they played. + +Jordan's voice broke the profound silence. "The patterns in the signal disruptions sync with none other than zenithal star alignments. It's as if... as if these 'meet and greets' were scheduled, predestined by celestial mechanics." + +The statement hung heavy, daring the occupants of the room to unravel its implications. Alex Mercer, his prior military resolve momentarily suspended, absorbed the hypothesis with a visible hunger. "It's like we're adhering to an appointment we never knew we had," he murmured, his heart a drumbeat in his chest. + +Taylor Cruz snorted—a sound that clattered against the high concepts like a tumbledown shack in a futurist cityscape. Folding their arms, they glanced between the agents, their apprehension clad in the contempt of practicality. "What we need are facts, not mystic conjecture." + +Alex pivoted on his heel, facing Taylor squarely, and his voice found its edge of steel. "This isn't mysticism, Cruz. It's a hypothesis based on observed phenomena as unpredictable as the place we're standing in." + +Taylor's gaze never wavered, yet the slight twitch at the corner of their mouth belied their taut composure. "If there's a semblance of truth to it, then it's critical intel. But remember, we're not astrologers—we're soldiers and scientists." + +Jordan met Taylor’s gaze with a curt nod, accepting the caution even as the crucible of their intellect smoldered with the fervor of cosmic discovery. Their eyes flicked to Sam, whose steady presence and ready tech affirmed a burgeoning dynamic—the makings of a sentinel, standing guard over the threshold of human understanding and cosmic reality. + +With the projector casting pallid light over their features, each agent became a silhouette of purpose, shadows pillared against the backdrop of an endless universe. The story they were embroiled in would soon demand they plunge into darkness to retrieve the light of knowledge—a light that could very well redraw the shape of their world. + +They left the briefing room with a shared silence, each pondering the vast weave of celestial intent and terrestrial response, sensing that the galactic appointment to which they'd unwittingly RSVP’d was more insistent—and more threatening—than any operation they’d faced before. + +\* + +As the Paranormal Military Squad team convened in the heart of the Dulce military complex, an air of bristling expectation clung to the walls of the underground sanctum. Alex Mercer’s brow furrowed while watching his companions—Jordan Hayes, diligently setting up their makeshift lab station, and Sam Rivera meticulously checking the communication relays they had restored. Taylor Cruz observed with hawk-like focus, yet to betray the strain that their command posed on them. + +The gravity of the mission had shifted, deepened; each member of the team felt its pull, tethered to the understanding that they were now part of a larger narrative—a cosmic play with Earth as a stage and the human race unwitting actors. + +Jordan paused, a tension creeping across their shoulders as they aligned the satellite data with the alien message that had been decoded. "The instructions in this message," Jordan started, the timbre of their voice betraying their usual composure. "They're coordinates and... a warning." + +Sam leaned in, their eyes widening behind the glow of their laptop screen. "A warning? Like, ‘stay away from’, or ‘beware of’...?" Their words trailed off, uncertainty a new companion in their lexicon. + +Alex exhaled slowly, his mind racing to connect the dots. "It doesn't matter which," he said, decisive yet contemplative. "What matters is we understand intent. Are we being warned out of concern, or are we stumbling upon a threat?" + +Cruz’s iron-clad facade momentarily cracked, a fleeting glimpse of vulnerability flashing through their eyes. "We need to know if this entails additional risk to the operation," they said, directing their gaze specifically at Alex. "Mercer, I rely on you to keep the team grounded. No one goes off-course." + +Their reminder seemed both a command and a plea—rooted in an understanding that each member of the team now faced the duality of their roles, protectors of earthly secrets and heralds of potentially devastating revelations. + +Sam's fingers stilled mid-type, their task forgotten as they absorbed the weight of the unfolding reality. "We're the first line of defense... or detection," they mused half to themselves, a growing sense of agency within the larger play they were cast into. + +Jordan returned to the data, more resolute in their actions. The warning, whether cautionary or dire, was a beacon they no longer could ignore; its light casting aside shadows of doubt and igniting a collective purpose within the team. + +Alex watched Jordan and Sam, feeling a brotherhood in their shared quest. As Cruz paced, poised on the cusp of decisions that would mark their career and perhaps the fate of many, Alex knew the narrative had changed. They were no longer mere operatives; they had become guardians of a threshold, keepers of a message from a realm beyond stars and stripes. This elevation in their mission could not be shackled by regulations and established protocols—it demanded a new perspective, a new resolve. + +Tension threaded through the dialogue of beeps and static as communications with Washington buzzed in the background. The team stood, a portentous air enveloping them. It was clear that the decisions they made in the ensuing hours could redefine humanity's place in the cosmos or condemn them to ignorance and potential peril. + +Their connection to the stars solidified, the group moved to address the crystallizing warning, shifting from passive recipients to active participants. Mercer’s latter instincts gained precedence— the team’s mandate had evolved, no longer solely to observe and report but to interact and prepare. A metamorphosis had begun, and Operation: Dulce hummed with the newfound frequency of their daring, a tone set not by the earthly hierarchies but by the pulsing symphony of the universe itself. + +\* + +The desert night loomed eerily still as echoes of hidden activity reverberated deep beneath the bleak sands of New Mexico. Diverting his gaze from the array of sensors before him, Jordan Hayes allowed a rare breath, deep and anxious. Turning to Alex Mercer's focused silhouette, the nocturnal landscape illuminated softly by makeshift floodlights, Jordan felt the syncopated tempo of apprehension and exhilaration jockey for primacy within. + +"The closer we get to unlocking these messages, the more I feel like we're peeling back layers of reality itself," Jordan confided, eyes not leaving the monitors that presented a constellation of data points. + +"Yes," Alex replied, his voice steady as he considered the implications of their discovery. "And we have to be ready for whatever we find beneath those layers. Whether it's a breakthrough or a Pandora's Box." + +Silence settled between them, broken only by the occasional buzz of communications equipment attempting to bridge terrestrial and extraterrestrial intelligences. Tense moments drifted by, laden with the expectant weight of near breakthrough, when a soft chime signaled an incoming transmission -- a rare sound that set every agent on high alert. + +Absent was the voice of Washington or Paranormal Military Squad command. Instead, a rhythmic series of pulses and tones filled the air, deliberately patterned, unmistakably non-human. + +Sam Rivera adjusted the sensitivity of the decoding equipment, their hands shaking with anticipation as much as focus. "I have it!" they announced, the signal transforming under their expertise into a sequence of visual symbols on the screen before them. + +Their shared excitement was palpable, a kinetic force resonating between the team members as they crowded around the display. + +"What does it say?" Taylor Cruz demanded, the urgency in his tone scraping against the newfound wonderment. + +Interpreting the alien syntax required not only decoding but intuition and empathy. The words that emerged upon the screen were at once coherent and enigmatic: "*Voyage. Convergence. Peril.*" + +The stark simplicity of the message struck them collectively, a chill breeze wafting through their resolve. + +Alex stepped forward, piecing together the cryptic communication with a growing sense of obligation. "It’s a call to action," he deduced, "or possibly a summons." + +Jordan's gaze met Alex’s, both understanding that this was no longer an investigation or mere extraction of hidden truths. This was humanity's unwitting enlistment into a galactic dialogue that defied boundaries of nation, creed, or protocol. + +Sam's eyes were aglow, not with fear, but with the profound acceptance of inevitability that comes with groundbreaking revelation. Moreover, within Taylor's stern exterior churned the seed of reluctant admiration for the unclassified, the uncharted realms they were approaching. + +Together, they accepted the pivot in their mission, readjusting their objectives from exploration to engagement, and from isolation to a communal outreach beyond the stars. As dawn's first light threatened the horizon, it became clear that they were no longer merely operatives of a clandestine governmental faction—they were delegates on behalf of Earth, embarking on a voyage orchestrated by destinies unrelated to the mere geopolitics of their world. + +Turning to each other, their silhouettes sketched against the coming dawn, the agents recognized the transformation within and amongst them. They were bound by more than duty—they were intricately woven into the fabric of an unfolding cosmic opera, one in which they had been granted an undeniable role. And as they set course for the coordinates that beckoned them like a distant siren's call, it was with a solemn dedication to not only uncover the mysteries ahead but to navigate the convergence, and the peril, as unified emissaries of a world on the cusp of a broader understanding. + +\* + +Beneath the hum of the fluorescent lights and the vigilance of silent monitors, Alex Mercer stood with his team in the threshold of the base's command center, their faces etched with the fatigue of hours spent unraveling galactic mysteries. Jordan Hayes broke the stillness with a delicate fusion of disbelief and resolve. "The signal..." they began, their tone deliberate, "it’s evolving. It’s not just sending a message—it’s responding to us." + +Taylor Cruz leaned over the console, their eyes narrowing with intrigue and a flicker of unease, studying the alternating patterns on the screen. "Responding? Like it’s alive?" Taylor asked, a question that bordered on the edge of wonder and alarm. + +Sam Rivera’s gaze was locked onto their interface, a digital orchestra at their fingertips. "It could be some form of advanced AI. Or something else entirely," they contributed, a note of exhilaration betraying the gravity of the situation. + +Alex paced before the terminal, absorbing the enormity of their predicament. Their mission—once rooted in the solid ground of military discipline and covert operations—had transcended into an encounter of unprecedented import. "We need to be cautious," he advised, his voice a low rumble of cautious strategy. "If this signal is intelligent, how we interact with it could dictate the outcome of this entire operation." + +Jordan met Alex's gaze with a nod, the weight of the responsibility shared and accepted. "We have protocols for first contact, but nothing for... this," Jordan admitted. The room was gripped with tension, each breath seemingly louder than the last. + +Then, with a sudden burst that filled the command center, the signal coalesced into a clear and distinct pattern which replicated and expanded, its complexity revealing the hand—or mind—of an intelligent architect. + +Taylor's instinct for command surged forth. "Prepare to record and analyze. Whatever it is, we need to understand it—" But their words were cut short as the signal surged, enveloping the room in a brief, blinding cascade of light. + +In that pulse of brilliance, a shared revelation coursed through the team. The signal had become a bridge, an extension of unknown consciousness reaching towards them, testing, communicating, searching. + +Alex stepped back from the light, feeling a profound change unravelling within him. The path forward would not be one of confrontation or conquest, but of connection and comprehension. + +Jordan turned to Alex and Taylor, seeing in their faces a reflection of the same metamorphosis taking place within themselves—a movement from observers to participants, from agents to ambassadors. + +With a collective breath, the team faced the kaleidoscope of lights. The alien signal, once a harbinger of enigma, was now a catalyst for transformation—a symphony of light and sound that echoed the beginnings of a new relationship between humanity and the alien unknown. + +And so, with deliberate steps, Alex Mercer led his team into the luminous fray. Science, protocol, and survival instinct harmonized within them, each member poised on the cusp of a new chapter in human history. + +They were no longer merely the instruments of Paranormal Military Squad's will—they were the vanguard of humankind’s first definitive leap into the cosmic community. + +With the last echoes of the signal resonating in the control room, they each embraced the sequencing of the transmission, the dance of extraterrestrial light that now wrote itself into their story. The chapter of Operation: Dulce drew to a close, but the narrative of their destiny had only just begun. + +## Chapter 6 + +\* + +The cool darkness of the command center at Dulce base was a stark contrast to the brewing storm outside, where the unforgiving New Mexico desert winds whispered of the hidden truths that lay buried deep beneath its surface. Dr. Jordan Hayes sat, their eyes fixed on the readout, the frenetic dance of symbols and numbers reflecting off their determined face. They were on the cusp of an epiphany, teetering between the widely accepted laws of physics and the promise of a new cosmic paradigm. + +Alex Mercer watched from across the room, noting the subtle shifts in Jordan’s posture that belied a developing readiness to embrace the unbelievable. “Find something?” Alex’s question, asked with a blend of curiosity and solidarity, bridged the gap between a command and a genuine query among equals. + +Jordan's response was slow, measured against the magnitude of their analysis. “This isn’t random static. It’s a pattern - a repeated sequence phasing in and out but distinctly artificial.” Jordan turned away from the screen, locking eyes with Alex. “This could change everything.” + +Sam Rivera leaned in, their eyes alight with the fires of revelation and a quenchless thirst for understanding. “A pattern means intention. Could it be a message?” + +A figure emerged from the doorway, casting a long shadow into the room - Taylor Cruz. “Intentions can be friendly, or hostile. We shouldn’t forget that,” said Taylor, bringing a dose of their usual pragmatism into the heart of discovery. + +Alex acknowledged Taylor’s caution with a nod, understanding the need to keep their feet grounded even as their spirits soared toward the unknown. “Then let’s be the first to find out which it is." + +The team gathered around the monitors, the soft tapping of Jordan's keystrokes now punctuated by the occasional crackle of Sam's radio equipment. The sound was almost ritualistic, a prelude to humanity’s potential first, knowing foray into a larger universe. + +Jordan’s fingers paused, suspended in mid-air. The signal had evolved, becoming a beacon that somehow felt less alien and more familiar. It was as if the complexities of their message were unfolding into something more accessible, more terrestrial. + +A hushed excitement swept through the room. The transformation suggested an awareness on the part of the unknown senders; a finesse that spoke volumes about their capabilities and perhaps their intentions. + +With the growing realization that they were engaging with an intelligence far exceeding their previous understanding, the team prepared to reach back across the cosmic divide. Prepared or not, they were no longer bystanders in this galactic narrative. They were active correspondents in an exchange that transcended galaxies and welcomed them into an expansive, possibly fraught, interstellar conversation. + +\* + +Inside the cavernous central hub of Dulce military base, Dr. Jordan Hayes stood in near-darkness, surrounded by a nest of cables and monitors that buzzed with silent, cryptic life. Jordan's eyes narrowed to focus on the sequences that danced across the screen—patterns that could unravel the cosmic enigma surrounding them. + +Alex Mercer approached with his characteristic stride, a signal of reliability in the chaos. "Status report, Dr. Hayes?" he inquired, his voice low, almost blending into the soundscape of beeping consoles and swirling fans. + +"We're on the brink of unravelling the signal's origin," Jordan replied, the weight of implications heavy in their tone. "There's intelligence behind it, a thought process alien to our own." + +As if summoned by their analysis, Taylor Cruz approached with authority radiating from every pore. "Understand this, we need to know if it's friend or foe. Don't get wrapped up in the existential—our lives may depend on the answers you provide." + +Sam Rivera, their hands adroitly adjusting a device to fine-tune the signal, chimed in with optimism undercut by anxious anticipation. "We're deciphering the comm encryption. Soon, we'll have a channel open—not just listening in, but speaking back." + +Alex nodded his understanding, his strategic mind processing the tactical implications while grappling with the more profound humanistic impact. "When we do, we'll tread carefully, communicate with purpose," he reassured the team. + +The operation had evolved rapidly, from a stealthy incursion into a clandestine labyrinth to an exchange with an extraterrestrial intellect. Their earlier trepidation transformed into determined focus, as they prepared to extend humanity’s hand into the vast unknown. + +An alert on one of the monitor stations snapped the team into alarm. The signal had not simply been waiting—it had been calculating. Now, it reached its crescendo, demanding their attention with a provocative urgency. + +Jordan's fingers raced over the keyboard, their eyes simultaneously interpreting data and sharing directives. "It’s a linguistic lock, a test of comprehension. We crack this, we establish dialogue." + +Taylor's presence was a beacon of steely resolve. "Then let’s solve it. This is what we trained for—the unknown." + +Alex and Sam exchanged a look that telegraphed their shared determination—this was not only the mission they had trained for; it was the mission they had been destined for. + +Together, the Paranormal Military Squad team leaned into the challenge, their minds honing in on the complex patterns with a singular goal: to unlock the conversation with an intelligence that had already begun to shift the foundations of what they knew, or thought they knew, about the universe. + +In a symphony of clicks and murmurs, they worked, knowing they were about to make a giant leap not just for themselves or Paranormal Military Squad, but for all of humanity. As the final pieces fell into place, Dulce's militaristic silence was shattered by the sound of intergalactic contact—by the sound of history being made. + +## Chapter 7 + +In the enclosed space of Dulce’s command center, the air was thick with anticipation, each team member poised to tread the razor's edge between scientific breakthrough and galactic peril. Dr. Jordan Hayes focused intently on the screen, their fingers tapping a staccato rhythm against the keyboard as lines of alien code cascaded down the monitor. + +Alex Mercer's steely gaze surveyed the room, stopping on each member of his team. "Thoughts?" he asked, echoing the unspoken tension. His question, while directed at the group, lingered on Jordan—acknowledging their expertise and inviting collaboration rather than dictating orders. + +Jordan’s brow furrowed, an indicator of the mental gymnastics being performed. "It's unprecedented," they finally said, their voice a testament to the gravity of the moment. "Behavioral algorithms... if we're right, this code could reveal extraterrestrial thought patterns." + +Before anyone could react, Taylor Cruz interjected with the assertiveness of someone accustomed to commandeering the discourse. "Then let’s ensure we’re deciphering it correctly," Taylor stated, their tone suggesting they were still battling to maintain control over an increasingly alien situation. + +Sam Rivera hovered near the mainframe, youthful energy barely contained under the surface. "What if it’s more than just a message? What if they’re trying to extend consciousness across the stars?" + +The room fell into a contemplative silence, broken only by the hum of electronic equipment and the distant thud of secured doors locking in rhythm. The weight of responsibility rested on each agent's shoulders—a heaviness palpable in the air they shared. + +Alex stepped forward, reaching a subtle decision, one dictated by foresight and the humanity nestled at the core of their mission. "We approach with the aim to understand, not to confront," he said, softening his military bearing into a more diplomatic stance. + +Jordan nodded, appreciating the leadership that Alex displayed in the face of the unknown, and turned back to the cryptic data. Here, before them all, was a tangible piece of evidence—proof of an extraterrestrial sentience that had outreached the bounds of their expectations. + +Taylor took a breath, simultaneously exuding a sense of preparedness and venturing into the unknown alongside their peers. "Then let’s do what Paranormal Military Squad does best—investigate and adapt," Taylor added, finding comfort in the familiar even as they stood on the cusp of an unprecedented alchemy of science and mystery. + +The team leaned into their respective roles, driven by the urgency of the assignment and the pull of an insatiable curiosity. Sam offered a grin that belied the tension, a youthfulness that reminded them all of the profound excitement nested within the terror of the unknown. + +Quietly but resolutely, they turned back to their instruments, each of them a sentinel on the threshold of a new reality. The once implicit lines of command were now woven into a shared tapestry of hierarchy and camaraderie. As they danced with the unknown, they were beacons of sentient endeavor, casting the light of human consciousness into the vast darkness that called to them. + +\* + +\* + +Dulce Base's cavernous darkness was pierced by the sharp luminescence of monitors, casting an electric glow onto the faces of those who dared to unearth its secrets. Dr. Jordan Hayes stood motionless, eyes glazed in concentration, their mind a nexus where terrestrial science battled with celestial unknowns. + +Alex Mercer watched from a slight distance, the weight of command tangible upon his shoulders, though lightened by the shared burden now held amongst them. "We could be on the frontier of a new kind of diplomacy," he mused aloud, giving voice to the moment's gravity. + +At those words, Jordan's trance broke. "If that's the case, then these communications," Jordan motioned to the stream of data, "are our olive branch across the cosmos." + +Taylor Cruz, who paced with restless energy, halted and faced the team—his stoicism marred by the erratic dance of lights reflected in his eyes. "An olive branch, or an invitation to a battlefield?" he posed, ever the strategist, his words laced with a hint of cynicism. + +Sam Rivera, nestled amongst an array of equipment, licked their lips—a mixture of nerves and anticipation palpable. "We're mapping out something incredible here. Whether it's peace or war, we're the cartographers." + +Silence enveloped them like the expanse of space itself, each member contemplating the chasms they might bridge—or the abysses into which they might unwittingly descend. + +Alex's demeanor assumed a quiet resolve—the profound knowledge that this mission was as much about navigating uncharted philosophical territories as it was about ensuring survival. "Whichever it proves to be, we'll face it. Prepared, unified." + +A nod passed between Jordan and Alex, a silent exchange of mutual respect and shared mission. Sam, buoyed by the weighty encounters of the mind and machinery, entered keystrokes with a fervor that seemed to bring them ever closer to the alien mind. + +They stood there, the Paranormal Military Squad team, not just as guardians of homeworld secrets or as soldiers of clandestine wars, but as humankind's chosen few at the fulcrum of history—a history that was now unfolding to the rhythm of otherworldly codes. + +Each revelation, each parsed symbol, inched them toward the line between the earthly and otherworldly. And as they stood on this precipice of cosmic negotiations, it was clear the ensuing dialogue would not just shape the future of Paranormal Military Squad—it could very well redefine the parameters of human existence. + +\* + +The hum of advanced computational systems tingling with cryptic transmissions framed the ambiance of Dulce's mainframe chamber. Jordan Hayes, fingers hovering over a console dense with blinking lights, furrowed their brow as sequences of alien data streamed across the screen. + +Alex materialized behind them, his presence a stable beacon amidst the technological whirlwind. "Look for patterns, anomalies. Anything that might resemble a handshake protocol in their communications," he directed, his voice a low thrum, reverberating with cautious optimism. + +Jordan cast a glance over their shoulder, acknowledging Alex's contribution with the shared understanding of colleagues who had transcended mere professional acquaintance. "I’m isolating sequences that seem to recur with more intention than static. If these are their ‘handshakes,’ then we might just be making first contact," they remarked, their focus returning to the screen with renewed vigor. + +From the other end of the room, where shadows married the artificial light, Sam's voice crackled through the static of nearby speakers, "Don't forget the anomalies we detected earlier. Each one could be a word, a sentence, or even a concept untranslatable to our current understandings." + +Resolute, Taylor Cruz stood at Jordan's other side, a stoic figure wrestling with the implications of their mission. "Keep pursuing this line," Taylor instructed, an undercurrent of intensity carried forth in their otherwise composed demeanor. "And remember, this isn't just about making contact; it's about securing knowledge for humanity." + +Alex offered a nod that spoke volumes, conveying his understanding of the stakes at play. Here, in this chamber of possibility, the team's actions would determine if humanity stood at the brink of a new age of understanding or the onset of an unprecedented threat. + +Every second thrummed with significance as Jordan and Sam worked in tandem, each keystroke a foray into the unknown. Taylor observed with a commander's scrutiny, the gravity of their role sustaining them against the waves of ambiguity breaking against their resolve. + +Pivotal moments come rarely in the course of human events but here, amidst the electronic symphony of a stalwart command center, lay the incepting notes of a cosmic overture. The harmony between human and alien, between Paranormal Military Squad and the vast reaches of space, began its first tentative measures, with each member of the team a vital instrument in a celestial ensemble yet to be fully heard. + +\* + +The crisp air within the mainframe room of Dulce base seemed to hum with unspoken possibilities. Jordan Hayes was the centerpiece of focus, their hands dancing methodically over the console as streams of otherworldly code cascaded down monitors, each flicker a potential key to the cosmic doors they were inching open. + +Alex Mercer watched, posture relaxed but eyes sharp. "Remember, this could be our first introduction, maybe even our first impression," he said, mindful of the gravity carried by each action they made henceforth. + +A hint of a smile touched Jordan's face, a small acknowledgment of the monumental task at hand. "Understood. I'm balancing the signal's syntax with our algorithms. If we're interpreting this correctly, it could be... well, an invitation." + +Into the electric tension of the chamber walked Taylor Cruz, their silhouette a sharp contrast against the cool lighting, radiating a presence that spoke of command and chilly tenacity. "An invitation, or a challenge?” Taylor questioned, the weight of their suspicion casting a different tint on the cascading data. + +Sam Rivera, in a corner arrayed with sophisticated equipment, piped up, their voice a buoyant note amidst the tentative atmosphere. "Either way, it's a connection. One that we're uniquely positioned to navigate," they remarked with an air of optimism threading through the uncertainty. + +Alex channeled the strengths of his team into the core of their approach, his leadership adapting to the contours of an unprecedented scenario. "Cautious and curious," he reflected aloud, shaping a strategy that balanced their thirst for comprehension with the prudence required in addressing the unknown. + +Jordan, hands momentarily at rest, looked up. The signal was more than a sequence of bits and commands—it was a riddle wrapped in the depths of space-time, and they were on the cusp of parsing its meaning. + +Taylor, hardly a step away, nodded in silent agreement. The implications of their findings might very well direct the course of human destiny from this point onward. + +Finding a tempo among themselves, the Dulce team was a confluence of ambition and acumen, each member intuitive to the beats of discovery. The chamber around them held untold stories, secrets coaxed from the stars, that now, led by Paranormal Military Squad's finest, began to unravel. + +The future in those moments was unwritten, a narrative scribed not in the dust of desert confines, but in the potential for interstellar diplomacy and understanding. As they prepared to script humanity's next chapter, the room seemed to pulse with the heartbeat of a story far greater than the sum of its parts. + +## Chapter 8 + +The grit of an earthbound dust storm contrasted sharply with the pristine sterility of the underground command center. Alex Mercer, eyes set with fervent determination, stood over Jordan Hayes, whose fingers danced across the keyboard with rapid purpose. Monitoring the progression of alien code unraveling before them, Mercer spoke with a tempered urgency, "Keep it steady, Jordan. We might be initiating the first true interspecies communication bridge here. It's all about finesse now." + +Taylor Cruz, the embodiment of military precision, surveyed the room with a calculated gaze from their vigil beside an array of glimmering screens. "Remember, these could be delicate negotiations -- or coded threats. Stay sharp," Cruz added, their voice cool as polished steel. + +Jordan, with a silent nod, recognized the gravity of both stances. Gravitating between scientific acuity and diplomatic caution, they replied, "The sequence is aligning—syncing with our comms. It's looking more and more like direct engagement." + +Amid the banks of electronic machinery, the thrumming pulse of an impending interspecies signal exchange, Sam Rivera interjected with a youthful zeal that cut through the weighty atmosphere, "It's not just an exchange. It's a... symphony. It's as if they're teaching us their language through modulation." + +A moment of profound silence swept over the team. The isolation of their location, deep within the top-secret labyrinth of Dulce, became suffused with an almost palpable sense of historical significance. + +"Then our response needs to be equally symphonic," Alex uttered, contemplating the awe-inspiring transmutation of their task from a simple recovery mission to a full-blown cosmic concerto. + +With a renewed sense of wonder tempered by caution, the Paranormal Military Squad team found themselves harmonizing a delicate balance between envoys and interpreters. The long shadow cast by their duty was now illuminated by the brilliant glow of otherworldly dialogue. + +In this carefully orchestrated march towards the unknown, each individual's expertise became critical notes in a larger melody. The narrative of human achievement, so often defined by solitary pursuits, now emerged as a collaborative opus, each member of the team a maestro in their right. + +The protocols of encounters, the mathematics of languages, and the poetics of connection all fused into a singular moment of convergence. The echo of their efforts reverberated back to them, not through the cavernous base's concrete walls, but from light-years away, in the form of a reply, intangible yet infinitely profound. + +\* + +Amidst the hum of the supercomputers and the faint static from the scrambled transmissions, Alex Mercer cast a thoughtful glance across the dimly lit room toward where Dr. Jordan Hayes was methodically adjusting the archaic dials of the decryption machine. "Any progress?" he asked, his tone conveying both impatience and the deep-seated respect born from countless shared challenges. + +Jordan did not look up, their gaze remained locked on the flickering lights that represented a dialogue suspended between worlds. Their fingers ceased their dance, hovering meditatively over the controls. "We might be on the cusp of a breakthrough," Jordan suggested. "The signal... it's evolved. It's reflexive now, responsive in a way that suggests sentience." + +Taylor Cruz's familiar sharp strides approached the two, breaking the rhythm of soft beeps. "Responsive is good, if it means understanding," Taylor said, head tilted as they peered at the encryption data scrolling by. "But remember, comprehension can bring revelation or conflict." + +Sam Rivera’s youthful voice permeated the tension, brimming with an excitement edged by the enormity of what they faced. "If it's truly sentient, we're not just cracking a code; we're learning how to converse with an entirely new form of consciousness," they chimed in, the weight of history not lost on the zealous astrotechnician. + +Alex nodded, his thoughts alighting on potential strategies for navigating the conversation they were cultivating with the unfathomable. "We need to keep that conversation going, echo its patterns, and speak its language," he resolved, knowing the delicate nature of their work merited every ounce of their collective acumen. + +The chamber now was a crucible, forging within it the future narrative of human contact with the unknown. Every signal pulse they sent out was an invitation for understanding, and every echo back a step closer to bridging the cosmic divide. And so, together, they stood - agents in Paranormal Military Squad's clandestine ranks, united by purpose, sculpting humanity’s first sonnets into the void. + +\* + +#### Knowledge graph updates + +- (Jordan Hayes, Interprets, Communications as cosmic diplomacy, Moderate) + +- (Taylor Cruz, Questions, Potential aggressiveness of alien intent, Minor) + +- (Sam Rivera, Expresses, Optimism about forming a connection, Minor) + +- (Alex Mercer, Adopts, Balanced strategy for contact, Moderate) + +- (Paranormal Military Squad team, Navigates, Beats of cosmic discovery, Moderate) + +- (Paranormal Military Squad team, Prepares, To script humanity's interstellar narrative, Major) + +## Chapter 9 + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +Dr. Jordan Hayes, whose hands had been steadfastly working the decryption algorithms, paused and looked up at Alex. "We're through the next layer of encryption," Jordan announced, a mixture of pride and gravitas in their tone. "It's communicating. It's... aware." + +A shadow momentarily clouded Alex's determined features—awareness implied so much more than mere intelligence. "Aware and reactive or aware and proactive?" he queried, his experience anticipating the pivotal importance of intention. + +"Unknown at this stage," Taylor Cruz interjected, looking up from a datasheet. "But I urge caution. We tread the line between breakthrough and disaster with each keystroke." + +Sam Rivera, ever the source of technological acumen, added their voice to the conversation. "The signal's adapting every time we interact with it. Like a conversation where both parties are learning each other's language in real time." + +Alex leaned in, rested a hand on Jordan's shoulder—a sign of companionship and an affirmation of trust. "Keep the communication channels open. But let no message, no pulse go unchecked. This could be our Rosetta Stone or our Tower of Babel." + +Silence fell over them, a momentary lull as each member of the team contemplated the historic weight of their task. Yet, it was impregnated with a tangible sense of excitement—a collective energy that thrummed through the air just as palpably as the electric current through the banks of machines surrounding them. + +They continued their work, squaring shoulders against the magnitude of their undertaking. The agents were standing not just at the precipice of a new chapter for Paranormal Military Squad but for all of humanity. For now, they communicated with powerful unknowns, but with each exchange, they were etching the first words of a dialogue that might forever alter humanity's place in the cosmos. + +\* + +\* + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +Dr. Jordan Hayes, whose hands had been steadfastly working the decryption algorithms, paused and looked up at Alex. "We're through the next layer of encryption," Jordan announced, a mixture of pride and gravitas in their tone. "It's communicating. It's... aware." + +A shadow momentarily clouded Alex's determined features—awareness implied so much more than mere intelligence. "Aware and reactive or aware and proactive?" he queried, his experience anticipating the pivotal importance of intention. + +"Unknown at this stage," Taylor Cruz interjected, looking up from a datasheet. "But I urge caution. We tread the line between breakthrough and disaster with each keystroke." + +Sam Rivera, ever the source of technological acumen, added their voice to the conversation. "The signal's adapting every time we interact with it. Like a conversation where both parties are learning each other's language in real time." + +Alex leaned in, rested a hand on Jordan's shoulder—a sign of companionship and an affirmation of trust. "Keep the communication channels open. But let no message, no pulse go unchecked. This could be our Rosetta Stone or our Tower of Babel." + +Silence fell over them, a momentary lull as each member of the team contemplated the historic weight of their task. Yet, it was impregnated with a tangible sense of excitement—a collective energy that thrummed through the air just as palpably as the electric current through the banks of machines surrounding them. + +They continued their work, squaring shoulders against the magnitude of their undertaking. The agents were standing not just at the precipice of a new chapter for Paranormal Military Squad but for all of humanity. For now, they communicated with powerful unknowns, but with each exchange, they were etching the first words of a dialogue that might forever alter humanity's place in the cosmos. + +\* + +Alex Mercer's eyes were fixed on the monitors, the reflected light casting an ethereal glow across his stoic face. The room buzzed with tension, a cacophony of low hums and electronic beeps that underscored the historic nature of their actions. He moved to where Dr. Jordan Hayes was immersed in their work, scrutinizing the alien code streaming rapidly down the terminal. + +"Find anything that might look like an entry point or a... digital handshake?" Alex asked, his voice steady, betraying none of the tension gripping his chest. + +Jordan looked up briefly, their expression weary yet intense, "Potentially. It's as if the code is anticipating our input, modifying itself in real-time. I've never seen anything like it." + +From across the room, Taylor Cruz's sharp voice cut through the hum. "Then it's learning or, possibly worse, baiting us. Proceed with extreme caution," they commanded, their firm stance reinforcing the gravity of the situation. + +Sam Rivera, surrounded by a cascade of screens and interfaces, added, "It's almost organic in its complexity. Any minute now, and I might have a way in." + +A slight nod was Alex's immediate response, his mind racing through the potential scenarios. "Everyone, stay alert. This could be the beginning of something profound." His seasoned eyes never left the unfolding drama on the monitors. + +The room fell silent, the air heavy with unspoken questions. Were they mere moments away from unlocking an otherworldly dialogue? Or was it a Pandora's box that, once opened, could not be closed? + +Alex moved closer to the main console, his fingers hovering over the command keys. With the precision of a maestro orchestrating a symphony, he communicated silently with Jordan – respectful of their expertise, aware that the next move could alter the course of human history. + +Jordan met his gaze, nodding sharply, and refocused on the task. The signal seemed to pulse with sentient curiosity, drawing them further into its intricate web. + +A sudden flurry of alerts and the intensifying glow of monitors heralded that they had bridged a technological chasm. The alien intelligence on the other end was no longer a distant enigma – it was an active participant, responding to their digital overtures with an unknown agenda. + +The team's meticulous efforts had led them to a momentous threshold. Beyond lay unprecedented contact – a nexus of curiosity and potential peril. Within the confines of the base, against the backdrop of a silent desert night, the Paranormal Military Squad operatives became mediators of Earth's bid for cosmic relevance, their every action now a gesture in the grand dance of intergalactic relations. + +## Chapter 10 + +The corridors of the Dulce military base, now silent, echoed with a history of whispered conspiracies and furtive movements. But in the command center, a delicate tapestry of light and sound was being woven as the echoes of cosmic dialogue resonated through the high-tech enclave. Dr. Jordan Hayes, now leading the efforts, called out from their workstation, "I’ve isolated the signal's harmonics. It's more than a call; it's a song, an interstellar siren’s call." + +Alex Mercer, steady and resilient in the face of the incomprehensible, acknowledged with a quiet nod, "A song that we need to learn—quickly." His eyes, heavy with responsibility, scanned the room, watching his team work tirelessly at the intersection of science and speculation. + +Sam Rivera, dulled by fatigue yet driven by unshakeable resolve, manipulated a complex array of audio interfaces. "There's a pattern, a repeating motif. It's structured, intentional," they muttered, their revelation a bridge between the known and the unimaginable. + +Taylor Cruz, a figure of central authority, paced the length of the room, their usual unflappable demeanor betraying a rare flicker of apprehension. "We should be wary of the sirens’ call," Taylor interjected, invoking myths of old as a cautionary metaphor. "We don't want to crash upon unseen shores." + +Undeterred, Jordan cast a determined glance at the team. "We navigate by starlight now, not by the limited light of our previous understanding." Their voice was a beacon, charting a course through unchartered realities. + +Every individual was acutely aware that each moment in that room was a conduit to an epochal shift for civilization. The mysterious signals, once distant and alien, had coalesced into complex and harmonious oscillations—beacons of an extraterrestrial intellect inviting Earth to join in a cosmic consortium. + +Silently, Alex approached the mainframe, his trained fingers aligning with the console’s mechanisms. The room watched in collective breathlessness as he set the frequency in motion, an introductory phrase to an otherworldly melody—a symphony that could bind worlds or spell devastation for all they knew. + +In the control room of Dulce, amongst whispered legends and the quiet hum of machines, humanity's ambassadors now stood, stretching their hands into the void, reaching for the hand that would either pull them into the light of new stars or into the maw of darkness between them. + +\* + +Underground, the Dulce facility's command center was awash with frenetic energy, a stark juxtaposition against the silent, decrepit corridors that enveloped them. The air hummed with anticipation as Dr. Jordan Hayes and Alex Mercer hunched over a console. The sterile light from the monitors cast an otherworldly glow upon their faces, now reflecting a mosaic of alien characters rapidly translating across the screen. + +"The patterns are evolving," Jordan murmured, concentration etched into their every feature. "It’s as if our attempts to decrypt have accelerated its learning. It’s adapting to us." + +Alex, who stood steadfast behind Jordan, felt a tinge of uncharted fear quickly quelled by the fire of discovery raging within him. "Keep it up," he urged. "But whatever this is becoming, we need to ensure it remains within our control." + +Taylor Cruz interjected, their voice slicing through the buzz of activity. "Control may be an illusion when facing an intelligence that literally writes its own rules," they stated stoically, casting a watchful eye over the flurry of data. + +"It's like it's learning to communicate," offered Sam Rivera from a nearby interface, their youthful energy boding a mix of awe and anxiety. "This gives ‘talking to strangers’ a whole new meaning." + +Alex surveyed his team—each face a study in concentration, determination, and not a small measure of trepidation. "This might well be our first contact," he acknowledged, "And we need to be ready for whatever answers back." + +Together, they stood on the edge of the unknown, forging humanity’s response to a message from the heavens. The ensuing silence was palpable—a collective introspection about their role in this grand cosmic play, one that could rewrite human history. + +The encrypted dialogue continued to unfold, its intricate patterns showing an almost uncanny anticipation of their investigative strategies. The air turned heavy with the scent of electricity and ambition as they closed in on a pivotal response. + +As the signal’s intelligence—whether artificial or biological—grew more profound, so too did the realization that their mission had morphed from passive observation to active engagement. There was no turning back now. Each agent embraced their part in the delicate dance of an interstellar exchange that could change everything they thought they knew about life, intelligence, and the dark void beyond Earth's atmosphere. + +\* + +The underground halls of Dulce Base, usually buzzing with covert operations, now thrummed with a different kind of energy, an electric mix of fear and fascination. At the heart of the base, in a room shielded from the world’s eyes, Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera huddled around a bank of monitors. Each screen flickered erratically with the alien script that had become the center of their lives—and perhaps the pivot on which humanity’s future would turn. + +Jordan's eyes never wavered from the displays, their expression was one of rapt concentration, interspersed with flashes of revelation. "We're conversing with the stars," they whispered, almost to themselves. The words hung in the air, a testament to the awe-inspiring strangeness of the situation. + +"The language is morphing; changing its structure with every exchange we have," Sam chimed in, enthusiasm tinged with the solemnity of the occasion. "It's like witnessing the birth of a new form of dialogue—one that spans galaxies." + +Taylor, despite the situation's precariousness, maintained an appearance of ironclad composure. "Keep the communication stream secured and monitored. We don't know what we're dealing with yet," they reminded the team, a bastion of protocol amidst uncertainty. + +Alex watched his team expand the parameters of human achievement; their work here would possibly define an era. "This is untrodden territory," he acknowledged, "and in every word we script, in every response we decode, we're drawing a map that others will follow." + +Jordan turned to Alex, a nod acknowledging the shared responsibility of this moment. They had embarked on a new voyage, an odyssey not of the body, but of the intellect and spirit. No longer explorers of the Earthly realm, they had been promoted by circumstance to ambassadors of humanity in a silent and boundless ocean. + +A sudden pulse of energy from the monitors signaled a breakthrough; the language had not only adapted but it seemed to resonate, to harmonize with their attempts at making contact. The alien script now sprawled across the screens didn't just ask to be understood—it invited interpretation, collaboration, maybe even companionship across the cold distances of space. + +As they stood before the precipice of first contact, Paranormal Military Squad's finest became the architects of a symphony meant to echo through the cosmos. But more than architects, they were the first to play the notes of this cosmic composition, daring to believe that on the other end, someone—or something—might be listening, ready to join the chorus. + +\* + +The underground command center of Dulce Base, once pulsing with clandestine operations, now resonated with the charge of an impending cosmic threshold. Encircled by banks of whirring machinery, each monitor flickered erratically with alien script that had occupied center stage in the lives of Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera. + +Jordan's gaze didn’t flit for even a moment from the screens, where indiscernible alien messages ebbed and flowed like the tide. The ciphers and symbols cascaded down as they tweaked the algorithmic sliders. "This sequence here," Jordan began, voice both hushed and heavy, "it’s not just transmitting; it resonates—it's designed to be felt." + +The room took a collective breath, the remarkable implication hanging in the air like a careful revelation. Sam Rivera was the first to respond, their voice alive with ingenuity: "It's a form of communication stretching well beyond words. We need to respond in kind—the whole array of human expression might be at play here." + +Taylor's eyes remained fixed on the figures playing across the data sheets. "If that's the case," Taylor intoned pragmatically, "we must tread carefully. This is no longer just about being heard—it's about being understood." + +Alex watched his team, each a fulcrum of insight and expertise, and felt the solemnity of the role they were about to assume. "Then we'll ensure our message is clear and full. Our humanity is our strength in this dialogue," he declared, the depths of his experience fueling a commanding reassurance. + +The anticipation was palpable as the agents contemplated the vastness of their endeavor. They were not merely probing at the secrets of the planar cosmos—they were negotiating across the starry expanse, extending to distant intelligences the full spectrum of human curiosity and compassion. + +A symphony of beeping consoles orchestrated their next steps as they prepared to articulate their interplanetary overture. The rhythmic tapping of Jordan's keystrokes set the tempo for an undertaking that traversed beyond algorithms and encryption. + +The base withstood time and whispered secrets of its own, but none so grand as this moment of creation—an invitation to the universe that promised to echo through both the echoes of space and the annals of human history. + +## Chapter 11 + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +\* + +The thrum of the colossal machinery vibrated through the subterranean facility as Alex Mercer stood amidst the whispers of technology, each carrying voices from worlds apart. He watched as Sam Rivera adjusted a complex array of cosmic translators, their expression a mixture of anticipation and awe. + +"Are we ready, Mercer?" Taylor Cruz asked, the soft glow of the command center consoles reflecting upon their stern face. + +Alex turned towards Taylor, his eyes holding a depth that betrayed the enormity of the threshold they were about to cross. "This is it," he said. "Initiate the protocol. It's time we answer the cosmos." + +Jordan Hayes, stationed at the mainframe, typed rhythmically, a blue hue painting their focused features. The eerie silence that had settled over the team was interrupted by a visceral sound—humankind's response to the alien dialogue, now streaming into the abyss. + +The control room, once a fortress of solitude, erupted into an oasis of life. Lights flickered in tandem, echoing the symphony of interstellar communication. They stood together at the edge of discovery, facing the symmetry and discord of a universe unknown. + +"If we're right, we've just become Earth's first emissaries to a celestial congress we're only beginning to comprehend," Jordan's voice was somber, resonating with a mix of trepidation and honor. + +The room filled with the resonance of human and alien minds converging, creating a new narrative within the fathomless expanse of existence. Paranormal Military Squad, once protectors of Earth's clandestine secrets, had now become the tether linking humanity to the cosmic fold. + +\* + +The underground command center of Dulce Base, once pulsing with covert operations, now resonated with the charge of an impending cosmic threshold. Encircled by banks of whirring machinery, each monitor flickered erratically with alien script that had occupied center stage in the lives of Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera. + +Jordan's gaze didn’t flit for even a moment from the screens, where indiscernible alien messages ebbed and flowed like the tide. The ciphers and symbols cascaded down as they tweaked the algorithmic sliders. "This sequence here," Jordan began, voice both hushed and heavy, "it’s not just transmitting; it resonates—it's designed to be felt." + +The room took a collective breath, the remarkable implication hanging in the air like a careful revelation. Sam Rivera was the first to respond, their voice alive with ingenuity: "It's a form of communication stretching well beyond words. We need to respond in kind—the whole array of human expression might be at play here." + +Taylor's eyes remained fixed on the figures playing across the data sheets. "If that's the case," Taylor intoned pragmatically, "we must tread carefully. This is no longer just about being heard—it's about being understood." + +Alex watched his team, each a fulcrum of insight and expertise, and felt the solemnity of the role they were about to assume. "Then we'll ensure our message is clear and full. Our humanity is our strength in this dialogue," he declared, the depths of his experience fueling a commanding reassurance. + +The anticipation was palpable as the agents contemplated the vastness of their endeavor. They were not merely probing at the secrets of the planar cosmos—they were negotiating across the starry expanse, extending to distant intelligences the full spectrum of human curiosity and compassion. + +A symphony of beeping consoles orchestrated their next steps as they prepared to articulate their interplanetary overture. The rhythmic tapping of Jordan's keystrokes set the tempo for an undertaking that traversed beyond algorithms and encryption. + +The base withstood time and whispered secrets of its own, but none so grand as this moment of creation—an invitation to the universe that promised to echo through both the echoes of space and the annals of human history. + +## Chapter 12 + +The underground facility of Dulce Base, once shrouded in silence and operational secrecy, now hummed with an energy that cradled the promise of cosmic revelation. Alex Mercer stood pensively by the central terminal, flanked by Dr. Jordan Hayes, Taylor Cruz, and Sam Rivera, each poised at the edge of a history-defining moment. + +Jordan's fingers ghosted across the console, tracing patterns of otherworldly origin. "The signal’s architecture is becoming more complex, resembling aspects of human cognition—recognition, learning, even... empathy?" they postulated with furrowed concern. + +Alex turned his gaze upon Jordan, his voice quiet but resolute, "Empathy could bridge galaxies. Let's harness this connection and proceed with cautious optimism." + +Taylor, ever the sober sentinel, projected a more pragmatic standpoint. "Empathy or not, we are duty-bound to assess the risk to humanity. Every new discovery warrants a measured response." + +The static hiss of communications equipment filled the air, its purpose now transformed into a dialogue with an intelligence beyond the stars. It was Sam, wide-eyed amid the myriad lights and switches, who broke the silence, "We have provisional confirmation of the signal’s intent—initiation. We’re being brought into a broader spectrum of cognizance." + +The chamber lay still for a heartbeat, the Paranormal Military Squad agents steeped in contemplation of the path unfurling before them—a path paved with possibilities of diplomacy or disruption, each step a venture further into the cosmic unknown. + +Alex stepped closer to the viewing monitors, each depicting alien symbols seemingly reaching out from the void. "Initiate the broadcast," he spoke with quiet command. "Our response will mark humanity’s readiness to partake in the wider conversation of conscious beings." + +Amidst the crackling air of expectation, the team wordlessly returned to their stations. They had transcended their roles as protectors of Earth's clandestine lore to become the harbingers of an interstellar parley that could change the existential course of life on their pale blue dot. + +The deep hum of the terminal emitted a signal—a testament to the uncanny reality that Earth was now actively partaking in an exchange not bound by gravity nor the limits of the solar wind. + +Here, in the depths of Dulce, a message from humanity woven from understanding and uncertainty was cast into the firmament, an epitheg of their desire to join the universal dialogue and discover their place among the constellations. + +\* + +The somber depths of the Dulce Base command center stood in stark counterpoint to the animated flurry of activity around the central comms array. Alex Mercer's silhouette loomed behind Dr. Jordan Hayes, who sat with a posture indicating laser focus on the decryption process. A quiet murmur of digital soundscape filled the space, subtly heightened by the anticipation of contact with an intelligence beyond the Earth. + +Jordan's voice was steady, betraying none of the extraordinary nature of their work, "Looking through the signal's pattern, it's evident we’re dealing with a form of intelligence—calculating, mirroring, possibly even understanding." + +Alex's reflection bounced off the darkened screens, his head nodding in silent affirmation. "We’re walking a delicate line. Our response should be thoughtful, measured. We’re ambassadors, not merely explorers." + +Taylor Cruz approached, arms folded, their words slicing through the din of careful keystrokes and soft whirrs, "If there’s even the slightest chance it understands, we can’t afford missteps. The language of the stars might be more absolute than ours." + +From another terminal, Sam Rivera brought youthful vigor to the conversation, "There’s rhythm in these patterns. If this is their way of reaching out, our reply should encapsulate all that we are—all that humanity stands for." + +Looking around at his team, Alex saw resolve etched on every face. The chamber, usually somber and echoing with the quiet steps of covert agents, now felt alive with the heartbeat of discovery. They were not just professionals operating in the gloom; they were a collective standing at the helm of a momentous journey. + +"Let’s begin," he said, returned by the resolve in his voice. "Every second counts." With that, they pressed forward, setting in motion a reply to a conversation billions of years in the making. + +The dance with an unseen partner commenced, each pulse they sent out a step taken with caution and hope. And as those digital pulses journeyed through the black sea of infinity, Earth, for perhaps the first time, joined a pan-galactic dialogue that whispered secrets of the cosmos—secrets that, until now, had been lost in the silent vastness of space. + +\* + +As the team stood in the centralized nerve center of Dulce's underground fortress, the solemn atmosphere was reverent, overseeing systems that engaged with an intelligence from the void. Alex's stance was contemplative as he gazed at Jordan Hayes, who presided over the console, the tension of the moment reaching a tactile fervor. Each rhythmic tap of Hayes's fingers on the keys was a foray into uncharted symphonies of contact. + +Observing Hayes unravel the dense alien encryption, Alex spoke, a diplomatic tenor underpinning his words, "Keep focused on the syntax, dissect its nuances. We're not just decoding signals; we're translating intentions." + +Without diverting from their task, Jordan acknowledged the insight. "Indeed, if their understanding of us is as deep as we hope, we're paving the way for dialogue far beyond our current realm." + +Taylor Cruz, near the rear of the room, provided a steady oversight. "As horizonless as our prospects may seem," Taylor intoned, "remain diligent. Complacency before alien cognition could spell catastrophe." + +Sam's youthful voice resonated with optimism, "Imagine—forming a rapport with a consciousness separate from our reality; we're drafting the bridge to stars alive with minds!" + +The sentiment hung for a moment before Alex gathered his conviction. "Dialogue is our vessel. We are not just agents of enigma; we are the threads that may weave a new cosmic relationship." His words seemed to reflect off the walls, reaching beyond the room's confines, a quiet yet resilient vow. + +Their task was titanic, stepping stones laid delicately into new territories of existence. The signal, once an esoteric strand in the echo of the universe, beckoned now with a clarity rocketing the complexity of thoughts from a distant order. + +Action by action, the Paranormal Military Squad team bridged the vast interstellar distances, their expertise and empathy casting a beacon of unity into frontiers of intelligence and knowledge. Their work, a partnership struck with an unseen cosmic congregation, each pulse sent and received a line in Earth's novitiate envoi to the cosmic shores. + +\* + +Under the stark, unforgiving lights of Dulce Base's underground command center, tension buzzed harder than the banks of supercomputers that lined the walls. Agent Alex Mercer leaned over the shoulder of Jordan Hayes, whose eyes were locked onto the display screen, where an incomprehensible series of alien symbols streamed past incessantly. + +“Any progress on the decryption?” Alex's voice was steady, a controlled presence necessary in the gravity of their undertaking. + +Jordan tapped a key, pausing the flow of code, and leaned back with a deep sigh. "We've broken through another subset of the cipher. It's revealing... well, indications of a complex society, not unlike our own." His eyes met Alex's with an unspoken question that hung heavily between them—were they truly prepared for what they might find? + +Taylor Cruz strode into the room, a tightly coiled spring of ambition and authority, and peered at the screen. "Understand their society, and we may predict behavior. Remain expedient—we don't know how much time we have before the situation shifts." There was an edge of stark realism to Taylor's words, the underlying message clear: every revelation bore its own set of risks. + +Alex nodded thoughtfully, recognizing the validity of Cruz's caution. Turning to Sam, who was tinkering with a device that buzzed quietly on the table, he asked, “Sam, can your contraption get us any further?” + +Sam looked up with a smirk, a twinkle of mischief in their eye. “It’s not just any contraption, it’s potentially a direct line to their thoughts. Give me a moment more, and I'll have something for you.” + +The air ticked with electronic beeps and the rustling sound of the Paranormal Military Squad team at work. They were so close to peering into the intelligence of an alien race—a reality on the brink of dramatically expanding their understanding of the universe. + +The machinery whirred in response to Sam’s precise touches, and suddenly, the room filled with a low hum—something had changed, a signal had been successfully sent. The team held their breath as they listened. The sound that filled the room was unmistakable: a response, an alien voice filtered through the static of space and time. + +Alex exchanged a look of quiet triumph with Jordan. The breakthrough was monumental; they were no longer casting messages into the void but engaged in a dialogue—an exchange that marked the beginning of Operation: Dulce’s true unfolding. This was it, the first steps into an interstellar odyssey that demanded every ounce of their courage and wit. + +## Chapter 13 + +Dr. Jordan Hayes shuffled a stack of papers, their eyes revealing a tinge of skepticism at Taylor Cruz's authoritarian performance. _Protocols_, Jordan thought, _are just the framework, the true challenges we're about to face lie well beyond the boundaries of any protocol._ They cleared their throat before speaking, tone cautious yet firm, "Let's remember, the unknown variables exceed the known. We should remain adaptive." + +A murmur of agreement echoed from Sam Rivera, who leaned forward, lacing their fingers together as if weaving a digital framework in the air before them, "Exactly, adaptability could be the key to interpreting the signal distortions and system malfunctions. We shouldn't discount the… erratic." + +Their words hung like an electric charge in the room, challenging Taylor's position with an inherent truth. Cruz’s jaw tightened almost imperceptibly, but the agent masked it with a small nod, conceding to the omnipresent threat of the unpredictable. + +Alex glanced at Jordan, who never looked back, their gaze fixed instead on a distant point, as if envisioning the immense dark corridors they were soon to navigate in Dulce. Jordan was not one to embrace fantastical theories, but the air of cautious calculation betrayed a mind bracing for confrontation with the inexplicable, an internal battle between the evidence of their research and the calculating skepticism that kept them alive in their field. + +The meeting adjourned with no further comments, the team members quietly retreading the paths to their personal preparations. Alex, trailing slightly behind, observed the others. _The cautious reserve Jordan wears like armor doesn't fool me_, he thought, _their analytical mind sees the patterns I do. And that's worth more than protocol. That's the connection we need to survive this._ + +As the agents dispersed into the labyrinth of the facility, lost in their thoughts and preparations, the base's halogen lights flickered, a brief and unnoticed harbingers of the darkness to come. + +\* + +The gritty, wind-tossed surface of New Mexico, just above the cavernous domain of Dulce Base, offered no shelter from the burgeoning storm—the scouring sands an earthly reminder of chaos theories in motion. Far beneath, a similar maelstrom brewed within the confines of the command center, as Paranormal Military Squad's handpicked squad stood poised for potential enormities of contact. + +Ruffling through printed transmission logs, Jordan Hayes dialed the focus of their analytical prowess onto the emerging pattern of signals crisscrossing between Earth and the unfathomable. "Our responses so far have echoed their complexity, but the real divergence is yet to come," Jordan remarked stoically, the calm belying the mounting surge of adrenaline for the revelation ahead. + +Alex Mercer's figure, a silhouette sharpened by the purpose, loomed at the periphery of the monitors' sickly glow. "Indeed," he assented, "The echoes are the easy part. It will be the introduction of our own, human variable that truly begins our dialogue." + +Taylor Cruz, windowless command center notwithstanding, appeared as though they could feel the tempest above. Their eyes never left the monitors as they unspooled their hard wisdom. "For all our advances, we find ourselves deciphering the swings and nuances of an interstellar pendulum. Predict its arc, and we may preempt the gravity of its message." + +Amidst a chorus of bleeps and static, Sam Rivera's tech-clad hands moved rhythmically, their spirited approach to unruly streams of data bordering an intimate dance with entropy. "Entropy that leads to discovery," Sam mused, responding to Taylor's metaphor. "Each step into the unknown is a step away from precedent." + +Alex, drawing near Jordan, spoke again, his voice now a thread woven through the very fabric of their operations. "Let's be the cartographers of this new territory. Our initial shades of understanding could color the cosmos for generations to come." + +Their gazes fell upon a screen as the latest transmission painted its digital blooms of alien script across the black. This time, the pattern wavered in an almost imperceptible fashion, a modification that whispered of active, alien thought awaiting their next move. A hush enveloped the Paranormal Military Squad ensemble, the gravity of the pathogen undeniable. They were about to issue a reply, one poised to reshape the very concept of humanity's outreach into the cosmos. + +The New Mexico desert's secrets were infamous, its storms a mere prelude to the revelations that the team—united in purpose—would unleash upon the world. The howling winds outside found their counterpart in the newfound resolve within, as Dulce's stalwart guardians readied themselves to send forth humanity's retort to the echoes from beyond. + +\* + +The cavernous control room, deeply entrenched beneath the desolate New Mexico terrain, held the Paranormal Military Squad team in intense focus; an island of calm amid the storm of cosmic dialectics. Dr. Jordan Hayes worked methodically, every keystroke an intricate step in their tenuous cosmic ballet. Suddenly, they paused, a signal pattern resonating from the screen. "This is new; it's...inviting. It’s as if the signal is not just calling to us but weaving its intelligence through ours." + +Alex Mercer scrutinized the shift in data. "A confluence of minds, then. If we're to meet them halfway, Jordan, our reply must be both innovative and discerning," he proposed, a glimmer of profound curiosity behind his authoritative demeanor. + +Taylor Cruz, whose sharp eyes missed nothing, nodded from beside a secondary panel. "Innovative, yes, but also defensive. This interaction is a razor’s edge, and we cannot afford to bleed before the unknown," Taylor reminded them, the metaphor a stark warning of potential dangers. + +Against the backdrop of their conversation, Sam Rivera’s youthful optimism cut through the tension. "If they’re weaving through our intellect, then we've achieved something beyond first contact—we're at the genesis of interstellar symbiosis," they posited with a mix of reverence and excitement. + +Alex returned Sam’s smile with his own, tempered and faint, as he turned back to the task at hand. The magnitude of their mission extended beyond the fabric of the universe, an exploration into the threads that connected sentient beings across the vast expanse. “Let’s reply with our own woven tapestry of thought—delicate, but deliberate.” + +With renewed determination, the room came alive with an undercurrent of anticipation, its occupants charged with the potential of forging an alliance with the cosmos. Paranormal Military Squad's finest were no longer merely soldiers and scientists; they had become pioneers on the vanguard of humanity’s greatest odyssey. + +The New Mexican sands above, impassive to the change brewing underneath, stood as silent sentinels as Earth's emissaries crafted their response. A response that, composed with care and imbued with humanity's essence, reached into the void, connecting with an otherworldly intelligence that awaited their harmony in the cosmic conversation. + +## Chapter 14 + +The command center of Dulce Base lay shrouded in shadows that seemed to claw at the edges of the dimly lit array of screens and consoles. Alex Mercer, focused and unwavering, watched as Dr. Jordan Hayes parsed the latest string of alien signals—a symphony of otherworldly communications that threatened to either enlighten or confound. + +"We’re encountering a paradigm shift with every transmission," Jordan Hayes murmured, the pulsing glow of the monitor painting their features with an almost spectral hue. "This signal... it’s evolving, becoming denser, more sophisticated. As if it's growing alongside us—tandem evolution." + +The air was electric, charged with the raw potential of uncharted discovery and laden with the gravity of existential risk. Taylor Cruz, who always seemed here to mold such gravity into actionable strategies, stepped forward. "We must contain this evolution within parameters we can manage. We cannot be bystanders to an uncontrolled ascent of intelligence." + +Sam Rivera, the youngest of the cohort, worked feverishly at their station. "It's not just intelligence—these signals have rhythm, a kind of music suggesting not just evolution, but a dance! We're being invited to partake in the cosmos's ballet!" they exclaimed, a touch of youthful exuberance breaking through the solemnity. + +Alex turned, facing his team, the stoic mask of command tempered by the perceptible flicker of awe in his gaze. "Let this dance then be our dialogue. We will match their steps with prudent but daring measures—our humanity as our guide." + +In the ensuing hours, the Paranormal Military Squad team forged a rhythm of their own, their collective expertise a beacon piercing through the fog of the unknown. The signal, increasingly intricate and seemingly conscious, now demanded not just observation but participation, an interstellar pas de deux that hummed with the promise and peril of first contact. + +Before them, the communications interface flickered to life with a received transmission—a resonant hum that seemed to vibrate through the very foundations of the base. They had successfully established a back-and-forth with whatever intelligence lay hidden among the stars. Every subsequent note they struck within the cosmic ether would come to define humanity's place within the galactic community—heralds of Earth's grand entrance into a universe far less silent than once perceived. + +\* + +In the concrete belly of Dulce Base, dimly lit by the jagged dance of fluorescent lights above, Sam Rivera perched on the edge of their seat, their eager fingers fluttering across an ancient keyboard. The stark, cold room—reminiscent of a time when covert operations and unspoken dread ruled supreme—now housed a peculiar blend of old-world machinery and sleek, modern interfaces. + +Alex Mercer, standing steadfast like a bridge between the enigmatic past and the unfathomable present, watched on. In his eyes flashed the foreboding excitement of change. "Sam," he started, his voice steadfast, "the patterns in these signals, what do they tell us about the nature of our... guest?" + +Sam's eyes glimmered with something akin to thrill—or was it trepidation? "It's like we're mirroring each other, evolving together through this.. dialogue. Like it knows us, understands us, and it's… learning." + +Jordan Hayes, preoccupied at a nearby console, chimed in without lifting their gaze. "It's a dialogue that transcends mere words, Alex. We're being woven into a narrative far grander than the sum of our known sciences." + +Taylor Cruz, arms crossed, wore the heavy mantle of their skepticism comfortably. "Keep theorizing," they interjected crisply, "but remember the grounding reality of what we are part of here. This contact is a blade that cuts both ways." + +In this cavern of history, voices both human and inhuman whispered secrets to those brave enough to listen. Each member present understood the gravity that pulled at their feet; no longer were they mere mortals shackled to their terrestrial plane. The digital pings and encrypted calls resonated with an implication of a cosmic agenda that would not be ignored. + +Jordan's fingers paused, hovering in hesitation. What ripple might the next keystroke send through the fabric of known existence? It was a step into the ballet of the infinite, where the Paranormal Military Squad team played their part in the waltz of wonders with an audience of stars. + +\* + +## Chapter 15 + +In the clandestine hush of Dulce Base's subterranean command center, the Paranormal Military Squad team had become a crucible for interstellar communication. Dr. Jordan Hayes' gaze lingered on the screen as they navigated through the convolution of alien code. Each character held the potential to unravel a new dimension of contact, and with Sam Rivera's keen interjection, they were crafting humanity's inaugural cosmological discourse. + +Alex Mercer peered over Jordan's shoulder, calculating the implications of every visual nuance that cascaded across the monitor. "Look for consistency—any repeating motifs could signal a willingness to engage. We're drafting history with each exchange," he remarked, aware of the delicate balance between forging a bond and exposing vulnerabilities. + +Taylor Cruz, stoic and enigmatic, observed the interplay from the threshold, a silhouette against the machinery's luminescence. "Remember, while we seek common ground, the foundation we stand upon remains Terra firma. Caution must temper our curiosity," they stated, their voice an anchor amidst the current of excitement. + +The command center buzzed with energy, rivaled only by the tempest overhead that concealed their operation. Sam, with swift dexterity, navigated the communications relay. "Their signals resonate almost musically. It's as if they're composing a symphony, and we've been handed the baton to conduct the next movement," they offered, imbuing the scenario with a blend of scientific adventurism and poetic license. + +Amidst the whirring servers and the occasional flicker of emergency lighting, the essence of their mission transcended mere reconnaissance. They were humanity's elected envoys at the brink of a celestial alliance—or confrontation—with an audience as vast as the universe itself. + +Alex stepped back, his profile etched by the chamber's artificial day. "Then let's ensure our contribution to this symphony harmonizes with theirs. It's time for humanity's voice to rise and be counted among the cosmic ensemble." + +Under his directive, the Paranormal Military Squad team initiated their calculated response, weaving thoughts and theories into a digital overture aimed at the heart of alien intellect. As the digital stream punctured the endless night, each member of this clandestine group was acutely aware of the irrevocable step they undertook—bringing Earth into the pantheon of galactic entities designed to converse among the stars. + +\* + +Clusters of high-tech equipment bathed the Dulce underground command center in an eerie blue light. Sam Rivera's fingers flew across the keyboard, navigating an elaborate network of alien patterns. The very air seemed to pulse with the ebb and flow of cryptic communications reaching across the stars. "I've got something!" Sam's announcement tore through the focus in the room, drawing every pair of eyes to the torrent of symbols unraveling on the screen. + +With the pacing of a seasoned officer gauging the moment before action, Alex Mercer approached, his calm demeanor belying an acute awareness of the precipice on which they now stood. "Define 'something," Alex prompted, reinforcing the need for clarity amidst the extraordinary. + +"It's repeating—a sequence that’s evolved with each interaction, almost as if it's... singing," Sam theorized, the awe in their voice reflecting the potential magnitude of their discovery. + +Jordan Hayes interjected from across the console, their eyes not leaving the display as they absorbed the new data. "A cosmic vocalization, then," they mused, intrigued. "A singularity in the signal that might represent a point of reference for both parties." + +Taylor Cruz, hands clasped behind their back, regarded the unfolding scene, their own calculations etching lines of concern onto their stern visage. "Or a beacon—a homing tune, calling out to something we might not be ready to greet," Taylor offered, voicing the group's unspoken apprehension. + +Alex's eyes locked on the screen, taking in the scope of what they were attempting to interpret. Drawing a deep breath, Alex gave a slight nod. "If this is their song, then let us respond with ours. We've come this far by mirroring their signals, now let's engage in an interstellar duet, and see where the music leads us." + +With the expectation of the significant achieving a crescendo, the members of Paranormal Military Squad huddled over their equipment—sages at the threshold of a potentially world-altering communion. The strange harmonies that reverberated through the command center suggested that their interlocutors were poised, waiting, perhaps even eager, for Earth's chorus to join the symphony. + +As the team initiated their reply, weaving humanity's own intricate melody into the vast cosmic dialogue, they each felt a profound change within—an evolution of purpose. They were not just messengers or investigators; they had become co-composers in a galactic orchestra, with the universe itself as their witness and concert hall. + +With the exchange of harmonious signals crawling through the vacuum of space, the Paranormal Military Squad operatives found themselves part of a bridging of minds—a realization that out there, among the vast arrays of stars and planets, harmony was the true universal language. + +\* + +The dim glow of monitors cast an otherworldly ambiance upon Dulce Base's command center, where Paranormal Military Squad's chosen stood huddled over their instruments, suspended at history's threshold. Codes—alien in origin and nature—were being deciphered by Dr. Jordan Hayes, whose countenance bore the marks of deep concentration. + +Alex Mercer, the bedrock upon which their team's resolve was founded, leaned in with an eagerness tempered by his chain of command. "Jordan, we've invested our expertise into comprehending their patterns, but now we must also endeavor to understand their intent," he urged, his voice bearing the gravitas of their mission's potential consequences. + +At another console, Sam Rivera's youth did not betray their crucial role in the operation. With eyes alight, they mirrored the rapid computing before them. "There's emotion here—complex, profound even. This isn't just the output of a cold machine; it's...sentience," Sam whispered, nearly drowned by the mechanical chorus around them. + +Jordan, without shifting focus from their work, replied, "It's a sentience that—should we succeed here—ushers us into a new era of existence. The cadence of these signals," they tapped the screen with a flourish, "could well be the heartbeat of this new dawn." + +Taylor Cruz paused beside Mercer, their expression unreadable beneath the sterile light. "And as it beats, we must gauge whether its rhythm bodes well for us, or spells our missteps. Courage must not blind us to the hazards intrinsic to such contact," Taylor cautioned, the sentinel within them ever alert. + +Alex nodded, a gesture that carried the weight of responsibility and a silent command: proceed, but with circumspection. They were not merely decoding a message; they were interpreting a dialogue across the celestial divide. + +The room fell into a rhythm akin to a well-conducted ensemble. Each member's expertise proved a critical note in the unfolding symphony. Their actions were now more than mere research or defense; they were the tentative overtures of humankind reaching out to grasp the vast unknown. + +Textures of sound meshed with the light from countless computations, the palpable anticipation of the agents at the edge of discovery cresting with an awareness that their work would reshape future chronicles. And when the response finally came—a signal piercing the deafening silence of uncertainty—all within Dulce's confines understood: the dawn of an interstellar continuum had just begun to break. + +\* + +In the sterile hum and flickering lights of Dulce Base's command center, the Paranormal Military Squad team stood as humanity's vanguard, verging on the brim of an intergalactic abyss. Dr. Jordan Hayes, analytical edges sharp, deciphered extraterrestrial patterns that bled across screens in enigmatic cascades—a daunting mosaic of potential threats and untapped wisdom. + +Agent Alex Mercer, the embodiment of focus and a steadfast nerve, observed the unfolding digital drama with the gravitas due a historic first contact. "Let the data weave its narrative, Jordan," he instructed, a moderate undertone of exhilaration within his command. "It's encoding more than information—it's outlining civilization." + +Jordan absorbed the directive, their gaze unflinching from the screens, feeling the weight of their next move. "The nuances here are extraordinary," they acknowledged. "It paints a picture of a culture steeped in complexities we're only starting to fathom.” + +Taylor Cruz, stoicism personified yet not immune to the situation's gravity, chimed in. "Understand it, but guard against it," they cautioned, bringing a sober prudence to the room. "This culture, however advanced, remains an unknown quantity—an ocean of wonders and darkness with uncertain tides." + +Sam Rivera, a visual contrast with wide eyes and restless hands, represented the other side of the room — intrigue and optimism against the drawn swords of precaution. “Think of it,” they proposed, voice bouncing with a rebellious upbeat timbre, “as the first act of a play written in constellations. We're setting the stage for a galactic narrative.” + +Each team member, in their way, was both actor and scribe in this moment of tense pageantry. Heavy with the presence of risk, the command center had become not just a room of computers and glass panels but a theater for performing the elaborate choreography of contact. + +Bound by resolve and curiosity, they proceeded, each data entry a trembling step onto the cosmic stage. And like all cautious pioneers edging into fertile but unnavigated lands, they understood: as they mapped the heavens, they were simultaneously mapping the furthest reaches of their own existential horizons. + diff --git a/graphrag/tests/fixtures/min-csv/settings.yml b/graphrag/tests/fixtures/min-csv/settings.yml new file mode 100644 index 0000000000000000000000000000000000000000..57a00c2751712d95995ae86b2958882ccc99161d --- /dev/null +++ b/graphrag/tests/fixtures/min-csv/settings.yml @@ -0,0 +1,20 @@ +input: + file_type: csv + +embeddings: + vector_store: + type: "lancedb" + uri_db: "./tests/fixtures/min-csv/lancedb" + store_in_table: True + + entity_name_description: + title_column: "name" + # id_column: "id" + # overwrite: true + # entity_name: ... + # relationship_description: ... + # community_report_full_content: ... + # community_report_summary: ... + # community_report_title: ... + # document_raw_content: ... + # text_unit_text: ... diff --git a/graphrag/tests/fixtures/text/config.json b/graphrag/tests/fixtures/text/config.json new file mode 100644 index 0000000000000000000000000000000000000000..809ca0f624fd09ebf8a0e8491b0e73ed2c315f0b --- /dev/null +++ b/graphrag/tests/fixtures/text/config.json @@ -0,0 +1,182 @@ +{ + "input_path": "./tests/fixtures/text", + "input_file_type": "text", + "workflow_config": { + "create_base_text_units": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 11, + "max_runtime": 10 + }, + "create_base_extracted_entities": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 2, + "max_runtime": 300 + }, + "create_final_covariates": { + "row_range": [ + 1, + 2000 + ], + "nan_allowed_columns": [ + "type", + "description", + "subject_type", + "object_id", + "object_type", + "status", + "start_date", + "end_date", + "source_text" + ], + "subworkflows": 6, + "max_runtime": 300 + }, + "create_summarized_entities": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 1, + "max_runtime": 300 + }, + "join_text_units_to_covariate_ids": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 2, + "max_runtime": 10 + }, + "create_base_entity_graph": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 2, + "max_runtime": 10 + }, + "create_final_entities": { + "row_range": [ + 1, + 2000 + ], + "nan_allowed_columns": [ + "type", + "description", + "graph_embedding" + ], + "subworkflows": 11, + "max_runtime": 300 + }, + "create_final_relationships": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 8, + "max_runtime": 100 + }, + "create_final_nodes": { + "row_range": [ + 1, + 2000 + ], + "nan_allowed_columns": [ + "entity_type", + "description", + "graph_embedding", + "community", + "level" + ], + "subworkflows": 10, + "max_runtime": 10 + }, + "create_final_communities": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 14, + "max_runtime": 10 + }, + "create_final_community_reports": { + "row_range": [ + 1, + 2000 + ], + "nan_allowed_columns": [ + "community_id", + "title", + "summary", + "full_content", + "full_content_json", + "rank", + "rank_explanation", + "findings" + ], + "subworkflows": 7, + "max_runtime": 300 + }, + "join_text_units_to_entity_ids": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 3, + "max_runtime": 10 + }, + "join_text_units_to_relationship_ids": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 4, + "max_runtime": 10 + }, + "create_final_text_units": { + "row_range": [ + 1, + 2000 + ], + "nan_allowed_columns": [ + "relationship_ids", + "entity_ids" + ], + "subworkflows": 7, + "max_runtime": 100 + }, + "create_base_documents": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 8, + "max_runtime": 10 + }, + "create_final_documents": { + "row_range": [ + 1, + 2000 + ], + "subworkflows": 1, + "max_runtime": 100 + } + }, + "query_config": [ + { + "query": "Who is Agent Alex Mercer and what are his goals?", + "method": "local" + }, + { + "query": "What is the major conflict in this story and who are the protagonist and antagonist?", + "method": "global" + } + ], + "slow": false +} \ No newline at end of file diff --git a/graphrag/tests/fixtures/text/input/ABOUT.md b/graphrag/tests/fixtures/text/input/ABOUT.md new file mode 100644 index 0000000000000000000000000000000000000000..42c316108ec0893e6b1df44f8f42e5a50a8edb43 --- /dev/null +++ b/graphrag/tests/fixtures/text/input/ABOUT.md @@ -0,0 +1,3 @@ +# About + +This document (Operation Dulce) in an AI-generated science fiction novella, included here for the purposes of integration testing. \ No newline at end of file diff --git a/graphrag/tests/fixtures/text/input/dulce.txt b/graphrag/tests/fixtures/text/input/dulce.txt new file mode 100644 index 0000000000000000000000000000000000000000..95c9e3cd3af76b570f0550d69b2025d7cd6fafbb --- /dev/null +++ b/graphrag/tests/fixtures/text/input/dulce.txt @@ -0,0 +1,970 @@ +# Operation: Dulce + +## Chapter 1 + +The thrumming of monitors cast a stark contrast to the rigid silence enveloping the group. Agent Alex Mercer, unfailingly determined on paper, seemed dwarfed by the enormity of the sterile briefing room where Paranormal Military Squad's elite convened. With dulled eyes, he scanned the projectors outlining their impending odyssey into Operation: Dulce. + +“I assume, Agent Mercer, you’re not having second thoughts?” It was Taylor Cruz’s voice, laced with an edge that demanded attention. + +Alex flickered a strained smile, still thumbing his folder's corner. "Of course not, Agent Cruz. Just trying to soak in all the details." The compliance in his tone was unsettling, even to himself. + +Jordan Hayes, perched on the opposite side of the table, narrowed their eyes but offered a supportive nod. "Details are imperative. We’ll need your clear-headedness down there, Mercer." + +A comfortable silence, the kind that threaded between veterans of shared secrets, lingered briefly before Sam Rivera, never one to submit to quiet, added, "I’ve combed through the last transmission logs. If anyone can make sense of the anomalies, it’s going to be the two of you." + +Taylor snorted dismissively. “Focus, people. We have protocols for a reason. Speculation is counter-productive.” The words 'counter-productive' seemed to hang in the air, a tacit reprimand directed at Alex. + +Feeling the weight of his compliance conflicting with his natural inclination to leave no stone unturned, Alex straightened in his seat. "I agree, Agent Cruz. Protocol is paramount," he said, meeting Taylor's steely gaze. It was an affirmation, but beneath it lay layers of unspoken complexities that would undoubtedly unwind with time. + +Alex's submission, though seemingly complete, didn't escape Jordan, who tilted their head ever so slightly, their eyes revealing a spark of understanding. They knew well enough the struggle of aligning personal convictions with overarching missions. As everyone began to collect their binders and prepare for departure, a quiet resolve took form within Alex, galvanized by the groundwork laid by their interactions. He may have spoken in compliance, but his determination had merely taken a subtler form — one that wouldn't surrender so easily to the forthcoming shadows. + +\* + +Dr. Jordan Hayes shuffled a stack of papers, their eyes revealing a tinge of skepticism at Taylor Cruz's authoritarian performance. _Protocols_, Jordan thought, _are just the framework, the true challenges we're about to face lie well beyond the boundaries of any protocol._ They cleared their throat before speaking, tone cautious yet firm, "Let's remember, the unknown variables exceed the known. We should remain adaptive." + +A murmur of agreement echoed from Sam Rivera, who leaned forward, lacing their fingers together as if weaving a digital framework in the air before them, "Exactly, adaptability could be the key to interpreting the signal distortions and system malfunctions. We shouldn't discount the… erratic." + +Their words hung like an electric charge in the room, challenging Taylor's position with an inherent truth. Cruz’s jaw tightened almost imperceptibly, but the agent masked it with a small nod, conceding to the omnipresent threat of the unpredictable. + +Alex glanced at Jordan, who never looked back, their gaze fixed instead on a distant point, as if envisioning the immense dark corridors they were soon to navigate in Dulce. Jordan was not one to embrace fantastical theories, but the air of cautious calculation betrayed a mind bracing for confrontation with the inexplicable, an internal battle between the evidence of their research and the calculating skepticism that kept them alive in their field. + +The meeting adjourned with no further comments, the team members quietly retreading the paths to their personal preparations. Alex, trailing slightly behind, observed the others. _The cautious reserve Jordan wears like armor doesn't fool me_, he thought, _their analytical mind sees the patterns I do. And that's worth more than protocol. That's the connection we need to survive this._ + +As the agents dispersed into the labyrinth of the facility, lost in their thoughts and preparations, the base's halogen lights flickered, a brief and unnoticed harbingers of the darkness to come. + +\* + +A deserted corridor inside the facility stretched before Taylor Cruz, each footstep rhythmic and precise. Cruz, ambitious and meticulous, eyed the troops passing by with a sardonic tilt of the lips. Obedience—it was as much a tool as any weapon in the arsenal, and Cruz wielded it masterfully. To them, it was another step toward unfettered power within the dark bowels of the military complex. + +Inside a secluded equipment bay, Cruz began checking over gear with mechanical efficiency. They traced fingers over the sleek surface of an encrypted radio transmitter. "If protocols are maintained," said Cruz aloud, rehearsing the speech for their subordinates, "not only will we re-establish a line of communication with Dulce, but we shall also illuminate the darkest secrets it conceals." + +Agent Hayes appeared in the doorway, arms crossed and a knowing glint in their eyes. "You do understand," Jordan began, the words measured and probing, "that once we're in the depths, rank gives way to survival instincts. It's not about commands—it's empowerment through trust." + +The sentiment snagged on Cruz's armor of confidence, probing at the insecurities festering beneath. Taylor offered a brief nod, perhaps too curt, but enough to acknowledge Jordan's point without yielding ground. "Trust," Cruz mused, "or the illusion thereof, is just as potent." + +Silence claimed the space between them, steeped in the reality of the unknown dangers lurking in the shadows of the mission. Cruz diligently returned to the equipment, the act a clear dismissal. + +Not much later, Cruz stood alone, the hollow echo of the bay a stark reminder of the isolation that power often wrought. With each checked box, their resolve steeled further, a silent vow to usher their team through the abyss—whatever it might hold—and emerge enshrined in the respect they so deeply craved. + +## Chapter 2 + +Sam Rivera sat alone in a cramped office, the hum of a dozen servers murmuring a digital lullaby in the background. Surrounded by the glow of multiple screens, their eyes danced across lines of code and intercepted comm signals from Dulce — a kaleidoscope of data that their curious and isolated mind hungered to decrypt. + +To an outsider, it might have looked like obsession, this fervent quest for answers. But to Sam, it was a dance — a give and take with the mysteries of the universe. Their fingers paused over the keyboard as they leaned back in the chair, whispering to thin air, "What secrets are you hiding from us?" + +The stillness of the room broke with the unexpected arrival of Alex Mercer, whose encroaching shadow loomed over Sam's workspace. The cybersecurity expert craned their neck upwards, met by the ever-so-slight furrow in Alex's brow. "Got a minute, Rivera?" + +"Always," Sam said, a smile surfacing as they swiveled to face their mentor more directly. _He has that look — like something's not sitting right with him,_ they noted inwardly. + +Alex hesitated, weighing his words carefully. "Our tech is top-tier, but the silence from Dulce... It's not just technology that will see us through, it's intuition and... trust." His gaze pierced through the digital haze, trying to instill something more profound than advice. + +Sam regarded Alex for a moment, the sincerity in his voice resonating with their own unspoken desire to prove their worth. "Intuition," they mirrored thoughtfully. "I guess sometimes the numbers don't have all the answers." + +Their shared silence held a newfound understanding, a recognition that between the ones and zeros, it was their combined human insights that might prevail against the impossible. As Alex turned to leave, Sam's eyes drifted back to the screens, now seeing them not as barriers to isolate behind, but as windows into the vast and enigmatic challenge that awaited their team. + +Outside the office, the persistent buzz of activity in the facility belied the unease that gripped its inhabitants. A restlessness that nibbled on the edges of reality, as though forewarning of the threshold they were soon to cross — from the known into the realm of cosmic secrets and silent threats. + +\* + +Shadows played against the walls of the cramped underground meeting room, where Alex Mercer stood gazing at the concealed elevator that would deliver them into the bowels of Dulce base. The air was thick, every breath laced with the weight of impending confrontation, the kind one feels when stepping into a legend. Though armed with an array of advanced weaponry and gear, there was an unshakeable sense that they were delving into a conflict where the physical might be of little consequence. + +"I know what you're thinking," Jordan Hayes remarked, approaching Mercer. Their voice was low, a blend of confidence and hidden apprehension. "This feels like more than a rescue or reconnaissance mission, doesn't it?" + +Alex turned, his features a mask of uneasy resolve. "It's like we're being pulled into someone else’s game. Not just observers or participants, but... pawns." + +Jordan gave a short nod, their analytical mind colliding with the uncertain dynamics of this operation. "I've felt that way since the briefing. Like there's a layer we’re not seeing. And yet, we have no choice but to play along." Their eyes locked with Alex's, silently exchanging a vow to remain vigilant. + +"You two need to cut the philosophical chatter. We have positions to secure," Taylor Cruz interjected sharply, stepping into their exchange. The authority in Taylor's voice brooked no argument; it was their way of pulling everyone back to the now. + +Alex's response was measured, more assertive than moments ago. "Acknowledged, Agent Cruz," he replied, his voice steadier, mirroring the transformation brewing within. He gripped his rifle with a newfound firmness. "Let's proceed." + +As they congregated at the elevator, a tension palpable, Sam Rivera piped in with a tone of balanced levity, "Hope everyone’s brought their good luck charms. Something tells me we’re going to need all the help we can get." + +Their laughter served as a brief respite from the gravity of their mission, a shared moment that reinforced their common humanity amidst the unknowable. Then, as one, they stepped into the elevator. The doors closed with a silent hiss, and they descended into the darkness together, aware that when they returned, if they returned, none of them would be the same. + +\* + +The sense of foreboding hung heavier than the darkness that the artificial lights of the elevator shaft failed to fully penetrate. The team was descending into the earth, carrying with them not only the weight of their equipment but also the silent pressure of the invisible war they were about to fight—a war that seemed to edge away from physicality and into the unnervingly psychological. + +As they descended, Dr. Jordan Hayes couldn't help but muse over the layers of data that could wait below, now almost longing for the comfort of empirical evidence. _To think that this reluctance to accept other possibilities may have been my biggest blind spot,_ Jordan contemplated, feeling the hard shell of skepticism begin to crack. + +Alex caught Jordan's reflective gaze and leaned in, his voice barely a murmur over the hum of the elevator. "Once we're down there, keep that analytical edge sharp. You see through the mazes of the unexplained better than anyone." + +The compliment was unexpected and weighed differently than praise from others. This was an acknowledgment from someone who stood on the front lines of the unknown with eyes wide open. "Thank you, Alex," Jordan said, the words carrying a trace of newfound assertiveness. "You can count on me." + +The exchange was cut short by a shudder that ran through the elevator, subtle, but enough to make them instinctively hold their breaths. It wasn't the mechanical stutter of old gears but a vibration that seemed to emanate from the very walls of the shaft—a whisper of something that defied natural explanation. + +Cruz was the first to react, all business despite the shadow that crossed their expression. "Systems check. Now," they barked out, masking the moment of disquiet with swift command. + +Every agent checked their gear, sending confirmation signals through their comms, creating a chorus of electronic beeps that promised readiness. But there was an unspoken question among them: was their technology, their weaponry, their protocols sufficient for what awaited them or merely a fragile comfort? + +Against the gravity of the silence that was once again closing in, Sam's voice crackled through, only half-jest. "I'd laugh if we run into Martians playing poker down there—just to lighten the mood, you know?" + +Despite—or perhaps because of—the oddity of the moment, this elicited a round of chuckles, an audible release of tension that ran counterpoint to the undercurrent of anxiety coursing through the team. + +As the elevator came to a halting, eerie calm at the sub-level, the group stepped off, finding themselves at the threshold of Dulce's mysterious halls. They stood in a tight pack, sharing a cautious glance before fanning out into the unknown, each one acutely aware that the truth was inevitably intertwined with danger. + +Into the depths of Dulce, the team advanced, their silence now a shared testament to the camaraderie born of facing the abyss together—and the steel resolve to uncover whatever horrors lay hidden in its shadows. + +\* + +The weight of the thick metal door closing behind them reverberated through the concrete hallway, marking the final threshold between the familiar world above and the strangeness that lay beneath. Dulce base, a name that had been whispered in the wind-blown deserts above and in the shadowed corners of conspiracy forums, now a tangible cold reality that they could touch — and that touched them back with a chill. + +Like lambs led to an altar of alien deities, so did Agents Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera proceed, their movements measured, their senses heightened. The air was still, almost respectful of the gravity of their presence. Their torch beams sliced through the darkness, uncovering steel doors with warnings that spoke of top secrets and mortal dangers. + +Taylor Cruz, stepping firmly into the role of de facto leader, set a brisk pace. "Eyes sharp, people. Comms check, every thirty seconds," Taylor ordered, their voice echoing slightly before being swallowed by the surrounding silence. + +Sam, fiddling with a handheld device aimed at detecting electronic anomalies, offered a murmured "Copy that," their usual buoyancy dimmed by the oppressive atmosphere. + +It was Jordan Hayes who paused at an innocuous looking panel, nondescript amongst the gauntlet of secured doorways. "Mercer, Rivera, come see this," Jordan’s voice was marked with a rare hint of urgency. + +Alex joined Jordan's side, examining the panel which, at a mere glance, seemed just another part of the base's infrastructure. Yet, to the trained eye, it appeared out of place—a facade. + +Jordan explained their reasoning as Sam approached, instinctively understanding the significance of what lay beneath, "This panel is a recent addition — covering something they didn't want found." + +Before Alex could respond, the soft whir of an approaching drone cut through their muffled exchange. Taylor had looped back upon hearing the commotion. "Explanations later. We can't afford to attract..." Cruz’s voice trailed off as the small airborne device came into view, its sensors locked onto the group. + +Sam was the first to react, their tech-savvy mind already steps ahead. "I've got this," they declared, fingers flying over the controls of their own gadgetry to ward off the impending threat. + +The drone lingered, its scan seeming more curious than hostile. But within moments, courtesy of Sam's interference, the little sentinel drifted away, retreating into the shadows as if accepting a silent truce. The crew exhaled, a moment of collective relief palpable in the air. + +Cruz squared their shoulders, clearly ruffled but not conceding any ground. "Move out," they directed, a hint more forceful than before. "And Rivera, keep that trick handy." + +The team pressed onward, the quiet now filled with the soft beeps of regular comms checks, their pace undeterred by the confrontation. Yet, every agent held a renewed sense of wariness, their trust in one another deepening with the knowledge that the base—its technology, its secrets—was alive in a way they hadn't fully anticipated. + +As they converged upon a central hub, the imposing doors to the mainframe room stood ajar — an invitation or a trap, neither option comforting. Without a word, they fortified their resolve and stepped through the threshold, where the dim glow of operational LED lights and the distant hum of machinery hinted at Dulce’s still-beating heart. + +Solemnly, yet unmistakably together, they moved deeper into the heart of the enigma, ready to unmask the lifeforce of Dulce base or confront whatever existential threat lay in wait. It was in that unwavering march towards the unknown that their destinies were forever cemented to the legacy of Operation: Dulce. + +## Chapter 3 + +The thrumming of monitors cast a stark contrast to the rigid silence enveloping the group. Agent Alex Mercer, unfailingly determined on paper, seemed dwarfed by the enormity of the sterile briefing room where Paranormal Military Squad's elite convened. With dulled eyes, he scanned the projectors outlining their impending odyssey into Operation: Dulce. + +\* + +The cooling vents hummed in a monotonous drone, but it was the crackle of the comms system coming to life that cut through the lab’s tension. Dr. Jordan Hayes hovered over a table arrayed with alien technology, their fingers delicately probing the enigmatic circuitry retrieved from the crash site. Agent Alex Mercer watched, admiration blooming in silent solidarity for Jordan's deft touch and unspoken drive. + +Jordan, always composed, only allowed the faintest furrow of concentration to mar their brow. "What we understand about physics..." they muttered, trailing off as they realigned a translucent component. The device emitted a low pulse, causing Jordan to still. "Could be fundamentally changed by this." + +A calculated risk—that's what this was. And for a person of science, a gamble was worth the potential paradigm shift. + +"I’ve been thinking," Alex started, his eyes still fixed on the immediately tangible mystery before them. "About what’s at stake here. Not the mission parameters, but what this means for us—humanity." + +Jordan glanced up, meeting his eyes just long enough to convey the shared enormity of their situation; the career-defining glory and existential dread entwined. "The quest for understanding always comes at a price. We're standing on the precipice of knowledge that could either elevate us or condemn us." + +The charged air between them spiked as Taylor Cruz’s brusque tones sliced through their reverie. "Hayes, Mercer, this isn't philosophy hour. Focus on the task. We need actionable intel, not daydreams." + +With a sound of restrained acknowledgment, Jordan returned their gaze to the device, while Alex clenched his jaw, the buzz of frustration dull against the backdrop of Taylor's authoritarian certainty. It was this competitive undercurrent that kept him alert, the sense that his and Jordan's shared commitment to discovery was an unspoken rebellion against Cruz's narrowing vision of control and order. + +Then Taylor did something unexpected. They paused beside Jordan and, for a moment, observed the device with something akin to reverence. “If this tech can be understood..." Taylor said, their voice quieter, "It could change the game for us. For all of us.” + +The underlying dismissal earlier seemed to falter, replaced by a glimpse of reluctant respect for the gravity of what lay in their hands. Jordan looked up, and for a fleeting heartbeat, their eyes locked with Taylor's, a wordless clash of wills softening into an uneasy truce. + +It was a small transformation, barely perceptible, but one that Alex noted with an inward nod. They had all been brought here by different paths and for different reasons. Yet, beneath the veneer of duty, the enticement of the vast unknown pulled them inexorably together, coalescing their distinct desires into a shared pulse of anticipation. + +Marshaled back to the moment by the blink of lights and whir of machinery, they refocused their efforts, each movement sharpened by the knowledge that beyond understanding the unearthly artifacts, they might be piecing together the future of their species. + +\* + +Amidst the sterility of the briefing room, the liminal space between the facts laid out and the hidden truths, sat Sam Rivera, his demeanor an artful balance of focus and a casual disguise of his razor-sharp talent with technology. Across from him, Alex Mercer lingered in thought, the mental cogs turning as each file on Dulce stirred more than curiosity—it beckoned to a past both honored and burdensome. + +"You've been quiet, Sam," Alex noted, catching the younger man's contemplative gaze. "Your take on these signal inconsistencies?" + +There was a respect in Alex's tone, though a respectful distance remained—a gulf of experience and a hint of protective mentorship that stood between them. Sam nodded, recognizing the space afforded to him, and he couldn't help but feel the weight of expectation pressing upon his shoulders. It wasn't just the mission that was immense, it was the trust being placed in him. + +"The patterns are... off," Sam admitted, hesitant but driven. "If I'm right, what we're looking at isn't random—it's a structured anomaly. We need to be ready for anything." + +Alex's eyes brightened with a subtle approval that crossed the distance like a silent nod. "Good. Keen eyes will keep us ahead—or at least not blindsided," he said, affirming the belief that inscribed Sam's role as more than the tech personnel—he was to be a guiding intellect in the heart of uncertainty. + +Their exchange was cut short by Taylor Cruz's abrupt arrival, his gait brimming with a robust confidence that veiled the sharp undercurrents of his striving nature. "Time to gear up. Dulce waits for no one," Taylor announced, his voice carrying an iron resolve that knew the costs of hesitation—though whether the cost was calculated in human or career terms was an ambiguity he wore like a badge of honor. + +As Sam and Alex nodded in unison, the icy chasm of hierarchy and cryptic protocols seemed momentarily to bridge over with an understanding—this mission was convergence, a nexus point that would challenge each of their motives and strength. + +They filed out of the briefing room, their footsteps synchronized, a rhythm that spoke volumes of the unknown cadence they would soon march to within the base's veins. For Alex Mercer, the link with Sam Rivera, though distant, was now poised with a mutuality ready to be tested; for Taylor Cruz, the initiative pulsed like a heartbeat, anticipation thinly veiled behind a mask of duty. + +In the midst of the descent, they were each alone yet irrevocably joined, stepping closer towards the volatile embrace of Operation: Dulce. + +## Chapter 4 + +The corridors of the Dulce military base were as silent as a tomb and twice as chilling. Alex Mercer walked with a surety that belied his bubbling undercurrents of doubt. The briefing had been definitive, sturdy pillars of facts and protocols, yet as he ventured deeper, the ominous atmosphere gnawed at him—a stark reminder of how much remained unknown. + +Jordan Hayes trailed a few steps behind, their detached exterior breaking for a moment as they caught up to Alex. "What's on your mind?" Jordan asked, their astuteness cutting through the unspoken tension. + +Alex glanced back at them. This place was a puzzle, a treacherous labyrinth where the walls whispered secrets, and among them, he sensed a call to question, to challenge the narrative they'd been sold. "The silence here... It's almost as if the base is waiting for something—or someone." + +"Just stay sharp, Mercer," Jordan cautioned, yet their eyes lingered on the quietude around them, conceiving the same shadow of doubt that unsettled Alex. + +Before they could delve into further discussion, the distinctive click of a safety catch echoed in the hollow space. Both agents turned to find Taylor Cruz standing resolute, primed for combat. Taylor's gaze was scrutinizing and cold, a stark contrast to the growing unease that smoldered silently amongst the rest. + +"Chatter is a liability," Taylor snapped, with a commanding flair that bordered on tyrannical. "We move forward, eyes open, mouths shut." + +Alex felt the tight grip of compliance strangle his gut, a lesson learned under the hard tutelage of rank and order. But here, in the bowels of Dulce, those instincts began to wane, the imperative to adhere now conflicting with the pressing urgency to confront the shadows they were enmeshed in. + +Then, unexpectedly, the lights flickered, a power fluctuation—or a sign? Alex's hand instinctively went to his sidearm, his mindset shifting from soldier to skeptic. The base, with its unyielding coldness, had just given them their first nudge into the realm of the speculative, an invitation to peel back the veneer of reality. + +"We should consider all possibilities," Alex murmured, more to himself than the others, his voice a barely audible breath against the sterile air of the complex. + +Taylor's posture stiffened at the challenge, yet their response was uncharacteristically reserved, notable in its lack of rebuke. "Agreed. For now, keep moving. But stay vigilant." + +A surprise—an echo of agreement from the last person Alex expected it from. And there it was, the glimpse of a wrinkle in the unyielding fabric of command, a hint that perhaps they were all starting to sense the strangeness that permeated this place. + +Progressing with determined steps, the trio moved deeper, silently acknowledging the evolution of their predicament. It was a small yet transformative concession to the unknown forces at play, an acknowledgment from each agent that, despite their disparate goals and ideals, the true nature of the Dulce base was an enigma that would forge new paths through their convictions. + +As they reached the central communications hub, the truth that awaited them lurked in the shadows, its eyes unseen but felt by all. The walls didn't just whisper now; they spoke in tones only the brave—or the foolish—would dare to listen to. + +\* + +The subterranean silence of Dulce was an oppressive entity of its own, wrapping the team in a cloak of uneasiness as they pressed on through the dimly lit corridor. Jordan Hayes found themselves contemplating the ramifications of each step taken into this suspended world, where the sterile air seemed to mock the gravity of their predicament. The closer they got to the communication hub, the more Jordan's mind wandered toward the realm of the inexplicable. + +Beside Jordan, Alex Mercer moved forward with deliberation, his gaze scanning the heavy utility doors they passed—one of which was partially ajar, beckoning them with its darkness. "After you, Dr. Hayes," Alex said, gesturing toward the mysterious opening. A hint of shared understanding passed between them; knowledge was the guiding star of this mission as much as confrontation or recovery. + +Jordan peered inside, the beam from their flashlight slicing through the obscurity. The room beyond was a chaotic cascade of papers, overturned furniture, and the particular kind of disorder born from hasty evacuation—or something far more sinister. + +"It's like they vanished in the middle of something urgent," Alex murmured, his voice tight with a mix of concern and anticipation. He began to sift through the scattered reports, each page a potential clue to the enigmatic silence that shrouded Dulce. + +Behind them, Taylor watched with a disciplined patience, their authority the foundation upon which the operation was built. Their voice cut into the stillness, a reminder of their presence, "Time is not our ally here." + +Drawing back from momentary distraction, Jordan acknowledged the wisdom in Taylor's words, yet could feel the shift in their stance—from skeptical, reserved analyst, to a proactive agent within the narrative. "You're right; these documents may hold critical insights. Let's collect what we can and analyze them properly." + +From the darkened hollows of the room, shadows seemed to cast subtle judgment as Alex and Jordan worked together with heightened urgency. Taylor, for once, didn't intervene but instead surveyed the entrance, their mind anticipating the unknown variables that lay ahead. + +Unexpectedly, a soft hiss emanated from a neglected terminal on the desk. Jordan's head snapped up, their heart rate accelerating at the potential ramifications. Without a word, they moved to the machine, hands driven by the newfound conviction that knowledge was more than power—it was survival. + +As Jordan began to extract what data they could from the terminal, the first comprehensible communication from the depths of Dulce in far too long crackled through: an automated distress marker, looping endlessly without further context. It was a revelation, one that reverberated through the group, confirming their fears and igniting an even greater need to press on. + +Watching Jordan's dogged determination, Alex witnessed the minor transformation in his colleague unfold—a shift from doubt to action, a sliver of belief in the possibilities beyond their rational understanding. This forge of resolve amidst the alien echoes of Dulce not only bonded them closer as a team but compelled them forward with a sharpened edge of responsibility to the truth, wherever it would lead. + +As they collected their findings and regrouped, the base around them imperceptibly changed, the air charged with the vibration of secrets poised on the brink of revelation. And in that charged silence, the group moved on, each now carrying pieces of a puzzle that would soon converge into a picture of galactic significance. + +\* + +In the chill of the cramped server room, the hum of machinery was the backbone to a symphony of data streams coursing through the air. Dr. Jordan Hayes, nerves alight with the mission's mounting unknowns, patched into the last known coordinates of the unsent distress broadcast they had uncovered. They were so close to the core now – to the truth behind the blackout – it was almost tangible. + +Beside them stood Agent Alex Mercer, ever the soldier, yet with eyes that betrayed an intellect craving to understand the murk beneath the surface. "Any progress, Dr. Hayes?" Alex queried, his voice betraying a subtle urgency. + +"Getting there," Jordan replied, fingers dancing across the keyboard. "Whoever sent this was cut off mid-transmission. It's as if Dulce itself swallowed the message whole." + +Taylor Cruz closed in, their frame casting a long shadow over the duo, evoking an almost palpable wall between them and the forward momentum of their mission. "Time is against us," Taylor intoned, more statement than threat. "What we uncover here determines our next course of action." + +Alex acknowledged Taylor with a brisk nod, his stance firm. Yet inwardly, the tightening grip he felt from Taylor's words couldn't throttle the swell of his own investigative instinct. His soldier's obedience had begun to war with the advocate's zeal for unveiling the dark heart of Dulce's secrets. + +And then, the unexpected occurred. The screens flashed in unison, spilling a discordant stream of symbols and images that defied immediate analysis. Jordan's breath caught – this was the response they had been fishing for, an alien communication protocol resonating just at the edge of human comprehension. + +Each member of the team felt it: a shift in the room’s very atmosphere, like a veil being drawn from their perception. Alex and Jordan stood still, absorbed in the bewilderment of contact, while Taylor, despite their authority, hesitated – a minor betrayal that unease was creeping into even their disciplined heart. + +"Thoughts, Rivera?" Taylor rallied, seeking the counsel of Sam Rivera, whose eyes were wide with exhilaration. + +Sam stepped forward, breaking the spell of stillness. "It's like nothing I've ever seen before, but I think I can bridge our systems to communicate," they declared, a wisp of optimism braiding their voice. They set about adapting their gear to transmute the foreign signals into something the team could dissect, their actions a testament to the mentorship and belief instilled in them by Mercer and the team. + +Taylor observed them, a cold calculation behind their facade, as they weighed the worth of this anomaly. It was a crossroad that potentially led to either monumental breakthrough or unprecedented catastrophe. "Once you've established a line, document everything. We can't afford to miss any detail," Taylor ordered, the words sharper than intended. + +The connection was made, and with trembling anticipation, the team listened as the first garbled outputs began to emerge, their very essence promising insights that could alter the course of history. It was an enigmatic dance with the unknown, the pulse of Dulce no longer just a place, but a herald to an alien register the team had yet to decipher. + +Together, they stood at the precipice of understanding, where the faint glow of their monitors cast more than just light – it cast the shadow of burgeoning transformation. It was in this moment, in the grasp of an extraterrestrial tongue, that the team, bound by a hunger for knowledge and the raw edge of survival, found their mission reframed from a search for answers to the articulation of a question humankind had yet to fully ask. + +Silent in their commune with the inexplicable frequency, they realized they were not merely investigators; they had become liaisons on behalf of Earth, interpreters of a cosmic message that could redefine their very existence. The implications loomed large, but now, they would not face them alone – they would face them as a united front, wrought together by the very mysteries that once drove them apart. + +## Chapter 5 + +Dr. Jordan Hayes clutched the edge of the briefing room table, their fingers white-knuckled against the laminate surface, as an array of constellations rotated on the projector—charts and graphs bleeding across the stars. In the dim room, nebulas and dark matter seemed within arm's reach, tangible yet unfathomable. + +Sam Rivera leaned back against the wall, arms crossed, gaze darting between the swirling cosmos and the faces of their companions. A taut line of concentration etched their young features, a mingling of fervent curiosity with the nascent understanding of the high stakes for which they played. + +Jordan's voice broke the profound silence. "The patterns in the signal disruptions sync with none other than zenithal star alignments. It's as if... as if these 'meet and greets' were scheduled, predestined by celestial mechanics." + +The statement hung heavy, daring the occupants of the room to unravel its implications. Alex Mercer, his prior military resolve momentarily suspended, absorbed the hypothesis with a visible hunger. "It's like we're adhering to an appointment we never knew we had," he murmured, his heart a drumbeat in his chest. + +Taylor Cruz snorted—a sound that clattered against the high concepts like a tumbledown shack in a futurist cityscape. Folding their arms, they glanced between the agents, their apprehension clad in the contempt of practicality. "What we need are facts, not mystic conjecture." + +Alex pivoted on his heel, facing Taylor squarely, and his voice found its edge of steel. "This isn't mysticism, Cruz. It's a hypothesis based on observed phenomena as unpredictable as the place we're standing in." + +Taylor's gaze never wavered, yet the slight twitch at the corner of their mouth belied their taut composure. "If there's a semblance of truth to it, then it's critical intel. But remember, we're not astrologers—we're soldiers and scientists." + +Jordan met Taylor’s gaze with a curt nod, accepting the caution even as the crucible of their intellect smoldered with the fervor of cosmic discovery. Their eyes flicked to Sam, whose steady presence and ready tech affirmed a burgeoning dynamic—the makings of a sentinel, standing guard over the threshold of human understanding and cosmic reality. + +With the projector casting pallid light over their features, each agent became a silhouette of purpose, shadows pillared against the backdrop of an endless universe. The story they were embroiled in would soon demand they plunge into darkness to retrieve the light of knowledge—a light that could very well redraw the shape of their world. + +They left the briefing room with a shared silence, each pondering the vast weave of celestial intent and terrestrial response, sensing that the galactic appointment to which they'd unwittingly RSVP’d was more insistent—and more threatening—than any operation they’d faced before. + +\* + +As the Paranormal Military Squad team convened in the heart of the Dulce military complex, an air of bristling expectation clung to the walls of the underground sanctum. Alex Mercer’s brow furrowed while watching his companions—Jordan Hayes, diligently setting up their makeshift lab station, and Sam Rivera meticulously checking the communication relays they had restored. Taylor Cruz observed with hawk-like focus, yet to betray the strain that their command posed on them. + +The gravity of the mission had shifted, deepened; each member of the team felt its pull, tethered to the understanding that they were now part of a larger narrative—a cosmic play with Earth as a stage and the human race unwitting actors. + +Jordan paused, a tension creeping across their shoulders as they aligned the satellite data with the alien message that had been decoded. "The instructions in this message," Jordan started, the timbre of their voice betraying their usual composure. "They're coordinates and... a warning." + +Sam leaned in, their eyes widening behind the glow of their laptop screen. "A warning? Like, ‘stay away from’, or ‘beware of’...?" Their words trailed off, uncertainty a new companion in their lexicon. + +Alex exhaled slowly, his mind racing to connect the dots. "It doesn't matter which," he said, decisive yet contemplative. "What matters is we understand intent. Are we being warned out of concern, or are we stumbling upon a threat?" + +Cruz’s iron-clad facade momentarily cracked, a fleeting glimpse of vulnerability flashing through their eyes. "We need to know if this entails additional risk to the operation," they said, directing their gaze specifically at Alex. "Mercer, I rely on you to keep the team grounded. No one goes off-course." + +Their reminder seemed both a command and a plea—rooted in an understanding that each member of the team now faced the duality of their roles, protectors of earthly secrets and heralds of potentially devastating revelations. + +Sam's fingers stilled mid-type, their task forgotten as they absorbed the weight of the unfolding reality. "We're the first line of defense... or detection," they mused half to themselves, a growing sense of agency within the larger play they were cast into. + +Jordan returned to the data, more resolute in their actions. The warning, whether cautionary or dire, was a beacon they no longer could ignore; its light casting aside shadows of doubt and igniting a collective purpose within the team. + +Alex watched Jordan and Sam, feeling a brotherhood in their shared quest. As Cruz paced, poised on the cusp of decisions that would mark their career and perhaps the fate of many, Alex knew the narrative had changed. They were no longer mere operatives; they had become guardians of a threshold, keepers of a message from a realm beyond stars and stripes. This elevation in their mission could not be shackled by regulations and established protocols—it demanded a new perspective, a new resolve. + +Tension threaded through the dialogue of beeps and static as communications with Washington buzzed in the background. The team stood, a portentous air enveloping them. It was clear that the decisions they made in the ensuing hours could redefine humanity's place in the cosmos or condemn them to ignorance and potential peril. + +Their connection to the stars solidified, the group moved to address the crystallizing warning, shifting from passive recipients to active participants. Mercer’s latter instincts gained precedence— the team’s mandate had evolved, no longer solely to observe and report but to interact and prepare. A metamorphosis had begun, and Operation: Dulce hummed with the newfound frequency of their daring, a tone set not by the earthly hierarchies but by the pulsing symphony of the universe itself. + +\* + +The desert night loomed eerily still as echoes of hidden activity reverberated deep beneath the bleak sands of New Mexico. Diverting his gaze from the array of sensors before him, Jordan Hayes allowed a rare breath, deep and anxious. Turning to Alex Mercer's focused silhouette, the nocturnal landscape illuminated softly by makeshift floodlights, Jordan felt the syncopated tempo of apprehension and exhilaration jockey for primacy within. + +"The closer we get to unlocking these messages, the more I feel like we're peeling back layers of reality itself," Jordan confided, eyes not leaving the monitors that presented a constellation of data points. + +"Yes," Alex replied, his voice steady as he considered the implications of their discovery. "And we have to be ready for whatever we find beneath those layers. Whether it's a breakthrough or a Pandora's Box." + +Silence settled between them, broken only by the occasional buzz of communications equipment attempting to bridge terrestrial and extraterrestrial intelligences. Tense moments drifted by, laden with the expectant weight of near breakthrough, when a soft chime signaled an incoming transmission -- a rare sound that set every agent on high alert. + +Absent was the voice of Washington or Paranormal Military Squad command. Instead, a rhythmic series of pulses and tones filled the air, deliberately patterned, unmistakably non-human. + +Sam Rivera adjusted the sensitivity of the decoding equipment, their hands shaking with anticipation as much as focus. "I have it!" they announced, the signal transforming under their expertise into a sequence of visual symbols on the screen before them. + +Their shared excitement was palpable, a kinetic force resonating between the team members as they crowded around the display. + +"What does it say?" Taylor Cruz demanded, the urgency in his tone scraping against the newfound wonderment. + +Interpreting the alien syntax required not only decoding but intuition and empathy. The words that emerged upon the screen were at once coherent and enigmatic: "*Voyage. Convergence. Peril.*" + +The stark simplicity of the message struck them collectively, a chill breeze wafting through their resolve. + +Alex stepped forward, piecing together the cryptic communication with a growing sense of obligation. "It’s a call to action," he deduced, "or possibly a summons." + +Jordan's gaze met Alex’s, both understanding that this was no longer an investigation or mere extraction of hidden truths. This was humanity's unwitting enlistment into a galactic dialogue that defied boundaries of nation, creed, or protocol. + +Sam's eyes were aglow, not with fear, but with the profound acceptance of inevitability that comes with groundbreaking revelation. Moreover, within Taylor's stern exterior churned the seed of reluctant admiration for the unclassified, the uncharted realms they were approaching. + +Together, they accepted the pivot in their mission, readjusting their objectives from exploration to engagement, and from isolation to a communal outreach beyond the stars. As dawn's first light threatened the horizon, it became clear that they were no longer merely operatives of a clandestine governmental faction—they were delegates on behalf of Earth, embarking on a voyage orchestrated by destinies unrelated to the mere geopolitics of their world. + +Turning to each other, their silhouettes sketched against the coming dawn, the agents recognized the transformation within and amongst them. They were bound by more than duty—they were intricately woven into the fabric of an unfolding cosmic opera, one in which they had been granted an undeniable role. And as they set course for the coordinates that beckoned them like a distant siren's call, it was with a solemn dedication to not only uncover the mysteries ahead but to navigate the convergence, and the peril, as unified emissaries of a world on the cusp of a broader understanding. + +\* + +Beneath the hum of the fluorescent lights and the vigilance of silent monitors, Alex Mercer stood with his team in the threshold of the base's command center, their faces etched with the fatigue of hours spent unraveling galactic mysteries. Jordan Hayes broke the stillness with a delicate fusion of disbelief and resolve. "The signal..." they began, their tone deliberate, "it’s evolving. It’s not just sending a message—it’s responding to us." + +Taylor Cruz leaned over the console, their eyes narrowing with intrigue and a flicker of unease, studying the alternating patterns on the screen. "Responding? Like it’s alive?" Taylor asked, a question that bordered on the edge of wonder and alarm. + +Sam Rivera’s gaze was locked onto their interface, a digital orchestra at their fingertips. "It could be some form of advanced AI. Or something else entirely," they contributed, a note of exhilaration betraying the gravity of the situation. + +Alex paced before the terminal, absorbing the enormity of their predicament. Their mission—once rooted in the solid ground of military discipline and covert operations—had transcended into an encounter of unprecedented import. "We need to be cautious," he advised, his voice a low rumble of cautious strategy. "If this signal is intelligent, how we interact with it could dictate the outcome of this entire operation." + +Jordan met Alex's gaze with a nod, the weight of the responsibility shared and accepted. "We have protocols for first contact, but nothing for... this," Jordan admitted. The room was gripped with tension, each breath seemingly louder than the last. + +Then, with a sudden burst that filled the command center, the signal coalesced into a clear and distinct pattern which replicated and expanded, its complexity revealing the hand—or mind—of an intelligent architect. + +Taylor's instinct for command surged forth. "Prepare to record and analyze. Whatever it is, we need to understand it—" But their words were cut short as the signal surged, enveloping the room in a brief, blinding cascade of light. + +In that pulse of brilliance, a shared revelation coursed through the team. The signal had become a bridge, an extension of unknown consciousness reaching towards them, testing, communicating, searching. + +Alex stepped back from the light, feeling a profound change unravelling within him. The path forward would not be one of confrontation or conquest, but of connection and comprehension. + +Jordan turned to Alex and Taylor, seeing in their faces a reflection of the same metamorphosis taking place within themselves—a movement from observers to participants, from agents to ambassadors. + +With a collective breath, the team faced the kaleidoscope of lights. The alien signal, once a harbinger of enigma, was now a catalyst for transformation—a symphony of light and sound that echoed the beginnings of a new relationship between humanity and the alien unknown. + +And so, with deliberate steps, Alex Mercer led his team into the luminous fray. Science, protocol, and survival instinct harmonized within them, each member poised on the cusp of a new chapter in human history. + +They were no longer merely the instruments of Paranormal Military Squad's will—they were the vanguard of humankind’s first definitive leap into the cosmic community. + +With the last echoes of the signal resonating in the control room, they each embraced the sequencing of the transmission, the dance of extraterrestrial light that now wrote itself into their story. The chapter of Operation: Dulce drew to a close, but the narrative of their destiny had only just begun. + +## Chapter 6 + +\* + +The cool darkness of the command center at Dulce base was a stark contrast to the brewing storm outside, where the unforgiving New Mexico desert winds whispered of the hidden truths that lay buried deep beneath its surface. Dr. Jordan Hayes sat, their eyes fixed on the readout, the frenetic dance of symbols and numbers reflecting off their determined face. They were on the cusp of an epiphany, teetering between the widely accepted laws of physics and the promise of a new cosmic paradigm. + +Alex Mercer watched from across the room, noting the subtle shifts in Jordan’s posture that belied a developing readiness to embrace the unbelievable. “Find something?” Alex’s question, asked with a blend of curiosity and solidarity, bridged the gap between a command and a genuine query among equals. + +Jordan's response was slow, measured against the magnitude of their analysis. “This isn’t random static. It’s a pattern - a repeated sequence phasing in and out but distinctly artificial.” Jordan turned away from the screen, locking eyes with Alex. “This could change everything.” + +Sam Rivera leaned in, their eyes alight with the fires of revelation and a quenchless thirst for understanding. “A pattern means intention. Could it be a message?” + +A figure emerged from the doorway, casting a long shadow into the room - Taylor Cruz. “Intentions can be friendly, or hostile. We shouldn’t forget that,” said Taylor, bringing a dose of their usual pragmatism into the heart of discovery. + +Alex acknowledged Taylor’s caution with a nod, understanding the need to keep their feet grounded even as their spirits soared toward the unknown. “Then let’s be the first to find out which it is." + +The team gathered around the monitors, the soft tapping of Jordan's keystrokes now punctuated by the occasional crackle of Sam's radio equipment. The sound was almost ritualistic, a prelude to humanity’s potential first, knowing foray into a larger universe. + +Jordan’s fingers paused, suspended in mid-air. The signal had evolved, becoming a beacon that somehow felt less alien and more familiar. It was as if the complexities of their message were unfolding into something more accessible, more terrestrial. + +A hushed excitement swept through the room. The transformation suggested an awareness on the part of the unknown senders; a finesse that spoke volumes about their capabilities and perhaps their intentions. + +With the growing realization that they were engaging with an intelligence far exceeding their previous understanding, the team prepared to reach back across the cosmic divide. Prepared or not, they were no longer bystanders in this galactic narrative. They were active correspondents in an exchange that transcended galaxies and welcomed them into an expansive, possibly fraught, interstellar conversation. + +\* + +Inside the cavernous central hub of Dulce military base, Dr. Jordan Hayes stood in near-darkness, surrounded by a nest of cables and monitors that buzzed with silent, cryptic life. Jordan's eyes narrowed to focus on the sequences that danced across the screen—patterns that could unravel the cosmic enigma surrounding them. + +Alex Mercer approached with his characteristic stride, a signal of reliability in the chaos. "Status report, Dr. Hayes?" he inquired, his voice low, almost blending into the soundscape of beeping consoles and swirling fans. + +"We're on the brink of unravelling the signal's origin," Jordan replied, the weight of implications heavy in their tone. "There's intelligence behind it, a thought process alien to our own." + +As if summoned by their analysis, Taylor Cruz approached with authority radiating from every pore. "Understand this, we need to know if it's friend or foe. Don't get wrapped up in the existential—our lives may depend on the answers you provide." + +Sam Rivera, their hands adroitly adjusting a device to fine-tune the signal, chimed in with optimism undercut by anxious anticipation. "We're deciphering the comm encryption. Soon, we'll have a channel open—not just listening in, but speaking back." + +Alex nodded his understanding, his strategic mind processing the tactical implications while grappling with the more profound humanistic impact. "When we do, we'll tread carefully, communicate with purpose," he reassured the team. + +The operation had evolved rapidly, from a stealthy incursion into a clandestine labyrinth to an exchange with an extraterrestrial intellect. Their earlier trepidation transformed into determined focus, as they prepared to extend humanity’s hand into the vast unknown. + +An alert on one of the monitor stations snapped the team into alarm. The signal had not simply been waiting—it had been calculating. Now, it reached its crescendo, demanding their attention with a provocative urgency. + +Jordan's fingers raced over the keyboard, their eyes simultaneously interpreting data and sharing directives. "It’s a linguistic lock, a test of comprehension. We crack this, we establish dialogue." + +Taylor's presence was a beacon of steely resolve. "Then let’s solve it. This is what we trained for—the unknown." + +Alex and Sam exchanged a look that telegraphed their shared determination—this was not only the mission they had trained for; it was the mission they had been destined for. + +Together, the Paranormal Military Squad team leaned into the challenge, their minds honing in on the complex patterns with a singular goal: to unlock the conversation with an intelligence that had already begun to shift the foundations of what they knew, or thought they knew, about the universe. + +In a symphony of clicks and murmurs, they worked, knowing they were about to make a giant leap not just for themselves or Paranormal Military Squad, but for all of humanity. As the final pieces fell into place, Dulce's militaristic silence was shattered by the sound of intergalactic contact—by the sound of history being made. + +## Chapter 7 + +In the enclosed space of Dulce’s command center, the air was thick with anticipation, each team member poised to tread the razor's edge between scientific breakthrough and galactic peril. Dr. Jordan Hayes focused intently on the screen, their fingers tapping a staccato rhythm against the keyboard as lines of alien code cascaded down the monitor. + +Alex Mercer's steely gaze surveyed the room, stopping on each member of his team. "Thoughts?" he asked, echoing the unspoken tension. His question, while directed at the group, lingered on Jordan—acknowledging their expertise and inviting collaboration rather than dictating orders. + +Jordan’s brow furrowed, an indicator of the mental gymnastics being performed. "It's unprecedented," they finally said, their voice a testament to the gravity of the moment. "Behavioral algorithms... if we're right, this code could reveal extraterrestrial thought patterns." + +Before anyone could react, Taylor Cruz interjected with the assertiveness of someone accustomed to commandeering the discourse. "Then let’s ensure we’re deciphering it correctly," Taylor stated, their tone suggesting they were still battling to maintain control over an increasingly alien situation. + +Sam Rivera hovered near the mainframe, youthful energy barely contained under the surface. "What if it’s more than just a message? What if they’re trying to extend consciousness across the stars?" + +The room fell into a contemplative silence, broken only by the hum of electronic equipment and the distant thud of secured doors locking in rhythm. The weight of responsibility rested on each agent's shoulders—a heaviness palpable in the air they shared. + +Alex stepped forward, reaching a subtle decision, one dictated by foresight and the humanity nestled at the core of their mission. "We approach with the aim to understand, not to confront," he said, softening his military bearing into a more diplomatic stance. + +Jordan nodded, appreciating the leadership that Alex displayed in the face of the unknown, and turned back to the cryptic data. Here, before them all, was a tangible piece of evidence—proof of an extraterrestrial sentience that had outreached the bounds of their expectations. + +Taylor took a breath, simultaneously exuding a sense of preparedness and venturing into the unknown alongside their peers. "Then let’s do what Paranormal Military Squad does best—investigate and adapt," Taylor added, finding comfort in the familiar even as they stood on the cusp of an unprecedented alchemy of science and mystery. + +The team leaned into their respective roles, driven by the urgency of the assignment and the pull of an insatiable curiosity. Sam offered a grin that belied the tension, a youthfulness that reminded them all of the profound excitement nested within the terror of the unknown. + +Quietly but resolutely, they turned back to their instruments, each of them a sentinel on the threshold of a new reality. The once implicit lines of command were now woven into a shared tapestry of hierarchy and camaraderie. As they danced with the unknown, they were beacons of sentient endeavor, casting the light of human consciousness into the vast darkness that called to them. + +\* + +\* + +Dulce Base's cavernous darkness was pierced by the sharp luminescence of monitors, casting an electric glow onto the faces of those who dared to unearth its secrets. Dr. Jordan Hayes stood motionless, eyes glazed in concentration, their mind a nexus where terrestrial science battled with celestial unknowns. + +Alex Mercer watched from a slight distance, the weight of command tangible upon his shoulders, though lightened by the shared burden now held amongst them. "We could be on the frontier of a new kind of diplomacy," he mused aloud, giving voice to the moment's gravity. + +At those words, Jordan's trance broke. "If that's the case, then these communications," Jordan motioned to the stream of data, "are our olive branch across the cosmos." + +Taylor Cruz, who paced with restless energy, halted and faced the team—his stoicism marred by the erratic dance of lights reflected in his eyes. "An olive branch, or an invitation to a battlefield?" he posed, ever the strategist, his words laced with a hint of cynicism. + +Sam Rivera, nestled amongst an array of equipment, licked their lips—a mixture of nerves and anticipation palpable. "We're mapping out something incredible here. Whether it's peace or war, we're the cartographers." + +Silence enveloped them like the expanse of space itself, each member contemplating the chasms they might bridge—or the abysses into which they might unwittingly descend. + +Alex's demeanor assumed a quiet resolve—the profound knowledge that this mission was as much about navigating uncharted philosophical territories as it was about ensuring survival. "Whichever it proves to be, we'll face it. Prepared, unified." + +A nod passed between Jordan and Alex, a silent exchange of mutual respect and shared mission. Sam, buoyed by the weighty encounters of the mind and machinery, entered keystrokes with a fervor that seemed to bring them ever closer to the alien mind. + +They stood there, the Paranormal Military Squad team, not just as guardians of homeworld secrets or as soldiers of clandestine wars, but as humankind's chosen few at the fulcrum of history—a history that was now unfolding to the rhythm of otherworldly codes. + +Each revelation, each parsed symbol, inched them toward the line between the earthly and otherworldly. And as they stood on this precipice of cosmic negotiations, it was clear the ensuing dialogue would not just shape the future of Paranormal Military Squad—it could very well redefine the parameters of human existence. + +\* + +The hum of advanced computational systems tingling with cryptic transmissions framed the ambiance of Dulce's mainframe chamber. Jordan Hayes, fingers hovering over a console dense with blinking lights, furrowed their brow as sequences of alien data streamed across the screen. + +Alex materialized behind them, his presence a stable beacon amidst the technological whirlwind. "Look for patterns, anomalies. Anything that might resemble a handshake protocol in their communications," he directed, his voice a low thrum, reverberating with cautious optimism. + +Jordan cast a glance over their shoulder, acknowledging Alex's contribution with the shared understanding of colleagues who had transcended mere professional acquaintance. "I’m isolating sequences that seem to recur with more intention than static. If these are their ‘handshakes,’ then we might just be making first contact," they remarked, their focus returning to the screen with renewed vigor. + +From the other end of the room, where shadows married the artificial light, Sam's voice crackled through the static of nearby speakers, "Don't forget the anomalies we detected earlier. Each one could be a word, a sentence, or even a concept untranslatable to our current understandings." + +Resolute, Taylor Cruz stood at Jordan's other side, a stoic figure wrestling with the implications of their mission. "Keep pursuing this line," Taylor instructed, an undercurrent of intensity carried forth in their otherwise composed demeanor. "And remember, this isn't just about making contact; it's about securing knowledge for humanity." + +Alex offered a nod that spoke volumes, conveying his understanding of the stakes at play. Here, in this chamber of possibility, the team's actions would determine if humanity stood at the brink of a new age of understanding or the onset of an unprecedented threat. + +Every second thrummed with significance as Jordan and Sam worked in tandem, each keystroke a foray into the unknown. Taylor observed with a commander's scrutiny, the gravity of their role sustaining them against the waves of ambiguity breaking against their resolve. + +Pivotal moments come rarely in the course of human events but here, amidst the electronic symphony of a stalwart command center, lay the incepting notes of a cosmic overture. The harmony between human and alien, between Paranormal Military Squad and the vast reaches of space, began its first tentative measures, with each member of the team a vital instrument in a celestial ensemble yet to be fully heard. + +\* + +The crisp air within the mainframe room of Dulce base seemed to hum with unspoken possibilities. Jordan Hayes was the centerpiece of focus, their hands dancing methodically over the console as streams of otherworldly code cascaded down monitors, each flicker a potential key to the cosmic doors they were inching open. + +Alex Mercer watched, posture relaxed but eyes sharp. "Remember, this could be our first introduction, maybe even our first impression," he said, mindful of the gravity carried by each action they made henceforth. + +A hint of a smile touched Jordan's face, a small acknowledgment of the monumental task at hand. "Understood. I'm balancing the signal's syntax with our algorithms. If we're interpreting this correctly, it could be... well, an invitation." + +Into the electric tension of the chamber walked Taylor Cruz, their silhouette a sharp contrast against the cool lighting, radiating a presence that spoke of command and chilly tenacity. "An invitation, or a challenge?” Taylor questioned, the weight of their suspicion casting a different tint on the cascading data. + +Sam Rivera, in a corner arrayed with sophisticated equipment, piped up, their voice a buoyant note amidst the tentative atmosphere. "Either way, it's a connection. One that we're uniquely positioned to navigate," they remarked with an air of optimism threading through the uncertainty. + +Alex channeled the strengths of his team into the core of their approach, his leadership adapting to the contours of an unprecedented scenario. "Cautious and curious," he reflected aloud, shaping a strategy that balanced their thirst for comprehension with the prudence required in addressing the unknown. + +Jordan, hands momentarily at rest, looked up. The signal was more than a sequence of bits and commands—it was a riddle wrapped in the depths of space-time, and they were on the cusp of parsing its meaning. + +Taylor, hardly a step away, nodded in silent agreement. The implications of their findings might very well direct the course of human destiny from this point onward. + +Finding a tempo among themselves, the Dulce team was a confluence of ambition and acumen, each member intuitive to the beats of discovery. The chamber around them held untold stories, secrets coaxed from the stars, that now, led by Paranormal Military Squad's finest, began to unravel. + +The future in those moments was unwritten, a narrative scribed not in the dust of desert confines, but in the potential for interstellar diplomacy and understanding. As they prepared to script humanity's next chapter, the room seemed to pulse with the heartbeat of a story far greater than the sum of its parts. + +## Chapter 8 + +The grit of an earthbound dust storm contrasted sharply with the pristine sterility of the underground command center. Alex Mercer, eyes set with fervent determination, stood over Jordan Hayes, whose fingers danced across the keyboard with rapid purpose. Monitoring the progression of alien code unraveling before them, Mercer spoke with a tempered urgency, "Keep it steady, Jordan. We might be initiating the first true interspecies communication bridge here. It's all about finesse now." + +Taylor Cruz, the embodiment of military precision, surveyed the room with a calculated gaze from their vigil beside an array of glimmering screens. "Remember, these could be delicate negotiations -- or coded threats. Stay sharp," Cruz added, their voice cool as polished steel. + +Jordan, with a silent nod, recognized the gravity of both stances. Gravitating between scientific acuity and diplomatic caution, they replied, "The sequence is aligning—syncing with our comms. It's looking more and more like direct engagement." + +Amid the banks of electronic machinery, the thrumming pulse of an impending interspecies signal exchange, Sam Rivera interjected with a youthful zeal that cut through the weighty atmosphere, "It's not just an exchange. It's a... symphony. It's as if they're teaching us their language through modulation." + +A moment of profound silence swept over the team. The isolation of their location, deep within the top-secret labyrinth of Dulce, became suffused with an almost palpable sense of historical significance. + +"Then our response needs to be equally symphonic," Alex uttered, contemplating the awe-inspiring transmutation of their task from a simple recovery mission to a full-blown cosmic concerto. + +With a renewed sense of wonder tempered by caution, the Paranormal Military Squad team found themselves harmonizing a delicate balance between envoys and interpreters. The long shadow cast by their duty was now illuminated by the brilliant glow of otherworldly dialogue. + +In this carefully orchestrated march towards the unknown, each individual's expertise became critical notes in a larger melody. The narrative of human achievement, so often defined by solitary pursuits, now emerged as a collaborative opus, each member of the team a maestro in their right. + +The protocols of encounters, the mathematics of languages, and the poetics of connection all fused into a singular moment of convergence. The echo of their efforts reverberated back to them, not through the cavernous base's concrete walls, but from light-years away, in the form of a reply, intangible yet infinitely profound. + +\* + +Amidst the hum of the supercomputers and the faint static from the scrambled transmissions, Alex Mercer cast a thoughtful glance across the dimly lit room toward where Dr. Jordan Hayes was methodically adjusting the archaic dials of the decryption machine. "Any progress?" he asked, his tone conveying both impatience and the deep-seated respect born from countless shared challenges. + +Jordan did not look up, their gaze remained locked on the flickering lights that represented a dialogue suspended between worlds. Their fingers ceased their dance, hovering meditatively over the controls. "We might be on the cusp of a breakthrough," Jordan suggested. "The signal... it's evolved. It's reflexive now, responsive in a way that suggests sentience." + +Taylor Cruz's familiar sharp strides approached the two, breaking the rhythm of soft beeps. "Responsive is good, if it means understanding," Taylor said, head tilted as they peered at the encryption data scrolling by. "But remember, comprehension can bring revelation or conflict." + +Sam Rivera’s youthful voice permeated the tension, brimming with an excitement edged by the enormity of what they faced. "If it's truly sentient, we're not just cracking a code; we're learning how to converse with an entirely new form of consciousness," they chimed in, the weight of history not lost on the zealous astrotechnician. + +Alex nodded, his thoughts alighting on potential strategies for navigating the conversation they were cultivating with the unfathomable. "We need to keep that conversation going, echo its patterns, and speak its language," he resolved, knowing the delicate nature of their work merited every ounce of their collective acumen. + +The chamber now was a crucible, forging within it the future narrative of human contact with the unknown. Every signal pulse they sent out was an invitation for understanding, and every echo back a step closer to bridging the cosmic divide. And so, together, they stood - agents in Paranormal Military Squad's clandestine ranks, united by purpose, sculpting humanity’s first sonnets into the void. + +\* + +#### Knowledge graph updates + +- (Jordan Hayes, Interprets, Communications as cosmic diplomacy, Moderate) + +- (Taylor Cruz, Questions, Potential aggressiveness of alien intent, Minor) + +- (Sam Rivera, Expresses, Optimism about forming a connection, Minor) + +- (Alex Mercer, Adopts, Balanced strategy for contact, Moderate) + +- (Paranormal Military Squad team, Navigates, Beats of cosmic discovery, Moderate) + +- (Paranormal Military Squad team, Prepares, To script humanity's interstellar narrative, Major) + +## Chapter 9 + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +Dr. Jordan Hayes, whose hands had been steadfastly working the decryption algorithms, paused and looked up at Alex. "We're through the next layer of encryption," Jordan announced, a mixture of pride and gravitas in their tone. "It's communicating. It's... aware." + +A shadow momentarily clouded Alex's determined features—awareness implied so much more than mere intelligence. "Aware and reactive or aware and proactive?" he queried, his experience anticipating the pivotal importance of intention. + +"Unknown at this stage," Taylor Cruz interjected, looking up from a datasheet. "But I urge caution. We tread the line between breakthrough and disaster with each keystroke." + +Sam Rivera, ever the source of technological acumen, added their voice to the conversation. "The signal's adapting every time we interact with it. Like a conversation where both parties are learning each other's language in real time." + +Alex leaned in, rested a hand on Jordan's shoulder—a sign of companionship and an affirmation of trust. "Keep the communication channels open. But let no message, no pulse go unchecked. This could be our Rosetta Stone or our Tower of Babel." + +Silence fell over them, a momentary lull as each member of the team contemplated the historic weight of their task. Yet, it was impregnated with a tangible sense of excitement—a collective energy that thrummed through the air just as palpably as the electric current through the banks of machines surrounding them. + +They continued their work, squaring shoulders against the magnitude of their undertaking. The agents were standing not just at the precipice of a new chapter for Paranormal Military Squad but for all of humanity. For now, they communicated with powerful unknowns, but with each exchange, they were etching the first words of a dialogue that might forever alter humanity's place in the cosmos. + +\* + +\* + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +Dr. Jordan Hayes, whose hands had been steadfastly working the decryption algorithms, paused and looked up at Alex. "We're through the next layer of encryption," Jordan announced, a mixture of pride and gravitas in their tone. "It's communicating. It's... aware." + +A shadow momentarily clouded Alex's determined features—awareness implied so much more than mere intelligence. "Aware and reactive or aware and proactive?" he queried, his experience anticipating the pivotal importance of intention. + +"Unknown at this stage," Taylor Cruz interjected, looking up from a datasheet. "But I urge caution. We tread the line between breakthrough and disaster with each keystroke." + +Sam Rivera, ever the source of technological acumen, added their voice to the conversation. "The signal's adapting every time we interact with it. Like a conversation where both parties are learning each other's language in real time." + +Alex leaned in, rested a hand on Jordan's shoulder—a sign of companionship and an affirmation of trust. "Keep the communication channels open. But let no message, no pulse go unchecked. This could be our Rosetta Stone or our Tower of Babel." + +Silence fell over them, a momentary lull as each member of the team contemplated the historic weight of their task. Yet, it was impregnated with a tangible sense of excitement—a collective energy that thrummed through the air just as palpably as the electric current through the banks of machines surrounding them. + +They continued their work, squaring shoulders against the magnitude of their undertaking. The agents were standing not just at the precipice of a new chapter for Paranormal Military Squad but for all of humanity. For now, they communicated with powerful unknowns, but with each exchange, they were etching the first words of a dialogue that might forever alter humanity's place in the cosmos. + +\* + +Alex Mercer's eyes were fixed on the monitors, the reflected light casting an ethereal glow across his stoic face. The room buzzed with tension, a cacophony of low hums and electronic beeps that underscored the historic nature of their actions. He moved to where Dr. Jordan Hayes was immersed in their work, scrutinizing the alien code streaming rapidly down the terminal. + +"Find anything that might look like an entry point or a... digital handshake?" Alex asked, his voice steady, betraying none of the tension gripping his chest. + +Jordan looked up briefly, their expression weary yet intense, "Potentially. It's as if the code is anticipating our input, modifying itself in real-time. I've never seen anything like it." + +From across the room, Taylor Cruz's sharp voice cut through the hum. "Then it's learning or, possibly worse, baiting us. Proceed with extreme caution," they commanded, their firm stance reinforcing the gravity of the situation. + +Sam Rivera, surrounded by a cascade of screens and interfaces, added, "It's almost organic in its complexity. Any minute now, and I might have a way in." + +A slight nod was Alex's immediate response, his mind racing through the potential scenarios. "Everyone, stay alert. This could be the beginning of something profound." His seasoned eyes never left the unfolding drama on the monitors. + +The room fell silent, the air heavy with unspoken questions. Were they mere moments away from unlocking an otherworldly dialogue? Or was it a Pandora's box that, once opened, could not be closed? + +Alex moved closer to the main console, his fingers hovering over the command keys. With the precision of a maestro orchestrating a symphony, he communicated silently with Jordan – respectful of their expertise, aware that the next move could alter the course of human history. + +Jordan met his gaze, nodding sharply, and refocused on the task. The signal seemed to pulse with sentient curiosity, drawing them further into its intricate web. + +A sudden flurry of alerts and the intensifying glow of monitors heralded that they had bridged a technological chasm. The alien intelligence on the other end was no longer a distant enigma – it was an active participant, responding to their digital overtures with an unknown agenda. + +The team's meticulous efforts had led them to a momentous threshold. Beyond lay unprecedented contact – a nexus of curiosity and potential peril. Within the confines of the base, against the backdrop of a silent desert night, the Paranormal Military Squad operatives became mediators of Earth's bid for cosmic relevance, their every action now a gesture in the grand dance of intergalactic relations. + +## Chapter 10 + +The corridors of the Dulce military base, now silent, echoed with a history of whispered conspiracies and furtive movements. But in the command center, a delicate tapestry of light and sound was being woven as the echoes of cosmic dialogue resonated through the high-tech enclave. Dr. Jordan Hayes, now leading the efforts, called out from their workstation, "I’ve isolated the signal's harmonics. It's more than a call; it's a song, an interstellar siren’s call." + +Alex Mercer, steady and resilient in the face of the incomprehensible, acknowledged with a quiet nod, "A song that we need to learn—quickly." His eyes, heavy with responsibility, scanned the room, watching his team work tirelessly at the intersection of science and speculation. + +Sam Rivera, dulled by fatigue yet driven by unshakeable resolve, manipulated a complex array of audio interfaces. "There's a pattern, a repeating motif. It's structured, intentional," they muttered, their revelation a bridge between the known and the unimaginable. + +Taylor Cruz, a figure of central authority, paced the length of the room, their usual unflappable demeanor betraying a rare flicker of apprehension. "We should be wary of the sirens’ call," Taylor interjected, invoking myths of old as a cautionary metaphor. "We don't want to crash upon unseen shores." + +Undeterred, Jordan cast a determined glance at the team. "We navigate by starlight now, not by the limited light of our previous understanding." Their voice was a beacon, charting a course through unchartered realities. + +Every individual was acutely aware that each moment in that room was a conduit to an epochal shift for civilization. The mysterious signals, once distant and alien, had coalesced into complex and harmonious oscillations—beacons of an extraterrestrial intellect inviting Earth to join in a cosmic consortium. + +Silently, Alex approached the mainframe, his trained fingers aligning with the console’s mechanisms. The room watched in collective breathlessness as he set the frequency in motion, an introductory phrase to an otherworldly melody—a symphony that could bind worlds or spell devastation for all they knew. + +In the control room of Dulce, amongst whispered legends and the quiet hum of machines, humanity's ambassadors now stood, stretching their hands into the void, reaching for the hand that would either pull them into the light of new stars or into the maw of darkness between them. + +\* + +Underground, the Dulce facility's command center was awash with frenetic energy, a stark juxtaposition against the silent, decrepit corridors that enveloped them. The air hummed with anticipation as Dr. Jordan Hayes and Alex Mercer hunched over a console. The sterile light from the monitors cast an otherworldly glow upon their faces, now reflecting a mosaic of alien characters rapidly translating across the screen. + +"The patterns are evolving," Jordan murmured, concentration etched into their every feature. "It’s as if our attempts to decrypt have accelerated its learning. It’s adapting to us." + +Alex, who stood steadfast behind Jordan, felt a tinge of uncharted fear quickly quelled by the fire of discovery raging within him. "Keep it up," he urged. "But whatever this is becoming, we need to ensure it remains within our control." + +Taylor Cruz interjected, their voice slicing through the buzz of activity. "Control may be an illusion when facing an intelligence that literally writes its own rules," they stated stoically, casting a watchful eye over the flurry of data. + +"It's like it's learning to communicate," offered Sam Rivera from a nearby interface, their youthful energy boding a mix of awe and anxiety. "This gives ‘talking to strangers’ a whole new meaning." + +Alex surveyed his team—each face a study in concentration, determination, and not a small measure of trepidation. "This might well be our first contact," he acknowledged, "And we need to be ready for whatever answers back." + +Together, they stood on the edge of the unknown, forging humanity’s response to a message from the heavens. The ensuing silence was palpable—a collective introspection about their role in this grand cosmic play, one that could rewrite human history. + +The encrypted dialogue continued to unfold, its intricate patterns showing an almost uncanny anticipation of their investigative strategies. The air turned heavy with the scent of electricity and ambition as they closed in on a pivotal response. + +As the signal’s intelligence—whether artificial or biological—grew more profound, so too did the realization that their mission had morphed from passive observation to active engagement. There was no turning back now. Each agent embraced their part in the delicate dance of an interstellar exchange that could change everything they thought they knew about life, intelligence, and the dark void beyond Earth's atmosphere. + +\* + +The underground halls of Dulce Base, usually buzzing with covert operations, now thrummed with a different kind of energy, an electric mix of fear and fascination. At the heart of the base, in a room shielded from the world’s eyes, Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera huddled around a bank of monitors. Each screen flickered erratically with the alien script that had become the center of their lives—and perhaps the pivot on which humanity’s future would turn. + +Jordan's eyes never wavered from the displays, their expression was one of rapt concentration, interspersed with flashes of revelation. "We're conversing with the stars," they whispered, almost to themselves. The words hung in the air, a testament to the awe-inspiring strangeness of the situation. + +"The language is morphing; changing its structure with every exchange we have," Sam chimed in, enthusiasm tinged with the solemnity of the occasion. "It's like witnessing the birth of a new form of dialogue—one that spans galaxies." + +Taylor, despite the situation's precariousness, maintained an appearance of ironclad composure. "Keep the communication stream secured and monitored. We don't know what we're dealing with yet," they reminded the team, a bastion of protocol amidst uncertainty. + +Alex watched his team expand the parameters of human achievement; their work here would possibly define an era. "This is untrodden territory," he acknowledged, "and in every word we script, in every response we decode, we're drawing a map that others will follow." + +Jordan turned to Alex, a nod acknowledging the shared responsibility of this moment. They had embarked on a new voyage, an odyssey not of the body, but of the intellect and spirit. No longer explorers of the Earthly realm, they had been promoted by circumstance to ambassadors of humanity in a silent and boundless ocean. + +A sudden pulse of energy from the monitors signaled a breakthrough; the language had not only adapted but it seemed to resonate, to harmonize with their attempts at making contact. The alien script now sprawled across the screens didn't just ask to be understood—it invited interpretation, collaboration, maybe even companionship across the cold distances of space. + +As they stood before the precipice of first contact, Paranormal Military Squad's finest became the architects of a symphony meant to echo through the cosmos. But more than architects, they were the first to play the notes of this cosmic composition, daring to believe that on the other end, someone—or something—might be listening, ready to join the chorus. + +\* + +The underground command center of Dulce Base, once pulsing with clandestine operations, now resonated with the charge of an impending cosmic threshold. Encircled by banks of whirring machinery, each monitor flickered erratically with alien script that had occupied center stage in the lives of Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera. + +Jordan's gaze didn’t flit for even a moment from the screens, where indiscernible alien messages ebbed and flowed like the tide. The ciphers and symbols cascaded down as they tweaked the algorithmic sliders. "This sequence here," Jordan began, voice both hushed and heavy, "it’s not just transmitting; it resonates—it's designed to be felt." + +The room took a collective breath, the remarkable implication hanging in the air like a careful revelation. Sam Rivera was the first to respond, their voice alive with ingenuity: "It's a form of communication stretching well beyond words. We need to respond in kind—the whole array of human expression might be at play here." + +Taylor's eyes remained fixed on the figures playing across the data sheets. "If that's the case," Taylor intoned pragmatically, "we must tread carefully. This is no longer just about being heard—it's about being understood." + +Alex watched his team, each a fulcrum of insight and expertise, and felt the solemnity of the role they were about to assume. "Then we'll ensure our message is clear and full. Our humanity is our strength in this dialogue," he declared, the depths of his experience fueling a commanding reassurance. + +The anticipation was palpable as the agents contemplated the vastness of their endeavor. They were not merely probing at the secrets of the planar cosmos—they were negotiating across the starry expanse, extending to distant intelligences the full spectrum of human curiosity and compassion. + +A symphony of beeping consoles orchestrated their next steps as they prepared to articulate their interplanetary overture. The rhythmic tapping of Jordan's keystrokes set the tempo for an undertaking that traversed beyond algorithms and encryption. + +The base withstood time and whispered secrets of its own, but none so grand as this moment of creation—an invitation to the universe that promised to echo through both the echoes of space and the annals of human history. + +## Chapter 11 + +The sterile silence of Dulce Base's command center was thick with concentration as Alex Mercer surveyed his team, hunched over their respective technological battle stations. Each agent was a weapon against ignorance, their adversary a code from beyond the stars that held secrets to alien thought. + +\* + +The thrum of the colossal machinery vibrated through the subterranean facility as Alex Mercer stood amidst the whispers of technology, each carrying voices from worlds apart. He watched as Sam Rivera adjusted a complex array of cosmic translators, their expression a mixture of anticipation and awe. + +"Are we ready, Mercer?" Taylor Cruz asked, the soft glow of the command center consoles reflecting upon their stern face. + +Alex turned towards Taylor, his eyes holding a depth that betrayed the enormity of the threshold they were about to cross. "This is it," he said. "Initiate the protocol. It's time we answer the cosmos." + +Jordan Hayes, stationed at the mainframe, typed rhythmically, a blue hue painting their focused features. The eerie silence that had settled over the team was interrupted by a visceral sound—humankind's response to the alien dialogue, now streaming into the abyss. + +The control room, once a fortress of solitude, erupted into an oasis of life. Lights flickered in tandem, echoing the symphony of interstellar communication. They stood together at the edge of discovery, facing the symmetry and discord of a universe unknown. + +"If we're right, we've just become Earth's first emissaries to a celestial congress we're only beginning to comprehend," Jordan's voice was somber, resonating with a mix of trepidation and honor. + +The room filled with the resonance of human and alien minds converging, creating a new narrative within the fathomless expanse of existence. Paranormal Military Squad, once protectors of Earth's clandestine secrets, had now become the tether linking humanity to the cosmic fold. + +\* + +The underground command center of Dulce Base, once pulsing with covert operations, now resonated with the charge of an impending cosmic threshold. Encircled by banks of whirring machinery, each monitor flickered erratically with alien script that had occupied center stage in the lives of Alex Mercer, Jordan Hayes, Taylor Cruz, and Sam Rivera. + +Jordan's gaze didn’t flit for even a moment from the screens, where indiscernible alien messages ebbed and flowed like the tide. The ciphers and symbols cascaded down as they tweaked the algorithmic sliders. "This sequence here," Jordan began, voice both hushed and heavy, "it’s not just transmitting; it resonates—it's designed to be felt." + +The room took a collective breath, the remarkable implication hanging in the air like a careful revelation. Sam Rivera was the first to respond, their voice alive with ingenuity: "It's a form of communication stretching well beyond words. We need to respond in kind—the whole array of human expression might be at play here." + +Taylor's eyes remained fixed on the figures playing across the data sheets. "If that's the case," Taylor intoned pragmatically, "we must tread carefully. This is no longer just about being heard—it's about being understood." + +Alex watched his team, each a fulcrum of insight and expertise, and felt the solemnity of the role they were about to assume. "Then we'll ensure our message is clear and full. Our humanity is our strength in this dialogue," he declared, the depths of his experience fueling a commanding reassurance. + +The anticipation was palpable as the agents contemplated the vastness of their endeavor. They were not merely probing at the secrets of the planar cosmos—they were negotiating across the starry expanse, extending to distant intelligences the full spectrum of human curiosity and compassion. + +A symphony of beeping consoles orchestrated their next steps as they prepared to articulate their interplanetary overture. The rhythmic tapping of Jordan's keystrokes set the tempo for an undertaking that traversed beyond algorithms and encryption. + +The base withstood time and whispered secrets of its own, but none so grand as this moment of creation—an invitation to the universe that promised to echo through both the echoes of space and the annals of human history. + +## Chapter 12 + +The underground facility of Dulce Base, once shrouded in silence and operational secrecy, now hummed with an energy that cradled the promise of cosmic revelation. Alex Mercer stood pensively by the central terminal, flanked by Dr. Jordan Hayes, Taylor Cruz, and Sam Rivera, each poised at the edge of a history-defining moment. + +Jordan's fingers ghosted across the console, tracing patterns of otherworldly origin. "The signal’s architecture is becoming more complex, resembling aspects of human cognition—recognition, learning, even... empathy?" they postulated with furrowed concern. + +Alex turned his gaze upon Jordan, his voice quiet but resolute, "Empathy could bridge galaxies. Let's harness this connection and proceed with cautious optimism." + +Taylor, ever the sober sentinel, projected a more pragmatic standpoint. "Empathy or not, we are duty-bound to assess the risk to humanity. Every new discovery warrants a measured response." + +The static hiss of communications equipment filled the air, its purpose now transformed into a dialogue with an intelligence beyond the stars. It was Sam, wide-eyed amid the myriad lights and switches, who broke the silence, "We have provisional confirmation of the signal’s intent—initiation. We’re being brought into a broader spectrum of cognizance." + +The chamber lay still for a heartbeat, the Paranormal Military Squad agents steeped in contemplation of the path unfurling before them—a path paved with possibilities of diplomacy or disruption, each step a venture further into the cosmic unknown. + +Alex stepped closer to the viewing monitors, each depicting alien symbols seemingly reaching out from the void. "Initiate the broadcast," he spoke with quiet command. "Our response will mark humanity’s readiness to partake in the wider conversation of conscious beings." + +Amidst the crackling air of expectation, the team wordlessly returned to their stations. They had transcended their roles as protectors of Earth's clandestine lore to become the harbingers of an interstellar parley that could change the existential course of life on their pale blue dot. + +The deep hum of the terminal emitted a signal—a testament to the uncanny reality that Earth was now actively partaking in an exchange not bound by gravity nor the limits of the solar wind. + +Here, in the depths of Dulce, a message from humanity woven from understanding and uncertainty was cast into the firmament, an epitheg of their desire to join the universal dialogue and discover their place among the constellations. + +\* + +The somber depths of the Dulce Base command center stood in stark counterpoint to the animated flurry of activity around the central comms array. Alex Mercer's silhouette loomed behind Dr. Jordan Hayes, who sat with a posture indicating laser focus on the decryption process. A quiet murmur of digital soundscape filled the space, subtly heightened by the anticipation of contact with an intelligence beyond the Earth. + +Jordan's voice was steady, betraying none of the extraordinary nature of their work, "Looking through the signal's pattern, it's evident we’re dealing with a form of intelligence—calculating, mirroring, possibly even understanding." + +Alex's reflection bounced off the darkened screens, his head nodding in silent affirmation. "We’re walking a delicate line. Our response should be thoughtful, measured. We’re ambassadors, not merely explorers." + +Taylor Cruz approached, arms folded, their words slicing through the din of careful keystrokes and soft whirrs, "If there’s even the slightest chance it understands, we can’t afford missteps. The language of the stars might be more absolute than ours." + +From another terminal, Sam Rivera brought youthful vigor to the conversation, "There’s rhythm in these patterns. If this is their way of reaching out, our reply should encapsulate all that we are—all that humanity stands for." + +Looking around at his team, Alex saw resolve etched on every face. The chamber, usually somber and echoing with the quiet steps of covert agents, now felt alive with the heartbeat of discovery. They were not just professionals operating in the gloom; they were a collective standing at the helm of a momentous journey. + +"Let’s begin," he said, returned by the resolve in his voice. "Every second counts." With that, they pressed forward, setting in motion a reply to a conversation billions of years in the making. + +The dance with an unseen partner commenced, each pulse they sent out a step taken with caution and hope. And as those digital pulses journeyed through the black sea of infinity, Earth, for perhaps the first time, joined a pan-galactic dialogue that whispered secrets of the cosmos—secrets that, until now, had been lost in the silent vastness of space. + +\* + +As the team stood in the centralized nerve center of Dulce's underground fortress, the solemn atmosphere was reverent, overseeing systems that engaged with an intelligence from the void. Alex's stance was contemplative as he gazed at Jordan Hayes, who presided over the console, the tension of the moment reaching a tactile fervor. Each rhythmic tap of Hayes's fingers on the keys was a foray into uncharted symphonies of contact. + +Observing Hayes unravel the dense alien encryption, Alex spoke, a diplomatic tenor underpinning his words, "Keep focused on the syntax, dissect its nuances. We're not just decoding signals; we're translating intentions." + +Without diverting from their task, Jordan acknowledged the insight. "Indeed, if their understanding of us is as deep as we hope, we're paving the way for dialogue far beyond our current realm." + +Taylor Cruz, near the rear of the room, provided a steady oversight. "As horizonless as our prospects may seem," Taylor intoned, "remain diligent. Complacency before alien cognition could spell catastrophe." + +Sam's youthful voice resonated with optimism, "Imagine—forming a rapport with a consciousness separate from our reality; we're drafting the bridge to stars alive with minds!" + +The sentiment hung for a moment before Alex gathered his conviction. "Dialogue is our vessel. We are not just agents of enigma; we are the threads that may weave a new cosmic relationship." His words seemed to reflect off the walls, reaching beyond the room's confines, a quiet yet resilient vow. + +Their task was titanic, stepping stones laid delicately into new territories of existence. The signal, once an esoteric strand in the echo of the universe, beckoned now with a clarity rocketing the complexity of thoughts from a distant order. + +Action by action, the Paranormal Military Squad team bridged the vast interstellar distances, their expertise and empathy casting a beacon of unity into frontiers of intelligence and knowledge. Their work, a partnership struck with an unseen cosmic congregation, each pulse sent and received a line in Earth's novitiate envoi to the cosmic shores. + +\* + +Under the stark, unforgiving lights of Dulce Base's underground command center, tension buzzed harder than the banks of supercomputers that lined the walls. Agent Alex Mercer leaned over the shoulder of Jordan Hayes, whose eyes were locked onto the display screen, where an incomprehensible series of alien symbols streamed past incessantly. + +“Any progress on the decryption?” Alex's voice was steady, a controlled presence necessary in the gravity of their undertaking. + +Jordan tapped a key, pausing the flow of code, and leaned back with a deep sigh. "We've broken through another subset of the cipher. It's revealing... well, indications of a complex society, not unlike our own." His eyes met Alex's with an unspoken question that hung heavily between them—were they truly prepared for what they might find? + +Taylor Cruz strode into the room, a tightly coiled spring of ambition and authority, and peered at the screen. "Understand their society, and we may predict behavior. Remain expedient—we don't know how much time we have before the situation shifts." There was an edge of stark realism to Taylor's words, the underlying message clear: every revelation bore its own set of risks. + +Alex nodded thoughtfully, recognizing the validity of Cruz's caution. Turning to Sam, who was tinkering with a device that buzzed quietly on the table, he asked, “Sam, can your contraption get us any further?” + +Sam looked up with a smirk, a twinkle of mischief in their eye. “It’s not just any contraption, it’s potentially a direct line to their thoughts. Give me a moment more, and I'll have something for you.” + +The air ticked with electronic beeps and the rustling sound of the Paranormal Military Squad team at work. They were so close to peering into the intelligence of an alien race—a reality on the brink of dramatically expanding their understanding of the universe. + +The machinery whirred in response to Sam’s precise touches, and suddenly, the room filled with a low hum—something had changed, a signal had been successfully sent. The team held their breath as they listened. The sound that filled the room was unmistakable: a response, an alien voice filtered through the static of space and time. + +Alex exchanged a look of quiet triumph with Jordan. The breakthrough was monumental; they were no longer casting messages into the void but engaged in a dialogue—an exchange that marked the beginning of Operation: Dulce’s true unfolding. This was it, the first steps into an interstellar odyssey that demanded every ounce of their courage and wit. + +## Chapter 13 + +Dr. Jordan Hayes shuffled a stack of papers, their eyes revealing a tinge of skepticism at Taylor Cruz's authoritarian performance. _Protocols_, Jordan thought, _are just the framework, the true challenges we're about to face lie well beyond the boundaries of any protocol._ They cleared their throat before speaking, tone cautious yet firm, "Let's remember, the unknown variables exceed the known. We should remain adaptive." + +A murmur of agreement echoed from Sam Rivera, who leaned forward, lacing their fingers together as if weaving a digital framework in the air before them, "Exactly, adaptability could be the key to interpreting the signal distortions and system malfunctions. We shouldn't discount the… erratic." + +Their words hung like an electric charge in the room, challenging Taylor's position with an inherent truth. Cruz’s jaw tightened almost imperceptibly, but the agent masked it with a small nod, conceding to the omnipresent threat of the unpredictable. + +Alex glanced at Jordan, who never looked back, their gaze fixed instead on a distant point, as if envisioning the immense dark corridors they were soon to navigate in Dulce. Jordan was not one to embrace fantastical theories, but the air of cautious calculation betrayed a mind bracing for confrontation with the inexplicable, an internal battle between the evidence of their research and the calculating skepticism that kept them alive in their field. + +The meeting adjourned with no further comments, the team members quietly retreading the paths to their personal preparations. Alex, trailing slightly behind, observed the others. _The cautious reserve Jordan wears like armor doesn't fool me_, he thought, _their analytical mind sees the patterns I do. And that's worth more than protocol. That's the connection we need to survive this._ + +As the agents dispersed into the labyrinth of the facility, lost in their thoughts and preparations, the base's halogen lights flickered, a brief and unnoticed harbingers of the darkness to come. + +\* + +The gritty, wind-tossed surface of New Mexico, just above the cavernous domain of Dulce Base, offered no shelter from the burgeoning storm—the scouring sands an earthly reminder of chaos theories in motion. Far beneath, a similar maelstrom brewed within the confines of the command center, as Paranormal Military Squad's handpicked squad stood poised for potential enormities of contact. + +Ruffling through printed transmission logs, Jordan Hayes dialed the focus of their analytical prowess onto the emerging pattern of signals crisscrossing between Earth and the unfathomable. "Our responses so far have echoed their complexity, but the real divergence is yet to come," Jordan remarked stoically, the calm belying the mounting surge of adrenaline for the revelation ahead. + +Alex Mercer's figure, a silhouette sharpened by the purpose, loomed at the periphery of the monitors' sickly glow. "Indeed," he assented, "The echoes are the easy part. It will be the introduction of our own, human variable that truly begins our dialogue." + +Taylor Cruz, windowless command center notwithstanding, appeared as though they could feel the tempest above. Their eyes never left the monitors as they unspooled their hard wisdom. "For all our advances, we find ourselves deciphering the swings and nuances of an interstellar pendulum. Predict its arc, and we may preempt the gravity of its message." + +Amidst a chorus of bleeps and static, Sam Rivera's tech-clad hands moved rhythmically, their spirited approach to unruly streams of data bordering an intimate dance with entropy. "Entropy that leads to discovery," Sam mused, responding to Taylor's metaphor. "Each step into the unknown is a step away from precedent." + +Alex, drawing near Jordan, spoke again, his voice now a thread woven through the very fabric of their operations. "Let's be the cartographers of this new territory. Our initial shades of understanding could color the cosmos for generations to come." + +Their gazes fell upon a screen as the latest transmission painted its digital blooms of alien script across the black. This time, the pattern wavered in an almost imperceptible fashion, a modification that whispered of active, alien thought awaiting their next move. A hush enveloped the Paranormal Military Squad ensemble, the gravity of the pathogen undeniable. They were about to issue a reply, one poised to reshape the very concept of humanity's outreach into the cosmos. + +The New Mexico desert's secrets were infamous, its storms a mere prelude to the revelations that the team—united in purpose—would unleash upon the world. The howling winds outside found their counterpart in the newfound resolve within, as Dulce's stalwart guardians readied themselves to send forth humanity's retort to the echoes from beyond. + +\* + +The cavernous control room, deeply entrenched beneath the desolate New Mexico terrain, held the Paranormal Military Squad team in intense focus; an island of calm amid the storm of cosmic dialectics. Dr. Jordan Hayes worked methodically, every keystroke an intricate step in their tenuous cosmic ballet. Suddenly, they paused, a signal pattern resonating from the screen. "This is new; it's...inviting. It’s as if the signal is not just calling to us but weaving its intelligence through ours." + +Alex Mercer scrutinized the shift in data. "A confluence of minds, then. If we're to meet them halfway, Jordan, our reply must be both innovative and discerning," he proposed, a glimmer of profound curiosity behind his authoritative demeanor. + +Taylor Cruz, whose sharp eyes missed nothing, nodded from beside a secondary panel. "Innovative, yes, but also defensive. This interaction is a razor’s edge, and we cannot afford to bleed before the unknown," Taylor reminded them, the metaphor a stark warning of potential dangers. + +Against the backdrop of their conversation, Sam Rivera’s youthful optimism cut through the tension. "If they’re weaving through our intellect, then we've achieved something beyond first contact—we're at the genesis of interstellar symbiosis," they posited with a mix of reverence and excitement. + +Alex returned Sam’s smile with his own, tempered and faint, as he turned back to the task at hand. The magnitude of their mission extended beyond the fabric of the universe, an exploration into the threads that connected sentient beings across the vast expanse. “Let’s reply with our own woven tapestry of thought—delicate, but deliberate.” + +With renewed determination, the room came alive with an undercurrent of anticipation, its occupants charged with the potential of forging an alliance with the cosmos. Paranormal Military Squad's finest were no longer merely soldiers and scientists; they had become pioneers on the vanguard of humanity’s greatest odyssey. + +The New Mexican sands above, impassive to the change brewing underneath, stood as silent sentinels as Earth's emissaries crafted their response. A response that, composed with care and imbued with humanity's essence, reached into the void, connecting with an otherworldly intelligence that awaited their harmony in the cosmic conversation. + +## Chapter 14 + +The command center of Dulce Base lay shrouded in shadows that seemed to claw at the edges of the dimly lit array of screens and consoles. Alex Mercer, focused and unwavering, watched as Dr. Jordan Hayes parsed the latest string of alien signals—a symphony of otherworldly communications that threatened to either enlighten or confound. + +"We’re encountering a paradigm shift with every transmission," Jordan Hayes murmured, the pulsing glow of the monitor painting their features with an almost spectral hue. "This signal... it’s evolving, becoming denser, more sophisticated. As if it's growing alongside us—tandem evolution." + +The air was electric, charged with the raw potential of uncharted discovery and laden with the gravity of existential risk. Taylor Cruz, who always seemed here to mold such gravity into actionable strategies, stepped forward. "We must contain this evolution within parameters we can manage. We cannot be bystanders to an uncontrolled ascent of intelligence." + +Sam Rivera, the youngest of the cohort, worked feverishly at their station. "It's not just intelligence—these signals have rhythm, a kind of music suggesting not just evolution, but a dance! We're being invited to partake in the cosmos's ballet!" they exclaimed, a touch of youthful exuberance breaking through the solemnity. + +Alex turned, facing his team, the stoic mask of command tempered by the perceptible flicker of awe in his gaze. "Let this dance then be our dialogue. We will match their steps with prudent but daring measures—our humanity as our guide." + +In the ensuing hours, the Paranormal Military Squad team forged a rhythm of their own, their collective expertise a beacon piercing through the fog of the unknown. The signal, increasingly intricate and seemingly conscious, now demanded not just observation but participation, an interstellar pas de deux that hummed with the promise and peril of first contact. + +Before them, the communications interface flickered to life with a received transmission—a resonant hum that seemed to vibrate through the very foundations of the base. They had successfully established a back-and-forth with whatever intelligence lay hidden among the stars. Every subsequent note they struck within the cosmic ether would come to define humanity's place within the galactic community—heralds of Earth's grand entrance into a universe far less silent than once perceived. + +\* + +In the concrete belly of Dulce Base, dimly lit by the jagged dance of fluorescent lights above, Sam Rivera perched on the edge of their seat, their eager fingers fluttering across an ancient keyboard. The stark, cold room—reminiscent of a time when covert operations and unspoken dread ruled supreme—now housed a peculiar blend of old-world machinery and sleek, modern interfaces. + +Alex Mercer, standing steadfast like a bridge between the enigmatic past and the unfathomable present, watched on. In his eyes flashed the foreboding excitement of change. "Sam," he started, his voice steadfast, "the patterns in these signals, what do they tell us about the nature of our... guest?" + +Sam's eyes glimmered with something akin to thrill—or was it trepidation? "It's like we're mirroring each other, evolving together through this.. dialogue. Like it knows us, understands us, and it's… learning." + +Jordan Hayes, preoccupied at a nearby console, chimed in without lifting their gaze. "It's a dialogue that transcends mere words, Alex. We're being woven into a narrative far grander than the sum of our known sciences." + +Taylor Cruz, arms crossed, wore the heavy mantle of their skepticism comfortably. "Keep theorizing," they interjected crisply, "but remember the grounding reality of what we are part of here. This contact is a blade that cuts both ways." + +In this cavern of history, voices both human and inhuman whispered secrets to those brave enough to listen. Each member present understood the gravity that pulled at their feet; no longer were they mere mortals shackled to their terrestrial plane. The digital pings and encrypted calls resonated with an implication of a cosmic agenda that would not be ignored. + +Jordan's fingers paused, hovering in hesitation. What ripple might the next keystroke send through the fabric of known existence? It was a step into the ballet of the infinite, where the Paranormal Military Squad team played their part in the waltz of wonders with an audience of stars. + +\* + +## Chapter 15 + +In the clandestine hush of Dulce Base's subterranean command center, the Paranormal Military Squad team had become a crucible for interstellar communication. Dr. Jordan Hayes' gaze lingered on the screen as they navigated through the convolution of alien code. Each character held the potential to unravel a new dimension of contact, and with Sam Rivera's keen interjection, they were crafting humanity's inaugural cosmological discourse. + +Alex Mercer peered over Jordan's shoulder, calculating the implications of every visual nuance that cascaded across the monitor. "Look for consistency—any repeating motifs could signal a willingness to engage. We're drafting history with each exchange," he remarked, aware of the delicate balance between forging a bond and exposing vulnerabilities. + +Taylor Cruz, stoic and enigmatic, observed the interplay from the threshold, a silhouette against the machinery's luminescence. "Remember, while we seek common ground, the foundation we stand upon remains Terra firma. Caution must temper our curiosity," they stated, their voice an anchor amidst the current of excitement. + +The command center buzzed with energy, rivaled only by the tempest overhead that concealed their operation. Sam, with swift dexterity, navigated the communications relay. "Their signals resonate almost musically. It's as if they're composing a symphony, and we've been handed the baton to conduct the next movement," they offered, imbuing the scenario with a blend of scientific adventurism and poetic license. + +Amidst the whirring servers and the occasional flicker of emergency lighting, the essence of their mission transcended mere reconnaissance. They were humanity's elected envoys at the brink of a celestial alliance—or confrontation—with an audience as vast as the universe itself. + +Alex stepped back, his profile etched by the chamber's artificial day. "Then let's ensure our contribution to this symphony harmonizes with theirs. It's time for humanity's voice to rise and be counted among the cosmic ensemble." + +Under his directive, the Paranormal Military Squad team initiated their calculated response, weaving thoughts and theories into a digital overture aimed at the heart of alien intellect. As the digital stream punctured the endless night, each member of this clandestine group was acutely aware of the irrevocable step they undertook—bringing Earth into the pantheon of galactic entities designed to converse among the stars. + +\* + +Clusters of high-tech equipment bathed the Dulce underground command center in an eerie blue light. Sam Rivera's fingers flew across the keyboard, navigating an elaborate network of alien patterns. The very air seemed to pulse with the ebb and flow of cryptic communications reaching across the stars. "I've got something!" Sam's announcement tore through the focus in the room, drawing every pair of eyes to the torrent of symbols unraveling on the screen. + +With the pacing of a seasoned officer gauging the moment before action, Alex Mercer approached, his calm demeanor belying an acute awareness of the precipice on which they now stood. "Define 'something," Alex prompted, reinforcing the need for clarity amidst the extraordinary. + +"It's repeating—a sequence that’s evolved with each interaction, almost as if it's... singing," Sam theorized, the awe in their voice reflecting the potential magnitude of their discovery. + +Jordan Hayes interjected from across the console, their eyes not leaving the display as they absorbed the new data. "A cosmic vocalization, then," they mused, intrigued. "A singularity in the signal that might represent a point of reference for both parties." + +Taylor Cruz, hands clasped behind their back, regarded the unfolding scene, their own calculations etching lines of concern onto their stern visage. "Or a beacon—a homing tune, calling out to something we might not be ready to greet," Taylor offered, voicing the group's unspoken apprehension. + +Alex's eyes locked on the screen, taking in the scope of what they were attempting to interpret. Drawing a deep breath, Alex gave a slight nod. "If this is their song, then let us respond with ours. We've come this far by mirroring their signals, now let's engage in an interstellar duet, and see where the music leads us." + +With the expectation of the significant achieving a crescendo, the members of Paranormal Military Squad huddled over their equipment—sages at the threshold of a potentially world-altering communion. The strange harmonies that reverberated through the command center suggested that their interlocutors were poised, waiting, perhaps even eager, for Earth's chorus to join the symphony. + +As the team initiated their reply, weaving humanity's own intricate melody into the vast cosmic dialogue, they each felt a profound change within—an evolution of purpose. They were not just messengers or investigators; they had become co-composers in a galactic orchestra, with the universe itself as their witness and concert hall. + +With the exchange of harmonious signals crawling through the vacuum of space, the Paranormal Military Squad operatives found themselves part of a bridging of minds—a realization that out there, among the vast arrays of stars and planets, harmony was the true universal language. + +\* + +The dim glow of monitors cast an otherworldly ambiance upon Dulce Base's command center, where Paranormal Military Squad's chosen stood huddled over their instruments, suspended at history's threshold. Codes—alien in origin and nature—were being deciphered by Dr. Jordan Hayes, whose countenance bore the marks of deep concentration. + +Alex Mercer, the bedrock upon which their team's resolve was founded, leaned in with an eagerness tempered by his chain of command. "Jordan, we've invested our expertise into comprehending their patterns, but now we must also endeavor to understand their intent," he urged, his voice bearing the gravitas of their mission's potential consequences. + +At another console, Sam Rivera's youth did not betray their crucial role in the operation. With eyes alight, they mirrored the rapid computing before them. "There's emotion here—complex, profound even. This isn't just the output of a cold machine; it's...sentience," Sam whispered, nearly drowned by the mechanical chorus around them. + +Jordan, without shifting focus from their work, replied, "It's a sentience that—should we succeed here—ushers us into a new era of existence. The cadence of these signals," they tapped the screen with a flourish, "could well be the heartbeat of this new dawn." + +Taylor Cruz paused beside Mercer, their expression unreadable beneath the sterile light. "And as it beats, we must gauge whether its rhythm bodes well for us, or spells our missteps. Courage must not blind us to the hazards intrinsic to such contact," Taylor cautioned, the sentinel within them ever alert. + +Alex nodded, a gesture that carried the weight of responsibility and a silent command: proceed, but with circumspection. They were not merely decoding a message; they were interpreting a dialogue across the celestial divide. + +The room fell into a rhythm akin to a well-conducted ensemble. Each member's expertise proved a critical note in the unfolding symphony. Their actions were now more than mere research or defense; they were the tentative overtures of humankind reaching out to grasp the vast unknown. + +Textures of sound meshed with the light from countless computations, the palpable anticipation of the agents at the edge of discovery cresting with an awareness that their work would reshape future chronicles. And when the response finally came—a signal piercing the deafening silence of uncertainty—all within Dulce's confines understood: the dawn of an interstellar continuum had just begun to break. + +\* + +In the sterile hum and flickering lights of Dulce Base's command center, the Paranormal Military Squad team stood as humanity's vanguard, verging on the brim of an intergalactic abyss. Dr. Jordan Hayes, analytical edges sharp, deciphered extraterrestrial patterns that bled across screens in enigmatic cascades—a daunting mosaic of potential threats and untapped wisdom. + +Agent Alex Mercer, the embodiment of focus and a steadfast nerve, observed the unfolding digital drama with the gravitas due a historic first contact. "Let the data weave its narrative, Jordan," he instructed, a moderate undertone of exhilaration within his command. "It's encoding more than information—it's outlining civilization." + +Jordan absorbed the directive, their gaze unflinching from the screens, feeling the weight of their next move. "The nuances here are extraordinary," they acknowledged. "It paints a picture of a culture steeped in complexities we're only starting to fathom.” + +Taylor Cruz, stoicism personified yet not immune to the situation's gravity, chimed in. "Understand it, but guard against it," they cautioned, bringing a sober prudence to the room. "This culture, however advanced, remains an unknown quantity—an ocean of wonders and darkness with uncertain tides." + +Sam Rivera, a visual contrast with wide eyes and restless hands, represented the other side of the room — intrigue and optimism against the drawn swords of precaution. “Think of it,” they proposed, voice bouncing with a rebellious upbeat timbre, “as the first act of a play written in constellations. We're setting the stage for a galactic narrative.” + +Each team member, in their way, was both actor and scribe in this moment of tense pageantry. Heavy with the presence of risk, the command center had become not just a room of computers and glass panels but a theater for performing the elaborate choreography of contact. + +Bound by resolve and curiosity, they proceeded, each data entry a trembling step onto the cosmic stage. And like all cautious pioneers edging into fertile but unnavigated lands, they understood: as they mapped the heavens, they were simultaneously mapping the furthest reaches of their own existential horizons. + diff --git a/graphrag/tests/fixtures/text/settings.yml b/graphrag/tests/fixtures/text/settings.yml new file mode 100644 index 0000000000000000000000000000000000000000..f5d6e2b591705d18b45be8152cd9b15ebb88e62c --- /dev/null +++ b/graphrag/tests/fixtures/text/settings.yml @@ -0,0 +1,14 @@ +claim_extraction: + enabled: true + +embeddings: + vector_store: + type: "azure_ai_search" + url: ${AZURE_AI_SEARCH_URL_ENDPOINT} + api_key: ${AZURE_AI_SEARCH_API_KEY} + collection_name: "simple_text_ci" + query_collection_name: "simple_text_ci_query" + store_in_table: True + + entity_name_description: + title_column: "name" diff --git a/graphrag/tests/integration/__init__.py b/graphrag/tests/integration/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/integration/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/integration/_pipeline/__init__.py b/graphrag/tests/integration/_pipeline/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/integration/_pipeline/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/integration/_pipeline/megapipeline.yml b/graphrag/tests/integration/_pipeline/megapipeline.yml new file mode 100644 index 0000000000000000000000000000000000000000..bc48af0d713cbb2020bd4fa29975a722c6904d28 --- /dev/null +++ b/graphrag/tests/integration/_pipeline/megapipeline.yml @@ -0,0 +1,72 @@ +input: + file_type: text + base_dir: ../../fixtures/min-csv + file_pattern: .*\.txt$ + +storage: + type: memory + +cache: + type: memory + +workflows: + - name: create_base_text_units + config: + text_chunk: + strategy: + type: sentence + + # Just lump everything together + chunk_by: [] + + - name: create_base_extracted_entities + config: + graphml_snapshot: True + entity_extract: + strategy: + type: nltk + + - name: create_base_entity_graph + config: + graphml_snapshot: True + embed_graph_enabled: True + cluster_graph: + strategy: + type: leiden + verbose: True + + - name: create_final_nodes + + - name: create_base_documents + + # - name: create_final_community_reports + # config: + # create_community_reports: + # <<: *llm_parallel_config + # strategy: + # type: graph_intelligence + # llm: *llm_config + + - name: create_final_communities + - name: create_final_text_units + config: + text_embed: + strategy: + type: mock + + - name: create_final_entities + config: + text_embed: + strategy: + type: mock + + - name: create_final_documents + config: + text_embed: + strategy: + type: mock + - name: create_final_relationships + config: + text_embed: + strategy: + type: mock diff --git a/graphrag/tests/integration/_pipeline/test_run.py b/graphrag/tests/integration/_pipeline/test_run.py new file mode 100644 index 0000000000000000000000000000000000000000..5eba5de80d83b133816c13bd5457698bd1708f4a --- /dev/null +++ b/graphrag/tests/integration/_pipeline/test_run.py @@ -0,0 +1,75 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import logging +import os +import unittest + +from graphrag.index.run import run_pipeline_with_config +from graphrag.index.typing import PipelineRunResult + +log = logging.getLogger(__name__) + + +class TestRun(unittest.IsolatedAsyncioTestCase): + async def test_megapipeline(self): + pipeline_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "./megapipeline.yml", + ) + pipeline_result = [gen async for gen in run_pipeline_with_config(pipeline_path)] + + errors = [] + for result in pipeline_result: + if result.errors is not None and len(result.errors) > 0: + errors.extend(result.errors) + + if len(errors) > 0: + print("Errors: ", errors) + assert len(errors) == 0, "received errors\n!" + "\n".join(errors) + + self._assert_text_units_and_entities_reference_each_other(pipeline_result) + + def _assert_text_units_and_entities_reference_each_other( + self, pipeline_result: list[PipelineRunResult] + ): + text_unit_df = next( + filter(lambda x: x.workflow == "create_final_text_units", pipeline_result) + ).result + entity_df = next( + filter(lambda x: x.workflow == "create_final_entities", pipeline_result) + ).result + + assert text_unit_df is not None, "Text unit dataframe should not be None" + assert entity_df is not None, "Entity dataframe should not be None" + + # Get around typing issues + if text_unit_df is None or entity_df is None: + return + + assert len(text_unit_df) > 0, "Text unit dataframe should not be empty" + assert len(entity_df) > 0, "Entity dataframe should not be empty" + + text_unit_entity_map = {} + log.info("text_unit_df %s", text_unit_df.columns) + + for _, row in text_unit_df.iterrows(): + values = row.get("entity_ids", []) + text_unit_entity_map[row["id"]] = set([] if values is None else values) + + entity_text_unit_map = {} + for _, row in entity_df.iterrows(): + # ALL entities should have text units + values = row.get("text_unit_ids", []) + entity_text_unit_map[row["id"]] = set([] if values is None else values) + + text_unit_ids = set(text_unit_entity_map.keys()) + entity_ids = set(entity_text_unit_map.keys()) + + for text_unit_id, text_unit_entities in text_unit_entity_map.items(): + assert text_unit_entities.issubset( + entity_ids + ), f"Text unit {text_unit_id} has entities {text_unit_entities} that are not in the entity set" + for entity_id, entity_text_units in entity_text_unit_map.items(): + assert entity_text_units.issubset( + text_unit_ids + ), f"Entity {entity_id} has text units {entity_text_units} that are not in the text unit set" diff --git a/graphrag/tests/notebook/__init__.py b/graphrag/tests/notebook/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/notebook/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/notebook/test_notebooks.py b/graphrag/tests/notebook/test_notebooks.py new file mode 100644 index 0000000000000000000000000000000000000000..9c1e789c2f95601569620c9347153853f19b7524 --- /dev/null +++ b/graphrag/tests/notebook/test_notebooks.py @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import subprocess +import tempfile +from pathlib import Path + +import nbformat +import pytest + +DOCS_PATH = Path("../../docsite") + +notebooks_list = list(DOCS_PATH.rglob("*.ipynb")) + + +def _notebook_run(filepath: Path): + """Execute a notebook via nbconvert and collect output. + :returns execution errors + """ + with tempfile.NamedTemporaryFile(suffix=".ipynb") as temp_file: + args = [ + "jupyter", + "nbconvert", + "--to", + "notebook", + "--execute", + "-y", + "--no-prompt", + "--output", + temp_file.name, + filepath.absolute().as_posix(), + ] + subprocess.check_call(args) + + temp_file.seek(0) + nb = nbformat.read(temp_file, nbformat.current_nbformat) + + return [ + output + for cell in nb.cells + if "outputs" in cell + for output in cell["outputs"] + if output.output_type == "error" + ] + + +@pytest.mark.parametrize("notebook_path", notebooks_list) +def test_notebook(notebook_path: Path): + assert _notebook_run(notebook_path) == [] diff --git a/graphrag/tests/smoke/__init__.py b/graphrag/tests/smoke/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/smoke/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/smoke/test_fixtures.py b/graphrag/tests/smoke/test_fixtures.py new file mode 100644 index 0000000000000000000000000000000000000000..b114b8291a27a0cac328007c4fdba3186010deb5 --- /dev/null +++ b/graphrag/tests/smoke/test_fixtures.py @@ -0,0 +1,302 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import json +import logging +import os +import shutil +import subprocess +from collections.abc import Callable +from functools import wraps +from pathlib import Path +from typing import Any, ClassVar +from unittest import mock + +import pandas as pd +import pytest + +from graphrag.index.storage.blob_pipeline_storage import BlobPipelineStorage + +log = logging.getLogger(__name__) + +debug = os.environ.get("DEBUG") is not None +gh_pages = os.environ.get("GH_PAGES") is not None + +# cspell:disable-next-line well-known-key +WELL_KNOWN_AZURITE_CONNECTION_STRING = "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1" + + +def _load_fixtures(): + """Load all fixtures from the tests/data folder.""" + params = [] + fixtures_path = Path("./tests/fixtures/") + # use the min-csv smoke test to hydrate the docsite parquet artifacts (see gh-pages.yml) + subfolders = ["min-csv"] if gh_pages else sorted(os.listdir(fixtures_path)) + + for subfolder in subfolders: + if not os.path.isdir(fixtures_path / subfolder): + continue + + config_file = fixtures_path / subfolder / "config.json" + with config_file.open() as f: + params.append((subfolder, json.load(f))) + + return params + + +def pytest_generate_tests(metafunc): + """Generate tests for all test functions in this module.""" + run_slow = metafunc.config.getoption("run_slow") + configs = metafunc.cls.params[metafunc.function.__name__] + + if not run_slow: + # Only run tests that are not marked as slow + configs = [config for config in configs if not config[1].get("slow", False)] + + funcarglist = [params[1] for params in configs] + id_list = [params[0] for params in configs] + + argnames = sorted(arg for arg in funcarglist[0] if arg != "slow") + metafunc.parametrize( + argnames, + [[funcargs[name] for name in argnames] for funcargs in funcarglist], + ids=id_list, + ) + + +def cleanup(skip: bool = False): + """Decorator to cleanup the output and cache folders after each test.""" + + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except AssertionError: + raise + finally: + if not skip: + root = Path(kwargs["input_path"]) + shutil.rmtree(root / "output", ignore_errors=True) + shutil.rmtree(root / "cache", ignore_errors=True) + + return wrapper + + return decorator + + +async def prepare_azurite_data(input_path: str, azure: dict) -> Callable[[], None]: + """Prepare the data for the Azurite tests.""" + input_container = azure["input_container"] + input_base_dir = azure.get("input_base_dir") + + root = Path(input_path) + input_storage = BlobPipelineStorage( + connection_string=WELL_KNOWN_AZURITE_CONNECTION_STRING, + container_name=input_container, + ) + # Bounce the container if it exists to clear out old run data + input_storage.delete_container() + input_storage.create_container() + + # Upload data files + txt_files = list((root / "input").glob("*.txt")) + csv_files = list((root / "input").glob("*.csv")) + data_files = txt_files + csv_files + for data_file in data_files: + with data_file.open(encoding="utf8") as f: + text = f.read() + file_path = ( + str(Path(input_base_dir) / data_file.name) + if input_base_dir + else data_file.name + ) + await input_storage.set(file_path, text, encoding="utf-8") + + return lambda: input_storage.delete_container() + + +class TestIndexer: + params: ClassVar[dict[str, list[tuple[str, dict[str, Any]]]]] = { + "test_fixture": _load_fixtures() + } + + def __run_indexer( + self, + root: Path, + input_file_type: str, + ): + command = [ + "poetry", + "run", + "poe", + "index", + "--verbose" if debug else None, + "--root", + root.absolute().as_posix(), + "--reporter", + "print", + ] + command = [arg for arg in command if arg] + log.info("running command ", " ".join(command)) + completion = subprocess.run( + command, env={**os.environ, "GRAPHRAG_INPUT_FILE_TYPE": input_file_type} + ) + assert ( + completion.returncode == 0 + ), f"Indexer failed with return code: {completion.returncode}" + + def __assert_indexer_outputs( + self, root: Path, workflow_config: dict[str, dict[str, Any]] + ): + outputs_path = root / "output" + output_entries = list(outputs_path.iterdir()) + # Sort the output folders by creation time, most recent + output_entries.sort(key=lambda entry: entry.stat().st_ctime, reverse=True) + + if not debug: + assert ( + len(output_entries) == 1 + ), f"Expected one output folder, found {len(output_entries)}" + + output_path = output_entries[0] + assert output_path.exists(), "output folder does not exist" + + artifacts = output_path / "artifacts" + assert artifacts.exists(), "artifact folder does not exist" + + # Check stats for all workflow + with (artifacts / "stats.json").open() as f: + stats = json.load(f) + + # Check all workflows run + expected_workflows = set(workflow_config.keys()) + workflows = set(stats["workflows"].keys()) + assert ( + workflows == expected_workflows + ), f"Workflows missing from stats.json: {expected_workflows - workflows}. Unexpected workflows in stats.json: {workflows - expected_workflows}" + + # [OPTIONAL] Check subworkflows + for workflow in expected_workflows: + if "subworkflows" in workflow_config[workflow]: + # Check number of subworkflows + subworkflows = stats["workflows"][workflow] + expected_subworkflows = workflow_config[workflow].get( + "subworkflows", None + ) + if expected_subworkflows: + assert ( + len(subworkflows) - 1 == expected_subworkflows + ), f"Expected {expected_subworkflows} subworkflows, found: {len(subworkflows) - 1} for workflow: {workflow}: [{subworkflows}]" + + # Check max runtime + max_runtime = workflow_config[workflow].get("max_runtime", None) + if max_runtime: + assert ( + stats["workflows"][workflow]["overall"] <= max_runtime + ), f"Expected max runtime of {max_runtime}, found: {stats['workflows'][workflow]['overall']} for workflow: {workflow}" + + # Check artifacts + artifact_files = os.listdir(artifacts) + assert ( + len(artifact_files) == len(expected_workflows) + 1 + ), f"Expected {len(expected_workflows) + 1} artifacts, found: {len(artifact_files)}" + + for artifact in artifact_files: + if artifact.endswith(".parquet"): + output_df = pd.read_parquet(artifacts / artifact) + artifact_name = artifact.split(".")[0] + workflow = workflow_config[artifact_name] + + # Check number of rows between range + assert ( + workflow["row_range"][0] + <= len(output_df) + <= workflow["row_range"][1] + ), f"Expected between {workflow['row_range'][0]} and {workflow['row_range'][1]}, found: {len(output_df)} for file: {artifact}" + + # Get non-nan rows + nan_df = output_df.loc[ + :, ~output_df.columns.isin(workflow.get("nan_allowed_columns", [])) + ] + nan_df = nan_df[nan_df.isna().any(axis=1)] + assert ( + len(nan_df) == 0 + ), f"Found {len(nan_df)} rows with NaN values for file: {artifact} on columns: {nan_df.columns[nan_df.isna().any()].tolist()}" + + def __run_query(self, root: Path, query_config: dict[str, str]): + command = [ + "poetry", + "run", + "poe", + "query", + "--root", + root.absolute().as_posix(), + "--method", + query_config["method"], + "--community_level", + str(query_config.get("community_level", 2)), + query_config["query"], + ] + + log.info("running command ", " ".join(command)) + return subprocess.run(command, capture_output=True, text=True) + + @cleanup(skip=debug) + @mock.patch.dict( + os.environ, + { + **os.environ, + "BLOB_STORAGE_CONNECTION_STRING": os.getenv( + "GRAPHRAG_CACHE_CONNECTION_STRING", WELL_KNOWN_AZURITE_CONNECTION_STRING + ), + "LOCAL_BLOB_STORAGE_CONNECTION_STRING": WELL_KNOWN_AZURITE_CONNECTION_STRING, + "GRAPHRAG_CHUNK_SIZE": "1200", + "GRAPHRAG_CHUNK_OVERLAP": "0", + "AZURE_AI_SEARCH_URL_ENDPOINT": os.getenv("AZURE_AI_SEARCH_URL_ENDPOINT"), + "AZURE_AI_SEARCH_API_KEY": os.getenv("AZURE_AI_SEARCH_API_KEY"), + }, + clear=True, + ) + @pytest.mark.timeout(600) # Extend the timeout to 600 seconds (10 minutes) + def test_fixture( + self, + input_path: str, + input_file_type: str, + workflow_config: dict[str, dict[str, Any]], + query_config: list[dict[str, str]], + ): + if workflow_config.get("skip", False): + print(f"skipping smoke test {input_path})") + return + + azure = workflow_config.get("azure") + root = Path(input_path) + dispose = None + if azure is not None: + dispose = asyncio.run(prepare_azurite_data(input_path, azure)) + + print("running indexer") + self.__run_indexer(root, input_file_type) + print("indexer complete") + + if dispose is not None: + dispose() + + if not workflow_config.get("skip_assert", False): + print("performing dataset assertions") + self.__assert_indexer_outputs(root, workflow_config) + + print("running queries") + for query in query_config: + result = self.__run_query(root, query) + print(f"Query: {query}\nResponse: {result.stdout}") + + # Check stderr because lancedb logs path creating as WARN which leads to false negatives + stderror = ( + result.stderr if "No existing dataset at" not in result.stderr else "" + ) + + assert stderror == "", f"Query failed with error: {stderror}" + assert result.stdout is not None, "Query returned no output" + assert len(result.stdout) > 0, "Query returned empty output" diff --git a/graphrag/tests/unit/__init__.py b/graphrag/tests/unit/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/config/__init__.py b/graphrag/tests/unit/config/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/config/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/config/prompt-a.txt b/graphrag/tests/unit/config/prompt-a.txt new file mode 100644 index 0000000000000000000000000000000000000000..af744d0eb068432d2651a9cea6f5e72152b599cb --- /dev/null +++ b/graphrag/tests/unit/config/prompt-a.txt @@ -0,0 +1 @@ +Hello, World! A \ No newline at end of file diff --git a/graphrag/tests/unit/config/prompt-b.txt b/graphrag/tests/unit/config/prompt-b.txt new file mode 100644 index 0000000000000000000000000000000000000000..2e12b140adf70d037deb8846a8161e4a49c119aa --- /dev/null +++ b/graphrag/tests/unit/config/prompt-b.txt @@ -0,0 +1 @@ +Hello, World! B \ No newline at end of file diff --git a/graphrag/tests/unit/config/prompt-c.txt b/graphrag/tests/unit/config/prompt-c.txt new file mode 100644 index 0000000000000000000000000000000000000000..f55e9771a0b31a620325464f39f55128e3d9a10f --- /dev/null +++ b/graphrag/tests/unit/config/prompt-c.txt @@ -0,0 +1 @@ +Hello, World! C \ No newline at end of file diff --git a/graphrag/tests/unit/config/prompt-d.txt b/graphrag/tests/unit/config/prompt-d.txt new file mode 100644 index 0000000000000000000000000000000000000000..bd6438515bf865d9dd3ac7f233a8d32417cfcef6 --- /dev/null +++ b/graphrag/tests/unit/config/prompt-d.txt @@ -0,0 +1 @@ +Hello, World! D \ No newline at end of file diff --git a/graphrag/tests/unit/config/test_default_config.py b/graphrag/tests/unit/config/test_default_config.py new file mode 100644 index 0000000000000000000000000000000000000000..6cde9475fb975ccea07821c18607b9b946b8ed46 --- /dev/null +++ b/graphrag/tests/unit/config/test_default_config.py @@ -0,0 +1,947 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import json +import os +import re +import unittest +from pathlib import Path +from typing import Any, cast +from unittest import mock + +import pytest +import yaml +from pydantic import ValidationError + +import graphrag.config.defaults as defs +from graphrag.config import ( + ApiKeyMissingError, + AzureApiBaseMissingError, + AzureDeploymentNameMissingError, + CacheConfig, + CacheConfigInput, + CacheType, + ChunkingConfig, + ChunkingConfigInput, + ClaimExtractionConfig, + ClaimExtractionConfigInput, + ClusterGraphConfig, + ClusterGraphConfigInput, + CommunityReportsConfig, + CommunityReportsConfigInput, + EmbedGraphConfig, + EmbedGraphConfigInput, + EntityExtractionConfig, + EntityExtractionConfigInput, + GlobalSearchConfig, + GraphRagConfig, + GraphRagConfigInput, + InputConfig, + InputConfigInput, + InputFileType, + InputType, + LLMParameters, + LLMParametersInput, + LocalSearchConfig, + ParallelizationParameters, + ReportingConfig, + ReportingConfigInput, + ReportingType, + SnapshotsConfig, + SnapshotsConfigInput, + StorageConfig, + StorageConfigInput, + StorageType, + SummarizeDescriptionsConfig, + SummarizeDescriptionsConfigInput, + TextEmbeddingConfig, + TextEmbeddingConfigInput, + UmapConfig, + UmapConfigInput, + create_graphrag_config, +) +from graphrag.index import ( + PipelineConfig, + PipelineCSVInputConfig, + PipelineFileCacheConfig, + PipelineFileReportingConfig, + PipelineFileStorageConfig, + PipelineInputConfig, + PipelineTextInputConfig, + PipelineWorkflowReference, + create_pipeline_config, +) + +current_dir = os.path.dirname(__file__) + +ALL_ENV_VARS = { + "GRAPHRAG_API_BASE": "http://some/base", + "GRAPHRAG_API_KEY": "test", + "GRAPHRAG_API_ORGANIZATION": "test_org", + "GRAPHRAG_API_PROXY": "http://some/proxy", + "GRAPHRAG_API_VERSION": "v1234", + "GRAPHRAG_ASYNC_MODE": "asyncio", + "GRAPHRAG_CACHE_STORAGE_ACCOUNT_BLOB_URL": "cache_account_blob_url", + "GRAPHRAG_CACHE_BASE_DIR": "/some/cache/dir", + "GRAPHRAG_CACHE_CONNECTION_STRING": "test_cs1", + "GRAPHRAG_CACHE_CONTAINER_NAME": "test_cn1", + "GRAPHRAG_CACHE_TYPE": "blob", + "GRAPHRAG_CHUNK_BY_COLUMNS": "a,b", + "GRAPHRAG_CHUNK_OVERLAP": "12", + "GRAPHRAG_CHUNK_SIZE": "500", + "GRAPHRAG_CLAIM_EXTRACTION_ENABLED": "True", + "GRAPHRAG_CLAIM_EXTRACTION_DESCRIPTION": "test 123", + "GRAPHRAG_CLAIM_EXTRACTION_MAX_GLEANINGS": "5000", + "GRAPHRAG_CLAIM_EXTRACTION_PROMPT_FILE": "tests/unit/config/prompt-a.txt", + "GRAPHRAG_COMMUNITY_REPORTS_MAX_LENGTH": "23456", + "GRAPHRAG_COMMUNITY_REPORTS_PROMPT_FILE": "tests/unit/config/prompt-b.txt", + "GRAPHRAG_EMBEDDING_BATCH_MAX_TOKENS": "17", + "GRAPHRAG_EMBEDDING_BATCH_SIZE": "1000000", + "GRAPHRAG_EMBEDDING_CONCURRENT_REQUESTS": "12", + "GRAPHRAG_EMBEDDING_DEPLOYMENT_NAME": "model-deployment-name", + "GRAPHRAG_EMBEDDING_MAX_RETRIES": "3", + "GRAPHRAG_EMBEDDING_MAX_RETRY_WAIT": "0.1123", + "GRAPHRAG_EMBEDDING_MODEL": "text-embedding-2", + "GRAPHRAG_EMBEDDING_REQUESTS_PER_MINUTE": "500", + "GRAPHRAG_EMBEDDING_SKIP": "a1,b1,c1", + "GRAPHRAG_EMBEDDING_SLEEP_ON_RATE_LIMIT_RECOMMENDATION": "False", + "GRAPHRAG_EMBEDDING_TARGET": "all", + "GRAPHRAG_EMBEDDING_THREAD_COUNT": "2345", + "GRAPHRAG_EMBEDDING_THREAD_STAGGER": "0.456", + "GRAPHRAG_EMBEDDING_TOKENS_PER_MINUTE": "7000", + "GRAPHRAG_EMBEDDING_TYPE": "azure_openai_embedding", + "GRAPHRAG_ENCODING_MODEL": "test123", + "GRAPHRAG_INPUT_STORAGE_ACCOUNT_BLOB_URL": "input_account_blob_url", + "GRAPHRAG_ENTITY_EXTRACTION_ENTITY_TYPES": "cat,dog,elephant", + "GRAPHRAG_ENTITY_EXTRACTION_MAX_GLEANINGS": "112", + "GRAPHRAG_ENTITY_EXTRACTION_PROMPT_FILE": "tests/unit/config/prompt-c.txt", + "GRAPHRAG_INPUT_BASE_DIR": "/some/input/dir", + "GRAPHRAG_INPUT_CONNECTION_STRING": "input_cs", + "GRAPHRAG_INPUT_CONTAINER_NAME": "input_cn", + "GRAPHRAG_INPUT_DOCUMENT_ATTRIBUTE_COLUMNS": "test1,test2", + "GRAPHRAG_INPUT_ENCODING": "utf-16", + "GRAPHRAG_INPUT_FILE_PATTERN": ".*\\test\\.txt$", + "GRAPHRAG_INPUT_SOURCE_COLUMN": "test_source", + "GRAPHRAG_INPUT_TYPE": "blob", + "GRAPHRAG_INPUT_TEXT_COLUMN": "test_text", + "GRAPHRAG_INPUT_TIMESTAMP_COLUMN": "test_timestamp", + "GRAPHRAG_INPUT_TIMESTAMP_FORMAT": "test_format", + "GRAPHRAG_INPUT_TITLE_COLUMN": "test_title", + "GRAPHRAG_INPUT_FILE_TYPE": "text", + "GRAPHRAG_LLM_CONCURRENT_REQUESTS": "12", + "GRAPHRAG_LLM_DEPLOYMENT_NAME": "model-deployment-name-x", + "GRAPHRAG_LLM_MAX_RETRIES": "312", + "GRAPHRAG_LLM_MAX_RETRY_WAIT": "0.1122", + "GRAPHRAG_LLM_MAX_TOKENS": "15000", + "GRAPHRAG_LLM_MODEL_SUPPORTS_JSON": "true", + "GRAPHRAG_LLM_MODEL": "test-llm", + "GRAPHRAG_LLM_N": "1", + "GRAPHRAG_LLM_REQUEST_TIMEOUT": "12.7", + "GRAPHRAG_LLM_REQUESTS_PER_MINUTE": "900", + "GRAPHRAG_LLM_SLEEP_ON_RATE_LIMIT_RECOMMENDATION": "False", + "GRAPHRAG_LLM_THREAD_COUNT": "987", + "GRAPHRAG_LLM_THREAD_STAGGER": "0.123", + "GRAPHRAG_LLM_TOKENS_PER_MINUTE": "8000", + "GRAPHRAG_LLM_TYPE": "azure_openai_chat", + "GRAPHRAG_MAX_CLUSTER_SIZE": "123", + "GRAPHRAG_NODE2VEC_ENABLED": "true", + "GRAPHRAG_NODE2VEC_ITERATIONS": "878787", + "GRAPHRAG_NODE2VEC_NUM_WALKS": "5000000", + "GRAPHRAG_NODE2VEC_RANDOM_SEED": "010101", + "GRAPHRAG_NODE2VEC_WALK_LENGTH": "555111", + "GRAPHRAG_NODE2VEC_WINDOW_SIZE": "12345", + "GRAPHRAG_REPORTING_STORAGE_ACCOUNT_BLOB_URL": "reporting_account_blob_url", + "GRAPHRAG_REPORTING_BASE_DIR": "/some/reporting/dir", + "GRAPHRAG_REPORTING_CONNECTION_STRING": "test_cs2", + "GRAPHRAG_REPORTING_CONTAINER_NAME": "test_cn2", + "GRAPHRAG_REPORTING_TYPE": "blob", + "GRAPHRAG_SKIP_WORKFLOWS": "a,b,c", + "GRAPHRAG_SNAPSHOT_GRAPHML": "true", + "GRAPHRAG_SNAPSHOT_RAW_ENTITIES": "true", + "GRAPHRAG_SNAPSHOT_TOP_LEVEL_NODES": "true", + "GRAPHRAG_STORAGE_STORAGE_ACCOUNT_BLOB_URL": "storage_account_blob_url", + "GRAPHRAG_STORAGE_BASE_DIR": "/some/storage/dir", + "GRAPHRAG_STORAGE_CONNECTION_STRING": "test_cs", + "GRAPHRAG_STORAGE_CONTAINER_NAME": "test_cn", + "GRAPHRAG_STORAGE_TYPE": "blob", + "GRAPHRAG_SUMMARIZE_DESCRIPTIONS_MAX_LENGTH": "12345", + "GRAPHRAG_SUMMARIZE_DESCRIPTIONS_PROMPT_FILE": "tests/unit/config/prompt-d.txt", + "GRAPHRAG_LLM_TEMPERATURE": "0.0", + "GRAPHRAG_LLM_TOP_P": "1.0", + "GRAPHRAG_UMAP_ENABLED": "true", + "GRAPHRAG_LOCAL_SEARCH_TEXT_UNIT_PROP": "0.713", + "GRAPHRAG_LOCAL_SEARCH_COMMUNITY_PROP": "0.1234", + "GRAPHRAG_LOCAL_SEARCH_LLM_TEMPERATURE": "0.1", + "GRAPHRAG_LOCAL_SEARCH_LLM_TOP_P": "0.9", + "GRAPHRAG_LOCAL_SEARCH_LLM_N": "2", + "GRAPHRAG_LOCAL_SEARCH_LLM_MAX_TOKENS": "12", + "GRAPHRAG_LOCAL_SEARCH_TOP_K_RELATIONSHIPS": "15", + "GRAPHRAG_LOCAL_SEARCH_TOP_K_ENTITIES": "14", + "GRAPHRAG_LOCAL_SEARCH_CONVERSATION_HISTORY_MAX_TURNS": "2", + "GRAPHRAG_LOCAL_SEARCH_MAX_TOKENS": "142435", + "GRAPHRAG_GLOBAL_SEARCH_LLM_TEMPERATURE": "0.1", + "GRAPHRAG_GLOBAL_SEARCH_LLM_TOP_P": "0.9", + "GRAPHRAG_GLOBAL_SEARCH_LLM_N": "2", + "GRAPHRAG_GLOBAL_SEARCH_MAX_TOKENS": "5123", + "GRAPHRAG_GLOBAL_SEARCH_DATA_MAX_TOKENS": "123", + "GRAPHRAG_GLOBAL_SEARCH_MAP_MAX_TOKENS": "4123", + "GRAPHRAG_GLOBAL_SEARCH_CONCURRENCY": "7", + "GRAPHRAG_GLOBAL_SEARCH_REDUCE_MAX_TOKENS": "15432", +} + + +class TestDefaultConfig(unittest.TestCase): + def test_clear_warnings(self): + """Just clearing unused import warnings""" + assert CacheConfig is not None + assert ChunkingConfig is not None + assert ClaimExtractionConfig is not None + assert ClusterGraphConfig is not None + assert CommunityReportsConfig is not None + assert EmbedGraphConfig is not None + assert EntityExtractionConfig is not None + assert GlobalSearchConfig is not None + assert GraphRagConfig is not None + assert InputConfig is not None + assert LLMParameters is not None + assert LocalSearchConfig is not None + assert ParallelizationParameters is not None + assert ReportingConfig is not None + assert SnapshotsConfig is not None + assert StorageConfig is not None + assert SummarizeDescriptionsConfig is not None + assert TextEmbeddingConfig is not None + assert UmapConfig is not None + assert PipelineConfig is not None + assert PipelineFileReportingConfig is not None + assert PipelineFileStorageConfig is not None + assert PipelineInputConfig is not None + assert PipelineFileCacheConfig is not None + assert PipelineWorkflowReference is not None + + @mock.patch.dict(os.environ, {"OPENAI_API_KEY": "test"}, clear=True) + def test_string_repr(self): + # __str__ can be json loaded + config = create_graphrag_config() + string_repr = str(config) + assert string_repr is not None + assert json.loads(string_repr) is not None + + # __repr__ can be eval()'d + repr_str = config.__repr__() + # TODO: add __repr__ to datashaper enum + repr_str = repr_str.replace("async_mode=,", "") + assert eval(repr_str) is not None + + # Pipeline config __str__ can be json loaded + pipeline_config = create_pipeline_config(config) + string_repr = str(pipeline_config) + assert string_repr is not None + assert json.loads(string_repr) is not None + + # Pipeline config __repr__ can be eval()'d + repr_str = pipeline_config.__repr__() + # TODO: add __repr__ to datashaper enum + repr_str = repr_str.replace( + "'async_mode': ,", "" + ) + assert eval(repr_str) is not None + + @mock.patch.dict(os.environ, {}, clear=True) + def test_default_config_with_no_env_vars_throws(self): + with pytest.raises(ApiKeyMissingError): + # This should throw an error because the API key is missing + create_pipeline_config(create_graphrag_config()) + + @mock.patch.dict(os.environ, {"GRAPHRAG_API_KEY": "test"}, clear=True) + def test_default_config_with_api_key_passes(self): + # doesn't throw + config = create_pipeline_config(create_graphrag_config()) + assert config is not None + + @mock.patch.dict(os.environ, {"OPENAI_API_KEY": "test"}, clear=True) + def test_default_config_with_oai_key_passes_envvar(self): + # doesn't throw + config = create_pipeline_config(create_graphrag_config()) + assert config is not None + + def test_default_config_with_oai_key_passes_obj(self): + # doesn't throw + config = create_pipeline_config( + create_graphrag_config({"llm": {"api_key": "test"}}) + ) + assert config is not None + + @mock.patch.dict( + os.environ, + {"GRAPHRAG_API_KEY": "test", "GRAPHRAG_LLM_TYPE": "azure_openai_chat"}, + clear=True, + ) + def test_throws_if_azure_is_used_without_api_base_envvar(self): + with pytest.raises(AzureApiBaseMissingError): + create_graphrag_config() + + @mock.patch.dict(os.environ, {"GRAPHRAG_API_KEY": "test"}, clear=True) + def test_throws_if_azure_is_used_without_api_base_obj(self): + with pytest.raises(AzureApiBaseMissingError): + create_graphrag_config( + GraphRagConfigInput(llm=LLMParametersInput(type="azure_openai_chat")) + ) + + @mock.patch.dict( + os.environ, + { + "GRAPHRAG_API_KEY": "test", + "GRAPHRAG_LLM_TYPE": "azure_openai_chat", + "GRAPHRAG_API_BASE": "http://some/base", + }, + clear=True, + ) + def test_throws_if_azure_is_used_without_llm_deployment_name_envvar(self): + with pytest.raises(AzureDeploymentNameMissingError): + create_graphrag_config() + + @mock.patch.dict(os.environ, {"GRAPHRAG_API_KEY": "test"}, clear=True) + def test_throws_if_azure_is_used_without_llm_deployment_name_obj(self): + with pytest.raises(AzureDeploymentNameMissingError): + create_graphrag_config( + GraphRagConfigInput( + llm=LLMParametersInput( + type="azure_openai_chat", api_base="http://some/base" + ) + ) + ) + + @mock.patch.dict( + os.environ, + { + "GRAPHRAG_API_KEY": "test", + "GRAPHRAG_EMBEDDING_TYPE": "azure_openai_embedding", + "GRAPHRAG_EMBEDDING_DEPLOYMENT_NAME": "x", + }, + clear=True, + ) + def test_throws_if_azure_is_used_without_embedding_api_base_envvar(self): + with pytest.raises(AzureApiBaseMissingError): + create_graphrag_config() + + @mock.patch.dict(os.environ, {"GRAPHRAG_API_KEY": "test"}, clear=True) + def test_throws_if_azure_is_used_without_embedding_api_base_obj(self): + with pytest.raises(AzureApiBaseMissingError): + create_graphrag_config( + GraphRagConfigInput( + embeddings=TextEmbeddingConfigInput( + llm=LLMParametersInput( + type="azure_openai_embedding", + deployment_name="x", + ) + ), + ) + ) + + @mock.patch.dict( + os.environ, + { + "GRAPHRAG_API_KEY": "test", + "GRAPHRAG_API_BASE": "http://some/base", + "GRAPHRAG_LLM_DEPLOYMENT_NAME": "x", + "GRAPHRAG_LLM_TYPE": "azure_openai_chat", + "GRAPHRAG_EMBEDDING_TYPE": "azure_openai_embedding", + }, + clear=True, + ) + def test_throws_if_azure_is_used_without_embedding_deployment_name_envvar(self): + with pytest.raises(AzureDeploymentNameMissingError): + create_graphrag_config() + + @mock.patch.dict(os.environ, {"GRAPHRAG_API_KEY": "test"}, clear=True) + def test_throws_if_azure_is_used_without_embedding_deployment_name_obj(self): + with pytest.raises(AzureDeploymentNameMissingError): + create_graphrag_config( + GraphRagConfigInput( + llm=LLMParametersInput( + type="azure_openai_chat", + api_base="http://some/base", + deployment_name="model-deployment-name-x", + ), + embeddings=TextEmbeddingConfigInput( + llm=LLMParametersInput( + type="azure_openai_embedding", + ) + ), + ) + ) + + @mock.patch.dict(os.environ, {"GRAPHRAG_API_KEY": "test"}, clear=True) + def test_minimim_azure_config_object(self): + config = create_graphrag_config( + GraphRagConfigInput( + llm=LLMParametersInput( + type="azure_openai_chat", + api_base="http://some/base", + deployment_name="model-deployment-name-x", + ), + embeddings=TextEmbeddingConfigInput( + llm=LLMParametersInput( + type="azure_openai_embedding", + deployment_name="model-deployment-name", + ) + ), + ) + ) + assert config is not None + + @mock.patch.dict( + os.environ, + { + "GRAPHRAG_API_KEY": "test", + "GRAPHRAG_LLM_TYPE": "azure_openai_chat", + "GRAPHRAG_LLM_DEPLOYMENT_NAME": "x", + }, + clear=True, + ) + def test_throws_if_azure_is_used_without_api_base(self): + with pytest.raises(AzureApiBaseMissingError): + create_graphrag_config() + + @mock.patch.dict( + os.environ, + { + "GRAPHRAG_API_KEY": "test", + "GRAPHRAG_LLM_TYPE": "azure_openai_chat", + "GRAPHRAG_LLM_API_BASE": "http://some/base", + }, + clear=True, + ) + def test_throws_if_azure_is_used_without_llm_deployment_name(self): + with pytest.raises(AzureDeploymentNameMissingError): + create_graphrag_config() + + @mock.patch.dict( + os.environ, + { + "GRAPHRAG_API_KEY": "test", + "GRAPHRAG_LLM_TYPE": "azure_openai_chat", + "GRAPHRAG_API_BASE": "http://some/base", + "GRAPHRAG_LLM_DEPLOYMENT_NAME": "model-deployment-name-x", + "GRAPHRAG_EMBEDDING_TYPE": "azure_openai_embedding", + }, + clear=True, + ) + def test_throws_if_azure_is_used_without_embedding_deployment_name(self): + with pytest.raises(AzureDeploymentNameMissingError): + create_graphrag_config() + + @mock.patch.dict( + os.environ, + {"GRAPHRAG_API_KEY": "test", "GRAPHRAG_INPUT_FILE_TYPE": "csv"}, + clear=True, + ) + def test_csv_input_returns_correct_config(self): + config = create_pipeline_config(create_graphrag_config(root_dir="/some/root")) + assert config.root_dir == "/some/root" + # Make sure the input is a CSV input + assert isinstance(config.input, PipelineCSVInputConfig) + assert (config.input.file_pattern or "") == ".*\\.csv$" # type: ignore + + @mock.patch.dict( + os.environ, + {"GRAPHRAG_API_KEY": "test", "GRAPHRAG_INPUT_FILE_TYPE": "text"}, + clear=True, + ) + def test_text_input_returns_correct_config(self): + config = create_pipeline_config(create_graphrag_config(root_dir=".")) + assert isinstance(config.input, PipelineTextInputConfig) + assert config.input is not None + assert (config.input.file_pattern or "") == ".*\\.txt$" # type: ignore + + def test_all_env_vars_is_accurate(self): + env_var_docs_path = Path("docsite/posts/config/env_vars.md") + query_docs_path = Path("docsite/posts/query/3-cli.md") + + env_var_docs = env_var_docs_path.read_text(encoding="utf-8") + query_docs = query_docs_path.read_text(encoding="utf-8") + + def find_envvar_names(text) -> set[str]: + pattern = r"`(GRAPHRAG_[^`]+)`" + found = re.findall(pattern, text) + found = {f for f in found if not f.endswith("_")} + return {*found} + + graphrag_strings = find_envvar_names(env_var_docs) | find_envvar_names( + query_docs + ) + + missing = {s for s in graphrag_strings if s not in ALL_ENV_VARS} - { + # Remove configs covered by the base LLM connection configs + "GRAPHRAG_LLM_API_KEY", + "GRAPHRAG_LLM_API_BASE", + "GRAPHRAG_LLM_API_VERSION", + "GRAPHRAG_LLM_API_ORGANIZATION", + "GRAPHRAG_LLM_API_PROXY", + "GRAPHRAG_EMBEDDING_API_KEY", + "GRAPHRAG_EMBEDDING_API_BASE", + "GRAPHRAG_EMBEDDING_API_VERSION", + "GRAPHRAG_EMBEDDING_API_ORGANIZATION", + "GRAPHRAG_EMBEDDING_API_PROXY", + } + if missing: + msg = f"{len(missing)} missing env vars: {missing}" + print(msg) + raise ValueError(msg) + + @mock.patch.dict( + os.environ, + {"GRAPHRAG_API_KEY": "test"}, + clear=True, + ) + def test_malformed_input_dict_throws(self): + with pytest.raises(ValidationError): + create_graphrag_config(cast(Any, {"llm": 12})) + + @mock.patch.dict( + os.environ, + ALL_ENV_VARS, + clear=True, + ) + def test_create_parameters_from_env_vars(self) -> None: + parameters = create_graphrag_config() + assert parameters.async_mode == "asyncio" + assert parameters.cache.storage_account_blob_url == "cache_account_blob_url" + assert parameters.cache.base_dir == "/some/cache/dir" + assert parameters.cache.connection_string == "test_cs1" + assert parameters.cache.container_name == "test_cn1" + assert parameters.cache.type == CacheType.blob + assert parameters.chunks.group_by_columns == ["a", "b"] + assert parameters.chunks.overlap == 12 + assert parameters.chunks.size == 500 + assert parameters.claim_extraction.enabled + assert parameters.claim_extraction.description == "test 123" + assert parameters.claim_extraction.max_gleanings == 5000 + assert parameters.claim_extraction.prompt == "tests/unit/config/prompt-a.txt" + assert parameters.cluster_graph.max_cluster_size == 123 + assert parameters.community_reports.max_length == 23456 + assert parameters.community_reports.prompt == "tests/unit/config/prompt-b.txt" + assert parameters.embed_graph.enabled + assert parameters.embed_graph.iterations == 878787 + assert parameters.embed_graph.num_walks == 5_000_000 + assert parameters.embed_graph.random_seed == 10101 + assert parameters.embed_graph.walk_length == 555111 + assert parameters.embed_graph.window_size == 12345 + assert parameters.embeddings.batch_max_tokens == 17 + assert parameters.embeddings.batch_size == 1_000_000 + assert parameters.embeddings.llm.concurrent_requests == 12 + assert parameters.embeddings.llm.deployment_name == "model-deployment-name" + assert parameters.embeddings.llm.max_retries == 3 + assert parameters.embeddings.llm.max_retry_wait == 0.1123 + assert parameters.embeddings.llm.model == "text-embedding-2" + assert parameters.embeddings.llm.requests_per_minute == 500 + assert parameters.embeddings.llm.sleep_on_rate_limit_recommendation is False + assert parameters.embeddings.llm.tokens_per_minute == 7000 + assert parameters.embeddings.llm.type == "azure_openai_embedding" + assert parameters.embeddings.parallelization.num_threads == 2345 + assert parameters.embeddings.parallelization.stagger == 0.456 + assert parameters.embeddings.skip == ["a1", "b1", "c1"] + assert parameters.embeddings.target == "all" + assert parameters.encoding_model == "test123" + assert parameters.entity_extraction.entity_types == ["cat", "dog", "elephant"] + assert parameters.entity_extraction.llm.api_base == "http://some/base" + assert parameters.entity_extraction.max_gleanings == 112 + assert parameters.entity_extraction.prompt == "tests/unit/config/prompt-c.txt" + assert parameters.input.storage_account_blob_url == "input_account_blob_url" + assert parameters.input.base_dir == "/some/input/dir" + assert parameters.input.connection_string == "input_cs" + assert parameters.input.container_name == "input_cn" + assert parameters.input.document_attribute_columns == ["test1", "test2"] + assert parameters.input.encoding == "utf-16" + assert parameters.input.file_pattern == ".*\\test\\.txt$" + assert parameters.input.file_type == InputFileType.text + assert parameters.input.source_column == "test_source" + assert parameters.input.text_column == "test_text" + assert parameters.input.timestamp_column == "test_timestamp" + assert parameters.input.timestamp_format == "test_format" + assert parameters.input.title_column == "test_title" + assert parameters.input.type == InputType.blob + assert parameters.llm.api_base == "http://some/base" + assert parameters.llm.api_key == "test" + assert parameters.llm.api_version == "v1234" + assert parameters.llm.concurrent_requests == 12 + assert parameters.llm.deployment_name == "model-deployment-name-x" + assert parameters.llm.max_retries == 312 + assert parameters.llm.max_retry_wait == 0.1122 + assert parameters.llm.max_tokens == 15000 + assert parameters.llm.model == "test-llm" + assert parameters.llm.model_supports_json + assert parameters.llm.n == 1 + assert parameters.llm.organization == "test_org" + assert parameters.llm.proxy == "http://some/proxy" + assert parameters.llm.request_timeout == 12.7 + assert parameters.llm.requests_per_minute == 900 + assert parameters.llm.sleep_on_rate_limit_recommendation is False + assert parameters.llm.temperature == 0.0 + assert parameters.llm.top_p == 1.0 + assert parameters.llm.tokens_per_minute == 8000 + assert parameters.llm.type == "azure_openai_chat" + assert parameters.parallelization.num_threads == 987 + assert parameters.parallelization.stagger == 0.123 + assert ( + parameters.reporting.storage_account_blob_url + == "reporting_account_blob_url" + ) + assert parameters.reporting.base_dir == "/some/reporting/dir" + assert parameters.reporting.connection_string == "test_cs2" + assert parameters.reporting.container_name == "test_cn2" + assert parameters.reporting.type == ReportingType.blob + assert parameters.skip_workflows == ["a", "b", "c"] + assert parameters.snapshots.graphml + assert parameters.snapshots.raw_entities + assert parameters.snapshots.top_level_nodes + assert parameters.storage.storage_account_blob_url == "storage_account_blob_url" + assert parameters.storage.base_dir == "/some/storage/dir" + assert parameters.storage.connection_string == "test_cs" + assert parameters.storage.container_name == "test_cn" + assert parameters.storage.type == StorageType.blob + assert parameters.summarize_descriptions.max_length == 12345 + assert ( + parameters.summarize_descriptions.prompt == "tests/unit/config/prompt-d.txt" + ) + assert parameters.umap.enabled + assert parameters.local_search.text_unit_prop == 0.713 + assert parameters.local_search.community_prop == 0.1234 + assert parameters.local_search.llm_max_tokens == 12 + assert parameters.local_search.top_k_relationships == 15 + assert parameters.local_search.conversation_history_max_turns == 2 + assert parameters.local_search.top_k_entities == 14 + assert parameters.local_search.temperature == 0.1 + assert parameters.local_search.top_p == 0.9 + assert parameters.local_search.n == 2 + assert parameters.local_search.max_tokens == 142435 + + assert parameters.global_search.temperature == 0.1 + assert parameters.global_search.top_p == 0.9 + assert parameters.global_search.n == 2 + assert parameters.global_search.max_tokens == 5123 + assert parameters.global_search.data_max_tokens == 123 + assert parameters.global_search.map_max_tokens == 4123 + assert parameters.global_search.concurrency == 7 + assert parameters.global_search.reduce_max_tokens == 15432 + + @mock.patch.dict(os.environ, {"API_KEY_X": "test"}, clear=True) + def test_create_parameters(self) -> None: + parameters = create_graphrag_config( + GraphRagConfigInput( + llm=LLMParametersInput(api_key="${API_KEY_X}", model="test-llm"), + storage=StorageConfigInput( + type=StorageType.blob, + connection_string="test_cs", + container_name="test_cn", + base_dir="/some/storage/dir", + storage_account_blob_url="storage_account_blob_url", + ), + cache=CacheConfigInput( + type=CacheType.blob, + connection_string="test_cs1", + container_name="test_cn1", + base_dir="/some/cache/dir", + storage_account_blob_url="cache_account_blob_url", + ), + reporting=ReportingConfigInput( + type=ReportingType.blob, + connection_string="test_cs2", + container_name="test_cn2", + base_dir="/some/reporting/dir", + storage_account_blob_url="reporting_account_blob_url", + ), + input=InputConfigInput( + file_type=InputFileType.text, + file_encoding="utf-16", + document_attribute_columns=["test1", "test2"], + base_dir="/some/input/dir", + connection_string="input_cs", + container_name="input_cn", + file_pattern=".*\\test\\.txt$", + source_column="test_source", + text_column="test_text", + timestamp_column="test_timestamp", + timestamp_format="test_format", + title_column="test_title", + type="blob", + storage_account_blob_url="input_account_blob_url", + ), + embed_graph=EmbedGraphConfigInput( + enabled=True, + num_walks=5_000_000, + iterations=878787, + random_seed=10101, + walk_length=555111, + ), + embeddings=TextEmbeddingConfigInput( + batch_size=1_000_000, + batch_max_tokens=8000, + skip=["a1", "b1", "c1"], + llm=LLMParametersInput(model="text-embedding-2"), + ), + chunks=ChunkingConfigInput( + size=500, overlap=12, group_by_columns=["a", "b"] + ), + snapshots=SnapshotsConfigInput( + graphml=True, + raw_entities=True, + top_level_nodes=True, + ), + entity_extraction=EntityExtractionConfigInput( + max_gleanings=112, + entity_types=["cat", "dog", "elephant"], + prompt="entity_extraction_prompt_file.txt", + ), + summarize_descriptions=SummarizeDescriptionsConfigInput( + max_length=12345, prompt="summarize_prompt_file.txt" + ), + community_reports=CommunityReportsConfigInput( + max_length=23456, + prompt="community_report_prompt_file.txt", + max_input_length=12345, + ), + claim_extraction=ClaimExtractionConfigInput( + description="test 123", + max_gleanings=5000, + prompt="claim_extraction_prompt_file.txt", + ), + cluster_graph=ClusterGraphConfigInput( + max_cluster_size=123, + ), + umap=UmapConfigInput(enabled=True), + encoding_model="test123", + skip_workflows=["a", "b", "c"], + ), + ".", + ) + + assert parameters.cache.base_dir == "/some/cache/dir" + assert parameters.cache.connection_string == "test_cs1" + assert parameters.cache.container_name == "test_cn1" + assert parameters.cache.type == CacheType.blob + assert parameters.cache.storage_account_blob_url == "cache_account_blob_url" + assert parameters.chunks.group_by_columns == ["a", "b"] + assert parameters.chunks.overlap == 12 + assert parameters.chunks.size == 500 + assert parameters.claim_extraction.description == "test 123" + assert parameters.claim_extraction.max_gleanings == 5000 + assert parameters.claim_extraction.prompt == "claim_extraction_prompt_file.txt" + assert parameters.cluster_graph.max_cluster_size == 123 + assert parameters.community_reports.max_input_length == 12345 + assert parameters.community_reports.max_length == 23456 + assert parameters.community_reports.prompt == "community_report_prompt_file.txt" + assert parameters.embed_graph.enabled + assert parameters.embed_graph.iterations == 878787 + assert parameters.embed_graph.num_walks == 5_000_000 + assert parameters.embed_graph.random_seed == 10101 + assert parameters.embed_graph.walk_length == 555111 + assert parameters.embeddings.batch_max_tokens == 8000 + assert parameters.embeddings.batch_size == 1_000_000 + assert parameters.embeddings.llm.model == "text-embedding-2" + assert parameters.embeddings.skip == ["a1", "b1", "c1"] + assert parameters.encoding_model == "test123" + assert parameters.entity_extraction.entity_types == ["cat", "dog", "elephant"] + assert parameters.entity_extraction.max_gleanings == 112 + assert ( + parameters.entity_extraction.prompt == "entity_extraction_prompt_file.txt" + ) + assert parameters.input.base_dir == "/some/input/dir" + assert parameters.input.connection_string == "input_cs" + assert parameters.input.container_name == "input_cn" + assert parameters.input.document_attribute_columns == ["test1", "test2"] + assert parameters.input.encoding == "utf-16" + assert parameters.input.file_pattern == ".*\\test\\.txt$" + assert parameters.input.source_column == "test_source" + assert parameters.input.type == "blob" + assert parameters.input.text_column == "test_text" + assert parameters.input.timestamp_column == "test_timestamp" + assert parameters.input.timestamp_format == "test_format" + assert parameters.input.title_column == "test_title" + assert parameters.input.file_type == InputFileType.text + assert parameters.input.storage_account_blob_url == "input_account_blob_url" + assert parameters.llm.api_key == "test" + assert parameters.llm.model == "test-llm" + assert parameters.reporting.base_dir == "/some/reporting/dir" + assert parameters.reporting.connection_string == "test_cs2" + assert parameters.reporting.container_name == "test_cn2" + assert parameters.reporting.type == ReportingType.blob + assert ( + parameters.reporting.storage_account_blob_url + == "reporting_account_blob_url" + ) + assert parameters.skip_workflows == ["a", "b", "c"] + assert parameters.snapshots.graphml + assert parameters.snapshots.raw_entities + assert parameters.snapshots.top_level_nodes + assert parameters.storage.base_dir == "/some/storage/dir" + assert parameters.storage.connection_string == "test_cs" + assert parameters.storage.container_name == "test_cn" + assert parameters.storage.type == StorageType.blob + assert parameters.storage.storage_account_blob_url == "storage_account_blob_url" + assert parameters.summarize_descriptions.max_length == 12345 + assert parameters.summarize_descriptions.prompt == "summarize_prompt_file.txt" + assert parameters.umap.enabled + + @mock.patch.dict( + os.environ, + {"GRAPHRAG_API_KEY": "test"}, + clear=True, + ) + def test_default_values(self) -> None: + parameters = create_graphrag_config() + assert parameters.async_mode == defs.ASYNC_MODE + assert parameters.cache.base_dir == defs.CACHE_BASE_DIR + assert parameters.cache.type == defs.CACHE_TYPE + assert parameters.cache.base_dir == defs.CACHE_BASE_DIR + assert parameters.chunks.group_by_columns == defs.CHUNK_GROUP_BY_COLUMNS + assert parameters.chunks.overlap == defs.CHUNK_OVERLAP + assert parameters.chunks.size == defs.CHUNK_SIZE + assert parameters.claim_extraction.description == defs.CLAIM_DESCRIPTION + assert parameters.claim_extraction.max_gleanings == defs.CLAIM_MAX_GLEANINGS + assert ( + parameters.community_reports.max_input_length + == defs.COMMUNITY_REPORT_MAX_INPUT_LENGTH + ) + assert ( + parameters.community_reports.max_length == defs.COMMUNITY_REPORT_MAX_LENGTH + ) + assert parameters.embeddings.batch_max_tokens == defs.EMBEDDING_BATCH_MAX_TOKENS + assert parameters.embeddings.batch_size == defs.EMBEDDING_BATCH_SIZE + assert parameters.embeddings.llm.model == defs.EMBEDDING_MODEL + assert parameters.embeddings.target == defs.EMBEDDING_TARGET + assert parameters.embeddings.llm.type == defs.EMBEDDING_TYPE + assert ( + parameters.embeddings.llm.requests_per_minute + == defs.LLM_REQUESTS_PER_MINUTE + ) + assert parameters.embeddings.llm.tokens_per_minute == defs.LLM_TOKENS_PER_MINUTE + assert ( + parameters.embeddings.llm.sleep_on_rate_limit_recommendation + == defs.LLM_SLEEP_ON_RATE_LIMIT_RECOMMENDATION + ) + assert ( + parameters.entity_extraction.entity_types + == defs.ENTITY_EXTRACTION_ENTITY_TYPES + ) + assert ( + parameters.entity_extraction.max_gleanings + == defs.ENTITY_EXTRACTION_MAX_GLEANINGS + ) + assert parameters.encoding_model == defs.ENCODING_MODEL + assert parameters.input.base_dir == defs.INPUT_BASE_DIR + assert parameters.input.file_pattern == defs.INPUT_CSV_PATTERN + assert parameters.input.encoding == defs.INPUT_FILE_ENCODING + assert parameters.input.type == defs.INPUT_TYPE + assert parameters.input.base_dir == defs.INPUT_BASE_DIR + assert parameters.input.text_column == defs.INPUT_TEXT_COLUMN + assert parameters.input.file_type == defs.INPUT_FILE_TYPE + assert parameters.llm.concurrent_requests == defs.LLM_CONCURRENT_REQUESTS + assert parameters.llm.max_retries == defs.LLM_MAX_RETRIES + assert parameters.llm.max_retry_wait == defs.LLM_MAX_RETRY_WAIT + assert parameters.llm.max_tokens == defs.LLM_MAX_TOKENS + assert parameters.llm.model == defs.LLM_MODEL + assert parameters.llm.request_timeout == defs.LLM_REQUEST_TIMEOUT + assert parameters.llm.requests_per_minute == defs.LLM_REQUESTS_PER_MINUTE + assert parameters.llm.tokens_per_minute == defs.LLM_TOKENS_PER_MINUTE + assert ( + parameters.llm.sleep_on_rate_limit_recommendation + == defs.LLM_SLEEP_ON_RATE_LIMIT_RECOMMENDATION + ) + assert parameters.llm.type == defs.LLM_TYPE + assert parameters.cluster_graph.max_cluster_size == defs.MAX_CLUSTER_SIZE + assert parameters.embed_graph.enabled == defs.NODE2VEC_ENABLED + assert parameters.embed_graph.iterations == defs.NODE2VEC_ITERATIONS + assert parameters.embed_graph.num_walks == defs.NODE2VEC_NUM_WALKS + assert parameters.embed_graph.random_seed == defs.NODE2VEC_RANDOM_SEED + assert parameters.embed_graph.walk_length == defs.NODE2VEC_WALK_LENGTH + assert parameters.embed_graph.window_size == defs.NODE2VEC_WINDOW_SIZE + assert ( + parameters.parallelization.num_threads == defs.PARALLELIZATION_NUM_THREADS + ) + assert parameters.parallelization.stagger == defs.PARALLELIZATION_STAGGER + assert parameters.reporting.type == defs.REPORTING_TYPE + assert parameters.reporting.base_dir == defs.REPORTING_BASE_DIR + assert parameters.snapshots.graphml == defs.SNAPSHOTS_GRAPHML + assert parameters.snapshots.raw_entities == defs.SNAPSHOTS_RAW_ENTITIES + assert parameters.snapshots.top_level_nodes == defs.SNAPSHOTS_TOP_LEVEL_NODES + assert parameters.storage.base_dir == defs.STORAGE_BASE_DIR + assert parameters.storage.type == defs.STORAGE_TYPE + assert parameters.umap.enabled == defs.UMAP_ENABLED + + @mock.patch.dict( + os.environ, + {"GRAPHRAG_API_KEY": "test"}, + clear=True, + ) + def test_prompt_file_reading(self): + config = create_graphrag_config({ + "entity_extraction": {"prompt": "tests/unit/config/prompt-a.txt"}, + "claim_extraction": {"prompt": "tests/unit/config/prompt-b.txt"}, + "community_reports": {"prompt": "tests/unit/config/prompt-c.txt"}, + "summarize_descriptions": {"prompt": "tests/unit/config/prompt-d.txt"}, + }) + strategy = config.entity_extraction.resolved_strategy(".", "abc123") + assert strategy["extraction_prompt"] == "Hello, World! A" + assert strategy["encoding_name"] == "abc123" + + strategy = config.claim_extraction.resolved_strategy(".") + assert strategy["extraction_prompt"] == "Hello, World! B" + + strategy = config.community_reports.resolved_strategy(".") + assert strategy["extraction_prompt"] == "Hello, World! C" + + strategy = config.summarize_descriptions.resolved_strategy(".") + assert strategy["summarize_prompt"] == "Hello, World! D" + + +@mock.patch.dict( + os.environ, + { + "PIPELINE_LLM_API_KEY": "test", + "PIPELINE_LLM_API_BASE": "http://test", + "PIPELINE_LLM_API_VERSION": "v1", + "PIPELINE_LLM_MODEL": "test-llm", + "PIPELINE_LLM_DEPLOYMENT_NAME": "test", + }, + clear=True, +) +def test_yaml_load_e2e(): + config_dict = yaml.safe_load( + """ +input: + file_type: text + +llm: + type: azure_openai_chat + api_key: ${PIPELINE_LLM_API_KEY} + api_base: ${PIPELINE_LLM_API_BASE} + api_version: ${PIPELINE_LLM_API_VERSION} + model: ${PIPELINE_LLM_MODEL} + deployment_name: ${PIPELINE_LLM_DEPLOYMENT_NAME} + model_supports_json: True + tokens_per_minute: 80000 + requests_per_minute: 900 + thread_count: 50 + concurrent_requests: 25 +""" + ) + # create default configuration pipeline parameters from the custom settings + model = config_dict + parameters = create_graphrag_config(model, ".") + + assert parameters.llm.api_key == "test" + assert parameters.llm.model == "test-llm" + assert parameters.llm.api_base == "http://test" + assert parameters.llm.api_version == "v1" + assert parameters.llm.deployment_name == "test" + + # generate the pipeline from the default parameters + pipeline_config = create_pipeline_config(parameters, True) + + config_str = pipeline_config.model_dump_json() + assert "${PIPELINE_LLM_API_KEY}" not in config_str + assert "${PIPELINE_LLM_API_BASE}" not in config_str + assert "${PIPELINE_LLM_API_VERSION}" not in config_str + assert "${PIPELINE_LLM_MODEL}" not in config_str + assert "${PIPELINE_LLM_DEPLOYMENT_NAME}" not in config_str diff --git a/graphrag/tests/unit/indexing/__init__.py b/graphrag/tests/unit/indexing/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/cache/__init__.py b/graphrag/tests/unit/indexing/cache/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/cache/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/cache/test_file_pipeline_cache.py b/graphrag/tests/unit/indexing/cache/test_file_pipeline_cache.py new file mode 100644 index 0000000000000000000000000000000000000000..ada3239602c3984210634fc23bd994ea1738f337 --- /dev/null +++ b/graphrag/tests/unit/indexing/cache/test_file_pipeline_cache.py @@ -0,0 +1,76 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import asyncio +import os +import unittest + +from graphrag.index.cache import ( + JsonPipelineCache, +) +from graphrag.index.storage.file_pipeline_storage import ( + FilePipelineStorage, +) + +TEMP_DIR = "./.tmp" + + +def create_cache(): + storage = FilePipelineStorage(os.path.join(os.getcwd(), ".tmp")) + return JsonPipelineCache(storage) + + +class TestFilePipelineCache(unittest.IsolatedAsyncioTestCase): + def setUp(self): + self.cache = create_cache() + + def tearDown(self): + asyncio.run(self.cache.clear()) + + async def test_cache_clear(self): + # Create a cache directory + if not os.path.exists(TEMP_DIR): + os.mkdir(TEMP_DIR) + with open(f"{TEMP_DIR}/test1", "w") as f: + f.write("This is test1 file.") + with open(f"{TEMP_DIR}/test2", "w") as f: + f.write("This is test2 file.") + + # this invokes cache.clear() + await self.cache.clear() + + # Check if the cache directory is empty + files = os.listdir(TEMP_DIR) + assert len(files) == 0 + + async def test_child_cache(self): + await self.cache.set("test1", "test1") + assert os.path.exists(f"{TEMP_DIR}/test1") + + child = self.cache.child("test") + assert os.path.exists(f"{TEMP_DIR}/test") + + await child.set("test2", "test2") + assert os.path.exists(f"{TEMP_DIR}/test/test2") + + await self.cache.set("test1", "test1") + await self.cache.delete("test1") + assert not os.path.exists(f"{TEMP_DIR}/test1") + + async def test_cache_has(self): + test1 = "this is a test file" + await self.cache.set("test1", test1) + + assert await self.cache.has("test1") + assert not await self.cache.has("NON_EXISTENT") + assert await self.cache.get("NON_EXISTENT") is None + + async def test_get_set(self): + test1 = "this is a test file" + test2 = "\\n test" + test3 = "\\\\\\" + await self.cache.set("test1", test1) + await self.cache.set("test2", test2) + await self.cache.set("test3", test3) + assert await self.cache.get("test1") == test1 + assert await self.cache.get("test2") == test2 + assert await self.cache.get("test3") == test3 diff --git a/graphrag/tests/unit/indexing/config/__init__.py b/graphrag/tests/unit/indexing/config/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/config/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/config/default_config_with_everything_overridden.yml b/graphrag/tests/unit/indexing/config/default_config_with_everything_overridden.yml new file mode 100644 index 0000000000000000000000000000000000000000..7a2f712e4677f92b4c955d845ca819107bc8ff81 --- /dev/null +++ b/graphrag/tests/unit/indexing/config/default_config_with_everything_overridden.yml @@ -0,0 +1,20 @@ +extends: default + +input: + file_type: text + base_dir: /some/overridden/dir + file_pattern: test.txt + +storage: + type: file + +cache: + type: file + +reporting: + type: file + +workflows: + - name: TEST_WORKFLOW + steps: + - verb: TEST_VERB diff --git a/graphrag/tests/unit/indexing/config/default_config_with_overridden_input.yml b/graphrag/tests/unit/indexing/config/default_config_with_overridden_input.yml new file mode 100644 index 0000000000000000000000000000000000000000..68631a315a3992b9821fee3dc0c61d39d7d88a68 --- /dev/null +++ b/graphrag/tests/unit/indexing/config/default_config_with_overridden_input.yml @@ -0,0 +1,5 @@ +extends: default +input: + file_type: text + base_dir: /some/overridden/dir + file_pattern: test.txt diff --git a/graphrag/tests/unit/indexing/config/default_config_with_overridden_workflows.yml b/graphrag/tests/unit/indexing/config/default_config_with_overridden_workflows.yml new file mode 100644 index 0000000000000000000000000000000000000000..c3c9d07c2c9ffb31aa9f6cb34014774f0b889396 --- /dev/null +++ b/graphrag/tests/unit/indexing/config/default_config_with_overridden_workflows.yml @@ -0,0 +1,6 @@ +extends: default + +workflows: + - name: TEST_WORKFLOW + steps: + - verb: TEST_VERB diff --git a/graphrag/tests/unit/indexing/config/helpers.py b/graphrag/tests/unit/indexing/config/helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..580d0a9fa7ecf5ad2c51fcf3d28fc8f3a83350d0 --- /dev/null +++ b/graphrag/tests/unit/indexing/config/helpers.py @@ -0,0 +1,59 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import json +import unittest +from typing import Any + +from graphrag.config import create_graphrag_config +from graphrag.index import PipelineConfig, create_pipeline_config + + +def assert_contains_default_config( + test_case: unittest.TestCase, + config: Any, + check_input=True, + check_storage=True, + check_reporting=True, + check_cache=True, + check_workflows=True, +): + """Asserts that the config contains the default config.""" + assert config is not None + assert isinstance(config, PipelineConfig) + + checked_config = json.loads( + config.model_dump_json(exclude_defaults=True, exclude_unset=True) + ) + + actual_default_config = json.loads( + create_pipeline_config(create_graphrag_config()).model_dump_json( + exclude_defaults=True, exclude_unset=True + ) + ) + props_to_ignore = ["root_dir", "extends"] + + # Make sure there is some sort of workflows + if not check_workflows: + props_to_ignore.append("workflows") + + # Make sure it tries to load some sort of input + if not check_input: + props_to_ignore.append("input") + + # Make sure it tries to load some sort of storage + if not check_storage: + props_to_ignore.append("storage") + + # Make sure it tries to load some sort of reporting + if not check_reporting: + props_to_ignore.append("reporting") + + # Make sure it tries to load some sort of cache + if not check_cache: + props_to_ignore.append("cache") + + for prop in props_to_ignore: + checked_config.pop(prop, None) + actual_default_config.pop(prop, None) + + assert actual_default_config == actual_default_config | checked_config diff --git a/graphrag/tests/unit/indexing/config/test_load.py b/graphrag/tests/unit/indexing/config/test_load.py new file mode 100644 index 0000000000000000000000000000000000000000..78f6a93a0a558302979a3e9f25820bd44ab0f017 --- /dev/null +++ b/graphrag/tests/unit/indexing/config/test_load.py @@ -0,0 +1,121 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT Licenses +import json +import os +import unittest +from pathlib import Path +from typing import Any +from unittest import mock + +from graphrag.config import create_graphrag_config +from graphrag.index import ( + PipelineConfig, + create_pipeline_config, + load_pipeline_config, +) + +current_dir = os.path.dirname(__file__) + + +class TestLoadPipelineConfig(unittest.TestCase): + @mock.patch.dict(os.environ, {"GRAPHRAG_API_KEY": "test"}, clear=True) + def test_config_passed_in_returns_config(self): + config = PipelineConfig() + result = load_pipeline_config(config) + assert result == config + + @mock.patch.dict(os.environ, {"GRAPHRAG_API_KEY": "test"}, clear=True) + def test_loading_default_config_returns_config(self): + result = load_pipeline_config("default") + self.assert_is_default_config(result) + + @mock.patch.dict(os.environ, {"GRAPHRAG_API_KEY": "test"}, clear=True) + def test_loading_default_config_with_input_overridden(self): + config = load_pipeline_config( + str(Path(current_dir) / "default_config_with_overridden_input.yml") + ) + + # Check that the config is merged + # but skip checking the input + self.assert_is_default_config(config, check_input=False) + + if config.input is None: + msg = "Input should not be none" + raise Exception(msg) + + # Check that the input is merged + assert config.input.file_pattern == "test.txt" + assert config.input.file_type == "text" + assert config.input.base_dir == "/some/overridden/dir" + + @mock.patch.dict(os.environ, {"GRAPHRAG_API_KEY": "test"}, clear=True) + def test_loading_default_config_with_workflows_overridden(self): + config = load_pipeline_config( + str(Path(current_dir) / "default_config_with_overridden_workflows.yml") + ) + + # Check that the config is merged + # but skip checking the input + self.assert_is_default_config(config, check_workflows=False) + + # Make sure the workflows are overridden + assert len(config.workflows) == 1 + assert config.workflows[0].name == "TEST_WORKFLOW" + assert config.workflows[0].steps is not None + assert len(config.workflows[0].steps) == 1 # type: ignore + assert config.workflows[0].steps[0]["verb"] == "TEST_VERB" # type: ignore + + @mock.patch.dict(os.environ, {"GRAPHRAG_API_KEY": "test"}, clear=True) + def assert_is_default_config( + self, + config: Any, + check_input=True, + check_storage=True, + check_reporting=True, + check_cache=True, + check_workflows=True, + ): + assert config is not None + assert isinstance(config, PipelineConfig) + + checked_config = json.loads( + config.model_dump_json(exclude_defaults=True, exclude_unset=True) + ) + + actual_default_config = json.loads( + create_pipeline_config( + create_graphrag_config(root_dir=".") + ).model_dump_json(exclude_defaults=True, exclude_unset=True) + ) + props_to_ignore = ["root_dir", "extends"] + + # Make sure there is some sort of workflows + if not check_workflows: + props_to_ignore.append("workflows") + + # Make sure it tries to load some sort of input + if not check_input: + props_to_ignore.append("input") + + # Make sure it tries to load some sort of storage + if not check_storage: + props_to_ignore.append("storage") + + # Make sure it tries to load some sort of reporting + if not check_reporting: + props_to_ignore.append("reporting") + + # Make sure it tries to load some sort of cache + if not check_cache: + props_to_ignore.append("cache") + + for prop in props_to_ignore: + checked_config.pop(prop, None) + actual_default_config.pop(prop, None) + + assert actual_default_config == actual_default_config | checked_config + + def setUp(self) -> None: + os.environ["GRAPHRAG_OPENAI_API_KEY"] = "test" + os.environ["GRAPHRAG_OPENAI_EMBEDDING_API_KEY"] = "test" + return super().setUp() diff --git a/graphrag/tests/unit/indexing/graph/__init__.py b/graphrag/tests/unit/indexing/graph/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/graph/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/graph/extractors/__init__.py b/graphrag/tests/unit/indexing/graph/extractors/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/graph/extractors/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/graph/extractors/community_reports/__init__.py b/graphrag/tests/unit/indexing/graph/extractors/community_reports/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/graph/extractors/community_reports/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/graph/extractors/community_reports/test_sort_context.py b/graphrag/tests/unit/indexing/graph/extractors/community_reports/test_sort_context.py new file mode 100644 index 0000000000000000000000000000000000000000..9b6647887617a4b5ac8ef4fedcaee836ce16020b --- /dev/null +++ b/graphrag/tests/unit/indexing/graph/extractors/community_reports/test_sort_context.py @@ -0,0 +1,204 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import math + +from graphrag.index.graph.extractors.community_reports import sort_context + +nan = math.nan + + +def test_sort_context(): + context: list[dict] = [ + { + "title": "ALI BABA", + "degree": 1, + "node_details": { + "human_readable_id": 26, + "title": "ALI BABA", + "description": "A character from Scrooge's reading, representing a memory of his childhood imagination", + "degree": 1, + }, + "edge_details": [ + nan, + { + "human_readable_id": 28, + "source": "SCROOGE", + "target": "ALI BABA", + "description": "Scrooge recalls Ali Baba as a fond memory from his childhood readings", + "rank": 32, + }, + ], + "claim_details": [nan], + }, + { + "title": "BELLE", + "degree": 1, + "node_details": { + "human_readable_id": 31, + "title": "BELLE", + "description": "A woman from Scrooge's past, reflecting on how Scrooge's pursuit of wealth changed him and led to the end of their relationship", + "degree": 1, + }, + "edge_details": [ + nan, + { + "human_readable_id": 32, + "source": "SCROOGE", + "target": "BELLE", + "description": "Belle and Scrooge were once engaged, but their relationship ended due to Scrooge's growing obsession with wealth", + "rank": 32, + }, + ], + "claim_details": [nan], + }, + { + "title": "CHRISTMAS", + "degree": 1, + "node_details": { + "human_readable_id": 17, + "title": "CHRISTMAS", + "description": "A festive season that highlights the contrast between abundance and want, joy and misery in the story", + "degree": 1, + }, + "edge_details": [ + nan, + { + "human_readable_id": 23, + "source": "SCROOGE", + "target": "CHRISTMAS", + "description": "Scrooge's disdain for Christmas is a central theme, highlighting his miserliness and lack of compassion", + "rank": 32, + }, + ], + "claim_details": [nan], + }, + { + "title": "CHRISTMAS DAY", + "degree": 1, + "node_details": { + "human_readable_id": 57, + "title": "CHRISTMAS DAY", + "description": "The day Scrooge realizes he hasn't missed the opportunity to celebrate and spread joy", + "degree": 1, + }, + "edge_details": [ + nan, + { + "human_readable_id": 46, + "source": "SCROOGE", + "target": "CHRISTMAS DAY", + "description": "Scrooge wakes up on Christmas Day with a changed heart, ready to celebrate and spread happiness", + "rank": 32, + }, + ], + "claim_details": [nan], + }, + { + "title": "DUTCH MERCHANT", + "degree": 1, + "node_details": { + "human_readable_id": 19, + "title": "DUTCH MERCHANT", + "description": "A historical figure mentioned as having built the fireplace in Scrooge's home, adorned with tiles illustrating the Scriptures", + "degree": 1, + }, + "edge_details": [ + nan, + { + "human_readable_id": 25, + "source": "SCROOGE", + "target": "DUTCH MERCHANT", + "description": "Scrooge's fireplace, built by the Dutch Merchant, serves as a focal point in his room where he encounters Marley's Ghost", + "rank": 32, + }, + ], + "claim_details": [nan], + }, + { + "title": "FAN", + "degree": 1, + "node_details": { + "human_readable_id": 27, + "title": "FAN", + "description": "Scrooge's sister, who comes to bring him home from school for Christmas, showing a loving family relationship", + "degree": 1, + }, + "edge_details": [ + nan, + { + "human_readable_id": 29, + "source": "SCROOGE", + "target": "FAN", + "description": "Fan is Scrooge's sister, who shows love and care by bringing him home for Christmas", + "rank": 32, + }, + ], + "claim_details": [nan], + }, + { + "title": "FRED", + "degree": 1, + "node_details": { + "human_readable_id": 58, + "title": "FRED", + "description": "Scrooge's nephew, who invites Scrooge to Christmas dinner, symbolizing family reconciliation", + "degree": 1, + }, + "edge_details": [ + nan, + { + "human_readable_id": 47, + "source": "SCROOGE", + "target": "FRED", + "description": "Scrooge accepts Fred's invitation to Christmas dinner, marking a significant step in repairing their relationship", + "rank": 32, + }, + ], + "claim_details": [nan], + }, + { + "title": "GENTLEMAN", + "degree": 1, + "node_details": { + "human_readable_id": 15, + "title": "GENTLEMAN", + "description": "Represents charitable efforts to provide for the poor during the Christmas season", + "degree": 1, + }, + "edge_details": [ + nan, + { + "human_readable_id": 21, + "source": "SCROOGE", + "target": "GENTLEMAN", + "description": "The gentleman approaches Scrooge to solicit donations for the poor, which Scrooge rebuffs", + "rank": 32, + }, + ], + "claim_details": [nan], + }, + { + "title": "GHOST", + "degree": 1, + "node_details": { + "human_readable_id": 25, + "title": "GHOST", + "description": "The Ghost is a spectral entity that plays a crucial role in guiding Scrooge through an introspective journey in Charles Dickens' classic tale. This spirit, likely one of the Christmas spirits, takes Scrooge on a transformative voyage through his past memories, the realities of his present, and the potential outcomes of his future. The purpose of this journey is to make Scrooge reflect deeply on his life, encouraging a profound understanding of the joy and meaning of Christmas. By showing Scrooge scenes from his life, including the potential fate of Tiny Tim, the Ghost rebukes Scrooge for his lack of compassion, ultimately aiming to instill in him a sense of responsibility and empathy towards others. Through this experience, the Ghost seeks to enlighten Scrooge, urging him to change his ways for the better.", + "degree": 1, + }, + "edge_details": [ + nan, + { + "human_readable_id": 27, + "source": "SCROOGE", + "target": "GHOST", + "description": "The Ghost is taking Scrooge on a transformative journey by showing him scenes from his past, aiming to make him reflect on his life choices and their consequences. This spectral guide is not only focusing on Scrooge's personal history but also emphasizing the importance of Christmas and the need for a change in perspective. Through these vivid reenactments, the Ghost highlights the error of Scrooge's ways and the significant impact his actions have on others, including Tiny Tim. This experience is designed to enlighten Scrooge, encouraging him to reconsider his approach to life and the people around him.", + "rank": 32, + }, + ], + "claim_details": [nan], + }, + ] + + ctx = sort_context(context) + assert ctx is not None diff --git a/graphrag/tests/unit/indexing/graph/utils/__init__.py b/graphrag/tests/unit/indexing/graph/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/graph/utils/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/graph/utils/test_stable_lcc.py b/graphrag/tests/unit/indexing/graph/utils/test_stable_lcc.py new file mode 100644 index 0000000000000000000000000000000000000000..02ddc2989a98a938fc9ba0da657d70132ba47616 --- /dev/null +++ b/graphrag/tests/unit/indexing/graph/utils/test_stable_lcc.py @@ -0,0 +1,71 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import unittest + +import networkx as nx + +from graphrag.index.graph.utils.stable_lcc import stable_largest_connected_component + + +class TestStableLCC(unittest.TestCase): + def test_undirected_graph_run_twice_produces_same_graph(self): + graph_in_1 = self._create_strongly_connected_graph() + graph_out_1 = stable_largest_connected_component(graph_in_1) + + graph_in_2 = self._create_strongly_connected_graph_with_edges_flipped() + graph_out_2 = stable_largest_connected_component(graph_in_2) + + # Make sure they're the same + assert "".join(nx.generate_graphml(graph_out_1)) == "".join( + nx.generate_graphml(graph_out_2) + ) + + def test_directed_graph_keeps_source_target_intact(self): + # create the test graph as a directed graph + graph_in = self._create_strongly_connected_graph_with_edges_flipped( + digraph=True + ) + graph_out = stable_largest_connected_component(graph_in.copy()) + + # Make sure edges are the same and the direction is preserved + edges_1 = [f"{edge[0]} -> {edge[1]}" for edge in graph_in.edges(data=True)] + edges_2 = [f"{edge[0]} -> {edge[1]}" for edge in graph_out.edges(data=True)] + + assert edges_1 == edges_2 + + def test_directed_graph_run_twice_produces_same_graph(self): + # create the test graph as a directed graph + graph_in = self._create_strongly_connected_graph_with_edges_flipped( + digraph=True + ) + graph_out_1 = stable_largest_connected_component(graph_in.copy()) + graph_out_2 = stable_largest_connected_component(graph_in.copy()) + + # Make sure the output is identical when run multiple times + assert "".join(nx.generate_graphml(graph_out_1)) == "".join( + nx.generate_graphml(graph_out_2) + ) + + def _create_strongly_connected_graph(self, digraph=False): + graph = nx.Graph() if not digraph else nx.DiGraph() + graph.add_node("1", node_name=1) + graph.add_node("2", node_name=2) + graph.add_node("3", node_name=3) + graph.add_node("4", node_name=4) + graph.add_edge("4", "5", degree=4) + graph.add_edge("3", "4", degree=3) + graph.add_edge("2", "3", degree=2) + graph.add_edge("1", "2", degree=1) + return graph + + def _create_strongly_connected_graph_with_edges_flipped(self, digraph=False): + graph = nx.Graph() if not digraph else nx.DiGraph() + graph.add_node("1", node_name=1) + graph.add_node("2", node_name=2) + graph.add_node("3", node_name=3) + graph.add_node("4", node_name=4) + graph.add_edge("5", "4", degree=4) + graph.add_edge("4", "3", degree=3) + graph.add_edge("3", "2", degree=2) + graph.add_edge("2", "1", degree=1) + return graph diff --git a/graphrag/tests/unit/indexing/storage/__init__.py b/graphrag/tests/unit/indexing/storage/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/storage/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/storage/test_blob_pipeline_storage.py b/graphrag/tests/unit/indexing/storage/test_blob_pipeline_storage.py new file mode 100644 index 0000000000000000000000000000000000000000..d2ea8683477a32d949e76f8bcafdb6d67488ecfb --- /dev/null +++ b/graphrag/tests/unit/indexing/storage/test_blob_pipeline_storage.py @@ -0,0 +1,96 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +"""Blob Storage Tests.""" + +import re + +from graphrag.index.storage.blob_pipeline_storage import BlobPipelineStorage + +# cspell:disable-next-line well-known-key +WELL_KNOWN_BLOB_STORAGE_KEY = "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" + + +async def test_find(): + storage = BlobPipelineStorage( + connection_string=WELL_KNOWN_BLOB_STORAGE_KEY, + container_name="testfind", + ) + try: + try: + items = list( + storage.find(base_dir="input", file_pattern=re.compile(r".*\.txt$")) + ) + items = [item[0] for item in items] + assert items == [] + + await storage.set( + "input/christmas.txt", "Merry Christmas!", encoding="utf-8" + ) + items = list( + storage.find(base_dir="input", file_pattern=re.compile(r".*\.txt$")) + ) + items = [item[0] for item in items] + assert items == ["input/christmas.txt"] + + await storage.set("test.txt", "Hello, World!", encoding="utf-8") + items = list(storage.find(file_pattern=re.compile(r".*\.txt$"))) + items = [item[0] for item in items] + assert items == ["input/christmas.txt", "test.txt"] + + output = await storage.get("test.txt") + assert output == "Hello, World!" + finally: + await storage.delete("test.txt") + output = await storage.get("test.txt") + assert output is None + finally: + storage.delete_container() + + +async def test_dotprefix(): + storage = BlobPipelineStorage( + connection_string=WELL_KNOWN_BLOB_STORAGE_KEY, + container_name="testfind", + path_prefix=".", + ) + try: + await storage.set("input/christmas.txt", "Merry Christmas!", encoding="utf-8") + items = list(storage.find(file_pattern=re.compile(r".*\.txt$"))) + items = [item[0] for item in items] + assert items == ["input/christmas.txt"] + finally: + storage.delete_container() + + +async def test_child(): + parent = BlobPipelineStorage( + connection_string=WELL_KNOWN_BLOB_STORAGE_KEY, + container_name="testchild", + ) + try: + try: + storage = parent.child("input") + await storage.set("christmas.txt", "Merry Christmas!", encoding="utf-8") + items = list(storage.find(re.compile(r".*\.txt$"))) + items = [item[0] for item in items] + assert items == ["christmas.txt"] + + await storage.set("test.txt", "Hello, World!", encoding="utf-8") + items = list(storage.find(re.compile(r".*\.txt$"))) + items = [item[0] for item in items] + print("FOUND", items) + assert items == ["christmas.txt", "test.txt"] + + output = await storage.get("test.txt") + assert output == "Hello, World!" + + items = list(parent.find(re.compile(r".*\.txt$"))) + items = [item[0] for item in items] + print("FOUND ITEMS", items) + assert items == ["input/christmas.txt", "input/test.txt"] + finally: + await parent.delete("input/test.txt") + has_test = await parent.has("input/test.txt") + assert not has_test + finally: + parent.delete_container() diff --git a/graphrag/tests/unit/indexing/storage/test_file_pipeline_storage.py b/graphrag/tests/unit/indexing/storage/test_file_pipeline_storage.py new file mode 100644 index 0000000000000000000000000000000000000000..643c2a9f69b757c73d1a77dd79135070788bab51 --- /dev/null +++ b/graphrag/tests/unit/indexing/storage/test_file_pipeline_storage.py @@ -0,0 +1,50 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +"""Blob Storage Tests.""" + +import os +import re +from pathlib import Path + +from graphrag.index.storage.file_pipeline_storage import FilePipelineStorage + +__dirname__ = os.path.dirname(__file__) + + +async def test_find(): + storage = FilePipelineStorage() + items = list( + storage.find( + base_dir="tests/fixtures/text", + file_pattern=re.compile(r".*\.txt$"), + progress=None, + file_filter=None, + ) + ) + assert items == [(str(Path("tests/fixtures/text/input/dulce.txt")), {})] + output = await storage.get("tests/fixtures/text/input/dulce.txt") + assert len(output) > 0 + + await storage.set("test.txt", "Hello, World!", encoding="utf-8") + output = await storage.get("test.txt") + assert output == "Hello, World!" + await storage.delete("test.txt") + output = await storage.get("test.txt") + assert output is None + + +async def test_child(): + storage = FilePipelineStorage() + storage = storage.child("tests/fixtures/text") + items = list(storage.find(re.compile(r".*\.txt$"))) + assert items == [(str(Path("input/dulce.txt")), {})] + + output = await storage.get("input/dulce.txt") + assert len(output) > 0 + + await storage.set("test.txt", "Hello, World!", encoding="utf-8") + output = await storage.get("test.txt") + assert output == "Hello, World!" + await storage.delete("test.txt") + output = await storage.get("test.txt") + assert output is None diff --git a/graphrag/tests/unit/indexing/test_exports.py b/graphrag/tests/unit/indexing/test_exports.py new file mode 100644 index 0000000000000000000000000000000000000000..232dfbbdf304e2acbacfb99938b007166828cca8 --- /dev/null +++ b/graphrag/tests/unit/indexing/test_exports.py @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +from graphrag.index import ( + create_pipeline_config, + run_pipeline, + run_pipeline_with_config, +) + + +def test_exported_functions(): + assert callable(create_pipeline_config) + assert callable(run_pipeline_with_config) + assert callable(run_pipeline) diff --git a/graphrag/tests/unit/indexing/test_init_content.py b/graphrag/tests/unit/indexing/test_init_content.py new file mode 100644 index 0000000000000000000000000000000000000000..eeb641cbf6fd7f4d871aed8c1f3095ec5942882d --- /dev/null +++ b/graphrag/tests/unit/indexing/test_init_content.py @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +import re +from typing import Any, cast + +import yaml + +from graphrag.config import ( + GraphRagConfig, + create_graphrag_config, +) +from graphrag.index.init_content import INIT_YAML + + +def test_init_yaml(): + data = yaml.load(INIT_YAML, Loader=yaml.FullLoader) + config = create_graphrag_config(data) + GraphRagConfig.model_validate(config, strict=True) + + +def test_init_yaml_uncommented(): + lines = INIT_YAML.splitlines() + lines = [line for line in lines if "##" not in line] + + def uncomment_line(line: str) -> str: + leading_whitespace = cast(Any, re.search(r"^(\s*)", line)).group(1) + return re.sub(r"^\s*# ", leading_whitespace, line, count=1) + + content = "\n".join([uncomment_line(line) for line in lines]) + data = yaml.load(content, Loader=yaml.FullLoader) + config = create_graphrag_config(data) + GraphRagConfig.model_validate(config, strict=True) diff --git a/graphrag/tests/unit/indexing/verbs/__init__.py b/graphrag/tests/unit/indexing/verbs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/verbs/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/verbs/entities/__init__.py b/graphrag/tests/unit/indexing/verbs/entities/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/verbs/entities/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/verbs/entities/extraction/__init__.py b/graphrag/tests/unit/indexing/verbs/entities/extraction/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/verbs/entities/extraction/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/verbs/entities/extraction/strategies/__init__.py b/graphrag/tests/unit/indexing/verbs/entities/extraction/strategies/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/verbs/entities/extraction/strategies/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/verbs/entities/extraction/strategies/graph_intelligence/__init__.py b/graphrag/tests/unit/indexing/verbs/entities/extraction/strategies/graph_intelligence/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/verbs/entities/extraction/strategies/graph_intelligence/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/verbs/entities/extraction/strategies/graph_intelligence/test_gi_entity_extraction.py b/graphrag/tests/unit/indexing/verbs/entities/extraction/strategies/graph_intelligence/test_gi_entity_extraction.py new file mode 100644 index 0000000000000000000000000000000000000000..1ebca2bf247a601ab08e84460e603933fe04718c --- /dev/null +++ b/graphrag/tests/unit/indexing/verbs/entities/extraction/strategies/graph_intelligence/test_gi_entity_extraction.py @@ -0,0 +1,221 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import unittest + +import networkx as nx + +from graphrag.index.verbs.entities.extraction.strategies.graph_intelligence.run_graph_intelligence import ( + Document, + run_extract_entities, +) +from tests.unit.indexing.verbs.helpers.mock_llm import create_mock_llm + + +class TestRunChain(unittest.IsolatedAsyncioTestCase): + async def test_run_extract_entities_single_document_correct_entities_returned(self): + results = await run_extract_entities( + docs=[Document("test_text", "1")], + entity_types=["person"], + reporter=None, + args={ + "prechunked": True, + "max_gleanings": 0, + "summarize_descriptions": False, + }, + llm=create_mock_llm( + responses=[ + """ + ("entity"<|>TEST_ENTITY_1<|>COMPANY<|>TEST_ENTITY_1 is a test company) + ## + ("entity"<|>TEST_ENTITY_2<|>COMPANY<|>TEST_ENTITY_2 owns TEST_ENTITY_1 and also shares an address with TEST_ENTITY_1) + ## + ("entity"<|>TEST_ENTITY_3<|>PERSON<|>TEST_ENTITY_3 is director of TEST_ENTITY_1) + ## + ("relationship"<|>TEST_ENTITY_1<|>TEST_ENTITY_2<|>TEST_ENTITY_1 and TEST_ENTITY_2 are related because TEST_ENTITY_1 is 100% owned by TEST_ENTITY_2 and the two companies also share the same address)<|>2) + ## + ("relationship"<|>TEST_ENTITY_1<|>TEST_ENTITY_3<|>TEST_ENTITY_1 and TEST_ENTITY_3 are related because TEST_ENTITY_3 is director of TEST_ENTITY_1<|>1)) + """.strip() + ] + ), + ) + + # self.assertItemsEqual isn't available yet, or I am just silly + # so we sort the lists and compare them + assert sorted(["TEST_ENTITY_1", "TEST_ENTITY_2", "TEST_ENTITY_3"]) == sorted([ + entity["name"] for entity in results.entities + ]) + + async def test_run_extract_entities_multiple_documents_correct_entities_returned( + self, + ): + results = await run_extract_entities( + docs=[Document("text_1", "1"), Document("text_2", "2")], + entity_types=["person"], + reporter=None, + args={ + "prechunked": True, + "max_gleanings": 0, + "summarize_descriptions": False, + }, + llm=create_mock_llm( + responses=[ + """ + ("entity"<|>TEST_ENTITY_1<|>COMPANY<|>TEST_ENTITY_1 is a test company) + ## + ("entity"<|>TEST_ENTITY_2<|>COMPANY<|>TEST_ENTITY_2 owns TEST_ENTITY_1 and also shares an address with TEST_ENTITY_1) + ## + ("relationship"<|>TEST_ENTITY_1<|>TEST_ENTITY_2<|>TEST_ENTITY_1 and TEST_ENTITY_2 are related because TEST_ENTITY_1 is 100% owned by TEST_ENTITY_2 and the two companies also share the same address)<|>2) + ## + """.strip(), + """ + ("entity"<|>TEST_ENTITY_1<|>COMPANY<|>TEST_ENTITY_1 is a test company) + ## + ("entity"<|>TEST_ENTITY_3<|>PERSON<|>TEST_ENTITY_3 is director of TEST_ENTITY_1) + ## + ("relationship"<|>TEST_ENTITY_1<|>TEST_ENTITY_3<|>TEST_ENTITY_1 and TEST_ENTITY_3 are related because TEST_ENTITY_3 is director of TEST_ENTITY_1<|>1)) + """.strip(), + ] + ), + ) + + # self.assertItemsEqual isn't available yet, or I am just silly + # so we sort the lists and compare them + assert sorted(["TEST_ENTITY_1", "TEST_ENTITY_2", "TEST_ENTITY_3"]) == sorted([ + entity["name"] for entity in results.entities + ]) + + async def test_run_extract_entities_multiple_documents_correct_edges_returned(self): + results = await run_extract_entities( + docs=[Document("text_1", "1"), Document("text_2", "2")], + entity_types=["person"], + reporter=None, + args={ + "prechunked": True, + "max_gleanings": 0, + "summarize_descriptions": False, + }, + llm=create_mock_llm( + responses=[ + """ + ("entity"<|>TEST_ENTITY_1<|>COMPANY<|>TEST_ENTITY_1 is a test company) + ## + ("entity"<|>TEST_ENTITY_2<|>COMPANY<|>TEST_ENTITY_2 owns TEST_ENTITY_1 and also shares an address with TEST_ENTITY_1) + ## + ("relationship"<|>TEST_ENTITY_1<|>TEST_ENTITY_2<|>TEST_ENTITY_1 and TEST_ENTITY_2 are related because TEST_ENTITY_1 is 100% owned by TEST_ENTITY_2 and the two companies also share the same address)<|>2) + ## + """.strip(), + """ + ("entity"<|>TEST_ENTITY_1<|>COMPANY<|>TEST_ENTITY_1 is a test company) + ## + ("entity"<|>TEST_ENTITY_3<|>PERSON<|>TEST_ENTITY_3 is director of TEST_ENTITY_1) + ## + ("relationship"<|>TEST_ENTITY_1<|>TEST_ENTITY_3<|>TEST_ENTITY_1 and TEST_ENTITY_3 are related because TEST_ENTITY_3 is director of TEST_ENTITY_1<|>1)) + """.strip(), + ] + ), + ) + + # self.assertItemsEqual isn't available yet, or I am just silly + # so we sort the lists and compare them + assert results.graphml_graph is not None, "No graphml graph returned!" + graph = nx.parse_graphml(results.graphml_graph) # type: ignore + + # convert to strings for more visual comparison + edges_str = sorted([f"{edge[0]} -> {edge[1]}" for edge in graph.edges]) + assert edges_str == sorted([ + "TEST_ENTITY_1 -> TEST_ENTITY_2", + "TEST_ENTITY_1 -> TEST_ENTITY_3", + ]) + + async def test_run_extract_entities_multiple_documents_correct_entity_source_ids_mapped( + self, + ): + results = await run_extract_entities( + docs=[Document("text_1", "1"), Document("text_2", "2")], + entity_types=["person"], + reporter=None, + args={ + "prechunked": True, + "max_gleanings": 0, + "summarize_descriptions": False, + }, + llm=create_mock_llm( + responses=[ + """ + ("entity"<|>TEST_ENTITY_1<|>COMPANY<|>TEST_ENTITY_1 is a test company) + ## + ("entity"<|>TEST_ENTITY_2<|>COMPANY<|>TEST_ENTITY_2 owns TEST_ENTITY_1 and also shares an address with TEST_ENTITY_1) + ## + ("relationship"<|>TEST_ENTITY_1<|>TEST_ENTITY_2<|>TEST_ENTITY_1 and TEST_ENTITY_2 are related because TEST_ENTITY_1 is 100% owned by TEST_ENTITY_2 and the two companies also share the same address)<|>2) + ## + """.strip(), + """ + ("entity"<|>TEST_ENTITY_1<|>COMPANY<|>TEST_ENTITY_1 is a test company) + ## + ("entity"<|>TEST_ENTITY_3<|>PERSON<|>TEST_ENTITY_3 is director of TEST_ENTITY_1) + ## + ("relationship"<|>TEST_ENTITY_1<|>TEST_ENTITY_3<|>TEST_ENTITY_1 and TEST_ENTITY_3 are related because TEST_ENTITY_3 is director of TEST_ENTITY_1<|>1)) + """.strip(), + ] + ), + ) + + assert results.graphml_graph is not None, "No graphml graph returned!" + graph = nx.parse_graphml(results.graphml_graph) # type: ignore + + # TODO: The edges might come back in any order, but we're assuming they're coming + # back in the order that we passed in the docs, that might not be true + assert ( + graph.nodes["TEST_ENTITY_3"].get("source_id") == "2" + ) # TEST_ENTITY_3 should be in just 2 + assert ( + graph.nodes["TEST_ENTITY_2"].get("source_id") == "1" + ) # TEST_ENTITY_2 should be in just 1 + assert sorted( + graph.nodes["TEST_ENTITY_1"].get("source_id").split(",") + ) == sorted(["1", "2"]) # TEST_ENTITY_1 should be 1 and 2 + + async def test_run_extract_entities_multiple_documents_correct_edge_source_ids_mapped( + self, + ): + results = await run_extract_entities( + docs=[Document("text_1", "1"), Document("text_2", "2")], + entity_types=["person"], + reporter=None, + args={ + "prechunked": True, + "max_gleanings": 0, + "summarize_descriptions": False, + }, + llm=create_mock_llm( + responses=[ + """ + ("entity"<|>TEST_ENTITY_1<|>COMPANY<|>TEST_ENTITY_1 is a test company) + ## + ("entity"<|>TEST_ENTITY_2<|>COMPANY<|>TEST_ENTITY_2 owns TEST_ENTITY_1 and also shares an address with TEST_ENTITY_1) + ## + ("relationship"<|>TEST_ENTITY_1<|>TEST_ENTITY_2<|>TEST_ENTITY_1 and TEST_ENTITY_2 are related because TEST_ENTITY_1 is 100% owned by TEST_ENTITY_2 and the two companies also share the same address)<|>2) + ## + """.strip(), + """ + ("entity"<|>TEST_ENTITY_1<|>COMPANY<|>TEST_ENTITY_1 is a test company) + ## + ("entity"<|>TEST_ENTITY_3<|>PERSON<|>TEST_ENTITY_3 is director of TEST_ENTITY_1) + ## + ("relationship"<|>TEST_ENTITY_1<|>TEST_ENTITY_3<|>TEST_ENTITY_1 and TEST_ENTITY_3 are related because TEST_ENTITY_3 is director of TEST_ENTITY_1<|>1)) + """.strip(), + ] + ), + ) + + assert results.graphml_graph is not None, "No graphml graph returned!" + graph = nx.parse_graphml(results.graphml_graph) # type: ignore + edges = list(graph.edges(data=True)) + + # should only have 2 edges + assert len(edges) == 2 + + # Sort by source_id for consistent ordering + edge_source_ids = sorted([edge[2].get("source_id", "") for edge in edges]) # type: ignore + assert edge_source_ids[0].split(",") == ["1"] # type: ignore + assert edge_source_ids[1].split(",") == ["2"] # type: ignore diff --git a/graphrag/tests/unit/indexing/verbs/helpers/__init__.py b/graphrag/tests/unit/indexing/verbs/helpers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/verbs/helpers/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/verbs/helpers/mock_llm.py b/graphrag/tests/unit/indexing/verbs/helpers/mock_llm.py new file mode 100644 index 0000000000000000000000000000000000000000..ba27da9c682df9fb04578c0f6dff772b5988bd30 --- /dev/null +++ b/graphrag/tests/unit/indexing/verbs/helpers/mock_llm.py @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +from graphrag.llm import CompletionLLM, MockChatLLM + + +def create_mock_llm( + responses: list[str], +) -> CompletionLLM: + """Creates a mock LLM that returns the given responses.""" + return MockChatLLM(responses) diff --git a/graphrag/tests/unit/indexing/verbs/text/__init__.py b/graphrag/tests/unit/indexing/verbs/text/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/verbs/text/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/verbs/text/test_split.py b/graphrag/tests/unit/indexing/verbs/text/test_split.py new file mode 100644 index 0000000000000000000000000000000000000000..d9ced0640f5dc4272f311f03f02f1c2944ab32ec --- /dev/null +++ b/graphrag/tests/unit/indexing/verbs/text/test_split.py @@ -0,0 +1,51 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import unittest + +import pandas as pd +import pytest + +from graphrag.index.verbs.text.split import text_split_df + + +class TestTextSplit(unittest.TestCase): + def test_empty_string(self): + input = pd.DataFrame([{"in": ""}]) + result = text_split_df(input, "in", "out", ",").to_dict(orient="records") + + assert len(result) == 1 + assert result[0]["out"] == [] + + def test_string_without_seperator(self): + input = pd.DataFrame([{"in": "test_string_without_seperator"}]) + result = text_split_df(input, "in", "out", ",").to_dict(orient="records") + + assert len(result) == 1 + assert result[0]["out"] == ["test_string_without_seperator"] + + def test_string_with_seperator(self): + input = pd.DataFrame([{"in": "test_1,test_2"}]) + result = text_split_df(input, "in", "out", ",").to_dict(orient="records") + + assert len(result) == 1 + assert result[0]["out"] == ["test_1", "test_2"] + + def test_row_with_list_as_column(self): + input = pd.DataFrame([{"in": ["test_1", "test_2"]}]) + result = text_split_df(input, "in", "out", ",").to_dict(orient="records") + + assert len(result) == 1 + assert result[0]["out"] == ["test_1", "test_2"] + + def test_non_string_column_throws_error(self): + input = pd.DataFrame([{"in": 5}]) + with pytest.raises(TypeError): + text_split_df(input, "in", "out", ",").to_dict(orient="records") + + def test_more_than_one_row_returns_correctly(self): + input = pd.DataFrame([{"in": "row_1_1,row_1_2"}, {"in": "row_2_1,row_2_2"}]) + result = text_split_df(input, "in", "out", ",").to_dict(orient="records") + + assert len(result) == 2 + assert result[0]["out"] == ["row_1_1", "row_1_2"] + assert result[1]["out"] == ["row_2_1", "row_2_2"] diff --git a/graphrag/tests/unit/indexing/workflows/__init__.py b/graphrag/tests/unit/indexing/workflows/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a3e38adfb9fc92bbba9f4ee103a96f7d6092a02 --- /dev/null +++ b/graphrag/tests/unit/indexing/workflows/__init__.py @@ -0,0 +1,2 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License diff --git a/graphrag/tests/unit/indexing/workflows/helpers.py b/graphrag/tests/unit/indexing/workflows/helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..512e8294c22201b7d5d75fa6321e19510136faea --- /dev/null +++ b/graphrag/tests/unit/indexing/workflows/helpers.py @@ -0,0 +1,31 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +mock_verbs = { + "mock_verb": lambda x: x, + "mock_verb_2": lambda x: x, +} + +mock_workflows = { + "mock_workflow": lambda _x: [ + { + "verb": "mock_verb", + "args": { + "column": "test", + }, + } + ], + "mock_workflow_2": lambda _x: [ + { + "verb": "mock_verb", + "args": { + "column": "test", + }, + }, + { + "verb": "mock_verb_2", + "args": { + "column": "test", + }, + }, + ], +} diff --git a/graphrag/tests/unit/indexing/workflows/test_load.py b/graphrag/tests/unit/indexing/workflows/test_load.py new file mode 100644 index 0000000000000000000000000000000000000000..6d037d51a5d569eddea6e1ae8dcfe9854badef01 --- /dev/null +++ b/graphrag/tests/unit/indexing/workflows/test_load.py @@ -0,0 +1,237 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License +import unittest + +import pytest + +from graphrag.index.config import PipelineWorkflowReference +from graphrag.index.errors import UnknownWorkflowError +from graphrag.index.workflows.load import create_workflow, load_workflows + +from .helpers import mock_verbs, mock_workflows + + +class TestCreateWorkflow(unittest.TestCase): + def test_workflow_with_steps_should_not_fail(self): + create_workflow( + "workflow_with_steps", + [ + { + "verb": "mock_verb", + "args": { + "column": "test", + }, + } + ], + config=None, + additional_verbs=mock_verbs, + ) + + def test_non_existent_workflow_without_steps_should_crash(self): + # since we don't have a workflow named "test", and the user didn't provide any steps, we should crash + # since we don't know what to do + with pytest.raises(UnknownWorkflowError): + create_workflow("test", None, config=None, additional_verbs=mock_verbs) + + def test_existing_workflow_should_not_crash(self): + create_workflow( + "mock_workflow", + None, + config=None, + additional_verbs=mock_verbs, + additional_workflows=mock_workflows, + ) + + +class TestLoadWorkflows(unittest.TestCase): + def test_non_existent_workflow_should_crash(self): + with pytest.raises(UnknownWorkflowError): + load_workflows( + [ + PipelineWorkflowReference( + name="some_workflow_that_does_not_exist", + config=None, + ) + ], + additional_workflows=mock_workflows, + additional_verbs=mock_verbs, + ) + + def test_single_workflow_should_not_crash(self): + load_workflows( + [ + PipelineWorkflowReference( + name="mock_workflow", + config=None, + ) + ], + additional_workflows=mock_workflows, + additional_verbs=mock_verbs, + ) + + def test_multiple_workflows_should_not_crash(self): + load_workflows( + [ + PipelineWorkflowReference( + name="mock_workflow", + config=None, + ), + PipelineWorkflowReference( + name="mock_workflow_2", + config=None, + ), + ], + # the two above are in the "mock_workflows" list + additional_workflows=mock_workflows, + additional_verbs=mock_verbs, + ) + + def test_two_interdependent_workflows_should_provide_correct_order(self): + ordered_workflows, _deps = load_workflows( + [ + PipelineWorkflowReference( + name="interdependent_workflow_1", + steps=[ + { + "verb": "mock_verb", + "args": { + "column": "test", + }, + "input": { + "source": "workflow:interdependent_workflow_2" + }, # This one is dependent on the second one, so when it comes out of load_workflows, it should be first + } + ], + ), + PipelineWorkflowReference( + name="interdependent_workflow_2", + steps=[ + { + "verb": "mock_verb", + "args": { + "column": "test", + }, + } + ], + ), + ], + # the two above are in the "mock_workflows" list + additional_workflows=mock_workflows, + additional_verbs=mock_verbs, + ) + + # two should only come out + assert len(ordered_workflows) == 2 + assert ordered_workflows[0].workflow.name == "interdependent_workflow_2" + assert ordered_workflows[1].workflow.name == "interdependent_workflow_1" + + def test_three_interdependent_workflows_should_provide_correct_order(self): + ordered_workflows, _deps = load_workflows( + [ + PipelineWorkflowReference( + name="interdependent_workflow_3", + steps=[ + { + "verb": "mock_verb", + "args": { + "column": "test", + }, + } + ], + ), + PipelineWorkflowReference( + name="interdependent_workflow_1", + steps=[ + { + "verb": "mock_verb", + "args": { + "column": "test", + }, + "input": {"source": "workflow:interdependent_workflow_2"}, + } + ], + ), + PipelineWorkflowReference( + name="interdependent_workflow_2", + steps=[ + { + "verb": "mock_verb", + "args": { + "column": "test", + }, + "input": {"source": "workflow:interdependent_workflow_3"}, + } + ], + ), + ], + # the two above are in the "mock_workflows" list + additional_workflows=mock_workflows, + additional_verbs=mock_verbs, + ) + + order = [ + "interdependent_workflow_3", + "interdependent_workflow_2", + "interdependent_workflow_1", + ] + assert [x.workflow.name for x in ordered_workflows] == order + + def test_two_workflows_dependent_on_another_single_workflow_should_provide_correct_order( + self, + ): + ordered_workflows, _deps = load_workflows( + [ + # Workflows 1 and 2 are dependent on 3, so 3 should come out first + PipelineWorkflowReference( + name="interdependent_workflow_3", + steps=[ + { + "verb": "mock_verb", + "args": { + "column": "test", + }, + } + ], + ), + PipelineWorkflowReference( + name="interdependent_workflow_1", + steps=[ + { + "verb": "mock_verb", + "args": { + "column": "test", + }, + "input": {"source": "workflow:interdependent_workflow_3"}, + } + ], + ), + PipelineWorkflowReference( + name="interdependent_workflow_2", + steps=[ + { + "verb": "mock_verb", + "args": { + "column": "test", + }, + "input": {"source": "workflow:interdependent_workflow_3"}, + } + ], + ), + ], + # the two above are in the "mock_workflows" list + additional_workflows=mock_workflows, + additional_verbs=mock_verbs, + ) + + assert len(ordered_workflows) == 3 + assert ordered_workflows[0].workflow.name == "interdependent_workflow_3" + + # The order of the other two doesn't matter, but they need to be there + assert ordered_workflows[1].workflow.name in [ + "interdependent_workflow_1", + "interdependent_workflow_2", + ] + assert ordered_workflows[2].workflow.name in [ + "interdependent_workflow_1", + "interdependent_workflow_2", + ] diff --git a/index_app.py b/index_app.py new file mode 100644 index 0000000000000000000000000000000000000000..5db5c3d8e0244f2cc4cfa9db2ff37faae0ed3f27 --- /dev/null +++ b/index_app.py @@ -0,0 +1,1041 @@ +import gradio as gr +import requests +import logging +import os +import json +import shutil +import glob +import queue +import lancedb +from datetime import datetime +from dotenv import load_dotenv, set_key +import yaml +import pandas as pd +from typing import List, Optional +from pydantic import BaseModel + +# Set up logging +log_queue = queue.Queue() +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') +logger = logging.getLogger(__name__) + +load_dotenv('indexing/.env') + +API_BASE_URL = os.getenv('API_BASE_URL', 'http://localhost:8012') +LLM_API_BASE = os.getenv('LLM_API_BASE', 'http://localhost:11434') +EMBEDDINGS_API_BASE = os.getenv('EMBEDDINGS_API_BASE', 'http://localhost:11434') +ROOT_DIR = os.getenv('ROOT_DIR', 'indexing') + +# Data models +class IndexingRequest(BaseModel): + llm_model: str + embed_model: str + llm_api_base: str + embed_api_base: str + root: str + verbose: bool = False + nocache: bool = False + resume: Optional[str] = None + reporter: str = "rich" + emit: List[str] = ["parquet"] + custom_args: Optional[str] = None + +class PromptTuneRequest(BaseModel): + root: str = "./{ROOT_DIR}" + domain: Optional[str] = None + method: str = "random" + limit: int = 15 + language: Optional[str] = None + max_tokens: int = 2000 + chunk_size: int = 200 + no_entity_types: bool = False + output: str = "./{ROOT_DIR}/prompts" + +class QueueHandler(logging.Handler): + def __init__(self, log_queue): + super().__init__() + self.log_queue = log_queue + + def emit(self, record): + self.log_queue.put(self.format(record)) +queue_handler = QueueHandler(log_queue) +logging.getLogger().addHandler(queue_handler) + + +def update_logs(): + logs = [] + while not log_queue.empty(): + logs.append(log_queue.get()) + return "\n".join(logs) + +##########SETTINGS################ +def load_settings(): + config_path = os.getenv('GRAPHRAG_CONFIG', 'config.yaml') + if os.path.exists(config_path): + with open(config_path, 'r') as config_file: + config = yaml.safe_load(config_file) + else: + config = {} + + settings = { + 'llm_model': os.getenv('LLM_MODEL', config.get('llm_model')), + 'embedding_model': os.getenv('EMBEDDINGS_MODEL', config.get('embedding_model')), + 'community_level': int(os.getenv('COMMUNITY_LEVEL', config.get('community_level', 2))), + 'token_limit': int(os.getenv('TOKEN_LIMIT', config.get('token_limit', 4096))), + 'api_key': os.getenv('GRAPHRAG_API_KEY', config.get('api_key')), + 'api_base': os.getenv('LLM_API_BASE', config.get('api_base')), + 'embeddings_api_base': os.getenv('EMBEDDINGS_API_BASE', config.get('embeddings_api_base')), + 'api_type': os.getenv('API_TYPE', config.get('api_type', 'openai')), + } + + return settings + + +#######FILE_MANAGEMENT############## +def list_output_files(root_dir): + output_dir = os.path.join(root_dir, "output") + files = [] + for root, _, filenames in os.walk(output_dir): + for filename in filenames: + files.append(os.path.join(root, filename)) + return files + +def update_file_list(): + files = list_input_files() + return gr.update(choices=[f["path"] for f in files]) + +def update_file_content(file_path): + if not file_path: + return "" + try: + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + return content + except Exception as e: + logging.error(f"Error reading file: {str(e)}") + return f"Error reading file: {str(e)}" + +def list_output_folders(): + output_dir = os.path.join(ROOT_DIR, "output") + folders = [f for f in os.listdir(output_dir) if os.path.isdir(os.path.join(output_dir, f))] + return sorted(folders, reverse=True) + +def update_output_folder_list(): + folders = list_output_folders() + return gr.update(choices=folders, value=folders[0] if folders else None) + +def list_folder_contents(folder_name): + folder_path = os.path.join(ROOT_DIR, "output", folder_name, "artifacts") + contents = [] + if os.path.exists(folder_path): + for item in os.listdir(folder_path): + item_path = os.path.join(folder_path, item) + if os.path.isdir(item_path): + contents.append(f"[DIR] {item}") + else: + _, ext = os.path.splitext(item) + contents.append(f"[{ext[1:].upper()}] {item}") + return contents + +def update_folder_content_list(folder_name): + if isinstance(folder_name, list) and folder_name: + folder_name = folder_name[0] + elif not folder_name: + return gr.update(choices=[]) + + contents = list_folder_contents(folder_name) + return gr.update(choices=contents) + +def handle_content_selection(folder_name, selected_item): + if isinstance(selected_item, list) and selected_item: + selected_item = selected_item[0] # Take the first item if it's a list + + if isinstance(selected_item, str) and selected_item.startswith("[DIR]"): + dir_name = selected_item[6:] # Remove "[DIR] " prefix + sub_contents = list_folder_contents(os.path.join(ROOT_DIR, "output", folder_name, dir_name)) + return gr.update(choices=sub_contents), "", "" + elif isinstance(selected_item, str): + file_name = selected_item.split("] ")[1] if "]" in selected_item else selected_item # Remove file type prefix if present + file_path = os.path.join(ROOT_DIR, "output", folder_name, "artifacts", file_name) + file_size = os.path.getsize(file_path) + file_type = os.path.splitext(file_name)[1] + file_info = f"File: {file_name}\nSize: {file_size} bytes\nType: {file_type}" + content = read_file_content(file_path) + return gr.update(), file_info, content + else: + return gr.update(), "", "" + +def initialize_selected_folder(folder_name): + if not folder_name: + return "Please select a folder first.", gr.update(choices=[]) + folder_path = os.path.join(ROOT_DIR, "output", folder_name, "artifacts") + if not os.path.exists(folder_path): + return f"Artifacts folder not found in '{folder_name}'.", gr.update(choices=[]) + contents = list_folder_contents(folder_path) + return f"Folder '{folder_name}/artifacts' initialized with {len(contents)} items.", gr.update(choices=contents) + +def upload_file(file): + if file is not None: + input_dir = os.path.join(ROOT_DIR, 'input') + os.makedirs(input_dir, exist_ok=True) + + # Get the original filename from the uploaded file + original_filename = file.name + + # Create the destination path + destination_path = os.path.join(input_dir, os.path.basename(original_filename)) + + # Move the uploaded file to the destination path + shutil.move(file.name, destination_path) + + logging.info(f"File uploaded and moved to: {destination_path}") + status = f"File uploaded: {os.path.basename(original_filename)}" + else: + status = "No file uploaded" + + # Get the updated file list + updated_file_list = [f["path"] for f in list_input_files()] + + return status, gr.update(choices=updated_file_list), update_logs() + +def list_input_files(): + input_dir = os.path.join(ROOT_DIR, 'input') + files = [] + if os.path.exists(input_dir): + files = [f for f in os.listdir(input_dir) if os.path.isfile(os.path.join(input_dir, f))] + return [{"name": f, "path": os.path.join(input_dir, f)} for f in files] + +def delete_file(file_path): + try: + os.remove(file_path) + logging.info(f"File deleted: {file_path}") + status = f"File deleted: {os.path.basename(file_path)}" + except Exception as e: + logging.error(f"Error deleting file: {str(e)}") + status = f"Error deleting file: {str(e)}" + + # Get the updated file list + updated_file_list = [f["path"] for f in list_input_files()] + + return status, gr.update(choices=updated_file_list), update_logs() + +def read_file_content(file_path): + try: + if file_path.endswith('.parquet'): + df = pd.read_parquet(file_path) + + # Get basic information about the DataFrame + info = f"Parquet File: {os.path.basename(file_path)}\n" + info += f"Rows: {len(df)}, Columns: {len(df.columns)}\n\n" + info += "Column Names:\n" + "\n".join(df.columns) + "\n\n" + + # Display first few rows + info += "First 5 rows:\n" + info += df.head().to_string() + "\n\n" + + # Display basic statistics + info += "Basic Statistics:\n" + info += df.describe().to_string() + + return info + else: + with open(file_path, 'r', encoding='utf-8', errors='replace') as file: + content = file.read() + return content + except Exception as e: + logging.error(f"Error reading file: {str(e)}") + return f"Error reading file: {str(e)}" + +def save_file_content(file_path, content): + try: + with open(file_path, 'w') as file: + file.write(content) + logging.info(f"File saved: {file_path}") + status = f"File saved: {os.path.basename(file_path)}" + except Exception as e: + logging.error(f"Error saving file: {str(e)}") + status = f"Error saving file: {str(e)}" + return status, update_logs() + +def manage_data(): + db = lancedb.connect(f"{ROOT_DIR}/lancedb") + tables = db.table_names() + table_info = "" + if tables: + table = db[tables[0]] + table_info = f"Table: {tables[0]}\nSchema: {table.schema}" + + input_files = list_input_files() + + return { + "database_info": f"Tables: {', '.join(tables)}\n\n{table_info}", + "input_files": input_files + } + + +def find_latest_graph_file(root_dir): + pattern = os.path.join(root_dir, "output", "*", "artifacts", "*.graphml") + graph_files = glob.glob(pattern) + if not graph_files: + # If no files found, try excluding .DS_Store + output_dir = os.path.join(root_dir, "output") + run_dirs = [d for d in os.listdir(output_dir) if os.path.isdir(os.path.join(output_dir, d)) and d != ".DS_Store"] + if run_dirs: + latest_run = max(run_dirs) + pattern = os.path.join(root_dir, "output", latest_run, "artifacts", "*.graphml") + graph_files = glob.glob(pattern) + + if not graph_files: + return None + + # Sort files by modification time, most recent first + latest_file = max(graph_files, key=os.path.getmtime) + return latest_file + +def find_latest_output_folder(): + root_dir =f"{ROOT_DIR}/output" + folders = [f for f in os.listdir(root_dir) if os.path.isdir(os.path.join(root_dir, f))] + + if not folders: + raise ValueError("No output folders found") + + # Sort folders by creation time, most recent first + sorted_folders = sorted(folders, key=lambda x: os.path.getctime(os.path.join(root_dir, x)), reverse=True) + + latest_folder = None + timestamp = None + + for folder in sorted_folders: + try: + # Try to parse the folder name as a timestamp + timestamp = datetime.strptime(folder, "%Y%m%d-%H%M%S") + latest_folder = folder + break + except ValueError: + # If the folder name is not a valid timestamp, skip it + continue + + if latest_folder is None: + raise ValueError("No valid timestamp folders found") + + latest_path = os.path.join(root_dir, latest_folder) + artifacts_path = os.path.join(latest_path, "artifacts") + + if not os.path.exists(artifacts_path): + raise ValueError(f"Artifacts folder not found in {latest_path}") + + return latest_path, latest_folder + +def initialize_data(): + global entity_df, relationship_df, text_unit_df, report_df, covariate_df + + tables = { + "entity_df": "create_final_nodes", + "relationship_df": "create_final_edges", + "text_unit_df": "create_final_text_units", + "report_df": "create_final_reports", + "covariate_df": "create_final_covariates" + } + + timestamp = None # Initialize timestamp to None + + try: + latest_output_folder, timestamp = find_latest_output_folder() + artifacts_folder = os.path.join(latest_output_folder, "artifacts") + + for df_name, file_prefix in tables.items(): + file_pattern = os.path.join(artifacts_folder, f"{file_prefix}*.parquet") + matching_files = glob.glob(file_pattern) + + if matching_files: + latest_file = max(matching_files, key=os.path.getctime) + df = pd.read_parquet(latest_file) + globals()[df_name] = df + logging.info(f"Successfully loaded {df_name} from {latest_file}") + else: + logging.warning(f"No matching file found for {df_name} in {artifacts_folder}. Initializing as an empty DataFrame.") + globals()[df_name] = pd.DataFrame() + + except Exception as e: + logging.error(f"Error initializing data: {str(e)}") + for df_name in tables.keys(): + globals()[df_name] = pd.DataFrame() + + return timestamp + +# Call initialize_data and store the timestamp +current_timestamp = initialize_data() + + +###########MODELS################## +def normalize_api_base(api_base: str) -> str: + """Normalize the API base URL by removing trailing slashes and /v1 or /api suffixes.""" + api_base = api_base.rstrip('/') + if api_base.endswith('/v1') or api_base.endswith('/api'): + api_base = api_base[:-3] + return api_base + +def is_ollama_api(base_url: str) -> bool: + """Check if the given base URL is for Ollama API.""" + try: + response = requests.get(f"{normalize_api_base(base_url)}/api/tags") + return response.status_code == 200 + except requests.RequestException: + return False + +def get_ollama_models(base_url: str) -> List[str]: + """Fetch available models from Ollama API.""" + try: + response = requests.get(f"{normalize_api_base(base_url)}/api/tags") + response.raise_for_status() + models = response.json().get('models', []) + return [model['name'] for model in models] + except requests.RequestException as e: + logger.error(f"Error fetching Ollama models: {str(e)}") + return [] + +def get_openai_compatible_models(base_url: str) -> List[str]: + """Fetch available models from OpenAI-compatible API.""" + try: + response = requests.get(f"{normalize_api_base(base_url)}/v1/models") + response.raise_for_status() + models = response.json().get('data', []) + return [model['id'] for model in models] + except requests.RequestException as e: + logger.error(f"Error fetching OpenAI-compatible models: {str(e)}") + return [] + +def get_local_models(base_url: str) -> List[str]: + """Get available models based on the API type.""" + if is_ollama_api(base_url): + return get_ollama_models(base_url) + else: + return get_openai_compatible_models(base_url) + +def get_model_params(base_url: str, model_name: str) -> dict: + """Get model parameters for Ollama models.""" + if is_ollama_api(base_url): + try: + response = requests.post(f"{normalize_api_base(base_url)}/api/show", json={"name": model_name}) + response.raise_for_status() + model_info = response.json() + return model_info.get('parameters', {}) + except requests.RequestException as e: + logger.error(f"Error fetching Ollama model parameters: {str(e)}") + return {} + + + + + + + + +#########API########### +def start_indexing(request: IndexingRequest): + url = f"{API_BASE_URL}/v1/index" + + try: + response = requests.post(url, json=request.dict()) + response.raise_for_status() + result = response.json() + return result['message'], gr.update(interactive=False), gr.update(interactive=True) + except requests.RequestException as e: + logger.error(f"Error starting indexing: {str(e)}") + return f"Error: {str(e)}", gr.update(interactive=True), gr.update(interactive=False) + +def check_indexing_status(): + url = f"{API_BASE_URL}/v1/index_status" + try: + response = requests.get(url) + response.raise_for_status() + result = response.json() + return result['status'], "\n".join(result['logs']) + except requests.RequestException as e: + logger.error(f"Error checking indexing status: {str(e)}") + return "Error", f"Failed to check indexing status: {str(e)}" + +def start_prompt_tuning(request: PromptTuneRequest): + url = f"{API_BASE_URL}/v1/prompt_tune" + + try: + response = requests.post(url, json=request.dict()) + response.raise_for_status() + result = response.json() + return result['message'], gr.update(interactive=False) + except requests.RequestException as e: + logger.error(f"Error starting prompt tuning: {str(e)}") + return f"Error: {str(e)}", gr.update(interactive=True) + +def check_prompt_tuning_status(): + url = f"{API_BASE_URL}/v1/prompt_tune_status" + try: + response = requests.get(url) + response.raise_for_status() + result = response.json() + return result['status'], "\n".join(result['logs']) + except requests.RequestException as e: + logger.error(f"Error checking prompt tuning status: {str(e)}") + return "Error", f"Failed to check prompt tuning status: {str(e)}" + +def update_model_params(model_name): + params = get_model_params(model_name) + return gr.update(value=json.dumps(params, indent=2)) + + + + + + + + + +########################### +css = """ +html, body { + margin: 0; + padding: 0; + height: 100vh; + overflow: hidden; +} + +.gradio-container { + margin: 0 !important; + padding: 0 !important; + width: 100vw !important; + max-width: 100vw !important; + height: 100vh !important; + max-height: 100vh !important; + overflow: auto; + display: flex; + flex-direction: column; +} + +#main-container { + flex: 1; + display: flex; + overflow: hidden; +} + +#left-column, #right-column { + height: 100%; + overflow-y: auto; + padding: 10px; +} + +#left-column { + flex: 1; +} + +#right-column { + flex: 2; + display: flex; + flex-direction: column; +} + +#chat-container { + flex: 0 0 auto; /* Don't allow this to grow */ + height: 100%; + display: flex; + flex-direction: column; + overflow: hidden; + border: 1px solid var(--color-accent); + border-radius: 8px; + padding: 10px; + overflow-y: auto; +} + +#chatbot { + overflow-y: hidden; + height: 100%; +} + +#chat-input-row { + margin-top: 10px; +} + +#visualization-plot { + width: 100%; + aspect-ratio: 1 / 1; + max-height: 600px; /* Adjust this value as needed */ +} + +#vis-controls-row { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 10px; +} + +#vis-controls-row > * { + flex: 1; + margin: 0 5px; +} + +#vis-status { + margin-top: 10px; +} + +/* Chat input styling */ +#chat-input-row { + display: flex; + flex-direction: column; +} + +#chat-input-row > div { + width: 100% !important; +} + +#chat-input-row input[type="text"] { + width: 100% !important; +} + +/* Adjust padding for all containers */ +.gr-box, .gr-form, .gr-panel { + padding: 10px !important; +} + +/* Ensure all textboxes and textareas have full height */ +.gr-textbox, .gr-textarea { + height: auto !important; + min-height: 100px !important; +} + +/* Ensure all dropdowns have full width */ +.gr-dropdown { + width: 100% !important; +} + +:root { + --color-background: #2C3639; + --color-foreground: #3F4E4F; + --color-accent: #A27B5C; + --color-text: #DCD7C9; +} + +body, .gradio-container { + background-color: var(--color-background); + color: var(--color-text); +} + +.gr-button { + background-color: var(--color-accent); + color: var(--color-text); +} + +.gr-input, .gr-textarea, .gr-dropdown { + background-color: var(--color-foreground); + color: var(--color-text); + border: 1px solid var(--color-accent); +} + +.gr-panel { + background-color: var(--color-foreground); + border: 1px solid var(--color-accent); +} + +.gr-box { + border-radius: 8px; + margin-bottom: 10px; + background-color: var(--color-foreground); +} + +.gr-padded { + padding: 10px; +} + +.gr-form { + background-color: var(--color-foreground); +} + +.gr-input-label, .gr-radio-label { + color: var(--color-text); +} + +.gr-checkbox-label { + color: var(--color-text); +} + +.gr-markdown { + color: var(--color-text); +} + +.gr-accordion { + background-color: var(--color-foreground); + border: 1px solid var(--color-accent); +} + +.gr-accordion-header { + background-color: var(--color-accent); + color: var(--color-text); +} + +#visualization-container { + display: flex; + flex-direction: column; + border: 2px solid var(--color-accent); + border-radius: 8px; + margin-top: 20px; + padding: 10px; + background-color: var(--color-foreground); + height: calc(100vh - 300px); /* Adjust this value as needed */ +} + +#visualization-plot { + width: 100%; + height: 100%; +} + +#vis-controls-row { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 10px; +} + +#vis-controls-row > * { + flex: 1; + margin: 0 5px; +} + +#vis-status { + margin-top: 10px; +} + +#log-container { + background-color: var(--color-foreground); + border: 1px solid var(--color-accent); + border-radius: 8px; + padding: 10px; + margin-top: 20px; + max-height: auto; + overflow-y: auto; +} + +.setting-accordion .label-wrap { + cursor: pointer; +} + +.setting-accordion .icon { + transition: transform 0.3s ease; +} + +.setting-accordion[open] .icon { + transform: rotate(90deg); +} + +.gr-form.gr-box { + border: none !important; + background: none !important; +} + +.model-params { + border-top: 1px solid var(--color-accent); + margin-top: 10px; + padding-top: 10px; +} +""" + + +def create_interface(): + settings = load_settings() + llm_api_base = normalize_api_base(settings['api_base']) + embeddings_api_base = normalize_api_base(settings['embeddings_api_base']) + + with gr.Blocks(theme=gr.themes.Base(), css=css) as demo: + gr.Markdown("# GraphRAG Indexer") + + with gr.Tabs(): + with gr.TabItem("Indexing"): + with gr.Row(): + with gr.Column(scale=1): + gr.Markdown("## Indexing Configuration") + + with gr.Row(): + llm_name = gr.Dropdown(label="LLM Model", choices=[], value=settings['llm_model'], allow_custom_value=True) + refresh_llm_btn = gr.Button("🔄", size='sm', scale=0) + + with gr.Row(): + embed_name = gr.Dropdown(label="Embedding Model", choices=[], value=settings['embedding_model'], allow_custom_value=True) + refresh_embed_btn = gr.Button("🔄", size='sm', scale=0) + + save_config_button = gr.Button("Save Configuration", variant="primary") + config_status = gr.Textbox(label="Configuration Status", lines=2) + + with gr.Row(): + with gr.Column(scale=1): + root_dir = gr.Textbox(label="Root Directory (Edit in .env file)", value=f"{ROOT_DIR}") + with gr.Group(): + verbose = gr.Checkbox(label="Verbose", interactive=True, value=True) + nocache = gr.Checkbox(label="No Cache", interactive=True, value=True) + + with gr.Accordion("Advanced Options", open=True): + resume = gr.Textbox(label="Resume Timestamp (optional)") + reporter = gr.Dropdown( + label="Reporter", + choices=["rich", "print", "none"], + value="rich", + interactive=True + ) + emit_formats = gr.CheckboxGroup( + label="Emit Formats", + choices=["json", "csv", "parquet"], + value=["parquet"], + interactive=True + ) + custom_args = gr.Textbox(label="Custom CLI Arguments", placeholder="--arg1 value1 --arg2 value2") + + with gr.Column(scale=1): + gr.Markdown("## Indexing Output") + index_output = gr.Textbox(label="Output", lines=10) + index_status = gr.Textbox(label="Status", lines=2) + + run_index_button = gr.Button("Run Indexing", variant="primary") + check_status_button = gr.Button("Check Indexing Status") + + + with gr.TabItem("Prompt Tuning"): + with gr.Row(): + with gr.Column(scale=1): + gr.Markdown("## Prompt Tuning Configuration") + + pt_root = gr.Textbox(label="Root Directory", value=f"{ROOT_DIR}", interactive=True) + pt_domain = gr.Textbox(label="Domain (optional)") + pt_method = gr.Dropdown( + label="Method", + choices=["random", "top", "all"], + value="random", + interactive=True + ) + pt_limit = gr.Number(label="Limit", value=15, precision=0, interactive=True) + pt_language = gr.Textbox(label="Language (optional)") + pt_max_tokens = gr.Number(label="Max Tokens", value=2000, precision=0, interactive=True) + pt_chunk_size = gr.Number(label="Chunk Size", value=200, precision=0, interactive=True) + pt_no_entity_types = gr.Checkbox(label="No Entity Types", value=False) + pt_output_dir = gr.Textbox(label="Output Directory", value=f"{ROOT_DIR}/prompts", interactive=True) + save_pt_config_button = gr.Button("Save Prompt Tuning Configuration", variant="primary") + + with gr.Column(scale=1): + gr.Markdown("## Prompt Tuning Output") + pt_output = gr.Textbox(label="Output", lines=10) + pt_status = gr.Textbox(label="Status", lines=10) + + run_pt_button = gr.Button("Run Prompt Tuning", variant="primary") + check_pt_status_button = gr.Button("Check Prompt Tuning Status") + + with gr.TabItem("Data Management"): + with gr.Row(): + with gr.Column(scale=1): + with gr.Accordion("File Upload", open=True): + file_upload = gr.File(label="Upload File", file_types=[".txt", ".csv", ".parquet"]) + upload_btn = gr.Button("Upload File", variant="primary") + upload_output = gr.Textbox(label="Upload Status", visible=True) + + with gr.Accordion("File Management", open=True): + file_list = gr.Dropdown(label="Select File", choices=[], interactive=True) + refresh_btn = gr.Button("Refresh File List", variant="secondary") + + file_content = gr.TextArea(label="File Content", lines=10) + + with gr.Row(): + delete_btn = gr.Button("Delete Selected File", variant="stop") + save_btn = gr.Button("Save Changes", variant="primary") + + operation_status = gr.Textbox(label="Operation Status", visible=True) + + with gr.Column(scale=1): + with gr.Accordion("Output Folders", open=True): + output_folder_list = gr.Dropdown(label="Select Output Folder", choices=[], interactive=True) + refresh_output_btn = gr.Button("Refresh Output Folders", variant="secondary") + folder_content_list = gr.Dropdown(label="Folder Contents", choices=[], interactive=True, multiselect=False) + + file_info = gr.Textbox(label="File Info", lines=3) + output_content = gr.TextArea(label="File Content", lines=10) + + + + # Event handlers + def refresh_llm_models(): + models = get_local_models(llm_api_base) + return gr.update(choices=models) + + def refresh_embed_models(): + models = get_local_models(embeddings_api_base) + return gr.update(choices=models) + + refresh_llm_btn.click( + refresh_llm_models, + outputs=[llm_name] + ) + + refresh_embed_btn.click( + refresh_embed_models, + outputs=[embed_name] + ) + + # Initialize model lists on page load + demo.load(refresh_llm_models, outputs=[llm_name]) + demo.load(refresh_embed_models, outputs=[embed_name]) + + def create_indexing_request(): + return IndexingRequest( + llm_model=llm_name.value, + embed_model=embed_name.value, + llm_api_base=llm_api_base, + embed_api_base=embeddings_api_base, + root=root_dir.value, + verbose=verbose.value, + nocache=nocache.value, + resume=resume.value if resume.value else None, + reporter=reporter.value, + emit=[fmt for fmt in emit_formats.value], + custom_args=custom_args.value if custom_args.value else None + ) + + run_index_button.click( + lambda: start_indexing(create_indexing_request()), + outputs=[index_output, run_index_button, check_status_button] + ) + + check_status_button.click( + check_indexing_status, + outputs=[index_status, index_output] + ) + + def create_prompt_tune_request(): + return PromptTuneRequest( + root=pt_root.value, + domain=pt_domain.value if pt_domain.value else None, + method=pt_method.value, + limit=int(pt_limit.value), + language=pt_language.value if pt_language.value else None, + max_tokens=int(pt_max_tokens.value), + chunk_size=int(pt_chunk_size.value), + no_entity_types=pt_no_entity_types.value, + output=pt_output_dir.value + ) + + def update_pt_output(request): + result, button_update = start_prompt_tuning(request) + return result, button_update, gr.update(value=f"Request: {request.dict()}") + + run_pt_button.click( + lambda: update_pt_output(create_prompt_tune_request()), + outputs=[pt_output, run_pt_button, pt_status] + ) + + check_pt_status_button.click( + check_prompt_tuning_status, + outputs=[pt_status, pt_output] + ) + + # Add event handlers for real-time updates + pt_root.change(lambda x: gr.update(value=f"Root Directory changed to: {x}"), inputs=[pt_root], outputs=[pt_status]) + pt_limit.change(lambda x: gr.update(value=f"Limit changed to: {x}"), inputs=[pt_limit], outputs=[pt_status]) + pt_max_tokens.change(lambda x: gr.update(value=f"Max Tokens changed to: {x}"), inputs=[pt_max_tokens], outputs=[pt_status]) + pt_chunk_size.change(lambda x: gr.update(value=f"Chunk Size changed to: {x}"), inputs=[pt_chunk_size], outputs=[pt_status]) + pt_output_dir.change(lambda x: gr.update(value=f"Output Directory changed to: {x}"), inputs=[pt_output_dir], outputs=[pt_status]) + + # Event handlers for Data Management + upload_btn.click( + upload_file, + inputs=[file_upload], + outputs=[upload_output, file_list, operation_status] + ) + + refresh_btn.click( + update_file_list, + outputs=[file_list] + ) + + refresh_output_btn.click( + update_output_folder_list, + outputs=[output_folder_list] + ) + + file_list.change( + update_file_content, + inputs=[file_list], + outputs=[file_content] + ) + + delete_btn.click( + delete_file, + inputs=[file_list], + outputs=[operation_status, file_list, operation_status] + ) + + save_btn.click( + save_file_content, + inputs=[file_list, file_content], + outputs=[operation_status, operation_status] + ) + + output_folder_list.change( + update_folder_content_list, + inputs=[output_folder_list], + outputs=[folder_content_list] + ) + + folder_content_list.change( + handle_content_selection, + inputs=[output_folder_list, folder_content_list], + outputs=[folder_content_list, file_info, output_content] + ) + + # Event handler for saving configuration + save_config_button.click( + update_env_file, + inputs=[llm_name, embed_name], + outputs=[config_status] + ) + + # Event handler for saving prompt tuning configuration + save_pt_config_button.click( + save_prompt_tuning_config, + inputs=[pt_root, pt_domain, pt_method, pt_limit, pt_language, pt_max_tokens, pt_chunk_size, pt_no_entity_types, pt_output_dir], + outputs=[pt_status] + ) + + # Initialize file list and output folder list + demo.load(update_file_list, outputs=[file_list]) + demo.load(update_output_folder_list, outputs=[output_folder_list]) + + return demo + +def update_env_file(llm_model, embed_model): + env_path = os.path.join(ROOT_DIR, '.env') + + set_key(env_path, 'LLM_MODEL', llm_model) + set_key(env_path, 'EMBEDDINGS_MODEL', embed_model) + + # Reload the environment variables + load_dotenv(env_path, override=True) + + return f"Environment updated: LLM_MODEL={llm_model}, EMBEDDINGS_MODEL={embed_model}" + +def save_prompt_tuning_config(root, domain, method, limit, language, max_tokens, chunk_size, no_entity_types, output_dir): + config = { + 'prompt_tuning': { + 'root': root, + 'domain': domain, + 'method': method, + 'limit': limit, + 'language': language, + 'max_tokens': max_tokens, + 'chunk_size': chunk_size, + 'no_entity_types': no_entity_types, + 'output': output_dir + } + } + + config_path = os.path.join(ROOT_DIR, 'prompt_tuning_config.yaml') + with open(config_path, 'w') as f: + yaml.dump(config, f) + + return f"Prompt Tuning configuration saved to {config_path}" + +demo = create_interface() + +if __name__ == "__main__": + demo.launch(server_port=7861) diff --git a/indexing/.DS_Store b/indexing/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..fd9cc09263281e094add4ba9c8f5bb7e39f890f2 Binary files /dev/null and b/indexing/.DS_Store differ diff --git a/indexing/.env b/indexing/.env new file mode 100644 index 0000000000000000000000000000000000000000..c29658ada2722851eef3495ccf362b96e88a08db --- /dev/null +++ b/indexing/.env @@ -0,0 +1,19 @@ +LLM_PROVIDER=openai +LLM_API_BASE=http://localhost:11434/v1 +LLM_MODEL='mistral-large:123b-instruct-2407-q4_0' +LLM_API_KEY=12345 + +EMBEDDINGS_PROVIDER=openai +EMBEDDINGS_API_BASE=http://localhost:11434 +EMBEDDINGS_MODEL='snowflake-arctic-embed:335m' +EMBEDDINGS_API_KEY=12345 + + +GRAPHRAG_API_KEY=12345 +ROOT_DIR=indexing +INPUT_DIR=${ROOT_DIR}/output/${timestamp}/artifacts +LLM_SERVICE_TYPE=openai_chat +EMBEDDINGS_SERVICE_TYPE=openai_embedding + +API_URL=http://localhost:8012 +API_PORT=8012 diff --git a/indexing/input/Tree frog adhesion biomimetics_ opportunit - Unknown.txt b/indexing/input/Tree frog adhesion biomimetics_ opportunit - Unknown.txt new file mode 100644 index 0000000000000000000000000000000000000000..a0bf865fb358e853ff4bdc4dd941bd5196a724dc --- /dev/null +++ b/indexing/input/Tree frog adhesion biomimetics_ opportunit - Unknown.txt @@ -0,0 +1,2311 @@ +Tree frog adhesion + +biomimetics: opportunities + +royalsocietypublishing.org/journal/rsta + +for the development of new, + +smart adhesives that adhere + +Review + +under wet conditions + +Cite this article: Meng F, Liu Q, Wang X, Tan + +Fandong Meng1, Quan Liu1, Xin Wang1, Di Tan1, + +D, Xue L, Barnes WJP. 2019 Tree frog adhesion + +biomimetics: opportunities for the + +Longjian Xue1 and W. Jon. P. Barnes2 + +development of new, smart adhesives that + +1School of Power and Mechanical Engineering, Wuhan University, + +adhere under wet conditions. Phil. Trans. R. + +Soc. A 377: 20190131. + +South Donghu Road 8, Wuhan, People’s Republic of China + +2 + +http://dx.doi.org/10.1098/rsta.2019.0131 + +Centre for Cell Engineering, University of Glasgow, Joseph Black + +Building, Glasgow G12 8QQ, UK + +Received: 4 April 2019 + +WJPB, 0000-0002-1359-5803 + +Accepted: 5 April 2019 + +Enlarged adhesive toe pads on the tip of each + +digit allow tree frogs to climb smooth vertical + +One contribution of 15 to a theme issue + +and overhanging surfaces, and are effective in + +‘Bioinspired materials and surfaces for green + +generating reversible adhesion under both dry and + +science and technology (part 2)’. + +wet conditions. In this review, we discuss the + +complexities of the structure of tree frog toe pads + +Subject Areas: + +in relation to their function and review their + +materials science, nanotechnology, biomedical + +biomimetic potential. Of particular importance are + +engineering, biomechanics, electron + +the (largely) hexagonal epithelial cells surrounded + +microscopy, light microscopy + +by deep channels that cover the surface of each + +toe pad and the array of nanopillars on their + +surface. Fluid secreted by the pads covers the + +Keywords: + +surface of each pad, so the pads adhere by wet + +tree frog, biomimetics, reversible adhesion, + +adhesion, involving both capillarity and viscosity- + +capillarity, wet adhesives, bioinspired + +dependent forces. The fabrication and testing of + +adhesives + +toe pad mimics are challenging, but valuable both + +for testing hypotheses concerning tree frog toe pad + +function and for developing toe pad mimics. Initial + +Authors for correspondence: + +Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +mimics involved the fabrication of hexagonal pillars + +Longjian Xue + +mimicking the toe pad epithelial structure. More + +e-mail: xuelongjian@whu.edu.cn + +recent ones additionally replicate the nanostructures + +W. Jon. P. Barnes + +on their surface. Finally we describe some of the + +e-mail: jon.barnes@glasgow.ac.uk + +biomimetic applications that have been developed + +from toe pad mimics, which include both bioinspired + +adhesives and friction-generating devices. + +This article is part of the theme issue ‘Bioinspired + +materials and surfaces for green science and + +technology (part 2)’. + +2019 The Author(s) Published by the Royal Society. All rights reserved. + + + + + +1. Introduction + +2 + +Evolution through natural selection has, over many millions of years, produced structures in r + +............................................................... oy + +animals and plants that are superbly adapted to their functions. It is therefore of no surprise that alsociet + +scientists have looked at the natural world for inspiration in solving complex human problems, a field known as bioinspiration or biomimetics [1]. Thinking particularly of surfaces, we have, for ypublishing + +example, developed swimsuits with increased drag reduction to enhance swimming efficiency, based on the pattern of dermal denticles (skin scales) that cover the skin of fast-swimming sharks + +[2] and Lotusan, a self-cleaning exterior paint, based on the superhydrophobic surface of lotus + +.or + +leaves [3]. Many more examples are described in a recent review by Sun & Bhushan [4]. + +g/journal/rsta + +The adhesive mechanisms of climbing animals have clear-cut implications for biomimetics. + +For example, they adhere well to many surfaces, adhesion is reversible so that the adhesive is re-usable, and only stick when required [5,6]. Additionally, they self-clean, so that they are resistant to failure through the accumulation of dirt particles [7–9]. Initially, work was mainly carried out P + +on geckos [5,10,11], because they are among the heaviest animals using reversible adhesion for hil.T + +their locomotion and have an amazing ability to run across ceilings. These studies have shown ran + +that adhesion is mainly (if not entirely) due to van der Waals forces, as the extremely small tips s.R + +(spatulae ca. 200 nm wide and 5–20 nm thick) of the highly branched adhesive setae (hairs) on + +.So + +the toe pads of geckos are able to achieve extremely close contact with the surface to which the c.A + +gecko is adhering. A number of gecko-inspired adhesive structures have been designed and some 377 + +can support the weight of a human [12]. However, such gecko-inspired structures are difficult to + +:20190131 + +mimic and their durability is far from satisfactory. + +The adhesion mechanism of tree and torrent frogs is quite different, which means the biomimetic applications arising from it will differ from those developed from geckos. As will be described in this review, tree frogs mainly adhere by wet adhesion, as there is a thin layer of fluid between the toe pad and the adhering substrate. The adhesive forces are thought to be capillarity and viscosity-dependent hydrodynamic forces [13–15], but a role for van der Waals forces cannot be excluded [16]. Tree frog toe pads also generate friction forces; indeed, maximum friction forces may exceed those arising from adhesion [17,18]. As we shall describe, the tree frog’s adhesive mechanism provides good adhesion and friction on soft wet surfaces, and, as a result, is likely to have many important applications, particularly in the field of medicine. + +A significant body of work has also been carried out on insects. Insects may have hairy pads like geckos (e.g. beetles and flies) or smooth pads like tree frogs (e.g. cockroaches and grasshoppers) [19]. As there is fluid between pad and external surface, it has, until recently, been assumed that insects, like tree frogs, adhere by wet adhesion. However, Labonte & Federle [20] + +have recently questioned this conclusion as their most recent data could be better explained by adhesion using van der Waals forces. + +In this short review, we will discuss the complexities of the structure of tree frog toe pads in relation to their function as well as the development of artificial toe pad analogues. As we will make clear, studies of the properties of such artificial structures provide insights into the Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +functioning of actual toe pads as well as assisting the development of new smart adhesives based on tree frog adhesive and friction mechanisms. Additionally, we will describe some recent applications of the tree frog’s mechanisms of adhesion and friction and discuss the current challenges and future perspectives of this exciting field of research. + +2. Tree/torrent frog adhesion + +(a) Toe-pad structure and function + +Adhesive toe pads are thought to have evolved separately by convergent evolution in several different families of frogs [21]. Most of these families are arboreal, living in trees or shrubs (tree frogs such as Hypsiboas boans (figure 1)). However, adhesive pads are also found in frogs living in the region of waterfalls (torrent frogs of the family Ranidae). The adhesive pads are located on + + + +( a) + +( b) + +3 + +r + +............................................................... oyalsociet ypublishing + +.org/journal/rsta + +Phil.Trans.R + +hypsiboas boans + +.Soc.A + +Figure 1. Hypsiboas boans is the largest tree frog found in Trinidad (West Indies), with a snout/vent length of ca 100 mm ( a). + +37 + +Living high in trees, it is a gliding frog, as can be seen by the presence of webbing between the digits of the fore-limbs. This frog 7:2 + +has just landed on a bamboo stem, and has slipped downwards, leaving behind some of the watery fluid that forms its adhesive 0190131 + +joint ( b) (Allan L, 2013, personal communication). + +the ventral surface of the toes (toe pads), with related structures (sub-articular tubercles) being located on the ventral surface of more proximal digits. The latter is mainly used in attachment to small diameter structures such as twigs [22]. Features important to the functioning of the toe pads are highlighted below: + +Grooves surround each toe pad ( circumferal and proximal grooves). These grooves (shown in + +figure 2 b) will divert water around the pad in the wet environments (e.g. rain forests) in which the majority of tree frog species live. Such structures are particularly important in torrent frogs, which would otherwise be washed downstream by the water that covers the rocks on which they are found [24]. + +The toe pads are epithelial structures, consisting of several layers of cells [14, 25,26]. Their development can be clearly seen by the examination of transverse sections of the toes, where the deepest layers are the least specialized and the outermost the fully developed pad cells. At intervals, the outermost layer is shed, the layer beneath becoming the new surface layer (figure 3). + +In this way, the frog can maintain fully functional toe pads throughout its adult life. + +Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +Toe pads are extremely soft structures, aiding close contact to external surfaces and enhancing both adhesion and friction. Indentation experiments using spherical indenters of 264 and 1500 µm diameter [27] show a gradient of elastic modulus from 4 to 25 kPa, the higher values being found in the outermost, keratinized, layers. Such low values for the elastic modulus are comparable to sea anemone mesoglea or jellyfish jelly ( E ≈ 3 kPa [28]). The elastic modulus of a surface can also be calculated from force/distance curves produced by an AFM indenter [29]. Using this method, estimates of the elastic modulus of the external surface of the pad (the method does not provide information on deeper structures), are significantly higher, giving a median value of 5.7 MPa. Surface structures will thus have an increased resistance to wear. By contrast, the innermost layers, lying close to sub-dermal lymph spaces and a capillary network, have much lower elastic moduli and thus are extremely soft and pliable. Keratin filaments run inwards from the surface (figure 3) into the pad allowing the pad to maintain its shape in spite of the softness of the pad material [18,24,30,31]. + + + + + +polygonal + +4 + +toe pad + +epithelial cells + +r + +............................................................... o + +( a) + +( b) + +( c) + +yalsociet + +ypublishing + +.or + +100 mm + +5 mm + +g/journal/rsta + +( d ) + +( e) + +Phil.Tran + +1 mm + +500 nm + +s.R.S + +tightly packed nanopillars (SEM and TEM) + +oc.A37 + +Figure 2. Litoria caerulea toe pads. ( a) frog; ( b) toe pad surrounded on three sides by a groove (black line); ( c) polygonal (mostly 7: + +hexagonal) epithelial cells surrounded by deep channels; ( d, e) the nanopillars that cover the surface of the epithelial cells, shown 20190131 + +in surface view (SEM) and section (TEM). Reproduced from Federle et al. [23]. + +( a) + +( b) + +1 mm + +1 mm + +Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +Figure 3. TEM images of toe pad epithelium of Staurois parvus. ( a) Outer cell layer showing nanopillars and dense bundles of keratin filaments (arrows). ( b) Border between outer cell layer on left and the second layer of cells which also have keratin filaments; arrows show invaginations of the cell membrane, which will become the gaps between the nanopillars by the time this layer becomes the outermost layer. Reproduced from Drotlef et al. [24]. + +The actual epithelial cells ( the outermost layer), have a complex structure. As described below, they are mainly hexagonal in shape and are surrounded by deep, fluid-filled channels (figure 2 c). These channels are thought to serve two functions. First, they help spread the fluid over the entire pad surface, so that there are no air pockets that would reduce adhesion. Second, under wet conditions, they would help to get rid of excess fluid which would reduce adhesion by increasing the separation of pad and surface. The epithelial surface is not flat, but consists of a dense array of nanopillars, 300–500 nm in diameter and 200–300 nm in height (figure 2 d, e) [29]. As figure 4 + + + +Cryo-SEM images of nanopillars + +5 + +( a) + +( c) + +r + +............................................................... oyalsociet ypublishing + +. + +2 + +or + +mm + +g/journal/rsta + +( b) + +Phil.Trans.R.So + +300 nm + +c + +1 mm + +.A377:20190131 + +Figure 4. Cryo-SEM images of nanopillars of Staurois parvus ( a, b) and Rhacophorus prominanus ( c). The nanopillars are filled with keratin fibrils (arrows in b) and have a concave top ( c). Image ( a) shows the tops of the nanopillars standing clear of the surrounding frozen fluid (ice). The arrows in ( c) show ice partially filling gaps between the nanopillars. ( a, b) reproduced from Drotlef et al. [24]; ( c) is reproduced from Scholz et al. [29]. + +shows, the nanopillars are filled with keratin filaments (figure 4 b) and have a concave upper surface. This opens the question as to whether they could act as miniature suction discs, but this has yet to be investigated. There are thus two sets of structures (the cells separated by grooves and the nanopillars) that allow the pad to keep close contact to rough as well as smooth surfaces, promoting both adhesion and friction forces. + +The watery pad fluid has a viscosity of 1.25–1.51 mPa s−1. Using a laser tweezer technique, Federle et al. [23] have shown that the fluid secreted by the toe pads has a low viscosity in the range 1.25–1.51 mPa s−1 (figure 5). It is usually referred to as mucus, but detailed chemistry remains to be identified. It is secreted by glands within the toes and passes to the pad surface through narrow ducts which open into the grooves that separate the pad epithelial cells. It completely fills the space below the pad and forms a meniscus around the edge of the pad, producing capillary forces [14, 32]. The fluid is, however, known to contain molecules that act as surfactants Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +[33], lowering surface tension and thus allowing capillary adhesion to hydrophobic as well as hydrophilic surfaces (e.g. surfaces of waxy leaves). + +The fluid layer below each epithelial cell has a thickness of the order of a few nanometres. Federle et al. + +[23], using interference reflection microscopy, have shown that the fluid under the toe pads has a low thickness, except around the edges of the epithelial cells, where the channels between the epithelial cells are located (figure 6). This means that, in addition to capillary forces, substantial velocity-dependent hydrodynamic forces will be present [34]. Indeed, torrent frogs can adhere in running water when the pads are completely submerged, a situation where capillary forces would be absent [35,36]. + +Tree frog toe pads produce higher friction than adhesive forces, a surprising finding for a fluid joint. + +Federle et al. [23] have shown that it is due to the nanopillars, which form extremely close contact with the external surface (in the range 0–5 nm (figure 6 d)). Nanopillars cover the surface of all the pad epithelial cells (figures 2 and 4), but are absent from other, non-adhesive areas of the skin + + + + + +( a) 1.0 + +6 + +r + +............................................................... o + +0.5 + +yalsociet + +mm) + +ypublishing + +0 + +position ( –0.5 + +.org/journal/rsta + +–1.0 0 + +2 + +4 + +6 + +8 + +10 + +12 + +14 + +16 + +18 + +20 + +time (s) + +( b) 1.0 + +Phi + +frog mucus + +l.Tra + +water + +n + +0.8 + +s.R.Soc + +mm) 0.6 + +.A377:2 + +0.4 + +0190131 + +amplitude ( + +0.2 + +0 + +0.5 + +1.0 + +1.5 + +2.0 + +2.5 + +3.0 + +frequency (Hz) + +Figure 5. Viscosity measurements of Litoria caerulea toe pad mucus using laser tweezers. ( a) Bead displacement elicited by sinusoidal fluid movement at three different frequencies. ( b) Relationship of bead displacement amplitude and velocity (frequency) measured for toe pad mucus and pure water. The difference in the slopes indicates the viscosity. Reproduced from Federle et al. [23]. + +surface. However, it is important to note that the presence of these areas of very close contact means that molecular mechanisms of adhesion cannot be excluded [16]. + +Lymph spaces whose profiles are easily deformed by the slightest application of pressure. These spaces lie in the dermis below the toe pads and contribute to their remarkable softness and high deformability. Under pressure, they increase the contact area and improve conformation to the Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +underlying surface topography [31], thus promoting both adhesion and friction. + +Pad detachment occurs by peeling from the proximal edge of the pads during both forward walking and climbing [37], a mechanism requiring rather small forces (less than 10 mN). + +Self-cleaning. Force measurements on both unrestrained free-walking frogs and individual toe pads [8] show that, following contamination by glass beads, toe pad adhesive forces recover after a few steps. Both shear movements and a flushing effect of the secreted mucus play important roles in shedding contaminating particles. + +Adhesion to rough surfaces. In their natural habitat, tree frogs need to be able to adhere to surfaces of various roughnesses, including leaves, rocks and bark. Tests in a laboratory setting demonstrate that both adhesion and friction are maintained [38] or increased [39] on micro-rough surfaces (asperity size 0.1–30 µm) and only show a significant decline when asperity size reaches 50 µm. + +Crawford et al. provide evidence that, on these roughest surfaces, the pads secrete insufficient fluid to fill the space under the pad, leaving air pockets that would significantly reduce the + + + + + +( a) + +7 + +( b) 1.0 + +r + +............................................................... oy + +mm) + +alsociet + +0.5 + +ypublishing + +(epidermal cell) + +ilm thickness ( + +(mucus) + +. + +fluid f + +0 + +or + +(substrate) + +g/journal/rsta + +0 + +2 + +4 + +6 + +8 + +10 + +12 + +14 + +16 + +18 + +position (mm) + +( c) + +( d ) 45 + +40 + +35 + +Phi + +30 + +l + +y + +.Tr + +25 + +ans + +20 + +.R + +frequenc + +. + +15 + +Soc + +10 + +.A + +5 + +377 + +0 + +:2 + +0–5 + +5–10 10–15 15–20 20–25 25–30 30–35 + +0190131 + +fluid film thickness (nm) + +Figure 6. Interference reflection microscopy (IRM) used to measure the thickness of the fluid layer under a toe pad of a living, adhering tree frog ( Litoria caerulea). What one sees is the interference pattern resulting from the interference of light reflected from the surface of the pad with light reflected from the top surface of the glass to which the frog is adhering. By comparing images of the same pad with green and blue monochromatic light, one can identify which fringe is which, and thus estimate the thickness of the fluid layer under each pad epithelial cell. ( a) A representative IRM image and ( b) the calculated thickness of the fluid layer along the white arrow in ( a). Note that this arrow goes through the middle of an epithelial cell, and that the thickness of the fluid layer at these points is very small. ( c) Opening the aperture of the microscope reduces the depth of focus so that only zero-order fringes are seen, allowing a more accurate measurement of pad/ground distances under the pad epithelial cells. As shown in ( d), 41% of the epithelial cells have an average fluid film thickness in the range 0–5 nm. Reproduced from Federle et al. [23]. + +Laplace pressure component of capillarity [39]. However, the conflicting results on the lower roughnesses leave unanswered the question of whether the low elastic modulus of the toe pads allows them to mould themselves to the contours of all but the largest asperities. However, as Crawford et al., using interference reflection microscopy, were able to observe that small glass Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +beads (less than 5 µm diameter) could become lodged in the channels between the cells, it is clear that the nature of the epithelium (cells surrounded by channels) allows interdigitation of asperities on the external surface and the toe pad epithelium. + +Similarity of toe pad structure in different families of tree frogs. There are extraordinary similarities between the structure of toe pads in different frog families (hylid and rhacophorid frogs have been compared in detail by Barnes et al. [30]). They have important implications for biomimetics, for such convergent evolution suggests a good starting point for attempts to develop adhesives that will function in wet conditions. + +(b) Mechanisms of adhesion and friction and the forces they produce: physical principles Although the dominant force in tree frog adhesion is thought to be capillarity, viscosity-dependent hydrodynamic forces are also considered to play a role. Additionally, since the + + + +8 + +r + +............................................................... oyalsociet R + +ypublishing + +q 2 q + +. + +1 + +org/journal/rsta + +Figure 7. Capillarity model of sphere on a plane surface connected by a drop of fluid. Redrawn from Endlein & Barnes [6]. + +Ph + +(Online version in colour.) + +il.Trans.R.S + +thickness of the fluid layer under each toe pad epithelial cell is less than 35 nm [23], it is likely oc.A + +that there is actual contact between nanopillars on the pad surface and asperities on the substrate. + +37 + +Thus, van der Waals forces will also be involved, but to what extent is unknown. The physical 7:2 + +principles underlying capillarity and hydrodynamic forces are outlined below. + +0190131 + +Wet adhesion—capillary forces. A common model that has been used for quantifying capillary forces consists of a sphere on a plane surface, connected by a drop of liquid (figure 7). In this model, appropriate as toe pads are slightly domed, the surface tension of the meniscus results in a pressure difference, where the pressure inside the liquid is lower than it is outside, so long as the meniscus is concave. This pressure difference, the Laplace pressure, will resist the separation of the two surfaces. The attractive Laplace force for a macroscopic, perfectly smooth and homogeneous sphere in contact with a plane is given by + +FL = −2 πRγ (cos θ 1 + cos θ 2), + +(2.1) + +where R is the radius of the sphere, γ is the surface tension of the liquid, and θ 1 and θ 2 are the contact angles of the liquid with the plane surface and sphere, respectively. If the liquid completely wets both surfaces (i.e. θ 1 and θ 2 both equal 0), equation (2.1) simplifies to FL = −4 πRγ . + +(2.2) + +An alternative model examines capillary forces between two rigid plates, separated by a thin layer of fluid (figure 8). This model produces substantial forces if the radius ( r) of the area of contact is large and the separation distance of the plates ( h) is small, according to the following Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +equation: + +FL = πr 2 γ [ r−1 − (cos θ 1 + cos θ 2) h−1]. + +(2.3) + +In a large flat meniscus where r h and θ 1 = θ 2 = 0, equation (2.3) approximates to equation (2.4), namely + +FL ≈ − 2 πr 2 γ . + +(2.4) + +h + +A second component of the adhesive force is the tensile force of the meniscus (figure 9). In the rigid plate model, this surface tension force is + +FT = −2 πrγ . + +(2.5) + + + + + +9 + +r + +............................................................... oya + +q + +q + +2 + +2 + +lsociet + +h + +q + +q + +1 + +1 + +ypublishing + +.org/journal/rsta + +2 r + +Figure 8. Capillarity model of two flat, rigid surfaces separated by a small volume of fluid. Redrawn from Endlein & Barnes [6]. + +(Online version in colour.) + +Phil.Trans.R.Soc.A37 + +h + +7:20190131 + +r + +Fv + +Figure 9. Viscous force model of two flat rigid plates, fully immersed in a fluid, subject to an external force. Redrawn from Endlein & Barnes [6]. (Online version in colour.) + +The total meniscal force ( FM) is the sum of FL and FT + +FM = FL + FT, + +(2.6) + +where FT is negligible in any single large meniscus (e.g. ones with a radius of 0.5–3 mm as occur in tree frog toe pads), but would dominate adhesive forces in a fly’s adhesive pad where you have Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +large numbers of microscopic menisci (radii of ca 1 µm). + +In a recent study [40], equation (2.4) has been extended from hard, undeformable surfaces and spheres to soft, elastic materials, such as the toe pad of a tree frog. The mathematical equations relate the capillary attraction between the bodies to their elastic repulsion. Although they do not lend themselves to any easy calculation of the adhesive force, they are of interest in that they predict that FM scaling will gradually change from length scaling to area scaling with increasing r, this change occurring more rapidly for materials with a lower effective elastic modulus ( E eff). + +For instance, in equation (2.7) which deals with the Laplace pressure component of adhesion, the first term is proportional to r and is identical to the force with a hard sphere (equation (2.4)), while the second term is proportional to r 2. It is negligible for high Young’s moduli, but becomes significant for soft materials. + +πγ 3 + +FL = −4 πrγ − + +· 2 r 2 , + +(2.7) + +2 r + +3( E eff)2 + +where r is the radius of curvature of the meniscus. + +10 + +Wet adhesion—viscous forces. The second component of wet adhesion is provided by viscosity-r + +dependent hydrodynamic forces, usually referred to as Stefan adhesion. Consider two rigid plates + +............................................................... oya + +fully submersed in a fluid (figure 9). Separating the plates involves fluid flowing into the gap lsociet + +between them, so that separation is resisted by a viscous force until the fluid movements are ypublishing + +complete. This hydrodynamic force ( FV) will be greater for more viscous fluids and for smaller values of h. As equation (2.8) indicates, FV scales with area squared. + +3 πηr 4 + +. + +FV = − d h . + +, + +(2.8) + +or + +d t + +2 h 3 + +g/journal/rsta + +where η is the viscosity of the liquid and t is the time needed to separate the two plates. For completeness, the equation for the hydrodynamic force between a sphere and a plate (equation (2.9)) is also included. + +d h + + + +Ph + +FV = −6 πηr + +1 + r , + +(2.9) + +il + +d t + +h + +.Tran + +when the sphere touches the plate, as in figure 1, h = 0. + +s.R + +Viscous-poroelastic adhesion. Recently, Tulchinsky & Gat [41] have introduced the new concept of + +.So + +‘temporary adhesion’ by ignoring inertial and capillary effects, based on the interaction between c.A37 + +elastic deformation and viscous flow. During tests on a ‘model toe pad’, the pad generated forces 7 + +that resisted slip for periods in excess of 200 s. This is fine for a moving frog, but could present + +:20190131 + +problems for a frog at rest. Also, as the fluid used in the model toe pad (silicone oil) had a viscosity several orders of magnitude greater than tree frog mucus, it remains unclear whether the mechanism is applicable to frogs. + +Toe pad adhesion and friction forces. Tree frogs are good climbers, many tropical species being found high in the canopy of rain forests. On effectively flat surfaces (e.g. smooth tree trunks), adhesion is the only means by which tree frogs can climb without falling, but on smaller diameter structures (e.g. small stems/twigs), they can additionally climb using adduction forces by grasping around these structures with their digits [22]. Indeed, as Hill et al. describe, climbing is rapid on small diameter smooth surfaces because adduction and adhesion act together, and the subarticular tubercles are also brought into play. Unlike geckos, tree frogs cannot run across a ceiling, but they can climb vertical and overhanging surfaces, and a small tree frog can hang on to an inverted glass plate using just its toe pads [32]. At rest, thigh and belly skin aid adhesion. + +Quantitative measurements of the adhesive forces that can be generated by tree frogs have been made by a simple procedure first developed by Emerson & Diehl [14]. Frogs are weighed and then placed ‘head-up’ on a smooth surface on a rotation platform that is rotated slowly from 0° + +(horizontal), through 90° (vertical) to 180° (upside-down). The angles at which the frog falls from the surface (fall angle) are recorded. These fall angles are used to calculate maximum adhesive forces by simple trigonometry [32]. If the total toe pad area is also measured, these values can be converted to the force per unit area that toe pads can generate. Figure 10 a shows the masses of Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +14 different frog species (12 of which were hylids). Measured total toe pad areas of these same frogs appear in figure 10 b, while angles of fall from the rotation platform for these 14 frog species (means of 10 measurements for each frog) are plotted in figure 11 c. Since frogs have an area-based adhesive system (the toe pads), it is unsurprising that larger (and hence heavier) species fall from the platform at lower angles. From this information, the force per unit area of these toe pads can be calculated (figure 11 d). The positive slope of the line of best fit, though small, is statistically significant ( r = 0.68; d.f. = 11; p < 0.05), and reflects the fact that larger tree frogs have more efficient toe pads. A similar study, but looking at the effects of growth on adhesion of these same species [43], shows similar effects, toe pads becoming more structurally complex as the frogs grow. Close examination of the behaviour of tree frogs during such tilting experiments [42,44] + +demonstrates that tree frogs have evolved special strategies to maintain adhesion on overhanging surfaces. As the angle of tilt increases, tree frogs spread their limbs out sideways, and to a more limited extent, forwards or backwards as well. As figure 11 shows, this reduces the angle of + + + + + +( a) + +( b) + +100 + +1000 + +11 + +)2 + +r + +............................................................... oya + +10 + +100 + +lsociet + +ypublishing + +mass (g) + +1 + +10 + +toe-pad area (mm + +0.1 + +1 + +.or + +10 + +100 + +10 + +100 + +g/journal/rsta + +SVL (mm) + +SVL (mm) + +( c) + +( d ) + +) + +180 + +10 + +–2 + +135 + +Phil.Tra + +90 + +1 + +ns.R + +fall angle (º) + +.S + +45 + +oc.A37 + +0 + +force/unit area (mN mm 0.1 + +7 + +10 + +100 + +10 + +100 + +:20190131 + +SVL (mm) + +SVL (mm) + +Figure 10. Allometric relationships of 13 hylid species (open circles) and two non-hylids (filled triangles) plotted against snout– + +vent length (SVL). ( a, b) Morphometric relationships between frog mass, toe pad area and length (log : log plots). ( c) Fall angle against length (log : linear plot). ( d) Force per unit area plotted against length (log : log plot). Modified from Barnes et al. [32]. + +( a) + +( b) + +a + +b + +gravity + +both toes and legs are extended to reduce + +angles a and b and thus reduce the chances + +Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +of peeling + +b + +a, leg/substrate angle; b, toe/substrate angle + +Figure 11. ( a) Video-image of ventral view of a tree frog ( Hypsiboas boans) clinging to an overhanging translucent surface, with both fore and hind limbs stretched out sideways. Only areas in contact with the surface are in sharp focus. Scale: large squares are 10 mm across. From Barnes et al. [42]. ( b) Explanatory model. + +contact between pad and surface, reducing the tendency to peel as the mass of the frog is now supported by friction as well as adhesive forces. + +In recent years, the development of miniature force plates that can measure friction and adhesive forces from single toe pads have allowed many interesting findings. As well as providing direct measurements of the friction and adhesive forces that toe pads can produce (see + + + +60 N values 25 + +25 + +33 + +33 (4 frogs) + +12 + +r + +50 + +............................................................... oyalsociet 40 + +ypublishing + +30 + +. + +force (mN) + +or + +20 + +g/journal/rsta + +10 + +0 + +Phi + +adh-normal frict-normal + +adh-H O + +frict-H O + +l.T + +2 + +2 + +r + +drop + +drop + +ans.R + +Figure 12. Single pad adhesion and friction forces in the tree frog, + +. + +Litoria caerulea, before and after adding a drop of water to + +Soc + +the pad. This abolished the meniscus around the edge of the toe pad and resulted in a small increase in pad/ground distance. + +.A37 + +Hence the reduction in both adhesive and friction forces. Typical pad forces were of the order of 1 mN mm−2. Barnes WJP & 7: + +Federle W, 2006. + +20190131 + +below), experiments can be carried out that test different possible mechanisms by which toe pads can adhere. + +Figure 12 shows the results of a simple experiment designed to examine the role/importance of capillarity in tree frog adhesion (Barnes WJP & Federle W, 2006). Both friction and adhesion components of the resultant force are shown for a 70° pull-off, which followed a short initial slide, designed to ensure good initial contact of pad and force plate. A drop of water was then gently added, covering the pad in such a way that the meniscus around the edge of the pad was abolished. As expected, adhesive forces fell to low levels, but recovered following removal of the water (not shown). What was not expected was that friction forces declined as well. The only possible conclusion, supported by subsequent experiments examining the effects of the procedure on the thickness of the fluid layer under the pad using interference reflection microscopy, was that this simple procedure had increased the pad–ground distance. Such a change would of course also have reduced adhesion from viscosity-dependent hydrodynamic forces, and also molecular interactions (e.g. van der Waals forces) that depended on close contact of pad and surface. The experiment is, however, interesting, even though it did not confirm the dominant role of capillarity that it was intended to test. This is because it demonstrates another, equally Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +important role for capillary forces in holding the pad close enough to the ground to allow the other forces to exert their adhesive action. + +A second interesting result resulting from single pad force recordings comes from the work of Federle et al. [23] in which friction forces were recorded during a short horizontal pull. + +Since friction forces developed before the pad began to slide and, additionally, there was a + +‘remaining’ friction force 2 min after the slide was completed, it is clear that toe pads can generate static friction, strongly suggesting that, during such times, there is actual contact between structures on the toe pads (presumably the nanopillars) and the force plate. + +Finally, as has been made clear from the above, these miniature force plates are particularly suitable for measuring the maximum adhesive and friction forces that tree frog toe pads can produce, since both the maximum force and the area of contact are easy to measure. In the gliding frog, Rhacophorus dennysi, the calculated values were 1.45 ± 1.14 mN mm−2 ( N = 33) for adhesive force and 6.21 ± 5.11 mN mm−2 ( N = 24) for friction [17]. This result supports one of the main + + + + + +conclusions of Langowski et al. [16], that toe pads are optimally developed for friction rather than 13 + +adhesion. + +r + +............................................................... oyalsociet 3. Biomimetics of tree frog adhesion and friction + +ypublishing + +Learning from biology to develop new materials and devices, aiming to solve problems in daily life, medical, industry, etc., comes along with human history, though the word ‘biomimetics’ is a relatively new word, coined by Otto Schmitt in 1957. The mimicking of the clinging abilities of geckos and tree-frogs are always attractive for people, so that animal-inspired adhesives have + +.org/journal/rsta + +aroused more and more attention in recent years. However, gecko-inspired materials/devices have caught most of the attention because the origin of gecko adhesion is considered mainly to be due to van der Waals forces so that gecko-mimicking can simply focus on the design and construction of pillar-like structures with various materials and dimensions. Though simple hexagonal structures are present on the toe pads of tree frogs, they are covered by an array of Ph + +nanopillars and the mechanism of its adhesion is much more complicated, as described above. + +il.T + +Though the toe pads of tree frogs look quite different from the hairy gecko pads (figure 2 a), rans + +they both can be considered as pillar arrays [45]. A variety of manufacturing technologies [4] + +.R. + +have been developed to construct pillar arrays in materials with Young’s moduli ranging from Soc + +1TPa to several MPa (for instance, 1TPa of carbon nanotube (CNT) [46], several GPa of polymers + +.A37 + +like polyurethane (PU) [47], polystyrene [48], polystyrene-block-poly(vinyl-2-pyridine) (PS-b-7: + +P2VP) [49] and 1–3 MPa of polydimethylsiloxane (PDMS) [50]). Because of the huge difference in 20190131 + +Young’s modulus, pillar arrays with different materials can produce different aspect ratios (AR), which is vital for the stability and adhesion performance of pillar arrays. + +(a) Influences of aspect ratio of pillar + +Though CNT possesses a large Young’s modulus of 1TPa, the CNT forest shows a much smaller effective modulus ( E eff), which allows CNT forests to maximize contacts, increasing the adhesion force [51]. CNT-based adhesives showed shear adhesion of approximately 100 N cm−2, 10 times higher than that of gecko foot-hairs [46]. The complicated fabrication process and the poor durability of CNT forest, however, hinder its future applications. By contrast, polydimethylsiloxane (PDMS), which has a relatively low modulus, has been widely used to construct structured adhesives due to its handling simplicity and commercial availability. + +Compared to the flat surface, PDMS micropillar arrays showed a remarkable decrease in E eff, so that a larger AR results in a smaller E eff (figure 13 a, b). The decreased E eff results in a higher compliance to the contact surface, causing a higher elastic energy dissipation during pull-off from the surface [52]. For instance, increasing the AR of PDMS micropillar arrays from 0.5 to 4 increased pull-off forces by a factor of 3 [53]. It is worth mentioning that measurement of the E eff of a pillar array with a small AR (e.g. 0.5) could be influenced by its backing material. However, higher ARs are not always beneficial for adhesion enhancement. In the case of frog-inspired hexagonal pillars Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +with height of H and side length of L (figure 13 c), the adhesion force was found to decrease when H/ L was increased from 0.75 to approximately 1.9 (figure 13 d) [54]. Similar adhesion dependence on the pillar AR was also reported by Iturri [55]. It was explained that the pillars tend to bend and cluster at a high AR, due to the small gap between pillars. The bending and clustering may contribute to the adhesion reduction in two possible ways: (1) the bending of pillars offers the pillar edge for contact, reducing the effective contact area; (2) the clustering of pillars may form a continuous area for contact, reducing the effect of contact splitting. Moreover, the contact density will be reduced by increasing the channel width W, resulting in a smaller adhesive force. This may explain why tree frog toe pads have a small pillar height and a small channel width. + +Though the adhesive toe pads on tree frogs and bush-crickets are normally called smooth adhesive pads, the pillar tops are never smooth. As described above, concave nanostructures have been found on the toe pads of tree frogs (figure 4), and peg-structures have also been reported in bush-crickets [56]. Li et al. [57] reported the hexagonal micropillars with + + + + + +( a) + +( b) + +14 + +1.5 + +r + +............................................................... oyalsociet moduluss a) 1.0 + +ypublishing + +oung’ + +* (MP + +e Y + +E 0.5 + +flat + +v + +r = 2.5 mm + +r = 5 mm + +r = 10 mm + +.or + +10 mm + +fecti + +r = 25 mm + +g/journal/rsta + +ef + +0 + +0 + +1 + +2 + +3 + +4 + +5 + +pillar aspect ratio l (–) + +( c) + +( d ) 24 + +22 + +W = 214 mm + +W = 100 mm + +20 + +P + +W = 71 mm + +h + +W + +i + +18 + +W = 50 + +l + +1 + +mm + +.T + +16 + +W = 33 mm + +r + +L + +a + +1 + +n + +14 + +s.R + +12 + +.S + +10 + +oc + +8 + +.A37 + +6 + +adhesion force (mN) + +7 + +100 mm + +4 + +:2 + +2 + +0190131 + +0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 + +height/length H/L + +Figure 13. ( a) SEM image of pillar arrays. ( b) The dependence of effective elastic modulus of PDMS micropillars on the AR. + +( c) Image of hexagonal pillars in top view. ( d) The dependence of the wet adhesion force on the height-to-length H/L. ( a, b) reproduced from Greiner et al. [52]; ( c, d) are reproduced from Wang et al. [53]. + +micro-bulges on pillar top prepared by combining hemispheric crater arrays on SiO2 wafer and conventional photolithography. The increased friction force of this hierarchical hexagonal structure, especially in the hydrophilic state, demonstrated the importance of nanostructures on toe pads of tree frogs (figure 14 b). Moreover, concave, spatular, T-shape and spherical micropillar tops were also constructed to investigate the adhesion properties. T-shape pillars, prepared by conventional moulding [59] and inking–printing–curing (IPC) methods, exhibited maximum adhesion strength, both in wet [60] and dry [48, 61] conditions. Both the higher compliance and comparatively large contact area contribute to the outstanding performance. Furthermore, the crack initiation tends to start from the centre during the detachment [62], which results in a suction effect, contributing positively to the adhesion [59]. + +Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +(b) Influences of micro- and nanostructure + +Inspired by the existence of nanopillars in toe pad of tree frogs, we fabricated a composite structure with aligned polystyrene (PS) nanopillars embedded in soft PDMS hexagonal micropillars [63]. Both adhesion and friction forces were greatly enhanced compared to the structure with pure PDMS. The finite-element simulation suggests that the embedded nanopillars could regulate the stress distribution across the contact interface, with the stress maximum being distributed on top of a row of nanopillars close to the micropillar perimeter (but not at the centre of contact area or at the very edge of the pillar; figure 14 d). This is similar to the T-shape pillars inspired by gecko setae, which can also shift the stress maximum to the centre of the contact area, inhibiting the crack initiation during pulling. However, the composite structure should possess a much higher stability and durability since the nanopillars are embedded. + + + + + +1.5 + +( b) + +( a) + +hydrophobic + +15 + +hydrophilic + +load: in; flood + +r + +1.0 + +............................................................... oyalsociet 0.5 + +ypublishing + +friction force (N) + +0 + +flat hexagon 10% + +20% + +30% + +40% + +area density of pillars ( l) + +.org/journal/rsta + +S / S + +33 + +33-avg + +( c) + +( d ) + +1.99 + +1.85 + +1.71 + +1.58 + +1.44 + +1.30 + +1.16 + +1.03 + +0.89 + +0.75 + +0.61 + +P + +0.47 + +h + +0.34 + +il.Trans.R.Soc.A + +( e) + +( f ) + +core + +shell + +/ R = 5/6 + +37 + +t/ R = 0.1 Ri + +7 + +E , v + +c + +c + +E , v + +: + +s + +s + +0.4 + +2 + +2 + +0190131 + +0.7 + +z + +H + +R + +/ s avg- + +i + +s z 1 + +control + +t + +R + +0 + +0.5 + +1.0 + +Figure 14. ( a) SEM images of hierarchical structure. ( b) Plot of different microstructures on friction force. ( c) Illustration of composite posts with an internal aligned-PS nanopillars. ( d) Simulated stress distribution on composite miacropillar during detachment. ( e) Schematic of core–shell post with a stiff core and compliant shell. ( f ) Distribution of normal stress along the adhered interface of the post with Ri/R = 5/6. ( a, b) Reproduced from Li et al. [57]; ( e, f ) are reproduced from Minsky & Turner + +[58]. + +More interestingly, this kind of stress-maximum shifting ability was also realized in a much simpler core–shell structure, which is composed of a rigid core of polyetheretherketone and a thin layer of PDMS [58, 64] (figure 14 e). It was found that a thinner layer of PDMS on the pillar end is Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +more efficient in reducing the stress at the pillar edge, contributing to the adhesion enhancement. + +Similarly, by coating a thin layer of PDMS onto the gecko-inspired T-shaped micropillar made of polyurethane acrylate (PUA) could sharply enhance the shear adhesion as compared the same structure but composed of either PDMS or PUA [65]. If the core is composed of a polymer material whose stiffness significant decreases by applying an electric current, dynamic tuning of adhesion was successfully realized by the modulation of subsurface stiffness [66]. + +(c) Adhesion with liquid at interface + +There is mucus on the toe pads of tree frogs, so that a thin layer of liquid is always present at the contact interface. Therefore, tree frog adhesion is considered as wet adhesion, compared to the dry adhesion of geckos. To mimic wet adhesion, spreading a layer of liquid on the structured surface is widely employed [60, 67,68]. The wet adhesion strength is therefore profoundly influenced + + + +microstructured + +flat + +( a) + +( b) + +5 + +50 + +200 + +5 + +50 + +200 mms–1 + +16 + +wet + +dry + +r + +............................................................... oy + +2 + +alsociet + +polymer-coating + +ypublishing + +1 + +heat + +low + +high + +adhesion force (mN) + +adhesion + +adhesion + +O + +O + +O + +O + +O + +O + +cool + +2 + +2 + +2 + +2 + +2 + +2 + +glycerol 99% + +glycerol 87% + +H + +glycerol 99% + +glycerol 87% + +H + +glycerol 99% + +glycerol 87% + +H + +glycerol 99% + +glycerol 87% + +H + +glycerol 99% + +glycerol 87% + +H + +glycerol 99% + +glycerol 87% + +H + +0 + +.org/journal/rsta + +Figure 15. ( a) Adhesion force tested with different velocity on hydrophilic flat and structured surfaces. ( b) Illustration of PDMS + +pillars coated with a responsive copolymer, realizing switchable adhesion under water. ( a) Reproduced from Drotlef et al. [60]; + +( b) is reproduced from Ma et al. [71]. + +Phil.T + +by the surface wettability [35, 60]. By applying glycerol (which is polar and does not evaporate ran + +at room temperature) to the interface, the adhesion of structured PDMS against a ruby sphere s.R + +was evaluated [60]. It was found that, in the main, short-range attractive forces dominate + +.So + +adhesion when the PDMS surface is hydrophobic, as the glycerol may be squeezed out from c.A37 + +the contact area forming direct contacts. It therefore behaves like gecko-inspired structured 7 + +adhesive, showing a strong dependence on the contact geometry [60]. By contrast, long-range + +:20190131 + +attractive forces associated with capillarity dominate when the surface is hydrophilic. In this situation, capillary force dominates the adhesion strength, independent of the microstructures on the surface. It was suggested that the adhesion enhancement in the presence of fluid could be the result of crack arresting by liquid, in addition to the capillary forces [69]. It should be noted that excessive liquid will produce a lubrication region, leading to a reduction in adhesion and friction [69,70]. Since the surface wettability has a strong influence on wet adhesion, the switching of a surface between hydrophilic and hydrophobic, e.g. by temperature, could therefore regulate the wet adhesion. By coating a layer of temperature responsive copolymer poly(dopamine methacrylamide-co-methoxyethyl acrylate-co-isopropyl acrylamide) (p(DMA-co-MEA-coNIPAAm) on PDMS micropillars, switching of underwater adhesion was successfully achieved by simply adjusting the temperature of the water bath (figure 15 b) [71]. + +The microstructure of the toe pads of animals like tree frogs is considered to play a very important role in wet adhesion. It is suggested that the microchannels between pillars can effectively drain liquid out from the contact area, maximizing the effective solid–solid contact + +[55, 67,72,73]. Due to the polygonal nature of frog-inspired micropatterns, shear adhesion (friction) shows orientation dependence. In our previous work, wet friction was found to be the highest along the direction of side-sliding (figure 16 a) [55]. Moreover, elongated hexagonal micropillars show an even higher friction at the same orientation. The effective arresting of cracks increases following the edge density per unit length along the friction direction, contributing to friction Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +enhancement. The theory was demonstrated by a macroscopic experiment, where the frog-inspired patterns were mounted on metal pieces and allowed to slide on a rotating surface covered with water (figure 16 c). However, Cheng et al. reported a contradictory result that the wet friction of corner-sliding was higher in both hexagonal and rhomboid pillar arrays [74]. Using Chinese ink as the indicator, the liquid squeezing out of the contact interface was found to be more effective in the direction of corner-sliding (figure 16 a). In the direction of side-sliding, liquid may flow into the contact interface due to the tilting of pillars and the flow pattern, resulting in decreased friction [74]. Recently, distinctive arch-shaped structures (figure 16 b) were reported to provide even larger wet friction force than tree frog-inspired hexagonal patterns, due to their optimal drainage effect and the high stiffness of the patterns [75]. This offers new possibilities for the design of wet adhesives in future. + +Recently, it was reported that the bioinspired wet adhesive exhibits better performance on rough than smooth substrates [76,77]. The introduced trace amounts of fluid result in capillary + + + + + +( a) + +( b) + +17 + +liquid + +arch I + +corner-sliding + +r + +............................................................... oyalsociet 50 mm + +ypublishing + +side-sliding + +liquid + +arch II + +. + +100 mm + +org/journal/rsta + +50 mm + +( c) + +flat + +hexagon + +Phil.Trans.R. + +50 mm + +Soc.A + +35º + +43º + +58º + +377: + +Figure 16. ( a) SEM image of hexagonal pillars with a different sliding direction for friction. Image on right shows the route 20190131 + +for flowing water. ( b) SEM images of different pattern (arch I, arch II and hexagon). ( c) Image shows the angles at which flat and micro-patterned hydrophilic samples (regular and elongated hexagonal pillars) slide on a slant terrace flooded with water. + +( a) Reproduced from Chen et al. [74]; ( b) Reproduced from Ko et al. [75]. ( c) Reproduced from Iturri et al. [55]. + +bridges, raising the effective contact area [78] in a way analogous to a thin layer of soft material on top of micropillars [79]. This means that capillary force may serve as the major contributor to wet adhesion on a rough surface [77]. Moreover, structured adhesives could effectively slow down the evaporation of liquid on the rough substrates, which is quite important for tree frogs and other animals using wet adhesion in their natural environment [38]. + +While most studies of wet adhesion on artificial materials involved coating a thin layer of liquid on the structured surface, a few reported the delivery of liquid to the contact area mimicking the secretion of animals [49, 80]. Making use of the microphase separation of block copolymer poly(styrene- b-2-vinylpyridine) (PS2VP), nanopillars with 98 nm internal channels were designed to deliver liquid to the contact area, mimicking the dynamic secretion of animals. + +The combination of material softening in high humidity and the transportation of mineral oil to the contact interface greatly increased the adhesion force by two orders of magnitude. The comparison of work of adhesion at different humidities suggests that the contribution of liquid Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +bridges remained the same, while direct solid–solid contact was 30 times higher when the relative humidity increased from 25 to 90% (figure 17 c). Interestingly, Vogel et al. [80] have designed a device with a plate full of holes. Water can be pumped into the holes via channels beneath the plate and form droplet arrays on the plate (figure 17 a). Each droplet can therefore form a liquid bridge with a contacting surface, creating an adhesion force at the interface. Indeed, with all the liquid droplets acting together, the device can generate a substantial adhesion force. + +4. Applications + +Although the mimicking of tree frog-inspired wet adhesion is still in its infancy, there are already some attempts to make use of it in the area of bionic robots [81], soft tissue engineering [82], etc. + +For instance, Tsipenyuk prepared a variety of polyvinylsiloxane (PVS) hexagonal patterns as the stretching unit for disposable safety razors [82]. During the process of sliding against lubricated + + + + + +( a) + +( b) + +18 + +20 + +r + +............................................................... oya + +J) + +15 + +lsociet + +–10 + +W ad,S + +(10 + +10 + +ypublishing + +W ad,C + +ad,90% + +5 + +W + +. + +0.5 mm + +or + +0 + +g/journal/rsta + +200 + +300 + +400 + +F (mN) + +L + +( c) + +Phil.Trans.R + +1 mm + +.Soc.A37 + +Figure 17. ( a) Image shows large number of liquid bridges were quickly formed by electronic control. ( b) SEM image of 7:2 + +continuous porous pillars. ( c) Dependence of W + +0190131 + +ad,S and W ad,C on FL at RH about 90%. ( c) Reproduced from Vogel et al. [80]. + +relieving unit + +( a) + +blades + +( c) + +stretching unit + +octopus-like + +convex cup + +base + +(1) + +amphibian-like + +hexegonal array + +(2) + +(3) PVS + +base + +template + +stretching unit + +(4) + +base + +drainable + +(5) + +PVS + +microchannel + +base + +bio-inspired patch + +120 + +( b) + +60 + +with hierarchial architectures + +840 + +bioinspired patch + +630 + +with conductive architectures + +420 + +z + +R + +210 + +120 + +T + +P + +50 mm + +0 + +x + +um + +0 + +210 + +420 + +630 + +840 + +Q S + +Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +Figure 18. ( a) Schematic illustration of the preparation process of the commercial safety razor cartridge with hexagonal surface. + +( b) Pig liver was deformed by using a normal force of 10 N. ( c) Schematic illustration of bioinspired patch for detecting ECG + +signals. ( a) Reproduced from Tsipenyuk et al. [82]. ( b) Reproduced from Chen et al. [74]. ( c) Reproduced from Kim et al. [83]. + +human skin, the hexagonal surface could increase the effective contact with the skin by draining excessive liquid through the channels. Thus, the friction force was double that of commercial products and stretched the moist skin much better. Also, Chen et al. prepared PDMS polygonal arrays and applied them to the gripping surface of surgical graspers (figure 18 b). Compared to the traditional tooth-textured surgical grasper, the new design can greatly reduce the gripping force, reducing damage to soft tissue [74]. More recently, a biomimetic skin patch inspired by the hexagonal pattern of tree frog toe pads and the convex cup of octopus suckers has been reported + +(figure 18 c) [83]. The patch exhibited outstanding adhesion performance on human skin, even in + + + + + +a water flowing environment. In addition, following coating with reduced graphene oxide, the 19 + +patch could serve as a flexible electrode, sensitive enough to receive bio-signals on a wet skin, r + +even under motion. + +............................................................... oyalsociet 5. Conclusion and outlook + +ypublishing + +It is clear that tree frogs exhibit outstanding wet adhesion properties. Significant progress has been made in recent years, both in our understanding of how tree frogs adhere and in the development of tree frog-inspired wet adhesives. But many questions remain unanswered. For instance, while + +.or + +most of the tree frog-mimicking studies have focused on the micropattern on the toe pad, more g/journal/rsta + +attention should be given to forming a better understanding of the role of the nanostructures. + +Could there be synergistic interactions between the micro- and nanostructures and the mucus? + +Moreover, since the animals keep secreting all the time, the liquid volume at the contacting interface should change accordingly. How will this dynamic process contribute to adhesion and P + +friction during the locomotion of animals? And can we make use of the dynamic process? The hil.T + +answers to these questions could deepen our understanding of the adhesion of tree frogs and ran + +speed the development of applications of bioinspired wet adhesion. + +s.R. + +Data accessibility. The article has no additional data. + +Soc + +Authors’ contributions. L.X. and W.J.P.B. conceived and designed the study. All authors drafted the manuscript. + +.A + +Competing interests. The authors declare that they have no competing interests. + +377 + +Funding. This work was supported the National Key R&D Program of China (2018YFB1105100) and National + +:20190131 + +Natural Science Foundation of China (51503156). + +Acknowledgements. W.J.P.B. thank Ross McAuley for his assistance with formatting the figures. + +References + +1. Vincent JF, Bogatyreva OA, Bogatyrev NR, Bowyer A, Pahl AK. 2006 Biomimetics: its practice and theory. J. R. Soc. Interface 3, 471–482. (doi:10.1098/rsif.2006.0127) + +2. Dean B, Bhushan B. 2010 Shark-skin surfaces for fluid-drag reduction in turbulent flow: a review. Phil. Trans. R. Soc. A 368, 4775–4806. (doi:10.1098/rsta.2010.0201) + +3. Barthlott W, Neinhuis C. 1997 Purity of the sacred lotus, or escape from contamination in biological surfaces. Planta 202, 1–8. (doi:10.2307/23384993) + +4. Sun J, Bhushan B. 2019 Nanomanufacturing of bioinspired surfaces. Tribol. Int. 129, 67–74. + +(doi:10.1016/j.triboint.2018.08.007) + +5. Autumn K. 2007 Gecko adhesion: structure, function, and applications. MRS Bull. 32, 473–478. + +(doi:10.1557/mrs2007.80) + +6. Endlein T, Barnes WJP. 2015 Wet adhesion in tree and torrent frogs. In Encyclopedia of nanotechnology, 2nd edn (ed. B Bhushan). Dordrecht, The Netherlands: Springer Science. + +7. Hansen WR, Autumn K. 2005 Evidence for self-cleaning in gecko setae. Proc. Natl Acad. Sci. + +USA 102, 385–389. (doi:10.1073/pnas.0408304102) + +8. Crawford N, Endlein T., Barnes WJP. 2012 Self-cleaning in tree frog toe pads; a mechanism for recovering from contamination without the need for grooming. J. Exp. Biol. 215, 3965–3972. + +Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +(doi:10.1242/jeb.073809) + +9. Hu S, Lopez S, Niewiarowski PH, Xia Z. 2012 Dynamic self-cleaning in gecko setae via digital hyperextension. J. R. Soc. Interface 9, 2781–2790. (doi:10.1098/rsif.2012.0108) + +10. Autumn K, Liang YA, Hsieh ST, Zesch W, Chan WP, Kenny TW, Fearing R. 2000 Adhesive force of a single gecko foot-hair. Nature 405, 681–685. (doi:10.1038/35015073) + +11. Autumn, K, Sitti M, Liang YA, Peattie AM, Hansen WR, Sponberg S. 2002 Evidence for van der Waals adhesion in gecko setae. Proc. Natl Acad. Sci. USA 99, 12 252–12 256. + +(doi:10.1073/pnas.192252799) + +12. Hawkes EW, Eason EV, Christensen DL, Cutkosky MR. 2015 Human climbing + +with efficiently scaled gecko-inspired dry adhesives. J. R. Soc. Interface 12, 20140675. + +(doi:10.1098/rsif.2014.0675) + +13. Nachtigall W. 1974 Biological mechanisms of attachment. Berlin, Germany: Springer. + +14. Emerson SB, Diehl D. 1980 Toe pad morphology and mechanisms of sticking in frogs. Biol. J. + +Linn. Soc. 13, 199–216. (doi:10.1111/j.1095-8312.1980.tb00082.x) + +15. Hanna G, Barnes WJP. 1991 Adhesion and detachment of the toe pads of tree frogs. J. Exp. + +20 + +Biol. 155, 103–125. + +16. Langowski JKA, Dodou D, Kamperman M, van Leeuwen JL. 2018 Tree frog attachment: r + +............................................................... oy + +mechanisms, challenges, and perspectives. Front. Zool. 2018, 15–32. (doi:10.1186/ + +alsociet + +s12983-018-0273-x) + +17. Endlein T, Ji A, Yuan S, Hill I, Wang H, Barnes WJP, Dai Z, Sitti M. 2017 The use of clamping ypublishing + +grips and friction pads by tree frogs for climbing curved surfaces. Proc. R. Soc. B 284, 20162867. + +(doi:10.1098/rspb.2016.2867) + +18. Langowski JKA, Schipper H, Blij A, van den Berg FT, Gussekloo SWS, van Leeuwen JL. 2018 + +Force-transmitting structures in the digital pads of the tree frog Hyla cinerea: a functional + +.org/journal/rsta + +interpretation. J. Anat. 233, 478–495. (doi:10.1111/joa.12860) + +19. Gorb S. 2001 Attachment devices of insect cuticle. Dordrecht, The Netherlands: Kluwer Academic Publishers. + +20. Labonte D, Federle W. 2015 Rate-dependence of ‘wet’ biological adhesives and the function of the pad secretion in insects. Soft Matter 11, 8661–8673. (doi:10.1039/C5SM01496D) + +P + +21. Duellman WE, Trueb L. 1994 Biology of amphibians. Baltimore, MD: John Hopkins University hil.T + +Press. + +ra + +22. Hill IDC, Dong B, Barnes WJP, Ji A, Endlein T. 2018 The biomechanics of tree frogs ns.R + +climbing curved surfaces: a gripping problem. J. Exp. Biol. 221, jeb.168179. (doi:10.1242/jeb. + +.S + +168179) + +oc.A + +23. Federle W, Barnes WJP, Baumgartner W, Drechsler P, Smith JM. 2006 Wet but not 37 + +slippery: boundary friction in tree frog adhesive toe pads. J. R. Soc. Interface 3, 689–697. + +7: + +(doi:10.1098/rsif.2006.0135) + +20190131 + +24. Drotlef DM, Appel E, Peisker H, Dening K, del Campo A, Gorb SN, Barnes WJP. 2014 + +Morphological studies of the toe pads of the rock frog, Staurois parvus (family: Ranidae) and their relevance to the development of new biomimetically inspired reversible adhesives. + +Interface Focus 5, 20140036. (doi:10.1098/rsfs.2014.0036) + +25. Green DM. 1979 Treefrog toe pads: comparative surface morphology using scanning electron microscopy. Can. J. Zool. 57, 2033–2046. (doi:10.1139/z79-268) + +26. Smith JM, Barnes WJP, Downie JR, Ruxton GD. 2006 Structural correlates of increased adhesive efficiency with adult size in the toe pads of hylid tree frogs. J. Comp. Physiol. A 192, 1193–1204. (doi:10.1111/j.1469-7998.2006.00145.x) + +27. Barnes WJP, Perez Goodwyn PJ, Nokhbatolfoghahai M, Gorb SN. 2011 Elastic modulus of tree frog adhesive toe pads. J. Comp. Physiol. A 197, 969–978. (doi:10.1007/s00359-011-0658-1) + +28. Alexander RM. 1968 Animal mechanics. London, UK: Sidgwick and Jackson. + +29. Scholz I, Barnes WJP, Smith JM, Baumgartner W. 2009 Ultrastructure and physical properties of an adhesive surface, the toe pad epithelium of the tree frog, Litoria caerulea White. J. Exp. + +Biol. 212, 155–162. (doi:10.1242/jeb.019232) + +30. Barnes WJP, Baum M, Peisker H, Gorb SN. 2013 Comparative cryo-SEM and AFM studies of hylid and rhacophorid tree frog toe pads. J. Morphol. 274, 1384–1396. (doi:10.1002/jmor. + +20186) + +31. Nakano M, Saino T. 2016 Light and electron microscopic analyses of the high deformability of adhesive toe pads in White’s tree frog, Litoria caerulea. J. Morphol. 277, 1509–1516. + +Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +(doi:10.1002/jmor.20592) + +32. Barnes WJP, Oines C, Smith JM. 2006 Whole animal measurements of shear and adhesive forces in adult tree frogs: insights into underlying mechanisms of adhesion obtained from studying the effects of size and scale. J. Comp. Physiol. A 192, 1179–1191. + +(doi:10.1007/s00359-006-0146-1) + +33. Barnes WJP, Khannoon E, Crawford N, Endlein T. 2016 Tree frog adhesion to surfaces differing in surface energy. In Proceedings of the Adhesion Society Annual Meeting, February 21–24, 2016, San Antonio, TX. Red Hook, NY: Curran Associates. + +34. Persson BNJ. 2007 Wet adhesion with application to tree frog adhesive toe pads and tires. J. + +Phys.: Condens. Matter 19, 376110 (16pp). (doi:10.1088/0953-8984/19/37/376110) + +35. Endlein T, Ji A, Samuel D, Yao N, Wang Z, Barnes WJP, Federle W, Kappl M, Dai Z. 2013 + +Sticking like sticky tape: tree frogs use friction forces to enhance attachment on overhanging surfaces. J. R. Soc. Interface 10, 20120838. (doi:10.1098/rsif.2012.0838) + +36. Hutt W, Persson BNJ. 2016 Soft matter dynamics: accelerated fluid squeeze-out during slip. J. + +Chem. Phys. 144, 124903. (doi:10.1063/1.4944384) + +37. Ji A et al. 2019 A force-measuring and behaviour-recording system consisting of 24 individual 21 + +3D force plates for the study of single limb forces in climbing animals on a quasi-cylindrical tower. Bioinspir. Biomim. In press. (doi:10.1088/1748-3190/ab1d11) + +r + +............................................................... oy + +38. Langowski JKA, Rummenie A, Pieters RPM, Kovalev A, Gorb SN, van Leeuwen JL. 2019 + +alsociet + +Estimating the maximum attachment performance of tree frogs on rough substrates. Bioinspir. + +Biomim. 14, 025001. (doi:10.1088/1748-3190/aafc37) + +ypublishing + +39. Crawford N, Endlein T, Pham JT, Barnes WJP. 2016 When the going gets rough – studying the effect of surface roughness on the adhesive abilities of tree frogs. Beilstein J. Nanotech. 7, 2116–2131. (doi:10.3762/bjnano.7.201) + +. + +40. Butt H-J, Barnes WJP, del Campo A, Kappl M, Schönfeld, F. 2010 Capillary forces between org/journal/rsta + +soft, elastic spheres. Soft Matter 6, 5930–5936. (doi:10.1039/C0SM00455C) + +41. Tulchinsky A, Gat AD. 2015 Viscous-poroelastic interaction as mechanism to create adhesion in frogs’ toe pads. J. Fluid Mech. 775, 288–303. (doi:10.1017/jfm.2015.293) + +42. Barnes WJP, Pearman J, Platter J. 2008 Application of peeling theory to tree frog adhesion, a biological system with biomimetic implications. Eur. Acad. Sci. E-Newsletter Sci. Technol. 1, 1–2. + +P + +43. Smith JM, Barnes WJP, Downie JR, Ruxton GD. 2006 Adhesion and allometry from hil.T + +metamorphosis to maturation in hylid tree frogs: a sticky problem. J. Zool. 270, 372–383. + +ra + +(doi:10.1111/j.1469–7998.2006.00145.x) + +ns.R + +44. Endlein T, Barnes WJP, Samuel DS, Crawford NA, Biaw AB, Grafe U. 2013 Sticking under wet + +.S + +conditions: the remarkable attachment abilities of the torrent frog, Staurois guttatus. PLoS ONE + +oc.A + +8, e73810. (doi:10.1371/journal.pone.0073810) + +37 + +45. Heepe L, Xue L, Gorb SN. 2017 Bio-inspired structured adhesives. Germany: Springer 7: + +International Publishing. + +20190131 + +46. Qu L, Dai L, Stone M, Xia Z, Wang ZL. 2008 Carbon nanotube arrays with strong shear binding-on and easy normal lifting-off. Science 322, 238–242. (doi:10.1126/science.1159503) + +47. Kim S, Cheung E, Sitti M. 2009 Wet self-cleaning of biologically inspired elastomer mushroom shaped microfibrillar adhesives. Langmuir 25, 7196–7199. (doi:10.1021/la900732h) + +48. Xue L, Kovalev A, Thöle F, Rengarajan G, Steinhart M, Gorb SN. 2012 Tailoring normal adhesion of arrays of thermoplastic, spring-like polymer nanorods by shaping nanorod tips. + +Langmuir 28, 10 781–10 788. (doi:10.1021/la3020354) + +49. Xue L, Kovalev A, Eichler-Volf A, Steinhart M, Gorb S. 2015 Humidity-enhanced wet adhesion on insect-inspired fibrillar adhesive pads. Nat. Commun. 6, 6621. (doi:10.1038/ncomms7621) + +50. Xue L, Iturri J, Kappl M, Butt H, del Campo A. 2014 Bioinspired orientation dependent friction. Langmuir 30, 11 175–11 182. (doi:10.1021/la502695d) + +51. Jeong HE, Suh KY. 2009 Nanohairs and nanotubes: efficient structural elements for gecko-inspired artificial dry adhesives. Nano Today 4, 335–346. (doi:10.1016/j.nantod.2009.06.004) + +52. Greiner C, del Campo A, Arzt E. 2007 Adhesion of bioinspired micropatterned surfaces: effects of pillar radius, aspect ratio, and preload. Langmuir 23, 3495–3502. (doi:10.1021/la0633987) + +53. Wang X, Tan D, Zhang X, Lei Y, Xue L. 2017 Effective elastic modulus of structured adhesives: from biology to biomimetics. Biomimetics 2, 10. (doi:10.3390/biomimetics2030010) + +54. Xie J, Li M, Dai Q, Huang W, Wang X. 2018 Key parameters of biomimetic patterned surface for wet adhesion. Int. J. Adhes. Adhes. 82, 72–78. (doi:10.1016/j.ijadhadh.2018.01.004) + +55. Iturri J, Xue L, Kappl M, García-Fernández L, Barnes WJP, Butt H-J, del Campo A. 2015 Torrent Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +frog-inspired adhesives: attachment to flooded surfaces. Adv. Funct. Mater. 25, 1499–1505. + +(doi:10.1002/adfm.201403751) + +56. Grohmann C, Henze M, Nørgaard T, Gorb SN. 2015 Two functional types of attachment pads on a single foot in the Namibia bush cricket, Acanthoproctus diadematus (Orthoptera: Tettigoniidae). Proc. R. Soc. B 282, 20142976. (doi:10.1098/rspb.2014.2976) + +57. Li M, Huang W, Wang X. 2015 Bioinspired, peg-studded hexagonal patterns for wetting and friction. Biointerphases 10, 031008. (doi:10.1116/1.4930176) + +58. Turner KT, Minsky HK. 2015 Achieving enhanced and tunable adhesion via composite posts. + +Appl. Phys. Lett. 106, 201604. (doi:10.1063/1.4921423) + +59. Tinnemann V, Hernández L, Fischer SCL, Arzt E, Bennewitz R, Hensel R. 2019 In situ observation reveals local detachment mechanisms and suction effects in micropatterned adhesives. Adv. Funct. Mater. 29, 201807713. (doi:10.1002/adfm.201807713) + +60. Drotlef D, Stepien L, Kappl M, Barnes WJP, Butt H, del Campo A. 2013 Insights into the adhesive mechanisms of tree frogs using artificial mimics. Adv. Funct. Mater. 23, 1137–1146. + +(doi:10.1002/adfm.201202024) + +61. del Campo A, Greiner C, Arzt E. 2007 Contact shape controls adhesion of bioinspired fibrillar 22 + +surfaces. Langmuir 23, 10 235–10 243. (doi:10.1021/la7010502) + +62. Heepe L, Kovalev AE, Filippov AE, Gorb SN. 2013 Adhesion failure at 180,000 frames per r + +............................................................... oy + +second: direct observation of the detachment process of a mushroom-shaped adhesive. Phys. + +alsociet + +Rev. Lett. 111, 104301. (doi:10.1103/PhysRevLett.111.104301) + +63. Xue L et al. 2017 Hybrid surface patterns mimicking the design of the adhesive toe pad of tree ypublishing + +frog. ACS Nano 11, 9711–9719. (doi:10.1021/acsnano.7b04994) + +64. Turner KT, Minsky HK. 2017 Composite microposts with high dry adhesion strength. ACS + +Appl. Mater. Interfaces 9, 18 322–18 327. (doi:10.1021/acsami.7b01491) + +. + +65. Bae W-G, Kwak MK, Jeong HE, Pang C, Jeong H, Suh K-Y. 2013 Fabrication and org/journal/rsta + +analysis of enforced dry adhesives with core–shell micropillars. Soft Matter 9, 1422–1427. + +(doi:10.1039/C2SM27323C) + +66. Milad T, Amir M, Kevin T, Shan W. 2018 Dynamically tunable dry adhesion via subsurface stiffness modulation. Adv. Mater. Interfaces 5, 1800321. (doi:10.1002/admi2018003 21) + +67. Varenberg M, Gorb S. 2009 Hexagonal surface micropattern for dry and wet friction. Adv. + +P + +Mater. 21, 483–486. (doi:10.1002/adma.200802734) + +hil.T + +68. Cheung E, Sitti M. 2008 Adhesion of biologically inspired oil-coated polymer micropillars. J. + +ra + +Adhes. Sci. Technol. 22, 569–589. (doi:10.1163/156856108X295545) + +ns.R + +69. Majumder A, Ghatak A, Sharma A. 2007 Microfluidic adhesion induced by subsurface + +.S + +microstructures. Science 318, 258–261. (doi:10.1126/science.1145839) + +oc.A + +70. Gong L, Yu H, Wu X, Wang X. 2018 Wet-adhesion properties of microstructured surfaces 37 + +inspired by newt footpads. Smart Mater. Struct. 27, 114001. (doi:10.1088/1361-665x/aad6d2) + +7: + +71. Ma Y, Ma S, Wu Y, Pei X, Gorb S, Wang Z, Liu W, Zhou F. 2018 Remote control over 20190131 + +underwater dynamic attachment/detachment and locomotion. Adv. Mater. 30, 1801595. + +(doi:10.1002/adma.201801595) + +72. Yi H, Lee S, Seong M, Kwak M, Jeong H. 2018 Bioinspired reversible hydrogel adhesives for wet and underwater surfaces. J. Mater. Chem. B 6, 8064. (doi:10.1039/c8tb02598c) + +73. Rao P, Sun T, Chen L, Takahashi R, Shinohara G, Guo H, Gong J. 2018 Tough hydrogels with fast, strong, and reversible underwater adhesion based on a multiscale design. Adv. Mater. 30, 1801884. (doi:10.1002/adma.201801884) + +74. Chen H, Zhang L, Zhang D, Zhang P, Han Z. 2015 Bioinspired surface for surgical graspers based on the strong wet friction of tree frog toe pads, ACS Appl. Mater. Interfaces 7, 13 987– + +13 995. (doi:10.1021/acsami.5b03039) + +75. Ko H, Seong M, Jeong HE. 2017 A micropatterned elastomeric surface with enhanced frictional properties under wet conditions and its application. Soft Matter 13, 8419–8425. + +(doi:10.1039/c7sm01493g) + +76. Pepelyshev A, Borodich FM, Galanov BA, Gorb EV, Gorb SN. 2018 Adhesion of soft materials to rough surfaces: experimental studies, statistical analysis and modelling. Coatings 350, 1–17. + +(doi:10.3390/coatings8100350) + +77. Kovalev AE, Varenberg M, Gorb SN. 2012 Wet versus dry adhesion of biomimetic mushroom-shaped microstructures. Soft Matter 8, 7560–7566. (doi:10.1039/C2SM25431J) + +78. Persson B. 2008 Capillary adhesion between elastic solids with randomly rough surfaces. J. + +Phys. Condens. Mat. 20, 315007. (doi:10.1088/0953-8984/20/31/315007) + +Downloaded from https://royalsocietypublishing.org/ on 09 July 2023 + +79. Bartlett MD, Croll AB, King DR, Paret BM, Irschick DJ, Crosby AJ. 2012 Looking beyond fibrillar features to scale gecko-like adhesion. Adv. Mater. 24, 1078–1083. + +(doi:0.1002/adma.201104191) + +80. Vogel MJ, Steen PH. 2010 Capillarity-based switchable adhesion. Proc. Natl. Acad. Sci. USA 107, 3377–3381. (doi:10.1073/pnas.0914720107) + +81. Nguyen PV, Huynh NV, Phan TT, Ho VA. 2018 Soft grasping with wet adhesion: Preliminary evaluation. In 2018 IEEE International Conference on Soft Robotics (Robosoft), Livorno, Italy, April 24–28, 2018, pp. 418–422. IEEE. + +82. Tsipenyuk A, Varenberg M. 2014 Use of biomimetic hexagonal surface texture in friction against lubricated skin. J. R. Soc. Interface 11, 20140113. (doi:10.1098/rsif.2014.0113) + +83. Kim DW, Baik S, Min H, Chun S, Lee HJ, Kim KH, Lee JY, Pang C. 2019 Highly permeable skin patch with conductive hierarchical architectures inspired by amphibians and octopi for omnidirectionally enhanced wet adhesion. Adv. Funct. Mater. 29, 201807614. + +(doi:0.1002/adfm.201807614) + + + + + +Document Outline + + +Introduction + +Tree/torrent frog adhesion Toe-pad structure and function + +Mechanisms of adhesion and friction and the forces they produce: physical principles + + + + + +Biomimetics of tree frog adhesion and friction Influences of aspect ratio of pillar + +Influences of micro- and nanostructure + +Adhesion with liquid at interface + + + + + +Applications + +Conclusion and outlook + +References + + + + + diff --git a/indexing/output/.DS_Store b/indexing/output/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2dbdedf39415c920aa3e9117271e1d6c3b324ac5 Binary files /dev/null and b/indexing/output/.DS_Store differ diff --git a/indexing/output/20240722-073448/.DS_Store b/indexing/output/20240722-073448/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..bb705cdd7c23831a64ffc942d5e917a72347a5e4 Binary files /dev/null and b/indexing/output/20240722-073448/.DS_Store differ diff --git a/indexing/output/20240722-073448/artifacts/clustered_graph.graphml b/indexing/output/20240722-073448/artifacts/clustered_graph.graphml new file mode 100644 index 0000000000000000000000000000000000000000..f51bb6d31159a798496efd6150b44ebc99ea69a0 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/clustered_graph.graphml @@ -0,0 +1,2046 @@ + + + + + + + + + + + + + + + + + + "ORGANIZATION" + The AskNature Team, associated with the entity named "ASKNATURE TEAM", is dedicated to creating educational content about living systems, which notably includes information about birds. Their work encompasses not only the creation of such materials but also involves cataloging knowledge on biomimicry and natural strategies like 'Spiral Fibers'. As a research-focused group, the AskNature Team conducts programs aimed at understanding nature's solutions for various applications in technology, design, and problem-solving processes, effectively bridging human innovation with ecological wisdom. + 30aa281b7ea0845a9f88c0914df109c3,4305d6610a2538765dc1ea9aed78ea5e,a3d83dc700d8d01b07a94c2a1180c2b4 + 0 + 0 + b45241d70f0e43fca764df95b2b81f77 + + + "PROCESS" + "The process by which birds inhale and exhale air through their respiratory system for oxygen intake and carbon dioxide expulsion.") ("entity" + a5430820e1ece1dff536ad804e55c798 + 0 + 1 + 4119fd06010c494caa07f439b333f4c5 + + + "PERSON" + "ANDY CARSTENS" refers to an author dedicated to exploring natural phenomena, with a notable focus on innovations inspired by nature. One of his works highlights the biological strategy adopted by birds utilizing ground effect to minimize drag and conserve energy while gliding over water, showcasing his deep interest in understanding and explaining the intricacies of natural behavior and engineering. + 4d6faade61b11859190946a315c34a2e,8afa448acb86b96422cea043f3fd6749 + 0 + 2 + d3835bf3dda84ead99deadbeac5d0d7d + + + "ORGANISM" + "The Flying squirrels are the subject of study due to their ability to control their glide." + 638dc502f70bb90aeb0465be8db1facc + 0 + 3 + 077d2820ae1845bcbb1803379a3d1eae + + + "ORGANIZATION" + The Biomimicry Institute is an organization centered on studying natural principles to address human challenges, promoting sustainability in design and technology through innovation inspired by nature. As a copyright holder, it specializes in finding solutions based on the strategies observed within ecosystems and operates through platforms like AskNature for disseminating educational content about nature-based innovations. The institute's primary objective is to educate and provide biological strategy insights for human design applications, specifically focusing on understanding and replicating mechanisms found in nature to enhance human technologies, such as observing glide behaviors of flying squirrels and applying that knowledge to improve areas like parachutes or skydiving suits. This organization behind Biomimicry.org provides comprehensive information and guidance on how to utilize nature's problem-solving methods within various sectors of human technology development. + 4d6faade61b11859190946a315c34a2e,74a8b683e829577d39bd3b12018ddee0,75be22a096d450ebe20ed42f79da45da,7c777850b39440dea33d9b60641e803b,809da8a35547ca53620a67d4f1cdb6f5,891d3f28f888b374a21d9c781295bbf9,90ede7f9f06fa68f01d8528ec2495d4b,e9161c0416f80b08625e2dcd9f70167f + 0 + 4 + 3671ea0dd4e84c1a9b02c5ab2c8f4bac + + + "PERSON" + "This refers to researchers who contributed to a study on gliding performance of mammals, particularly northern flying squirrels (Glaucomys sabrinus)." + a3d83dc700d8d01b07a94c2a1180c2b4 + 0 + 5 + 19a7f254a5d64566ab5cc15472df02de + + + "ORGANISM" + "The Black-tailed prairie dog is an animal that builds extensive burrows in the plains of North America and performs functions like distributing gases." + a3d83dc700d8d01b07a94c2a1180c2b4 + 0 + 6 + e7ffaee9d31d4d3c96e04f911d0a8f9e + + + "CREATIVE WORKER" + "This refers to a photographer whose image has been used in publications related to nature studies, with permission granted for use." + a3d83dc700d8d01b07a94c2a1180c2b4 + 0 + 7 + f7e11b0e297a44a896dc67928368f600 + + + "ORGANIZATION" + "AskNature.org, a component of the Biomimicry.org platform, serves as an online resource for users seeking to explore and apply natural strategies in their innovations. This unique website presents knowledge and tools related to nature-based solutions and biomimicry with a focus on heliotropism, the movement of plants towards the sun. As part of this mission, Lonny Lippsett shared insights on self-organization within diverse soil ecosystems on the AskNature.org platform. + +AskNature.org is dedicated to facilitating biologically inspired innovations by showcasing effective biological strategies that can help solve human challenges through nature's principles. This resource platform features a variety of organisms and ideas that have been adopted from natural systems, aiming to provide inspiration for sustainable problem-solving and design across multiple fields." + +Please note that there seems to be some confusion or inconsistency in the descriptions provided about whether 'AskNature' is one entity (AskNature.org) or if it refers to two distinct entities ('AskNature.ORG' and 'Asknature.org'). However, based on the context given and assuming a single entity for consistency, this summary provides an accurate synthesis of the provided information. + +If you need further clarification or another interpretation, please specify so I can assist better! + 0a71d2671ba6b6bceb2f13e60122c278,10a8260a1ac5e4f2ab531d67e534b83f,3678ab8d2bad24bba44d0a83fe09f8a6,42b463f5b40c4f86e9338c967c8d5bfa,75be22a096d450ebe20ed42f79da45da,fb3016519d20d8e4fc1d25d5690a550a + 0 + 8 + 1fd3fa8bb5a2408790042ab9573779ee + + + "PERSON" + "Sam Rivera appears to be associated with an unspecified organization that specializes in biological research, with a particular emphasis on adhesive mechanisms found in nature. This involves studying and understanding these natural adhesion properties which might have various applications or areas of interest. Although the exact location of this organization is not explicitly stated, it's suggested they are involved in projects conducted in Saudi Arabia where echolocation techniques are utilized for food searching. The research also includes interaction with an Egyptian fruit bat as part of these studies. Despite being mentioned in relation to an organization and these specific activities, the description contradicts itself by stating that Sam Rivera is 'not mentioned' in the provided real data." + 777a1482c060a064af315a8488df370a,b01ac6d637b8d31e396081208c8162d0,d99568b2216b6501020a719efe70edaf + 0 + 9 + 27f9fbe6ad8c4a8b9acee0d3596ed57c + + + "ORGANISM" + "A species of frog specifically adapted to living in water-filled tree hollows, utilizing their environment to amplify vocal calls.|) ("entity" + aff4d366caa94978fbabd1021d43d555 + 0 + 10 + e1fd0e904a53409aada44442f23a51cb + + + "SPECIES" + "Specific types of snakes known for their unique ability to create loud defensive sounds." + 4d6faade61b11859190946a315c34a2e + 0 + 11 + de988724cfdf45cebfba3b13c43ceede + + + "ACTION" + "Visiting a specific strategy on AskNature for investigation into interactions between vortices and trout. The website provides scientific articles related to the topic." + 8fa82d96bb00621623d0d7c9e9ac5034 + 0 + 12 + 96aad7cb4b7d40e9b7e13b94a67af206 + + + "OBJECT" + "Butterfly wings are a natural model that shows how micro-geometrical patterns enhance airflow and facilitate flight through specific scale configurations.") ("entity" + 01117b72383429324254870387eb4aba + 0 + 13 + c9632a35146940c2a86167c7726d35e9 + + + "BIOLOGICAL STRATEGY" + "The micro-geometry of butterfly wing scales provides insights into designing efficient wind turbines, improved structural stability in tall buildings, and more." + 5bec096731ec31b017777a7aadf747bc + 0 + 14 + 9646481f66ce4fd2b08c2eddda42fc82 + + + "ORGANIZATION" + "The Diving Bell Spider serves as a biological inspiration for technological innovations in air supply and water-resistant materials." ) ("entity" + 81eee876cafa81ab3b11ed19cc045cb6 + 0 + 15 + d91a266f766b4737a06b0fda588ba40b + + + "PERSON" + "Roger S. Seymour is an author who contributed to the Journal of Experimental Biology in 2011.") ("entity" + eedd4bc29a0007151fb16d1deec2f9eb + 0 + 16 + bc0e3f075a4c4ebbb7c7b152b65a5625 + + + "ORGANIZATION" + "Spiders use trichobothria for sensing and movement control in hunting and navigating their environment." + 3d22053debaab18c4e321d4cfe15f8af + 0 + 17 + 254770028d7a4fa9877da4ba0ad5ad21 + + + "CONCEPT" + "Trichobothria are sensory structures on spiders’ legs that enhance their sensitivity to touch, vibrations, and motion." + 3d22053debaab18c4e321d4cfe15f8af + 0 + 18 + 4a67211867e5464ba45126315a122a8a + + + "EVENT" + "The hypersensitivity provided by trichobothria allows spiders to detect underwater currents or the presence of sea life." + 3d22053debaab18c4e321d4cfe15f8af + 0 + 19 + 04dbbb2283b845baaeac0eaf0c34c9da + + + "CONCEPT" + "Spiders use information from their environment, like the activity of other organisms and environmental cues, for hunting, navigation, and self-defense." + 3d22053debaab18c4e321d4cfe15f8af + 0 + 20 + 1943f245ee4243bdbfbd2fd619ae824a + + + "ORGANIZATION" + "The concept of integrating spider's sensory capacity into wearable devices or clothing could improve motion detection beyond human vision." + 3d22053debaab18c4e321d4cfe15f8af + 0 + 21 + 273daeec8cad41e6b3e450447db58ee7 + + + "WEBSITE" + "Website for the organization Biomimicry Institute, providing information about strategies found in nature and how they can be applied." + 75be22a096d450ebe20ed42f79da45da + 0 + 22 + e69dc259edb944ea9ea41264b9fcfe59 + + + "PERSON" + "A researcher contributing his expertise in the biological strategy related to spiders and electric currents for biomimetics applications." + 75be22a096d450ebe20ed42f79da45da + 0 + 23 + e2f5735c7d714423a2c4f61ca2644626 + + + "PERSON" + "The individual credited with discovering or understanding how certain spiders fly using electrostatic repulsion, possibly contributing knowledge to biomimetic engineering." + 75be22a096d450ebe20ed42f79da45da + 0 + 24 + deece7e64b2a4628850d4bb6e394a9c3 + + + "PERSON" + "A contributor or researcher who provided insights or evidence supporting the spider flying phenomenon, influencing scientific community." + 75be22a096d450ebe20ed42f79da45da + 0 + 25 + e657b5121ff8456b9a610cfaead8e0cb + + + "PERSON" + "A researcher involved in the study that shed light on spiders' use of electrostatic forces for flight, providing significant biological data for biomimetics." + 75be22a096d450ebe20ed42f79da45da + 0 + 26 + bf4e255cdac94ccc83a56435a5e4b075 + + + "EVENT" + "Spiders were observed to exhibit 'balloon' like flight in low wind conditions due to atmospheric electric fields.") ("entity" + 621c0cd608f4ed99a4dd7a5c25c8e0b5 + 0 + 27 + 3b040bcc19f14e04880ae52881a89c1c + + + "PERSON" + "Mary Hoff authored a strategy on AskNature explaining how water striders communicate using vibrations and their legs.") ("entity" + 60d4060427254b2a553815d05dce7fcf + 0 + 28 + 3d6b216c14354332b1bf1927ba168986 + + + "ORGANISM" + "A species of insects that communicate through tapping the water surface and have highly sensitive motion-detecting structures on their legs.") ("entity" + bd3e8fcd1e1991500d9610859ecfabf4 + 0 + 29 + 1c109cfdc370463eb6d537e5b7b382fb + + + "PERSON" + "Pablo Perez is responsible for inventing devices that provide advanced warning of impending earthquakes or mudslides, possibly inspiring new technology.") + f228fcbbb8f2ec33599ea9a3d5d4e854 + 0 + 30 + 3d0dcbc8971b415ea18065edc4d8c8ef + + + "PERSON" + "He created an image for this document under CC BY-SA license.") ("entity" + 1ff6815fa5511debe6f17ad17c1707b1 + 0 + 31 + 68105770b523412388424d984e711917 + + + "ORGANISM" + "Plants use strategies like tropisms (gravitropism, thigmotropism, phototropism, heliotropism) to adapt and respond efficiently to their environment.") ("entity" + c8455055703093614be4105105a67f0e + 0 + 32 + 85c79fd84f5e4f918471c386852204c5 + + + "PERSON" + "Peter Prehn, a contributor to Biomimicry Institute and AskNature.org, explains the underground network strategy of mycorrhizal fungi in a Douglas-fir and pine forest context.") ("entity" + 2defde0504bd9c1a5bdd248980ce1ce1 + 0 + 33 + eae4259b19a741ab9f9f6af18c4a0470 + + + "ORGANISM" + "Mycorrhizal fungi form mutualistic partnerships with trees and other plants, facilitating nutrient exchange and communication through the Wood Wide Web.") ("entity" + dbf85def96906b82d29e7bcd512b920f + 0 + 34 + 3138f39f2bcd43a69e0697cd3b05bc4d + + + "CONCEPT" + "A network formed between the roots of plants and fungi, facilitating resource exchange, information sharing, and mutual support among plant communities.") ("entity" + ac3f4943aac0de17b70d54bf387fe19b + 0 + 35 + dde131ab575d44dbb55289a6972be18f + + + "PERSON" + "Lonny Lippsett wrote about biological strategies performed by organisms living in soil ecosystem, particularly focusing on self-organization." + 0a71d2671ba6b6bceb2f13e60122c278 + 0 + 36 + de9e343f2e334d88a8ac7f8813a915e5 + + + "ORGANIZATION" + "This refers to the diverse ecosystem that works together to break down organic matter and recycle it into nutrients for plants to reuse.")<|"\n"|"Entity" + 17c65307eb89a2d2f26db3e34ba78722 + 0 + 37 + e2bf260115514fb3b252fd879fb3e7be + + + "EVENT" + "AN-Bird Respiration_Final_05-2022 refers to a document that discusses bird respiration process which is being finalized in the month of May 2022.") ("entity" + 03018b77601ad2b2e8345af35fb84450 + 0 + 38 + b462b94ce47a4b8c8fffa33f7242acec + + + "CONCEPT" + "It is a system of classification developed by the Biomimicry Institute for organizing biological content on their website AskNature.org. This taxonomy categorizes strategies that organisms and natural systems use to meet functional challenges. The strategies are classified according to functions, which describe what the strategy accomplishes for the organism or living system. This helps users identify potential solutions to similar human challenges by looking at nature's approach to solving issues.") + ff760235e3461c93ff1fa2bee432fdb1 + 0 + 39 + 17ed1d92075643579a712cc6c29e8ddb + + + "ORGANIZATION" + "AskNature is an online platform providing access to strategies and insights from natural systems for design solutions." ) ("entity" + e4b6193a4ea13cb8c682998eb02efb6d + 0 + 40 + 3ce7c210a21b4deebad7cc9308148d86 + + + "BIOMIMICRY TAXONOMY" + "ORGANIZATION" encompasses diverse functions across various fields: + +1) Serving as a database central to bibliometric analysis, this entity supports researchers and academics by facilitating the discovery of pertinent publications and fostering an understanding of academic trends. + +2) In addition to its role in bibliometrics, "ORGANIZATION" is recognized for publishing research journals like 'Phil.Trans.RoyalSoc.A', making it both a publisher and an academic organization. + +3) It plays an innovative role in biomimicry through the Biomimicry Taxonomy framework. This entity helps drive innovation by identifying new verbs and related concepts, encouraging the application of nature-inspired solutions that foster creative activities involving interdisciplinary knowledge. + +4) Engaging with themes linked to sustainability, "ORGANIZATION" is dedicated to understanding ecological systems and their transformations as well as the services they offer, defining it as a part of CTU (Centre for Teaching and Understanding). + +5) As an entity involved in studying ecosystem dynamics, it collaborates on diverse themes including the physical state modifications and services provided by ecosystems. + +6) Notably, "ORGANIZATION" also includes NC 4.0, which might represent either a specific program or organization focused on creative license or collaborative efforts. + +In summary, this multifaceted entity acts as both a database for scholarly research analysis and dissemination, alongside a publisher of academic journals. It is pivotal in fostering innovation through nature-inspired solutions and contributes to ecological studies centered around sustainability. Moreover, it collaborates with diverse stakeholders under themes like creative activities and is involved in the exploration of ecosystem dynamics. + 170684a57b4848b420032214260ee67b,23c34b74899c04c60dc7b087b88e0137,3b302bec9259fbca0cf68da76392935c,44c8dff86ecf90b601e21ef2335e8c61,6de0fc3cc6011a0ce9267a0584f498b2,84d05d265cebbc1d33e9d523b860d87e,a19c62053cac11a3e022402443eeba83,dd615bbb350414d251cb1083b3142230,fe902bcadf86addbe747f348c1ccc56f + 0 + 41 + d64ed762ea924caa95c8d06f072a9a96 + + + "H" + "H could represent any individual within an organization or group dealing with eco-system management, focusing on behaviors optimization, space/material adaptation, and coordination with other groups." + 170684a57b4848b420032214260ee67b + 0 + 42 + adf4ee3fbe9b4d0381044838c4f889c8 + + + "PERSON" + "Alex is the leader of a team attempting first contact with an unknown intelligence, acknowledging the significance of their task." + 2b9b282e75a0a5345cc0cee8f327a2b1 + 0 + 43 + 32ee140946e5461f9275db664dc541a5 + + + "ORGANIZATION" + "BOHsihana is involved in the process of attempting to communicate with an unknown intelligence through their technological means and research." + 3b8a807b256d918245b0ffb8c88d4c09 + 0 + 44 + c160b9cb27d6408ba6ab20214a2f3f81 + + + "PERSON" + "A biomimetics researcher at the Department of Design, University of Brasília, who has contributed to studying the application and integration of biological knowledge in design.")|("entity" + 7323cecb72b3fa0472a26a5aa37c4131 + 0 + 45 + 23527cd679ff4d5a988d52e7cd056078 + + + "PUBLICATION" + "Biomimetics 2023" refers to a journal that focuses on sharing insights and research related to biomimetics in the year 2023. It published a study contained within volume 8, issue number 61 of the publication titled 'Biomimetics'. This article explores thematic aspects associated with design and biomimicry, emphasizing product conception and structural explorations of nature for new materials that contribute to sustainability while conserving resources. The journal's interest lies in showcasing how creative tools are applied in product design to achieve environmental responsibility." + 2aee03ca69624bff0ae2d030f6f31e19,7982a2e4054b66ae19457bde8585eaa8,af3fc23c5069edd0bdffd8f9a64d3ab2,b23a7cb845fd949e0baab80bf6f0c4f8 + 0 + 46 + f1c6eed066f24cbdb376b910fce29ed4 + + + "CONCEPT" + "Biological concepts or ideas that are mimicked by humans in various fields, often for innovation and problem-solving.") ("entity" + 6e87b92e6c843cb54a008ae676d3b416 + 0 + 47 + 83a6cb03df6b41d8ad6ee5f6fef5f024 + + + "CONCEPT" + "Imitative or biomimetic design that draws on concepts found in nature to solve human challenges and promote sustainability.") + a43faaba2ebb888387d5b0f59efb6381 + 0 + 48 + 147c038aef3e4422acbbc5f7938c4ab8 + + + "JOURNAL" + "Biomimetics is a comprehensive field of study that draws inspiration from nature's principles to address intricate human challenges. It focuses on exploring and emulating natural systems for solving engineering problems, which involves developing new materials and devising innovative devices based on biological concepts. This field studies both existing natural designs and presents analyses on design and architecture topics, as exemplified by the publication Biomimetics from the late 1990s." + 2790f03c21ca0d9a522e2c1276ad4f6e,b3c5de72ae4c784c9fef28c432a247eb,bc8c1b71a9bc00c67a64198dae0f5a42,d1f202cadb144570739c718437dd9c7b + 0 + 49 + b7702b90c7f24190b864e8c6e64612a5 + + + "ORGANIZATION" + "The Procedia Social and Behavioral Sciences is an academic journal that published 5 articles.") ("entity" + 17a811ea2375e85ee164ddd52dbe5a80 + 0 + 50 + de6fa24480894518ab3cbcb66f739266 + + + "EVENT" + "The article discusses the evolution of reaction centers that mimic photosynthesis for fuel production and water conversion processes." + b315f4391fd31deebdefc7e4496ccc53 + 0 + 51 + 6fae5ee1a831468aa585a1ea09095998 + + + "AUTHOR" + "Bhushan conducted research emphasizing biomimetic studies at micro and nano scales, focusing on creating designs inspired by biological surfaces and materials.") ("entity" + bc2123b5f86d53a8b6c4f35594131571 + 0 + 52 + ef32c4b208d041cc856f6837915dc1b0 + + + "ORGANIZATION" + "An organization that works in a field related to sustainable design and research, focusing on biomimicry." + c16a050b9f05d4adcbe87cd85974f73b + 0 + 53 + 07b2425216bd4f0aa4e079827cb48ef5 + + + "CONCEPT" + "A central theme in the works of 'The St Works Study' which deals with bio-based innovations, specifically biomimicry." + c16a050b9f05d4adcbe87cd85974f73b + 0 + 54 + 2670deebfa3f4d69bb82c28ab250a209 + + + "CONCEPT" + "MIMICRY" is the central theme encompassing the core concept behind studies and developments initiated by 'The St Works Study'. This approach leverages principles sourced from nature to address challenges and foster innovations. Additionally, it denotes a practical utilization of biomimetic traits in design, drawing inspiration from natural phenomena and forms. Consequently, "MIMICRY" embodies an integrated methodology that combines ecological insights with creative problem-solving strategies and design innovation. + 30c01680c32c27bbf40c2879200bb4ca,c16a050b9f05d4adcbe87cd85974f73b + 0 + 55 + 404309e89a5241d6bff42c05a45df206 + + + "PERSON" + "E.O. Wilson is known for conceptualizing nature as a model, measure, and mentor agent capable of generating efficient systems. He also encourages transferring natural knowledge to human contexts particularly in dealing with issues like waste management.") ("entity" + 10357a9455875b5f9c5deca2d9871135 + 0 + 56 + b785a9025069417f94950ad231bb1441 + + + "PERSON" + "Pawlyn is associated with work showcasing biomimicry and architecture interconnections, highlighting sustainable and innovative construction methods, particularly for restoration purposes.") ("entity" + b8f2d8b6f8181c950be1341e09d5f6ac + 0 + 57 + 3b6cd96a27304614850709aba1c9598b + + + "PERSON" + "These authors are responsible for the concept of designing with a focus on effectively having a positive impact on the environment.") ("entity" + 50d87eb794de75e87a2b0897c5432e39 + 0 + 58 + d54956b79dd147f894b67a8b97dcbef0 + + + "ORGANIZATION" + "The organization is involved in the research and functional analysis of natural and artificial systems using biomimetic approaches." + ea3022e7c889776437eec7e0ff1e3b2c + 0 + 59 + 958beecdb5bb4060948415ffd75d2b03 + + + "ORGANIZATION" + "The organization involved is a research institute or department that focuses on sustainable architecture and design.") + e01fbf716e63081d999f9f22c28e098a + 0 + 60 + b999ed77e19e4f85b7f1ae79af5c002a + + + "GEO" + "Climate is a subject associated with the adaptation and systems at ecological level, involving technical solutions, especially in the face of climate crisis." + 3cafe8221f0d2b661270f9e33c59993d + 0 + 61 + 48c0c4d72da74ff5bb926fa0c856d1a7 + + + "PERSON" + "A Researcher who specializes in biomimetics studies different organisms' abilities to identify two words which appear together frequently") + 4c8d34a6cb7efcbac85f88b2fbb3973e + 0 + 62 + 4f3c97517f794ebfb49c4c6315f9cf23 + + + "ORGANIZATION" + "Entomology is a field of study which focuses on the organisms, especially insects.")|("entity" + 5bb96e57d4c79ea40feeb5ecb3296afe + 0 + 63 + 1745a2485a9443bab76587ad650e9be0 + + + "GEO" + "This includes various designs and studies across architecture.")|("entity" + 439722d75181e1aa687e95df70e09d63 + 0 + 64 + 32e6ccab20d94029811127dbbe424c64 + + + "OBJECT" + "This represents a map created using data from the Web of Science, covering publications from 2018 to 2021. The map visually represents bibliographic coupling between documents." ) ("entity" + 8d7e6e7209519d7dec8948a364fdbab2 + 0 + 65 + 94a964c6992945ebb3833dfdfdc8d655 + + + "EVENT" + "An opportunity for redesigning materials, processes, and products that may inherently link with nature through their properties and functionality." + 30c01680c32c27bbf40c2879200bb4ca + 0 + 66 + 1eb829d0ace042089f0746f78729696c + + + "ACTION" + "The act of redesigning materials, processes, and products to improve efficiency or sustainability." + 30c01680c32c27bbf40c2879200bb4ca + 0 + 67 + 015e7b58d1a14b44beab3bbc9f912c18 + + + "ASPECT" + "A connection or relationship between the designed elements and natural principles or systems." + 30c01680c32c27bbf40c2879200bb4ca + 0 + 68 + 26f88ab3e2e04c33a459ad6270ade565 + + + "CONTEXT" + "Environmental changes that influence the functionality of kinetic architectural elements." + 30c01680c32c27bbf40c2879200bb4ca + 0 + 69 + babe97e1d9784cffa1c85abc1e588126 + + + "CONCEPT" + "A model where resources are kept in use for as long as possible, extracting maximum value while minimizing waste."> + 30c01680c32c27bbf40c2879200bb4ca + 0 + 70 + 1033a18c45aa4584b2aef6ab96890351 + + + "ORGANIZATION" + "Tate et al. are a team who reviewed relationships of mutualism found in nature and contributed to the recognition of biomimicry as an area useful for strategic planning in companies." + f770903009c82b1aeca7bf9e490877ad + 0 + 71 + c9b8ce91fc2945b4907fe35519339cac + + + "EVENT" + "The introduction of innovative concepts that integrate ecosystem services to support biodiversity and natural environment resilience against climate change.")|("entity" + f5fd896ed0c59d47158db316fad680dc + 0 + 72 + fa3c4204421c48609e52c8de2da4c654 + + + "ORGANIZATION" + "The Web of Science is a comprehensive database used for academic research that may limit the accessibility or dissemination of certain works based on specific criteria." + 916f17bde39ae650dad1b657a1887fa6 + 0 + 73 + 53af055f068244d0ac861b2e89376495 + + + "PERSON" + "A.A.M.D.S." refers to the primary individual responsible for conceptualizing the study, developing its methodology, and contributing as a co-author alongside D.M.V. This entity has notably worked on an exploration of biomimicry's application and significance in design processes. + 7982a2e4054b66ae19457bde8585eaa8,f8d611d2f89f42ca1550ee673a05d4dd + 0 + 74 + c03ab3ce8cb74ad2a03b94723bfab3c7 + + + "PERSON" + "D.M.V contributes to software development, formal analysis of data, validation, investigation, resource gathering, supervision of the project." + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 75 + ed6d2eee9d7b4f5db466b1f6404d31cc + + + "CONCEPT" + "A structured description of each authors' contribution to the research process, from conceptualization to final review." + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 76 + fc01e9baa80e417c9206f941bb279407 + + + "EVENT" + "Planning and ideation phase for the study conducted by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 77 + 56d0e5ebe79e4814bd1463cf6ca21394 + + + "EVENT" + "Process of planning how experiments or research will be designed and executed, carried out by A.A.M.d.S. and D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 78 + 7c49f2710e8b4d3b8dc9310834406ea5 + + + "TOOL" + "A.A.M.d.S utilized software tools for various tasks during the study's execution." + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 79 + c6d1e4f56c2843e89cf0b91c10bb6de2 + + + "EVENT" + "The process of confirming the accuracy or truthfulness of research findings, carried out by A.A.M.d.S. and D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 80 + 0adb2d9941f34ef7b2f7743cc6225844 + + + "TECHNIQUE" + "Careful examination and interpretation of data or concepts using systematic methods" + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 81 + 6b02373137fd438ba96af28f735cdbdb + + + "ACTIVITY" + "Research conducted to gather information, performed by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 82 + 36a4fcd8efc144e6b8af9a1c7ab8b2ce + + + "TOOL" + "Materials or assets used in the study which were collected or provided by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 83 + fbeef791d19b413a9c93c6608286ab63 + + + "PROCESS" + "Organization and management of data throughout its lifecycle, responsibility of A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 84 + d2b629c0396f4180a03e16ddf3818589 + + + "TASK" + "The initial writing phase where the first version of a paper or report is drafted by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 85 + 6102fc6619ed422ebc42588bfa97355d + + + "ACTIVITY" + "Process to refine and correct content, undertaken by both A.A.M.d.S. and D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 86 + 8d141c0b80f74b79a05eed7fe161fe49 + + + "TECHNIQUE" + "Representation of data or concepts through graphical means, performed by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 87 + e22d1d1cd8d14f12b81828d940f40d70 + + + "ROLE" + "Overseeing the research project's progress and ensuring quality control, done by D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + 0 + 88 + 9ab48505fb1b487babd0d1f6d3a3f980 + + + "PERSON" + "MacKinnon R.B., J.Oomen, M.P.Zari are authors in the paper 'Promises and Presuppositions of Biomimicry' contributing to the field of biomimetics.")<br>("entity" + ab0129037f27d2a0b3230e695cb66703 + 0 + 89 + 148fffeb994541b2b4b6dcefda7001a8 + + + "PERSON" + "Cohen is the author who wrote 'Biomimetic Design Method for Innovation and Sustainability' in Springer")|("entity" + 71820a84991aa839263c1542540c3d9a + 0 + 90 + 89c08e793298442686292454a1abff31 + + + "PERSON" + "Author of the book 'Biomimicry', exploring innovation inspired by nature.")|("entity" + d9c59b517b2e653c7c9cb7efb130c9b0 + 0 + 91 + 0467928aa65e4a4fba62bdb1467e3a54 + + + "ORGANIZATION" + "CrossRef is a not-for-profit membership organization that operates several databases for scholarly journals and books." + d41313a8b0e699443363728cc7ec56b7 + 0 + 92 + 43c3390303c6476cb65f584e37c3e81c + + + "PERSON" + "Michael Cutkosky is the author of one paper discussing the design and fabrication of multi-material structures for bioinspired robots." + d41313a8b0e699443363728cc7ec56b7 + 0 + 93 + fa14b16c17e3417dba5a4b473ea5b18d + + + "JOURNAL" + "This is a journal published by The Royal Society which features scientific papers in mathematical, physical, engineering sciences, life sciences and information science." + d41313a8b0e699443363728cc7ec56b7 + 0 + 94 + 7cc3356d38de4328a51a5cbcb187dac3 + + + "PERSON" + "Jorge Mendoza is an author of one paper discussing the integration of backcasting and eco-design for the circular economy using a framework named BECE." + d41313a8b0e699443363728cc7ec56b7 + 0 + 95 + bef16fb5fd7344cca5e295b13ef3e0cd + + + "JOURNAL" + "This journal focuses on issues in environmental sustainability, green business strategies, and sustainable development." + d41313a8b0e699443363728cc7ec56b7 + 0 + 96 + bb9e01bc171d4326a29afda59ece8d17 + + + "PERSON" + "Ben D. Sherman is an author of one paper discussing the evolution of reaction center mimics for systems capable of generating solar fuel." + d41313a8b0e699443363728cc7ec56b7 + 0 + 97 + 3c063eea52e94164b70c99431ea30bae + + + "JOURNAL" + "This journal publishes scientific papers about photosynthesis and related fields such as biochemistry, genetics, ecology, and physiology of plants and algae." + d41313a8b0e699443363728cc7ec56b7 + 0 + 98 + 252cc8452bfc4c2aa58cab68d8b61879 + + + "PERSON" + "Samantha N. Sponberg is an author of one paper discussing templates and anchors for antenna-based wall following in cockroaches and robots." + d41313a8b0e699443363728cc7ec56b7 + 0 + 99 + 7e2c84548fb94ee395ba8588d8f2a006 + + + "JOURNAL" + "This journal publishes research articles on robotics theory, experimentation, applications, and design, including topics like autonomous robots and robot systems." + d41313a8b0e699443363728cc7ec56b7 + 0 + 100 + f034618dde7948beb6dab30176d0fc87 + + + "PERSON" + "Qingyuan (Q.) Xu is an author of one paper discussing biomimetic self-cleaning surfaces." + d41313a8b0e699443363728cc7ec56b7 + 0 + 101 + 5c41f96be13e49dba649454297834546 + + + "PERSON" + "Mehrnaz Zari is the author of a paper discussing biomimetic design for climate change adaptation and mitigation." + d41313a8b0e699443363728cc7ec56b7 + 0 + 102 + 7ea4afbf8a264f29af29950ce98105ba + + + "JOURNAL" + "This journal covers various scientific fields including architecture, physics, engineering sciences, life sciences, and information science." + d41313a8b0e699443363728cc7ec56b7 + 0 + 103 + 91ff849d12b24574b0691dbddf44968b + + + "PERSON" + "Michael Helms is an author of a paper discussing biologically inspired design: process and products." + d41313a8b0e699443363728cc7ec56b7 + 0 + 104 + d73c1f2fb3094d8dace42ad2a76e9a52 + + + "JOURNAL" + "This journal publishes academic studies on design including issues related to cultural, social and psychological aspects of designing processes and artifacts." + d41313a8b0e699443363728cc7ec56b7 + 0 + 105 + cdc8901e668749889bd49bebdc4ff1f6 + + + "PERSON" + "Mark Pawlyn is the author of a book titled 'Biomimicry in Architecture' which focuses on principles of biomimicry as applied to architectural design." + d41313a8b0e699443363728cc7ec56b7 + 0 + 106 + 36084a9fab53433493f079e97e68bf65 + + + "PERSON" + "Amir Chakrabarti is mentioned with his involvement with other researchers in one paper discussed." + d41313a8b0e699443363728cc7ec56b7 + 0 + 107 + eebcc7ec8e3e4df7aea83659bbdc2199 + + + "PERSON" + "Mawson Pawlyn is the author of 'Biomimicry in Architecture', showcasing expertise and insight into architecture that draws inspiration from natural systems.") ("entity" + 70bfef2ab1bf8bc9a6db2cd5ae212340 + 0 + 108 + ceadf262ef834e9ab146b20650912cae + + + "PERSON" + "Ying Xing is the author of 'Exploring design principles of biological and living building envelopes: What can we learn from plant cell walls?' in Intell. Build. Int., contributing to discussions on biomimetic design.") ("entity" + 43eb56fd90297c8d3c9e125f8a258552 + 0 + 109 + 7f65feab75424b53b24470d305ba331a + + + "PERSON" + "Escobar is the author of 'Designs for the Pluriverse: Radical Interdependence, Autonomy, and the Making of Worlds', a book about radical interdependence and autonomy in making worlds."), ("entity" + 1e4a32f745aa007ef1215f21e5d61f20 + 0 + 110 + fd9cb733b28d420cb5cef01e545a132c + + + "PERSON" + "Dr. Meng F is a researcher who contributed to the study on biomimetics for new smart adhesives based on tree frog adhesion properties.") ("entity" + b1365ab133c6be5ea45465f8f66fde20 + 0 + 111 + 0fbcca3f17c649a08aea64b5a7d9ef36 + + + "PERSON" + "Longjian Xue contributed research on bioinspired adhesives through tree frog toe pad mimics." + 2790f03c21ca0d9a522e2c1276ad4f6e + 1 + 112 + 482027a59f32484c9c44fd700615c1b6 + + + "PERSON" + "W. Jon P. Barnes collaborated in the development of bioinspired adhesive materials and friction-generating devices based on biomimetic principles." + 2790f03c21ca0d9a522e2c1276ad4f6e + 1 + 113 + de837ff3d626451282ff6ac77a82216d + + + "ORGANIZATION" + "These are specific areas of study that focus on replicating biological features from tree frogs to design artificial adhesives and devices." + 2790f03c21ca0d9a522e2c1276ad4f6e + 1 + 114 + 460295fed3ae4cd39f9f274cec9c2506 + + + "CONCEPT" + "Bioinspiration refers to the process of drawing ideas or innovations from natural phenomena for technological applications." + 2790f03c21ca0d9a522e2c1276ad4f6e + 1 + 115 + 553b285bba60460ab1ed8341ae61282b + + + "EVENT" + "The study involves research on how climbing animals, like tree frogs, adhere to surfaces and applying these principles in artificial materials." + 2790f03c21ca0d9a522e2c1276ad4f6e + 1 + 116 + cec95bf17e7e4c939b56c9c6f402a29f + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + 1 + 117 + 599164aead034bc19446efacc77554d2 + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + 1 + 118 + bbf148ae4d48422f8fdef754cfa2b9e4 + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + 1 + 119 + de61b2670999433f807a6a1dc2b81e43 + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + 1 + 120 + 3e95dacfe57b4d57b5da4310ef2e157f + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + 1 + 121 + 1f1545308e9347af91fd03b94aadc21f + + + "ORGANIZATION" + "Sun & Bhushan are likely the authors of a recent review, suggesting they have expertise in biomimetics and adhesion mechanisms." + 7393bb6f9d3837d8e11cfbef8c7d7959 + 0 + 122 + 6ea81acaf232485e94fff638e03336e1 + + + "SPECIES" + "The species being discussed is a gliding frog that resides in trees and uses its toe pads for attachment"|>2) ("entity" + 86f10a539a2dae71ed0fb369a39cb0a5 + 0 + 123 + d136b08d586d488f9e4188b524c85a29 + + + "MATERIAL" + "Description of a material with an elastic modulus of approximately 3 kPa, which might relate to biological tissues like toe pads of frogs and other amphibians." + 1e6b8071c30040b985c9f084d73831fb + 0 + 124 + cccfa151fedc4b218a8d96adc7dceabe + + + "TOOL" + "An Atomic Force Microscope (AFM) indenter used for measuring the mechanical properties of materials, such as elasticity." + 1e6b8071c30040b985c9f084d73831fb + 0 + 125 + ce54725672a74ebcabe6127577dacb2b + + + "SURFACE" + "The outermost layer of a toe pad structure that has been measured to have an elastic modulus significantly higher than internal layers." + 1e6b8071c30040b985c9f084d73831fb + 0 + 126 + ea2b28ca1a974ffab4517811dc1d1e5c + + + "LAYER" + "Layers close to sub-dermal lymph spaces and a capillary network, which are much softer and pliable compared to the external surface of the pad." + 1e6b8071c30040b985c9f084d73831fb + 0 + 127 + aff21f1da1654e7babdcf3fb0e4a75fc + + + "MATERIAL" + "Structures that provide rigidity and strength to various biological tissues including toe pads and other skin components in amphibians." + 1e6b8071c30040b985c9f084d73831fb + 0 + 128 + dc2cc9016e3f49dbac7232f05cce794d + + + "ORGANIZATION" + "DROTLEF ET AL." is a team led by Sam Rivera dedicated to conducting extensive research and publishing findings related to cell structures and their adhesive capabilities. This organization has also undertaken studies involving the exploration of adhesion forces under varying velocities on both hydrophilic and hydrophobic surfaces, demonstrating comprehensive expertise in this field of study. + 65e8dd210ebbbf33013fa2f40f86c71a,b01ac6d637b8d31e396081208c8162d0 + 0 + 129 + 6ea0cef05f694dcea455478f40674e45 + + + "CONCEPT" + "Sam Rivera's work involves complex biological concepts, specifically focusing on the intricate designs of cells and nanopillars as they relate to adhesion." + b01ac6d637b8d31e396081208c8162d0 + 0 + 130 + 7ab5d53a872f4dfc98f3d386879f3c75 + + + "EVENT" + "In this context, 'First Contact' refers to Sam Rivera's team understanding new forms of adhesion from studying natural structures such as those found in epithelial cells and nanopillars." + b01ac6d637b8d31e396081208c8162d0 + 0 + 131 + af1d0fec22114a3398b8016f5225f9ed + + + "ORGANIZATION" + The entity referred to throughout these descriptions is the research group named FEDERLE ET AL. This team is known for their work in uncovering scientific findings related to frog mucus properties, specifically focusing on adhesion mechanisms that occur when interacting with various surfaces. Their research activities are centered around water frogs and their unique toe pad structures, indicating an extensive investigation into the biological properties of these creatures. + 136e4bfffb45ced656433f414fdc6b2f,fa424ca04288f43c5c699afb0d603c44 + 0 + 132 + b07a7f088364459098cd8511ff27a4c8 + + + "PERSON" + "The authors who have studied the adhesion ability of tree frogs to various rough surfaces in their natural habitat.")|("entity" + fffe8fad4dcfa583ff169283eb78ecb3 + 0 + 133 + 8870cf2b5df64d2cab5820f67e29b9f1 + + + "GEO" + "The image produced by interference reflection microscopy which helps in estimating the thickness of fluid layer.") + e78095af9990d29b641c393cc4eef335 + 0 + 134 + cd130938a2844050be991af70baf5ee0 + + + "EVENT" + "Tree frog adhesion refers to the adhesive capabilities displayed by tree frogs, which is a topic under study with respect to physical principles and forces.") + 7fb26cfacb7049c44680dc8301da770f + 0 + 135 + 43544b99c3b04b059546198a0ae6366d + + + "ORGANIZATION" + "The document contains equation 2.1, which simplifies to FL = −4 πRγ .") ("entity" + 73f5b09aa4346c6324664d57dd868e8c + 0 + 136 + a671bf7fea2f4514b6e96ba99127fafd + + + "EVENT" + "The recent study referred to in the text discusses the forces of adhesion in biological systems." + fa83531962b067f9e048396a31135c9e + 0 + 137 + 525f41ea20274a05af4e52b625b473f3 + + + "CONCEPT" + "Equation (2.4) is used as a comparison point for discussing the extension of adhesive force equations to soft, elastic materials like tree frog toe pads." + fa83531962b067f9e048396a31135c9e + 0 + 138 + 071a416efbec4f0886c19ac68f6d43cb + + + "CONCEPT" + "The text discusses how with increasing radius (r), adhesive forces may change from length scaling to area scaling." + fa83531962b067f9e048396a31135c9e + 0 + 139 + 6d8473ef3b1042bf87178a611e3dbcc6 + + + "CONCEPT" + "The term effective elastic modulus refers to the material's resistance to deformation, affecting adhesive force predictions." + fa83531962b067f9e048396a31135c9e + 0 + 140 + 30c9641543c24773938bd8ec57ea98ab + + + "CONCEPT" + "Refers to one aspect of how adhesive forces are explained mathematically in relation to geometry and elasticity." + fa83531962b067f9e048396a31135c9e + 0 + 141 + 18b839da898e4026b81727d759d95c6a + + + "CONCEPT" + "Referred to as Stefan adhesion, these forces resist plate separation due to fluid flow dynamics." + fa83531962b067f9e048396a31135c9e + 0 + 142 + eeef6ae5c464400c8755900b4f1ac37a + + + "ORGANIZATION" + "Tulchinsky & Gat introduced the concept of 'temporary adhesion' by considering only viscous flow and ignoring inertial and capillary effects." + 92dc318eef4563c8f3fa73fb7b3978bc + 0 + 143 + 422433aa45804c7ebb973b2fafce5da6 + + + "EVENT" + "Equation (2.9) describes this force, which involves a term with viscosity and radius of the sphere." + 92dc318eef4563c8f3fa73fb7b3978bc + 0 + 144 + 86505bca739d4bccaaa1a8e0f3baffdc + + + "CONCEPT" + "Concept introduced by Tulchinsky & Gat based on elastic deformation and viscous flow interactions." + 92dc318eef4563c8f3fa73fb7b3978bc + 0 + 145 + 1af9faf341e14a5bbf4ddc9080e8dc0b + + + "ITEM" + "A test subject used in studying adhesion, with forces resisting slip being measured during tests." + 92dc318eef4563c8f3fa73fb7b3978bc + 0 + 146 + 353d91abc68648639d65a549e59b5cf3 + + + "ORGANISM" + "Tree frogs, a species known for their remarkable wet adhesion properties and capable of climbing using both adhesion and adduction forces on smaller structures, refer to animals whose unique toe pad structure inspires materials development. Unlike geckos, while they also provide inspiration due to their adhesive capabilities, the mechanism in tree frogs is described as more complex." + 48a7645a66fe18b7377a1a842f7242b0,70bb442f494ac5321d4f1d3bc233e919,92dc318eef4563c8f3fa73fb7b3978bc,bc8c1b71a9bc00c67a64198dae0f5a42 + 0 + 147 + 7ce637e4f35b42e3a9f8272cab69cd22 + + + "PROPERTY" + "Viscosity of the fluid is several orders of magnitude greater for silicone oil than tree frog mucus, affecting applicability of the viscous-poroelastic adhesion concept." + 92dc318eef4563c8f3fa73fb7b3978bc + 0 + 148 + 4d999d7744b04a998475f8f8531589f0 + + + "EVENT" + "Means by which tree frogs climb on flat surfaces using only adhesive forces." + 92dc318eef4563c8f3fa73fb7b3978bc + 0 + 149 + 9a6f414210e14841a5b0e661aedc898d + + + "ACTIVITY" + "Force used by tree frogs to climb small diameter structures, aiding in climbing with their digits." + 92dc318eef4563c8f3fa73fb7b3978bc + 0 + 150 + db541b7260974db8bac94e953009f60e + + + "STRUCTURE" + "Components also contributing to climbing abilities alongside adhesion and adduction forces." + 92dc318eef4563c8f3fa73fb7b3978bc + 0 + 151 + f2ff8044718648e18acef16dd9a65436 + + + "ORGANIZATION" + "Developers of a simple procedure to measure adhesive forces generated by tree frogs." + 82d1d20cbed7dd86fe58e59fed8d44ad + 0 + 152 + 00d785e7d76b47ec81b508e768d40584 + + + "GEO" + "This refers to a graphical representation or diagram, likely used in academic literature." + 1647a94c674950bc1429d956f341aba2 + 0 + 153 + 87915637da3e474c9349bd0ae604bd95 + + + "ORGANIZATION" + "The development team of miniature force plates used in measuring friction and adhesive forces on frog toe pads.") ("entity" + bea216e0fcc7f946f0033c137012a930 + 0 + 154 + 8f1eba29f39e411188200bf0d14628ec + + + "EVENT" + "A procedure conducted to study effects on fluid layer thickness under a pad using interference reflection microscopy." + 0888854b6766d37662902e4d32772d60 + 0 + 155 + 7282c73622b8408e97289d959faff483 + + + "EFFECT" + "Increase observed in the distance between pad and ground as an outcome of the said procedure." + 0888854b6766d37662902e4d32772d60 + 0 + 156 + 3deb220d31f74103aa44870a36a63220 + + + "EFFECT" + "Diminished adhesion due to changes from viscosity-dependent hydrodynamic forces and van der Waals forces." + 0888854b6766d37662902e4d32772d60 + 0 + 157 + af7a1584dd15492cb9a4940e285f57fc + + + "CONCEPT" + "A significant role for capillary forces in maintaining close contact between pad and ground." + 0888854b6766d37662902e4d32772d60 + 0 + 158 + 6e8d9029ce4e4ea182367173ab2c7bbf + + + "CONTEXT" + "The necessity of close contact for the manifestation of other adhesive actions, as suggested by the study." + 0888854b6766d37662902e4d32772d60 + 0 + 159 + cbf232211e7d4eb6abdbe182f71c2cf0 + + + "EVENT" + "An experiment involving recording forces exerted by a single pad during horizontal pull." + 0888854b6766d37662902e4d32772d60 + 0 + 160 + bb0cff774a4440b289cc6f3b929fe13c + + + "CONCEPT" + "Evidence that toe pads can generate static friction, indicating contact between structures on toe pads and the surface." + 0888854b6766d37662902e4d32772d60 + 0 + 161 + ce55841ebfdd47008bab8c258f10372e + + + "COMPONENT" + "Structures potentially involved in creating contact with the force plate during toe pad experiments." + 0888854b6766d37662902e4d32772d60 + 0 + 162 + 6090e736374d45fd84f0e4610a314f8f + + + "MEASURE" + "Values measured using miniature force plates for tree frog toe pads." + 0888854b6766d37662902e4d32772d60 + 0 + 163 + 0e8d921ccd8d4a8594b65b7fd19f7120 + + + "SPECIES" + "A species of gliding frog mentioned in the study, used for calculating adhesive and friction forces." + 0888854b6766d37662902e4d32772d60 + 0 + 164 + 59c726a8792d443e84ab052cb7942b4a + + + "COMPARISON" + "Supporting an argument suggesting toe pads are better developed for friction than adhesion based on observed data." + 0888854b6766d37662902e4d32772d60 + 0 + 165 + 4f2c665decf242b0bfcaf7350b0e02ed + + + "ORGANIZATION" + "Geckos are used in biomimetics studies for their unique abilities related to adhesion which inspire various material developments." + bc8c1b71a9bc00c67a64198dae0f5a42 + 0 + 166 + 66cdf168f36d4a57a505028c97dc06e0 + + + "PRODUCT" + "Materials or devices that replicate aspects of geckos' adhesion mechanisms, often focusing on van der Waals forces." + bc8c1b71a9bc00c67a64198dae0f5a42 + 1 + 167 + 38f51478f41f48db9bee570859b6f43e + + + "CONCEPT" + "Force responsible for the adhesion capabilities in gecko-inspired materials, enabling simple pillar structure design and construction." + bc8c1b71a9bc00c67a64198dae0f5a42 + 0 + 168 + 896d2a51e8de47de85ba8ced108c3d53 + + + "PRODUCT" + "Structured formations made of multiple pillars that mimic natural systems like geckos' toe pads or tree frogs' adhesive mechanisms." + bc8c1b71a9bc00c67a64198dae0f5a42 + 1 + 169 + 14555b518e954637b83aa762dc03164e + + + + + bc8c1b71a9bc00c67a64198dae0f5a42 + 1 + 170 + b1f6164116d44fe8b8f135d7f65b9e58 + + + + + bc8c1b71a9bc00c67a64198dae0f5a42 + 1 + 171 + c8b2408617804483b620e1a6691ac90d + + + "PROPERTY" + "E eff allows CNT forests to maximize contacts, increasing adhesion force." + c69e8300c5e976bc2e0c66e470f0371b + 0 + 172 + a5e0d1644eb547ba9a5c3211aac4631a + + + "MATERIAL" + "Shows shear adhesion of approximately 100 N cm−2, significantly higher than gecko foot-hairs." + c69e8300c5e976bc2e0c66e470f0371b + 0 + 173 + 5a28b94bc63b44edb30c54748fd14f15 + + + "PROCESS" + "Hinders CNT forest applications due to complexity and durability issues." + c69e8300c5e976bc2e0c66e470f0371b + 0 + 174 + f97011b2a99d44648e18d517e1eae15c + + + "MATERIAL" + "Has relatively low modulus, used widely for structured adhesives due to ease of handling and commercial availability." + c69e8300c5e976bc2e0c66e470f0371b + 0 + 175 + 35489ca6a63b47d6a8913cf333818bc1 + + + "TYPE" + "Built using PDMS micropillar arrays, showing remarkable decrease in effective modulus compared to flat surfaces." + c69e8300c5e976bc2e0c66e470f0371b + 0 + 176 + 5d3344f45e654d2c808481672f2f08dd + + + "MEASUREMENT" + "Affects pull-off forces and elastic energy dissipation during contact surface interaction." + c69e8300c5e976bc2e0c66e470f0371b + 0 + 177 + 6fb57f83baec45c9b30490ee991f433f + + + "FACTOR" + "Affects CNT forest applications, influencing adhesion forces based on height-to-side length ratio of pillars." + c69e8300c5e976bc2e0c66e470f0371b + 0 + 178 + 68762e6f0d1c41cd857c6b964a8e76c3 + + + "CONFIGURATION" + "Show a decrease in E eff with an increase in AR leading to higher contact and pull-off forces." + c69e8300c5e976bc2e0c66e470f0371b + 1 + 179 + 70634e10a5e845aa8c6a32fe7e8eb2b2 + + + "INSPIRATION" + "Illustrate adhesion dependence on pillar AR, showing potential reduction of force at high ARs due to pillar bending and clustering." + c69e8300c5e976bc2e0c66e470f0371b + 0 + 180 + 04085f7cf46544b79597fc49286ff84d + + + "APPLICATION" + "Typically exhibit small pillar height and channel width, likely for maximizing adhesive strength." + c69e8300c5e976bc2e0c66e470f0371b + 0 + 181 + d203efdbfb2f4b2a899abfb31cf72e82 + + + "CLASSIFICATION" + "Conventionally described as smooth, but may actually display complex structural features enhancing adhesion." + c69e8300c5e976bc2e0c66e470f0371b + 0 + 182 + 6731a665561840c2898ce8c9788e4c88 + + + + + c69e8300c5e976bc2e0c66e470f0371b + 1 + 183 + 4026806fa92f4e849a59a7f5c9a45c79 + + + + + c69e8300c5e976bc2e0c66e470f0371b + 1 + 184 + 68e0c60d2e8845d89d9d0ad397833648 + + + + + c69e8300c5e976bc2e0c66e470f0371b + 1 + 185 + 101572f552b54e529fe7765c05168981 + + + "ORGANIZATION" + "Tree frogs and bush-crickets refer to specific animal species which exhibit certain biological features and adhesive mechanisms.")<br>("entity" + 10f68536dac42a1fe1015b64ac551c32 + 0 + 186 + 60c58026b2764b40adffca6eaa31d6d9 + + + "GEO" + "micro-bulges refer to the structures on pillar tops that contribute to increased friction forces." + c08200d48689acf908730b5b5a937f1a + 0 + 187 + ad1595a78935472999444c9330e7730e + + + "MATERIAL" + "Polydimethylsiloxane that can be used in microstructures to improve mechanical properties and enhance adhesion." + cfd357f03ebd53bb7b20477337baa849 + 0 + 188 + 735d19aea0744b2295556841c5c4c3fd + + + "ORGANIZATION" + "Chen et al.'s team is involved in the research that examines different patterns of micro and nanostructures for understanding wet adhesion mechanics, as published in journals such as Phil.Trans.R.Soc.A.") + 56de28d5378ea95f859724f171540a25 + 0 + 189 + c725babdb14a485582f8fbdf95429030 + + + "PUBLISHING ORGANIZATION" + "This organization operates on the web, contributing to scientific publications and research dissemination." + 7959e16097062f8a4801b98295269a6a + 0 + 190 + a0047221896d418d849847d422fa4bb8 + + + "A SPECIFIC EXPERIMENT WAS CONDUCTED BY INCREASING RELATIVE HUMIDITY FOR OBSERVING ITS IMPACT ON SOLID-SOLID CONTACT RESISTANCE." + 5 + 7959e16097062f8a4801b98295269a6a + 0 + 191 + 98fc2ee593184c5a839454db4eec7013 + + + "THE REFERENCE TO A NAMED GROUP SUGGESTS A TEAM OF RESEARCHERS INVOLVED IN DESIGNING AND IMPLEMENTING THE LIQUID BRIDGE FORMING DEVICE." + 6 + 7959e16097062f8a4801b98295269a6a + 0 + 192 + 80020a1da63042459e00266b2a605452 + + + + + 7959e16097062f8a4801b98295269a6a + 1 + 193 + 31a7e680c4d54101afe4c8d52d246913 + + + + + 7959e16097062f8a4801b98295269a6a + 1 + 194 + 351abba16e5c448994c6daf48121b14d + + + "ORGANIZATION" + "This refers to a specific type of microchannel base bio-inspired patch that is being developed.") ("entity" + 2e431df92f1954d7fdf7449771dac2e1 + 0 + 195 + 50ea7d3b69614bcdbfbff7ddbfbf3d34 + + + "PERSON" + "Co-author with Barthlott W, Neinhuis C contributed to the study of purity and contamination issues related to biological surfaces." + e8c373a905cc6ee3e696c2eb69267455 + 1 + 196 + 004f40a5aeca48a1879db728eb12bcba + + + "PERSON" + "Sun J worked on nanomanufacturing bioinspired surfaces as presented in Tribol. Int." + e8c373a905cc6ee3e696c2eb69267455 + 1 + 197 + 4465efb7f6ed4dedad72a658184addd2 + + + "PERSON" + "Bhushan B is associated with Sun J's research and the field of nanotechnology." + e8c373a905cc6ee3e696c2eb69267455 + 1 + 198 + b0dd60e11dad4ff782623acf039b3948 + + + "PERSON" + "Karl Autumn authored multiple works related to gecko adhesion, including explanations on structure, function, and applications." + e8c373a905cc6ee3e696c2eb69267455 + 1 + 199 + db8c43fa4df947b09e5754d3b1393ead + + + "PERSON" + "Tobias Endlein contributed a study on wet adhesion in tree frogs which was part of an encyclopedia on nanotechnology." + e8c373a905cc6ee3e696c2eb69267455 + 1 + 200 + 5dabc4cd05da425cb194a04482bf0c29 + + + "PERSON" + "W. J.P. Barnes co-authored the work by Endlein on wet adhesion and has expertise in this area." + e8c373a905cc6ee3e696c2eb69267455 + 1 + 201 + 9d08f285a7be4c79b8f359c51d51db37 + + + "PERSON" + "Wilfred R Hansen, alongside Autumn K, provided evidence for self-cleaning in gecko setae as reported in Proc. Natl Acad. Sci." + e8c373a905cc6ee3e696c2eb69267455 + 1 + 202 + adffed660d154b519c1817e514e83096 + + + "PERSON" + "Nathaniel Crawford contributed research on self-cleaning mechanisms in tree frog toe pads without the need for grooming, as seen in J. Exp. Biol." + e8c373a905cc6ee3e696c2eb69267455 + 1 + 203 + b7e9c9ef572c445a9574ca571e41fb96 + + + "PERSON" + "Sun Hu alongside Lopez S and Niewiarowski PH co-authored a paper on dynamic self-cleaning in gecko setae through digital hyperextension." + e8c373a905cc6ee3e696c2eb69267455 + 1 + 204 + dcb9f281cd6248c699e0ebb285a42a5e + + + "PERSON" + "Co-author with Hu S, Lopez contributed to research on dynamic self-cleaning mechanisms in gecko setae." + e8c373a905cc6ee3e696c2eb69267455 + 0 + 205 + 072cdee531b74513984f49d99a8d64a0 + + + "PERSON" + "Participated alongside Hu S and Lopez S in the study of dynamic self-cleaning processes in gecko setae." + e8c373a905cc6ee3e696c2eb69267455 + 0 + 206 + 5ae335d9210a45fda3f92a9a028d6d9b + + + "PERSON" + "Zeng Xia, together with Hu S et al., explored digital hyperextension mechanisms for self-cleaning in geckos." + e8c373a905cc6ee3e696c2eb69267455 + 0 + 207 + 5ac60a941a5b4934bdc43d2f87de601c + + + + + e8c373a905cc6ee3e696c2eb69267455 + 1 + 208 + d405c3154d0e48ce96fad4c28fe20590 + + + + + e8c373a905cc6ee3e696c2eb69267455 + 1 + 209 + 7923d8521c744bd9aab131c1aea91ffd + + + + + e8c373a905cc6ee3e696c2eb69267455 + 1 + 210 + 5bd156c87ec44e19ae6f8f62e6e50b9d + + + + + e8c373a905cc6ee3e696c2eb69267455 + 2 + 211 + c1a146d7fb16429ea6d0aa2a55ee597f + + + + + e8c373a905cc6ee3e696c2eb69267455 + 1 + 212 + ede9350632084da5b0b577ff799ab14b + + + + + e8c373a905cc6ee3e696c2eb69267455 + 1 + 213 + ed559fb4ebde45518849ec803b350fa3 + + + + + e8c373a905cc6ee3e696c2eb69267455 + 1 + 214 + f422035f8b78417f98e4d116971cf9f3 + + + + + e8c373a905cc6ee3e696c2eb69267455 + 2 + 215 + c79d686eba044c5586c706cdc096817d + + + + + e8c373a905cc6ee3e696c2eb69267455 + 1 + 216 + 0f70db1e598d463fbbcdd1e288bd9490 + + + "ORGANIZATION" + "Research focuses on the toe pads of this species as a source for developing new biomimetically inspired reversible adhesives.")<br>("entity" + 4d8b21398c70d24c39cd26cfa1dba5c0 + 0 + 217 + b35c3d1a7daa4924b6bdb58bc69c354d + + + "PERSON" + "Aino T.'s research is focused on the high deformability of adhesive toe pads in White's tree frog, specifically through light and electron microscopic analyses.")|("entity" + 39bb4090056fa3afa0591e818ff2e48b + 0 + 218 + a97e2ecd870944cfbe71c79bc0fcc752 + + + "ORGANIZATION" + "This system is comprised of 24 separate 3D force plates to study single limb forces in climbing animals on a quasi-cylindrical tower.") ("entity" + a2e84db4531e11bb05a5e5cbdb285bb8 + 0 + 219 + 3e1b063bbfa9423d84e50311296d2f3c + + + "PERSON" + "Samuel DS contributes to research on metamorphosis and maturation in hylid tree frogs at the Journal of Zoology.") ("entity" + b57944edc55bf9a8ed604f132186cac1 + 0 + 220 + 9a8ce816ee954bdabd01ea2081538009 + + + "PERSON" + "Xue L contributed to research on bioinspired orientation-dependent friction as well as effective elastic modulus of structured adhesives.")|("entity" + 8d4a6778098c667728901fd5eb6ae286 + 0 + 221 + 09f18f81442d4d6d93a90f0fac683f9b + + + "PERSON" + "A is a co-author in the publication 'Microfluidic adhesion induced by subsurface microstructures' published in Science in 2007.") ("entity" + 221b04279ff2633a5d567aa14627c640 + 0 + 222 + e02be3e37ca0454883a4c1fd859c24bb + + + "PERSON" + "Author Berg is associated with the publication 'Use of biomimetic hexagonal surface texture in friction against lubricated skin', indicating expertise or contribution to research in this field." + cda9b37513bc2f8036dfff4a389184d7 + 0 + 0 + 1 + 223 + 6e0c81bef5364c988b21bf9b709d9861 + + + "TEAM" + "The team of authors includes contributors from various institutions who together have published a paper on 'Highly permeable skin patch with conductive hierarchical architectures inspired by amphibians and octopi for omnidirectionally enhanced wet adhesion', showcasing collaborative research effort." + cda9b37513bc2f8036dfff4a389184d7 + 0 + 0 + 1 + 224 + 1dbc51475cb04dafa4a8833a8378635e + + + "ORGANIZATION" + "The team of authors is associated with the publication in Advanced Functional Materials, suggesting that the paper has undergone peer review and was accepted for publication by this reputable scientific journal." + cda9b37513bc2f8036dfff4a389184d7 + 0 + 0 + 1 + 225 + c12b9ebd8b4e42b7896822a32e3fa6eb + + + + + cda9b37513bc2f8036dfff4a389184d7 + 0 + 0 + 3 + 226 + 27505f6ade4b4e5f9316ffe9c34821f7 + + + 1.0 + "Longjian Xue contributed significantly to bioinspired adhesive development through studying tree frog toe pad structures." + 2790f03c21ca0d9a522e2c1276ad4f6e + 0ee7db2c6bea4630ba9f0c25e8a967ad + 0 + 0 + + + 1.0 + "W. Jon P. Barnes co-developed biomimetic adhesives and friction-generating devices with inspiration from natural climbing mechanisms." + 2790f03c21ca0d9a522e2c1276ad4f6e + 5a6c1d15424149f69052cd8d91fbff75 + 1 + 0 + + + 1.0 + "The primary focus of research in this area involves replicating the complex structures found on tree frogs' toes to enhance material performance." + 2790f03c21ca0d9a522e2c1276ad4f6e + d005bf75c31d4848ad7041f39651e59c + 2 + 0 + + + 1.0 + "Bioinspiration has influenced the development of artificial adhesives and devices by providing natural solutions for their design." + 2790f03c21ca0d9a522e2c1276ad4f6e + 9b3eef8f3a3a45e6873838db95295b8a + 3 + 0 + + + 1.0 + "The study of adhesive mechanisms in nature, especially from climbing animals, serves as a fundamental source of information for bioinspired material advancements." + 2790f03c21ca0d9a522e2c1276ad4f6e + fdc954b454744820804d7798f3e0b5de + 4 + 0 + + + 1.0 + "Inspired by the biological adhesion properties of geckos, leading to advancements in material science and engineering applications." + bc8c1b71a9bc00c67a64198dae0f5a42 + 49c1383836934ec495c3b35769100a73 + 5 + 0 + + + 1.0 + "Young's modulus of different materials influences the effectiveness and stability of pillar array designs used for biomimetic adhesive development." + bc8c1b71a9bc00c67a64198dae0f5a42 + 859dedcc3736439a8a563419f16cb3d8 + 6 + 0 + + + 1.0 + "Based on polydimethylsiloxane, a material known for its ease of handling and commercial availability." + c69e8300c5e976bc2e0c66e470f0371b + 6078b9980a6c4dcd9198d151b833ead7 + 7 + 0 + + + 1.0 + "Affects adhesion forces in hexagonal pillar configurations via AR calculations." + c69e8300c5e976bc2e0c66e470f0371b + f93cd6b8213e46dda67af7e5382e1bd2 + 8 + 0 + + + 1.0 + "publishing organization is responsible for releasing scientific studies or findings like this study on tree frog-inspired adhesion." + 7959e16097062f8a4801b98295269a6a + 496f17c2f74244c681db1b23c7a39c0c + 9 + 0 + + + 1.0 + "C was co-author with Barthlott W on work concerning purity and contamination issues related to biological surfaces." + e8c373a905cc6ee3e696c2eb69267455 + da1684437ab04f23adac28ff70bd8429 + 10 + 0 + + + 1.0 + "Sun J is an author of the paper on nanomanufacturing bioinspired surfaces in Tribol. Int." + e8c373a905cc6ee3e696c2eb69267455 + 4517768fc4e24bd2a790be0e08a7856e + 11 + 0 + + + 1.0 + "Is associated with Sun J's research and the field of nanotechnology as a co-author or author." + e8c373a905cc6ee3e696c2eb69267455 + 545edff337344e518f68d1301d745455 + 12 + 0 + + + 1.0 + "Karl Autumn is an author of works on gecko adhesion, including structure, function, and applications." + e8c373a905cc6ee3e696c2eb69267455 + 9376ce8940e647a99e5e087514b88fa4 + 13 + 0 + + + 1.0 + "Tobias Endlein contributed to the study on wet adhesion in tree frogs as part of a broader work on nanotechnology." + e8c373a905cc6ee3e696c2eb69267455 + b38a636e86984600bb4b57c2e2df9747 + 14 + 0 + + + 1.0 + "W. J.P. Barnes co-authored research with Endlein and likely has expertise in biological adhesion mechanisms." + e8c373a905cc6ee3e696c2eb69267455 + 4bc7440b8f4b4e4cae65a5c49defa923 + 15 + 0 + + + 1.0 + "Wilfred Hansen, along with Karl Autumn, provided evidence for self-cleaning gecko setae." + e8c373a905cc6ee3e696c2eb69267455 + 5d1b038ce8be4533b54dd79d6496de9b + 16 + 0 + + + 1.0 + "Nathaniel Crawford contributed research on self-cleaning mechanisms in tree frog toe pads as part of J. Exp. Biol." + e8c373a905cc6ee3e696c2eb69267455 + ac6e5a44e0c04a4fa93589376fde4c34 + 17 + 0 + + + 1.0 + "Sun Hu co-authored the study with Lopez and Niewiarowski on dynamic self-cleaning in gecko setae using digital hyperextension." + e8c373a905cc6ee3e696c2eb69267455 + 40e4ef7dbc98473ba311bd837859a62a + 18 + 0 + + + 1.0 + "Barthlott W contributed to studies on purity and contamination of biological surfaces in Planta." + e8c373a905cc6ee3e696c2eb69267455 + 222f0ea8a5684123a7045986640ec844 + 19 + 0 + + + 1.0 + "Author Berg is directly linked to the publication 'Use of biomimetic hexagonal surface texture in friction against lubricated skin', indicating a specific contribution or lead authorship to this research work." + cda9b37513bc2f8036dfff4a389184d7 + 668cf1fdfd644d39acc6350b86117ea2 + 20 + 0 + + + 1.0 + "The team of authors collectively contributed to the publication 'Highly permeable skin patch with conductive hierarchical architectures inspired by amphibians and octopi for omnidirectionally enhanced wet adhesion', highlighting their collaborative effort in advancing biomimetic research." + cda9b37513bc2f8036dfff4a389184d7 + 478e4c72d8fb46dd8cc9f0691c9878fd + 21 + 0 + + + 1.0 + "The publication 'Highly permeable skin patch with conductive hierarchical architectures' was published in this journal, indicating that the research meets high standards for originality and scientific rigor as required by peer-reviewed journals." + cda9b37513bc2f8036dfff4a389184d7 + 82b0446e7c9d4fc793f7b97f890e9049 + 22 + 0 + + + \ No newline at end of file diff --git a/indexing/output/20240722-073448/artifacts/create_base_documents.parquet b/indexing/output/20240722-073448/artifacts/create_base_documents.parquet new file mode 100644 index 0000000000000000000000000000000000000000..39aba5d602128c6932ec716b77fff5ad65f1342b --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/create_base_documents.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62e0b2b281f6fbbc98875dfb5b07ff8632f8b1cb69f4feee3ee0347541957328 +size 138709 diff --git a/indexing/output/20240722-073448/artifacts/create_base_entity_graph.parquet b/indexing/output/20240722-073448/artifacts/create_base_entity_graph.parquet new file mode 100644 index 0000000000000000000000000000000000000000..5705cfc47bac4f8f968d0a80b95fc29b8891cf30 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/create_base_entity_graph.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:066b4d03032e34486ebea0b9055c354cdd94d644bb79f6db8105b7884cd1b3ff +size 46719 diff --git a/indexing/output/20240722-073448/artifacts/create_base_extracted_entities.parquet b/indexing/output/20240722-073448/artifacts/create_base_extracted_entities.parquet new file mode 100644 index 0000000000000000000000000000000000000000..21e4632a2ccb42d67b2cd03e71ba408c49d1a402 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/create_base_extracted_entities.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11ebfe220abe00289426e6c753b3e458a3ae69fb4dca024d66e768d8614a57b2 +size 32918 diff --git a/indexing/output/20240722-073448/artifacts/create_base_text_units.parquet b/indexing/output/20240722-073448/artifacts/create_base_text_units.parquet new file mode 100644 index 0000000000000000000000000000000000000000..57e5a495f8b6bd6ded14eb05e0d84c1ca51a20d7 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/create_base_text_units.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcb26c69fe50b40e53858051699ca848d827d44d1294fbefb15e6f069bbcc75e +size 154889 diff --git a/indexing/output/20240722-073448/artifacts/create_final_communities.parquet b/indexing/output/20240722-073448/artifacts/create_final_communities.parquet new file mode 100644 index 0000000000000000000000000000000000000000..3a42a91390e105b18125ff9da32abe9d08eeb1e2 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/create_final_communities.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd7db6e13e1ac57d8c784e19978842dbfc3d0b2118580f93b23eb7274de5f0fe +size 5348 diff --git a/indexing/output/20240722-073448/artifacts/create_final_community_reports.parquet b/indexing/output/20240722-073448/artifacts/create_final_community_reports.parquet new file mode 100644 index 0000000000000000000000000000000000000000..e08d12b2dbcd79525e96038663dc5664a4ffab3c --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/create_final_community_reports.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:797a4d3b95d805b55e8e7b4c709b9dc7717ab5397002b87ba4b4da8d99879cff +size 7705 diff --git a/indexing/output/20240722-073448/artifacts/create_final_documents.parquet b/indexing/output/20240722-073448/artifacts/create_final_documents.parquet new file mode 100644 index 0000000000000000000000000000000000000000..95be351f5c0695aba11b337582950024c44500ec --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/create_final_documents.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:705683499cde4b037fd45a85a5f6b12a23ff1c10b236a5917ef6a4a6c5275307 +size 138744 diff --git a/indexing/output/20240722-073448/artifacts/create_final_entities.parquet b/indexing/output/20240722-073448/artifacts/create_final_entities.parquet new file mode 100644 index 0000000000000000000000000000000000000000..8046e973726540e305a25ebb771b8044ae6ea3c0 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/create_final_entities.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b3d336c6c2abf946520657fbfdb5621ad22534627afb284dbd7abe29cc54e2e +size 1410540 diff --git a/indexing/output/20240722-073448/artifacts/create_final_nodes.parquet b/indexing/output/20240722-073448/artifacts/create_final_nodes.parquet new file mode 100644 index 0000000000000000000000000000000000000000..9352c4dda678bdb15372d91eaae8978008eb5004 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/create_final_nodes.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcef593069420c4068e74ed7d0a38e3cd661a5f5099ccb4d1eeec4bded13446b +size 58888 diff --git a/indexing/output/20240722-073448/artifacts/create_final_relationships.parquet b/indexing/output/20240722-073448/artifacts/create_final_relationships.parquet new file mode 100644 index 0000000000000000000000000000000000000000..37279c955e59b9cbf23cf959b77dd43fa9daa816 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/create_final_relationships.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb095885730f4150f8ffffa5480f81363fba3f028d471b1f5e0ab707f8a0d50a +size 12499 diff --git a/indexing/output/20240722-073448/artifacts/create_final_text_units.parquet b/indexing/output/20240722-073448/artifacts/create_final_text_units.parquet new file mode 100644 index 0000000000000000000000000000000000000000..d68d0acaeaf14bcbabc12dc1f8985bee87037627 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/create_final_text_units.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2fcf170c4639d8d932576955fea9a0b6ef7b7b2c9b93aab7010868bfbf8a1c6c +size 162361 diff --git a/indexing/output/20240722-073448/artifacts/create_summarized_entities.parquet b/indexing/output/20240722-073448/artifacts/create_summarized_entities.parquet new file mode 100644 index 0000000000000000000000000000000000000000..fb01e78d89c14649bfaefc1967dc5a79f17bfe20 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/create_summarized_entities.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:814af547c34772e8fa1cb8aac4fe939b0222e807ebbfc498a88444bc543e7426 +size 34437 diff --git a/indexing/output/20240722-073448/artifacts/embedded_graph.graphml b/indexing/output/20240722-073448/artifacts/embedded_graph.graphml new file mode 100644 index 0000000000000000000000000000000000000000..cba68a608e6a1c455030609a16febf5c12cb70c9 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/embedded_graph.graphml @@ -0,0 +1,1280 @@ + + + + + + + + + + "ORGANIZATION" + The AskNature Team, associated with the entity named "ASKNATURE TEAM", is dedicated to creating educational content about living systems, which notably includes information about birds. Their work encompasses not only the creation of such materials but also involves cataloging knowledge on biomimicry and natural strategies like 'Spiral Fibers'. As a research-focused group, the AskNature Team conducts programs aimed at understanding nature's solutions for various applications in technology, design, and problem-solving processes, effectively bridging human innovation with ecological wisdom. + 30aa281b7ea0845a9f88c0914df109c3,4305d6610a2538765dc1ea9aed78ea5e,a3d83dc700d8d01b07a94c2a1180c2b4 + + + "PROCESS" + "The process by which birds inhale and exhale air through their respiratory system for oxygen intake and carbon dioxide expulsion.") ("entity" + a5430820e1ece1dff536ad804e55c798 + + + "PERSON" + "ANDY CARSTENS" refers to an author dedicated to exploring natural phenomena, with a notable focus on innovations inspired by nature. One of his works highlights the biological strategy adopted by birds utilizing ground effect to minimize drag and conserve energy while gliding over water, showcasing his deep interest in understanding and explaining the intricacies of natural behavior and engineering. + 4d6faade61b11859190946a315c34a2e,8afa448acb86b96422cea043f3fd6749 + + + "ORGANISM" + "The Flying squirrels are the subject of study due to their ability to control their glide." + 638dc502f70bb90aeb0465be8db1facc + + + "ORGANIZATION" + The Biomimicry Institute is an organization centered on studying natural principles to address human challenges, promoting sustainability in design and technology through innovation inspired by nature. As a copyright holder, it specializes in finding solutions based on the strategies observed within ecosystems and operates through platforms like AskNature for disseminating educational content about nature-based innovations. The institute's primary objective is to educate and provide biological strategy insights for human design applications, specifically focusing on understanding and replicating mechanisms found in nature to enhance human technologies, such as observing glide behaviors of flying squirrels and applying that knowledge to improve areas like parachutes or skydiving suits. This organization behind Biomimicry.org provides comprehensive information and guidance on how to utilize nature's problem-solving methods within various sectors of human technology development. + 4d6faade61b11859190946a315c34a2e,74a8b683e829577d39bd3b12018ddee0,75be22a096d450ebe20ed42f79da45da,7c777850b39440dea33d9b60641e803b,809da8a35547ca53620a67d4f1cdb6f5,891d3f28f888b374a21d9c781295bbf9,90ede7f9f06fa68f01d8528ec2495d4b,e9161c0416f80b08625e2dcd9f70167f + + + "PERSON" + "This refers to researchers who contributed to a study on gliding performance of mammals, particularly northern flying squirrels (Glaucomys sabrinus)." + a3d83dc700d8d01b07a94c2a1180c2b4 + + + "ORGANISM" + "The Black-tailed prairie dog is an animal that builds extensive burrows in the plains of North America and performs functions like distributing gases." + a3d83dc700d8d01b07a94c2a1180c2b4 + + + "CREATIVE WORKER" + "This refers to a photographer whose image has been used in publications related to nature studies, with permission granted for use." + a3d83dc700d8d01b07a94c2a1180c2b4 + + + "ORGANIZATION" + "AskNature.org, a component of the Biomimicry.org platform, serves as an online resource for users seeking to explore and apply natural strategies in their innovations. This unique website presents knowledge and tools related to nature-based solutions and biomimicry with a focus on heliotropism, the movement of plants towards the sun. As part of this mission, Lonny Lippsett shared insights on self-organization within diverse soil ecosystems on the AskNature.org platform. + +AskNature.org is dedicated to facilitating biologically inspired innovations by showcasing effective biological strategies that can help solve human challenges through nature's principles. This resource platform features a variety of organisms and ideas that have been adopted from natural systems, aiming to provide inspiration for sustainable problem-solving and design across multiple fields." + +Please note that there seems to be some confusion or inconsistency in the descriptions provided about whether 'AskNature' is one entity (AskNature.org) or if it refers to two distinct entities ('AskNature.ORG' and 'Asknature.org'). However, based on the context given and assuming a single entity for consistency, this summary provides an accurate synthesis of the provided information. + +If you need further clarification or another interpretation, please specify so I can assist better! + 0a71d2671ba6b6bceb2f13e60122c278,10a8260a1ac5e4f2ab531d67e534b83f,3678ab8d2bad24bba44d0a83fe09f8a6,42b463f5b40c4f86e9338c967c8d5bfa,75be22a096d450ebe20ed42f79da45da,fb3016519d20d8e4fc1d25d5690a550a + + + "PERSON" + "Sam Rivera appears to be associated with an unspecified organization that specializes in biological research, with a particular emphasis on adhesive mechanisms found in nature. This involves studying and understanding these natural adhesion properties which might have various applications or areas of interest. Although the exact location of this organization is not explicitly stated, it's suggested they are involved in projects conducted in Saudi Arabia where echolocation techniques are utilized for food searching. The research also includes interaction with an Egyptian fruit bat as part of these studies. Despite being mentioned in relation to an organization and these specific activities, the description contradicts itself by stating that Sam Rivera is 'not mentioned' in the provided real data." + 777a1482c060a064af315a8488df370a,b01ac6d637b8d31e396081208c8162d0,d99568b2216b6501020a719efe70edaf + + + "ORGANISM" + "A species of frog specifically adapted to living in water-filled tree hollows, utilizing their environment to amplify vocal calls.|) ("entity" + aff4d366caa94978fbabd1021d43d555 + + + "SPECIES" + "Specific types of snakes known for their unique ability to create loud defensive sounds." + 4d6faade61b11859190946a315c34a2e + + + "ACTION" + "Visiting a specific strategy on AskNature for investigation into interactions between vortices and trout. The website provides scientific articles related to the topic." + 8fa82d96bb00621623d0d7c9e9ac5034 + + + "OBJECT" + "Butterfly wings are a natural model that shows how micro-geometrical patterns enhance airflow and facilitate flight through specific scale configurations.") ("entity" + 01117b72383429324254870387eb4aba + + + "BIOLOGICAL STRATEGY" + "The micro-geometry of butterfly wing scales provides insights into designing efficient wind turbines, improved structural stability in tall buildings, and more." + 5bec096731ec31b017777a7aadf747bc + + + "ORGANIZATION" + "The Diving Bell Spider serves as a biological inspiration for technological innovations in air supply and water-resistant materials." ) ("entity" + 81eee876cafa81ab3b11ed19cc045cb6 + + + "PERSON" + "Roger S. Seymour is an author who contributed to the Journal of Experimental Biology in 2011.") ("entity" + eedd4bc29a0007151fb16d1deec2f9eb + + + "ORGANIZATION" + "Spiders use trichobothria for sensing and movement control in hunting and navigating their environment." + 3d22053debaab18c4e321d4cfe15f8af + + + "CONCEPT" + "Trichobothria are sensory structures on spiders’ legs that enhance their sensitivity to touch, vibrations, and motion." + 3d22053debaab18c4e321d4cfe15f8af + + + "EVENT" + "The hypersensitivity provided by trichobothria allows spiders to detect underwater currents or the presence of sea life." + 3d22053debaab18c4e321d4cfe15f8af + + + "CONCEPT" + "Spiders use information from their environment, like the activity of other organisms and environmental cues, for hunting, navigation, and self-defense." + 3d22053debaab18c4e321d4cfe15f8af + + + "ORGANIZATION" + "The concept of integrating spider's sensory capacity into wearable devices or clothing could improve motion detection beyond human vision." + 3d22053debaab18c4e321d4cfe15f8af + + + "WEBSITE" + "Website for the organization Biomimicry Institute, providing information about strategies found in nature and how they can be applied." + 75be22a096d450ebe20ed42f79da45da + + + "PERSON" + "A researcher contributing his expertise in the biological strategy related to spiders and electric currents for biomimetics applications." + 75be22a096d450ebe20ed42f79da45da + + + "PERSON" + "The individual credited with discovering or understanding how certain spiders fly using electrostatic repulsion, possibly contributing knowledge to biomimetic engineering." + 75be22a096d450ebe20ed42f79da45da + + + "PERSON" + "A contributor or researcher who provided insights or evidence supporting the spider flying phenomenon, influencing scientific community." + 75be22a096d450ebe20ed42f79da45da + + + "PERSON" + "A researcher involved in the study that shed light on spiders' use of electrostatic forces for flight, providing significant biological data for biomimetics." + 75be22a096d450ebe20ed42f79da45da + + + "EVENT" + "Spiders were observed to exhibit 'balloon' like flight in low wind conditions due to atmospheric electric fields.") ("entity" + 621c0cd608f4ed99a4dd7a5c25c8e0b5 + + + "PERSON" + "Mary Hoff authored a strategy on AskNature explaining how water striders communicate using vibrations and their legs.") ("entity" + 60d4060427254b2a553815d05dce7fcf + + + "ORGANISM" + "A species of insects that communicate through tapping the water surface and have highly sensitive motion-detecting structures on their legs.") ("entity" + bd3e8fcd1e1991500d9610859ecfabf4 + + + "PERSON" + "Pablo Perez is responsible for inventing devices that provide advanced warning of impending earthquakes or mudslides, possibly inspiring new technology.") + f228fcbbb8f2ec33599ea9a3d5d4e854 + + + "PERSON" + "He created an image for this document under CC BY-SA license.") ("entity" + 1ff6815fa5511debe6f17ad17c1707b1 + + + "ORGANISM" + "Plants use strategies like tropisms (gravitropism, thigmotropism, phototropism, heliotropism) to adapt and respond efficiently to their environment.") ("entity" + c8455055703093614be4105105a67f0e + + + "PERSON" + "Peter Prehn, a contributor to Biomimicry Institute and AskNature.org, explains the underground network strategy of mycorrhizal fungi in a Douglas-fir and pine forest context.") ("entity" + 2defde0504bd9c1a5bdd248980ce1ce1 + + + "ORGANISM" + "Mycorrhizal fungi form mutualistic partnerships with trees and other plants, facilitating nutrient exchange and communication through the Wood Wide Web.") ("entity" + dbf85def96906b82d29e7bcd512b920f + + + "CONCEPT" + "A network formed between the roots of plants and fungi, facilitating resource exchange, information sharing, and mutual support among plant communities.") ("entity" + ac3f4943aac0de17b70d54bf387fe19b + + + "PERSON" + "Lonny Lippsett wrote about biological strategies performed by organisms living in soil ecosystem, particularly focusing on self-organization." + 0a71d2671ba6b6bceb2f13e60122c278 + + + "ORGANIZATION" + "This refers to the diverse ecosystem that works together to break down organic matter and recycle it into nutrients for plants to reuse.")<|"\n"|"Entity" + 17c65307eb89a2d2f26db3e34ba78722 + + + "EVENT" + "AN-Bird Respiration_Final_05-2022 refers to a document that discusses bird respiration process which is being finalized in the month of May 2022.") ("entity" + 03018b77601ad2b2e8345af35fb84450 + + + "CONCEPT" + "It is a system of classification developed by the Biomimicry Institute for organizing biological content on their website AskNature.org. This taxonomy categorizes strategies that organisms and natural systems use to meet functional challenges. The strategies are classified according to functions, which describe what the strategy accomplishes for the organism or living system. This helps users identify potential solutions to similar human challenges by looking at nature's approach to solving issues.") + ff760235e3461c93ff1fa2bee432fdb1 + + + "ORGANIZATION" + "AskNature is an online platform providing access to strategies and insights from natural systems for design solutions." ) ("entity" + e4b6193a4ea13cb8c682998eb02efb6d + + + "BIOMIMICRY TAXONOMY" + "ORGANIZATION" encompasses diverse functions across various fields: + +1) Serving as a database central to bibliometric analysis, this entity supports researchers and academics by facilitating the discovery of pertinent publications and fostering an understanding of academic trends. + +2) In addition to its role in bibliometrics, "ORGANIZATION" is recognized for publishing research journals like 'Phil.Trans.RoyalSoc.A', making it both a publisher and an academic organization. + +3) It plays an innovative role in biomimicry through the Biomimicry Taxonomy framework. This entity helps drive innovation by identifying new verbs and related concepts, encouraging the application of nature-inspired solutions that foster creative activities involving interdisciplinary knowledge. + +4) Engaging with themes linked to sustainability, "ORGANIZATION" is dedicated to understanding ecological systems and their transformations as well as the services they offer, defining it as a part of CTU (Centre for Teaching and Understanding). + +5) As an entity involved in studying ecosystem dynamics, it collaborates on diverse themes including the physical state modifications and services provided by ecosystems. + +6) Notably, "ORGANIZATION" also includes NC 4.0, which might represent either a specific program or organization focused on creative license or collaborative efforts. + +In summary, this multifaceted entity acts as both a database for scholarly research analysis and dissemination, alongside a publisher of academic journals. It is pivotal in fostering innovation through nature-inspired solutions and contributes to ecological studies centered around sustainability. Moreover, it collaborates with diverse stakeholders under themes like creative activities and is involved in the exploration of ecosystem dynamics. + 170684a57b4848b420032214260ee67b,23c34b74899c04c60dc7b087b88e0137,3b302bec9259fbca0cf68da76392935c,44c8dff86ecf90b601e21ef2335e8c61,6de0fc3cc6011a0ce9267a0584f498b2,84d05d265cebbc1d33e9d523b860d87e,a19c62053cac11a3e022402443eeba83,dd615bbb350414d251cb1083b3142230,fe902bcadf86addbe747f348c1ccc56f + + + "H" + "H could represent any individual within an organization or group dealing with eco-system management, focusing on behaviors optimization, space/material adaptation, and coordination with other groups." + 170684a57b4848b420032214260ee67b + + + "PERSON" + "Alex is the leader of a team attempting first contact with an unknown intelligence, acknowledging the significance of their task." + 2b9b282e75a0a5345cc0cee8f327a2b1 + + + "ORGANIZATION" + "BOHsihana is involved in the process of attempting to communicate with an unknown intelligence through their technological means and research." + 3b8a807b256d918245b0ffb8c88d4c09 + + + "PERSON" + "A biomimetics researcher at the Department of Design, University of Brasília, who has contributed to studying the application and integration of biological knowledge in design.")|("entity" + 7323cecb72b3fa0472a26a5aa37c4131 + + + "PUBLICATION" + "Biomimetics 2023" refers to a journal that focuses on sharing insights and research related to biomimetics in the year 2023. It published a study contained within volume 8, issue number 61 of the publication titled 'Biomimetics'. This article explores thematic aspects associated with design and biomimicry, emphasizing product conception and structural explorations of nature for new materials that contribute to sustainability while conserving resources. The journal's interest lies in showcasing how creative tools are applied in product design to achieve environmental responsibility." + 2aee03ca69624bff0ae2d030f6f31e19,7982a2e4054b66ae19457bde8585eaa8,af3fc23c5069edd0bdffd8f9a64d3ab2,b23a7cb845fd949e0baab80bf6f0c4f8 + + + "CONCEPT" + "Biological concepts or ideas that are mimicked by humans in various fields, often for innovation and problem-solving.") ("entity" + 6e87b92e6c843cb54a008ae676d3b416 + + + "CONCEPT" + "Imitative or biomimetic design that draws on concepts found in nature to solve human challenges and promote sustainability.") + a43faaba2ebb888387d5b0f59efb6381 + + + "JOURNAL" + "Biomimetics is a comprehensive field of study that draws inspiration from nature's principles to address intricate human challenges. It focuses on exploring and emulating natural systems for solving engineering problems, which involves developing new materials and devising innovative devices based on biological concepts. This field studies both existing natural designs and presents analyses on design and architecture topics, as exemplified by the publication Biomimetics from the late 1990s." + 2790f03c21ca0d9a522e2c1276ad4f6e,b3c5de72ae4c784c9fef28c432a247eb,bc8c1b71a9bc00c67a64198dae0f5a42,d1f202cadb144570739c718437dd9c7b + + + "ORGANIZATION" + "The Procedia Social and Behavioral Sciences is an academic journal that published 5 articles.") ("entity" + 17a811ea2375e85ee164ddd52dbe5a80 + + + "EVENT" + "The article discusses the evolution of reaction centers that mimic photosynthesis for fuel production and water conversion processes." + b315f4391fd31deebdefc7e4496ccc53 + + + "AUTHOR" + "Bhushan conducted research emphasizing biomimetic studies at micro and nano scales, focusing on creating designs inspired by biological surfaces and materials.") ("entity" + bc2123b5f86d53a8b6c4f35594131571 + + + "ORGANIZATION" + "An organization that works in a field related to sustainable design and research, focusing on biomimicry." + c16a050b9f05d4adcbe87cd85974f73b + + + "CONCEPT" + "A central theme in the works of 'The St Works Study' which deals with bio-based innovations, specifically biomimicry." + c16a050b9f05d4adcbe87cd85974f73b + + + "CONCEPT" + "MIMICRY" is the central theme encompassing the core concept behind studies and developments initiated by 'The St Works Study'. This approach leverages principles sourced from nature to address challenges and foster innovations. Additionally, it denotes a practical utilization of biomimetic traits in design, drawing inspiration from natural phenomena and forms. Consequently, "MIMICRY" embodies an integrated methodology that combines ecological insights with creative problem-solving strategies and design innovation. + 30c01680c32c27bbf40c2879200bb4ca,c16a050b9f05d4adcbe87cd85974f73b + + + "PERSON" + "E.O. Wilson is known for conceptualizing nature as a model, measure, and mentor agent capable of generating efficient systems. He also encourages transferring natural knowledge to human contexts particularly in dealing with issues like waste management.") ("entity" + 10357a9455875b5f9c5deca2d9871135 + + + "PERSON" + "Pawlyn is associated with work showcasing biomimicry and architecture interconnections, highlighting sustainable and innovative construction methods, particularly for restoration purposes.") ("entity" + b8f2d8b6f8181c950be1341e09d5f6ac + + + "PERSON" + "These authors are responsible for the concept of designing with a focus on effectively having a positive impact on the environment.") ("entity" + 50d87eb794de75e87a2b0897c5432e39 + + + "ORGANIZATION" + "The organization is involved in the research and functional analysis of natural and artificial systems using biomimetic approaches." + ea3022e7c889776437eec7e0ff1e3b2c + + + "ORGANIZATION" + "The organization involved is a research institute or department that focuses on sustainable architecture and design.") + e01fbf716e63081d999f9f22c28e098a + + + "GEO" + "Climate is a subject associated with the adaptation and systems at ecological level, involving technical solutions, especially in the face of climate crisis." + 3cafe8221f0d2b661270f9e33c59993d + + + "PERSON" + "A Researcher who specializes in biomimetics studies different organisms' abilities to identify two words which appear together frequently") + 4c8d34a6cb7efcbac85f88b2fbb3973e + + + "ORGANIZATION" + "Entomology is a field of study which focuses on the organisms, especially insects.")|("entity" + 5bb96e57d4c79ea40feeb5ecb3296afe + + + "GEO" + "This includes various designs and studies across architecture.")|("entity" + 439722d75181e1aa687e95df70e09d63 + + + "OBJECT" + "This represents a map created using data from the Web of Science, covering publications from 2018 to 2021. The map visually represents bibliographic coupling between documents." ) ("entity" + 8d7e6e7209519d7dec8948a364fdbab2 + + + "EVENT" + "An opportunity for redesigning materials, processes, and products that may inherently link with nature through their properties and functionality." + 30c01680c32c27bbf40c2879200bb4ca + + + "ACTION" + "The act of redesigning materials, processes, and products to improve efficiency or sustainability." + 30c01680c32c27bbf40c2879200bb4ca + + + "ASPECT" + "A connection or relationship between the designed elements and natural principles or systems." + 30c01680c32c27bbf40c2879200bb4ca + + + "CONTEXT" + "Environmental changes that influence the functionality of kinetic architectural elements." + 30c01680c32c27bbf40c2879200bb4ca + + + "CONCEPT" + "A model where resources are kept in use for as long as possible, extracting maximum value while minimizing waste."> + 30c01680c32c27bbf40c2879200bb4ca + + + "ORGANIZATION" + "Tate et al. are a team who reviewed relationships of mutualism found in nature and contributed to the recognition of biomimicry as an area useful for strategic planning in companies." + f770903009c82b1aeca7bf9e490877ad + + + "EVENT" + "The introduction of innovative concepts that integrate ecosystem services to support biodiversity and natural environment resilience against climate change.")|("entity" + f5fd896ed0c59d47158db316fad680dc + + + "ORGANIZATION" + "The Web of Science is a comprehensive database used for academic research that may limit the accessibility or dissemination of certain works based on specific criteria." + 916f17bde39ae650dad1b657a1887fa6 + + + "PERSON" + "A.A.M.D.S." refers to the primary individual responsible for conceptualizing the study, developing its methodology, and contributing as a co-author alongside D.M.V. This entity has notably worked on an exploration of biomimicry's application and significance in design processes. + 7982a2e4054b66ae19457bde8585eaa8,f8d611d2f89f42ca1550ee673a05d4dd + + + "PERSON" + "D.M.V contributes to software development, formal analysis of data, validation, investigation, resource gathering, supervision of the project." + 7982a2e4054b66ae19457bde8585eaa8 + + + "CONCEPT" + "A structured description of each authors' contribution to the research process, from conceptualization to final review." + 7982a2e4054b66ae19457bde8585eaa8 + + + "EVENT" + "Planning and ideation phase for the study conducted by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "EVENT" + "Process of planning how experiments or research will be designed and executed, carried out by A.A.M.d.S. and D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TOOL" + "A.A.M.d.S utilized software tools for various tasks during the study's execution." + 7982a2e4054b66ae19457bde8585eaa8 + + + "EVENT" + "The process of confirming the accuracy or truthfulness of research findings, carried out by A.A.M.d.S. and D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TECHNIQUE" + "Careful examination and interpretation of data or concepts using systematic methods" + 7982a2e4054b66ae19457bde8585eaa8 + + + "ACTIVITY" + "Research conducted to gather information, performed by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TOOL" + "Materials or assets used in the study which were collected or provided by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "PROCESS" + "Organization and management of data throughout its lifecycle, responsibility of A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TASK" + "The initial writing phase where the first version of a paper or report is drafted by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "ACTIVITY" + "Process to refine and correct content, undertaken by both A.A.M.d.S. and D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TECHNIQUE" + "Representation of data or concepts through graphical means, performed by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "ROLE" + "Overseeing the research project's progress and ensuring quality control, done by D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + + + "PERSON" + "MacKinnon R.B., J.Oomen, M.P.Zari are authors in the paper 'Promises and Presuppositions of Biomimicry' contributing to the field of biomimetics.")<br>("entity" + ab0129037f27d2a0b3230e695cb66703 + + + "PERSON" + "Cohen is the author who wrote 'Biomimetic Design Method for Innovation and Sustainability' in Springer")|("entity" + 71820a84991aa839263c1542540c3d9a + + + "PERSON" + "Author of the book 'Biomimicry', exploring innovation inspired by nature.")|("entity" + d9c59b517b2e653c7c9cb7efb130c9b0 + + + "ORGANIZATION" + "CrossRef is a not-for-profit membership organization that operates several databases for scholarly journals and books." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Michael Cutkosky is the author of one paper discussing the design and fabrication of multi-material structures for bioinspired robots." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This is a journal published by The Royal Society which features scientific papers in mathematical, physical, engineering sciences, life sciences and information science." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Jorge Mendoza is an author of one paper discussing the integration of backcasting and eco-design for the circular economy using a framework named BECE." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal focuses on issues in environmental sustainability, green business strategies, and sustainable development." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Ben D. Sherman is an author of one paper discussing the evolution of reaction center mimics for systems capable of generating solar fuel." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal publishes scientific papers about photosynthesis and related fields such as biochemistry, genetics, ecology, and physiology of plants and algae." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Samantha N. Sponberg is an author of one paper discussing templates and anchors for antenna-based wall following in cockroaches and robots." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal publishes research articles on robotics theory, experimentation, applications, and design, including topics like autonomous robots and robot systems." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Qingyuan (Q.) Xu is an author of one paper discussing biomimetic self-cleaning surfaces." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Mehrnaz Zari is the author of a paper discussing biomimetic design for climate change adaptation and mitigation." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal covers various scientific fields including architecture, physics, engineering sciences, life sciences, and information science." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Michael Helms is an author of a paper discussing biologically inspired design: process and products." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal publishes academic studies on design including issues related to cultural, social and psychological aspects of designing processes and artifacts." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Mark Pawlyn is the author of a book titled 'Biomimicry in Architecture' which focuses on principles of biomimicry as applied to architectural design." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Amir Chakrabarti is mentioned with his involvement with other researchers in one paper discussed." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Mawson Pawlyn is the author of 'Biomimicry in Architecture', showcasing expertise and insight into architecture that draws inspiration from natural systems.") ("entity" + 70bfef2ab1bf8bc9a6db2cd5ae212340 + + + "PERSON" + "Ying Xing is the author of 'Exploring design principles of biological and living building envelopes: What can we learn from plant cell walls?' in Intell. Build. Int., contributing to discussions on biomimetic design.") ("entity" + 43eb56fd90297c8d3c9e125f8a258552 + + + "PERSON" + "Escobar is the author of 'Designs for the Pluriverse: Radical Interdependence, Autonomy, and the Making of Worlds', a book about radical interdependence and autonomy in making worlds."), ("entity" + 1e4a32f745aa007ef1215f21e5d61f20 + + + "PERSON" + "Dr. Meng F is a researcher who contributed to the study on biomimetics for new smart adhesives based on tree frog adhesion properties.") ("entity" + b1365ab133c6be5ea45465f8f66fde20 + + + "PERSON" + "Longjian Xue contributed research on bioinspired adhesives through tree frog toe pad mimics." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "PERSON" + "W. Jon P. Barnes collaborated in the development of bioinspired adhesive materials and friction-generating devices based on biomimetic principles." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "ORGANIZATION" + "These are specific areas of study that focus on replicating biological features from tree frogs to design artificial adhesives and devices." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "CONCEPT" + "Bioinspiration refers to the process of drawing ideas or innovations from natural phenomena for technological applications." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "EVENT" + "The study involves research on how climbing animals, like tree frogs, adhere to surfaces and applying these principles in artificial materials." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "ORGANIZATION" + "Sun & Bhushan are likely the authors of a recent review, suggesting they have expertise in biomimetics and adhesion mechanisms." + 7393bb6f9d3837d8e11cfbef8c7d7959 + + + "SPECIES" + "The species being discussed is a gliding frog that resides in trees and uses its toe pads for attachment"|>2) ("entity" + 86f10a539a2dae71ed0fb369a39cb0a5 + + + "MATERIAL" + "Description of a material with an elastic modulus of approximately 3 kPa, which might relate to biological tissues like toe pads of frogs and other amphibians." + 1e6b8071c30040b985c9f084d73831fb + + + "TOOL" + "An Atomic Force Microscope (AFM) indenter used for measuring the mechanical properties of materials, such as elasticity." + 1e6b8071c30040b985c9f084d73831fb + + + "SURFACE" + "The outermost layer of a toe pad structure that has been measured to have an elastic modulus significantly higher than internal layers." + 1e6b8071c30040b985c9f084d73831fb + + + "LAYER" + "Layers close to sub-dermal lymph spaces and a capillary network, which are much softer and pliable compared to the external surface of the pad." + 1e6b8071c30040b985c9f084d73831fb + + + "MATERIAL" + "Structures that provide rigidity and strength to various biological tissues including toe pads and other skin components in amphibians." + 1e6b8071c30040b985c9f084d73831fb + + + "ORGANIZATION" + "DROTLEF ET AL." is a team led by Sam Rivera dedicated to conducting extensive research and publishing findings related to cell structures and their adhesive capabilities. This organization has also undertaken studies involving the exploration of adhesion forces under varying velocities on both hydrophilic and hydrophobic surfaces, demonstrating comprehensive expertise in this field of study. + 65e8dd210ebbbf33013fa2f40f86c71a,b01ac6d637b8d31e396081208c8162d0 + + + "CONCEPT" + "Sam Rivera's work involves complex biological concepts, specifically focusing on the intricate designs of cells and nanopillars as they relate to adhesion." + b01ac6d637b8d31e396081208c8162d0 + + + "EVENT" + "In this context, 'First Contact' refers to Sam Rivera's team understanding new forms of adhesion from studying natural structures such as those found in epithelial cells and nanopillars." + b01ac6d637b8d31e396081208c8162d0 + + + "ORGANIZATION" + The entity referred to throughout these descriptions is the research group named FEDERLE ET AL. This team is known for their work in uncovering scientific findings related to frog mucus properties, specifically focusing on adhesion mechanisms that occur when interacting with various surfaces. Their research activities are centered around water frogs and their unique toe pad structures, indicating an extensive investigation into the biological properties of these creatures. + 136e4bfffb45ced656433f414fdc6b2f,fa424ca04288f43c5c699afb0d603c44 + + + "PERSON" + "The authors who have studied the adhesion ability of tree frogs to various rough surfaces in their natural habitat.")|("entity" + fffe8fad4dcfa583ff169283eb78ecb3 + + + "GEO" + "The image produced by interference reflection microscopy which helps in estimating the thickness of fluid layer.") + e78095af9990d29b641c393cc4eef335 + + + "EVENT" + "Tree frog adhesion refers to the adhesive capabilities displayed by tree frogs, which is a topic under study with respect to physical principles and forces.") + 7fb26cfacb7049c44680dc8301da770f + + + "ORGANIZATION" + "The document contains equation 2.1, which simplifies to FL = −4 πRγ .") ("entity" + 73f5b09aa4346c6324664d57dd868e8c + + + "EVENT" + "The recent study referred to in the text discusses the forces of adhesion in biological systems." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "Equation (2.4) is used as a comparison point for discussing the extension of adhesive force equations to soft, elastic materials like tree frog toe pads." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "The text discusses how with increasing radius (r), adhesive forces may change from length scaling to area scaling." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "The term effective elastic modulus refers to the material's resistance to deformation, affecting adhesive force predictions." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "Refers to one aspect of how adhesive forces are explained mathematically in relation to geometry and elasticity." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "Referred to as Stefan adhesion, these forces resist plate separation due to fluid flow dynamics." + fa83531962b067f9e048396a31135c9e + + + "ORGANIZATION" + "Tulchinsky & Gat introduced the concept of 'temporary adhesion' by considering only viscous flow and ignoring inertial and capillary effects." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "EVENT" + "Equation (2.9) describes this force, which involves a term with viscosity and radius of the sphere." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "CONCEPT" + "Concept introduced by Tulchinsky & Gat based on elastic deformation and viscous flow interactions." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "ITEM" + "A test subject used in studying adhesion, with forces resisting slip being measured during tests." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "ORGANISM" + "Tree frogs, a species known for their remarkable wet adhesion properties and capable of climbing using both adhesion and adduction forces on smaller structures, refer to animals whose unique toe pad structure inspires materials development. Unlike geckos, while they also provide inspiration due to their adhesive capabilities, the mechanism in tree frogs is described as more complex." + 48a7645a66fe18b7377a1a842f7242b0,70bb442f494ac5321d4f1d3bc233e919,92dc318eef4563c8f3fa73fb7b3978bc,bc8c1b71a9bc00c67a64198dae0f5a42 + + + "PROPERTY" + "Viscosity of the fluid is several orders of magnitude greater for silicone oil than tree frog mucus, affecting applicability of the viscous-poroelastic adhesion concept." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "EVENT" + "Means by which tree frogs climb on flat surfaces using only adhesive forces." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "ACTIVITY" + "Force used by tree frogs to climb small diameter structures, aiding in climbing with their digits." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "STRUCTURE" + "Components also contributing to climbing abilities alongside adhesion and adduction forces." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "ORGANIZATION" + "Developers of a simple procedure to measure adhesive forces generated by tree frogs." + 82d1d20cbed7dd86fe58e59fed8d44ad + + + "GEO" + "This refers to a graphical representation or diagram, likely used in academic literature." + 1647a94c674950bc1429d956f341aba2 + + + "ORGANIZATION" + "The development team of miniature force plates used in measuring friction and adhesive forces on frog toe pads.") ("entity" + bea216e0fcc7f946f0033c137012a930 + + + "EVENT" + "A procedure conducted to study effects on fluid layer thickness under a pad using interference reflection microscopy." + 0888854b6766d37662902e4d32772d60 + + + "EFFECT" + "Increase observed in the distance between pad and ground as an outcome of the said procedure." + 0888854b6766d37662902e4d32772d60 + + + "EFFECT" + "Diminished adhesion due to changes from viscosity-dependent hydrodynamic forces and van der Waals forces." + 0888854b6766d37662902e4d32772d60 + + + "CONCEPT" + "A significant role for capillary forces in maintaining close contact between pad and ground." + 0888854b6766d37662902e4d32772d60 + + + "CONTEXT" + "The necessity of close contact for the manifestation of other adhesive actions, as suggested by the study." + 0888854b6766d37662902e4d32772d60 + + + "EVENT" + "An experiment involving recording forces exerted by a single pad during horizontal pull." + 0888854b6766d37662902e4d32772d60 + + + "CONCEPT" + "Evidence that toe pads can generate static friction, indicating contact between structures on toe pads and the surface." + 0888854b6766d37662902e4d32772d60 + + + "COMPONENT" + "Structures potentially involved in creating contact with the force plate during toe pad experiments." + 0888854b6766d37662902e4d32772d60 + + + "MEASURE" + "Values measured using miniature force plates for tree frog toe pads." + 0888854b6766d37662902e4d32772d60 + + + "SPECIES" + "A species of gliding frog mentioned in the study, used for calculating adhesive and friction forces." + 0888854b6766d37662902e4d32772d60 + + + "COMPARISON" + "Supporting an argument suggesting toe pads are better developed for friction than adhesion based on observed data." + 0888854b6766d37662902e4d32772d60 + + + "ORGANIZATION" + "Geckos are used in biomimetics studies for their unique abilities related to adhesion which inspire various material developments." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + "PRODUCT" + "Materials or devices that replicate aspects of geckos' adhesion mechanisms, often focusing on van der Waals forces." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + "CONCEPT" + "Force responsible for the adhesion capabilities in gecko-inspired materials, enabling simple pillar structure design and construction." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + "PRODUCT" + "Structured formations made of multiple pillars that mimic natural systems like geckos' toe pads or tree frogs' adhesive mechanisms." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + + + bc8c1b71a9bc00c67a64198dae0f5a42 + + + + + bc8c1b71a9bc00c67a64198dae0f5a42 + + + "PROPERTY" + "E eff allows CNT forests to maximize contacts, increasing adhesion force." + c69e8300c5e976bc2e0c66e470f0371b + + + "MATERIAL" + "Shows shear adhesion of approximately 100 N cm−2, significantly higher than gecko foot-hairs." + c69e8300c5e976bc2e0c66e470f0371b + + + "PROCESS" + "Hinders CNT forest applications due to complexity and durability issues." + c69e8300c5e976bc2e0c66e470f0371b + + + "MATERIAL" + "Has relatively low modulus, used widely for structured adhesives due to ease of handling and commercial availability." + c69e8300c5e976bc2e0c66e470f0371b + + + "TYPE" + "Built using PDMS micropillar arrays, showing remarkable decrease in effective modulus compared to flat surfaces." + c69e8300c5e976bc2e0c66e470f0371b + + + "MEASUREMENT" + "Affects pull-off forces and elastic energy dissipation during contact surface interaction." + c69e8300c5e976bc2e0c66e470f0371b + + + "FACTOR" + "Affects CNT forest applications, influencing adhesion forces based on height-to-side length ratio of pillars." + c69e8300c5e976bc2e0c66e470f0371b + + + "CONFIGURATION" + "Show a decrease in E eff with an increase in AR leading to higher contact and pull-off forces." + c69e8300c5e976bc2e0c66e470f0371b + + + "INSPIRATION" + "Illustrate adhesion dependence on pillar AR, showing potential reduction of force at high ARs due to pillar bending and clustering." + c69e8300c5e976bc2e0c66e470f0371b + + + "APPLICATION" + "Typically exhibit small pillar height and channel width, likely for maximizing adhesive strength." + c69e8300c5e976bc2e0c66e470f0371b + + + "CLASSIFICATION" + "Conventionally described as smooth, but may actually display complex structural features enhancing adhesion." + c69e8300c5e976bc2e0c66e470f0371b + + + + + c69e8300c5e976bc2e0c66e470f0371b + + + + + c69e8300c5e976bc2e0c66e470f0371b + + + + + c69e8300c5e976bc2e0c66e470f0371b + + + "ORGANIZATION" + "Tree frogs and bush-crickets refer to specific animal species which exhibit certain biological features and adhesive mechanisms.")<br>("entity" + 10f68536dac42a1fe1015b64ac551c32 + + + "GEO" + "micro-bulges refer to the structures on pillar tops that contribute to increased friction forces." + c08200d48689acf908730b5b5a937f1a + + + "MATERIAL" + "Polydimethylsiloxane that can be used in microstructures to improve mechanical properties and enhance adhesion." + cfd357f03ebd53bb7b20477337baa849 + + + "ORGANIZATION" + "Chen et al.'s team is involved in the research that examines different patterns of micro and nanostructures for understanding wet adhesion mechanics, as published in journals such as Phil.Trans.R.Soc.A.") + 56de28d5378ea95f859724f171540a25 + + + "PUBLISHING ORGANIZATION" + "This organization operates on the web, contributing to scientific publications and research dissemination." + 7959e16097062f8a4801b98295269a6a + + + "A SPECIFIC EXPERIMENT WAS CONDUCTED BY INCREASING RELATIVE HUMIDITY FOR OBSERVING ITS IMPACT ON SOLID-SOLID CONTACT RESISTANCE." + 5 + 7959e16097062f8a4801b98295269a6a + + + "THE REFERENCE TO A NAMED GROUP SUGGESTS A TEAM OF RESEARCHERS INVOLVED IN DESIGNING AND IMPLEMENTING THE LIQUID BRIDGE FORMING DEVICE." + 6 + 7959e16097062f8a4801b98295269a6a + + + + + 7959e16097062f8a4801b98295269a6a + + + + + 7959e16097062f8a4801b98295269a6a + + + "ORGANIZATION" + "This refers to a specific type of microchannel base bio-inspired patch that is being developed.") ("entity" + 2e431df92f1954d7fdf7449771dac2e1 + + + "PERSON" + "Co-author with Barthlott W, Neinhuis C contributed to the study of purity and contamination issues related to biological surfaces." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Sun J worked on nanomanufacturing bioinspired surfaces as presented in Tribol. Int." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Bhushan B is associated with Sun J's research and the field of nanotechnology." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Karl Autumn authored multiple works related to gecko adhesion, including explanations on structure, function, and applications." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Tobias Endlein contributed a study on wet adhesion in tree frogs which was part of an encyclopedia on nanotechnology." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "W. J.P. Barnes co-authored the work by Endlein on wet adhesion and has expertise in this area." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Wilfred R Hansen, alongside Autumn K, provided evidence for self-cleaning in gecko setae as reported in Proc. Natl Acad. Sci." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Nathaniel Crawford contributed research on self-cleaning mechanisms in tree frog toe pads without the need for grooming, as seen in J. Exp. Biol." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Sun Hu alongside Lopez S and Niewiarowski PH co-authored a paper on dynamic self-cleaning in gecko setae through digital hyperextension." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Co-author with Hu S, Lopez contributed to research on dynamic self-cleaning mechanisms in gecko setae." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Participated alongside Hu S and Lopez S in the study of dynamic self-cleaning processes in gecko setae." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Zeng Xia, together with Hu S et al., explored digital hyperextension mechanisms for self-cleaning in geckos." + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + "ORGANIZATION" + "Research focuses on the toe pads of this species as a source for developing new biomimetically inspired reversible adhesives.")<br>("entity" + 4d8b21398c70d24c39cd26cfa1dba5c0 + + + "PERSON" + "Aino T.'s research is focused on the high deformability of adhesive toe pads in White's tree frog, specifically through light and electron microscopic analyses.")|("entity" + 39bb4090056fa3afa0591e818ff2e48b + + + "ORGANIZATION" + "This system is comprised of 24 separate 3D force plates to study single limb forces in climbing animals on a quasi-cylindrical tower.") ("entity" + a2e84db4531e11bb05a5e5cbdb285bb8 + + + "PERSON" + "Samuel DS contributes to research on metamorphosis and maturation in hylid tree frogs at the Journal of Zoology.") ("entity" + b57944edc55bf9a8ed604f132186cac1 + + + "PERSON" + "Xue L contributed to research on bioinspired orientation-dependent friction as well as effective elastic modulus of structured adhesives.")|("entity" + 8d4a6778098c667728901fd5eb6ae286 + + + "PERSON" + "A is a co-author in the publication 'Microfluidic adhesion induced by subsurface microstructures' published in Science in 2007.") ("entity" + 221b04279ff2633a5d567aa14627c640 + + + "PERSON" + "Author Berg is associated with the publication 'Use of biomimetic hexagonal surface texture in friction against lubricated skin', indicating expertise or contribution to research in this field." + cda9b37513bc2f8036dfff4a389184d7 + + + "TEAM" + "The team of authors includes contributors from various institutions who together have published a paper on 'Highly permeable skin patch with conductive hierarchical architectures inspired by amphibians and octopi for omnidirectionally enhanced wet adhesion', showcasing collaborative research effort." + cda9b37513bc2f8036dfff4a389184d7 + + + "ORGANIZATION" + "The team of authors is associated with the publication in Advanced Functional Materials, suggesting that the paper has undergone peer review and was accepted for publication by this reputable scientific journal." + cda9b37513bc2f8036dfff4a389184d7 + + + + + cda9b37513bc2f8036dfff4a389184d7 + + + 1.0 + "Longjian Xue contributed significantly to bioinspired adhesive development through studying tree frog toe pad structures." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "W. Jon P. Barnes co-developed biomimetic adhesives and friction-generating devices with inspiration from natural climbing mechanisms." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "The primary focus of research in this area involves replicating the complex structures found on tree frogs' toes to enhance material performance." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "Bioinspiration has influenced the development of artificial adhesives and devices by providing natural solutions for their design." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "The study of adhesive mechanisms in nature, especially from climbing animals, serves as a fundamental source of information for bioinspired material advancements." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "Inspired by the biological adhesion properties of geckos, leading to advancements in material science and engineering applications." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + 1.0 + "Young's modulus of different materials influences the effectiveness and stability of pillar array designs used for biomimetic adhesive development." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + 1.0 + "Based on polydimethylsiloxane, a material known for its ease of handling and commercial availability." + c69e8300c5e976bc2e0c66e470f0371b + + + 1.0 + "Affects adhesion forces in hexagonal pillar configurations via AR calculations." + c69e8300c5e976bc2e0c66e470f0371b + + + 1.0 + "publishing organization is responsible for releasing scientific studies or findings like this study on tree frog-inspired adhesion." + 7959e16097062f8a4801b98295269a6a + + + 1.0 + "C was co-author with Barthlott W on work concerning purity and contamination issues related to biological surfaces." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Sun J is an author of the paper on nanomanufacturing bioinspired surfaces in Tribol. Int." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Is associated with Sun J's research and the field of nanotechnology as a co-author or author." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Karl Autumn is an author of works on gecko adhesion, including structure, function, and applications." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Tobias Endlein contributed to the study on wet adhesion in tree frogs as part of a broader work on nanotechnology." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "W. J.P. Barnes co-authored research with Endlein and likely has expertise in biological adhesion mechanisms." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Wilfred Hansen, along with Karl Autumn, provided evidence for self-cleaning gecko setae." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Nathaniel Crawford contributed research on self-cleaning mechanisms in tree frog toe pads as part of J. Exp. Biol." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Sun Hu co-authored the study with Lopez and Niewiarowski on dynamic self-cleaning in gecko setae using digital hyperextension." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Barthlott W contributed to studies on purity and contamination of biological surfaces in Planta." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Author Berg is directly linked to the publication 'Use of biomimetic hexagonal surface texture in friction against lubricated skin', indicating a specific contribution or lead authorship to this research work." + cda9b37513bc2f8036dfff4a389184d7 + + + 1.0 + "The team of authors collectively contributed to the publication 'Highly permeable skin patch with conductive hierarchical architectures inspired by amphibians and octopi for omnidirectionally enhanced wet adhesion', highlighting their collaborative effort in advancing biomimetic research." + cda9b37513bc2f8036dfff4a389184d7 + + + 1.0 + "The publication 'Highly permeable skin patch with conductive hierarchical architectures' was published in this journal, indicating that the research meets high standards for originality and scientific rigor as required by peer-reviewed journals." + cda9b37513bc2f8036dfff4a389184d7 + + + \ No newline at end of file diff --git a/indexing/output/20240722-073448/artifacts/join_text_units_to_entity_ids.parquet b/indexing/output/20240722-073448/artifacts/join_text_units_to_entity_ids.parquet new file mode 100644 index 0000000000000000000000000000000000000000..3da0d4b68aacdd278bacb195cfdc51247e19b9cb --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/join_text_units_to_entity_ids.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26ecf7ed22c3347e6be889a71e62260eebcbb2e346a9e599cef50a9d6d42e2c9 +size 19844 diff --git a/indexing/output/20240722-073448/artifacts/join_text_units_to_relationship_ids.parquet b/indexing/output/20240722-073448/artifacts/join_text_units_to_relationship_ids.parquet new file mode 100644 index 0000000000000000000000000000000000000000..c01264bd56a7967356c5c922171ad59e125e4f4d --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/join_text_units_to_relationship_ids.parquet @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff19b5a70e251a6a59c3f8d0d73fcdc8387ccb127c31093ec52dcce8cf053768 +size 3703 diff --git a/indexing/output/20240722-073448/artifacts/merged_graph.graphml b/indexing/output/20240722-073448/artifacts/merged_graph.graphml new file mode 100644 index 0000000000000000000000000000000000000000..2a2ab1ff723e40ce94a03908e51a8d6665a00fb2 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/merged_graph.graphml @@ -0,0 +1,1298 @@ + + + + + + + + + + "ORGANIZATION" + "AskNature Team is responsible for creating educational content about living systems, including birds.") +"The entity 'AskNature Team' conducts research and educational programs on biomimicry, looking to nature for solutions in technology, design, and problem solving." +"The AskNature team is responsible for cataloging information about biomimicry and nature, including strategies like 'Spiral Fibers'.")||("entity" + 30aa281b7ea0845a9f88c0914df109c3,4305d6610a2538765dc1ea9aed78ea5e,a3d83dc700d8d01b07a94c2a1180c2b4 + + + "PROCESS" + "The process by which birds inhale and exhale air through their respiratory system for oxygen intake and carbon dioxide expulsion.") ("entity" + a5430820e1ece1dff536ad804e55c798 + + + "PERSON" + "Andy Carstens is an author who wrote about biological strategy of birds using ground effect to minimize drag and conserve energy when gliding over water.") ("entity" +"An author who has contributed content related to natural phenomena and innovations inspired by nature." + 4d6faade61b11859190946a315c34a2e,8afa448acb86b96422cea043f3fd6749 + + + "ORGANISM" + "The Flying squirrels are the subject of study due to their ability to control their glide." + 638dc502f70bb90aeb0465be8db1facc + + + "ORGANIZATION" + "The organization that provides insight and information on biological strategies for human design, specifically in this case the glide mechanism of flying squirrels. They suggest how understanding such biological performance could be applied to improve various human technologies like parachutes and skydiving suits.") ("entity" +"Biomimicry Institute is an organization that studies and applies principles observed in nature to solve human problems." +"Institute dedicated to fostering innovation inspired by nature, focusing on sustainable design and technology." +"The organization behind AskNature and its educational content on nature-based solutions and inspirations for human innovation." +"The organization responsible for providing biological strategy solutions and information through their website Biomimicry.org." +"The Biomimicry Institute is an organization dedicated to promoting the adoption of nature's problem-solving strategies in design." +"The Biomimicry Institute is an organization that specializes in finding solutions inspired by nature." +"The Biomimicry Institute is a copyright holder of the material and operates in the field of biomimicry." + 4d6faade61b11859190946a315c34a2e,74a8b683e829577d39bd3b12018ddee0,75be22a096d450ebe20ed42f79da45da,7c777850b39440dea33d9b60641e803b,809da8a35547ca53620a67d4f1cdb6f5,891d3f28f888b374a21d9c781295bbf9,90ede7f9f06fa68f01d8528ec2495d4b,e9161c0416f80b08625e2dcd9f70167f + + + "PERSON" + "This refers to researchers who contributed to a study on gliding performance of mammals, particularly northern flying squirrels (Glaucomys sabrinus)." + a3d83dc700d8d01b07a94c2a1180c2b4 + + + "ORGANISM" + "The Black-tailed prairie dog is an animal that builds extensive burrows in the plains of North America and performs functions like distributing gases." + a3d83dc700d8d01b07a94c2a1180c2b4 + + + "CREATIVE WORKER" + "This refers to a photographer whose image has been used in publications related to nature studies, with permission granted for use." + a3d83dc700d8d01b07a94c2a1180c2b4 + + + "ORGANIZATION" + "AskNature.org is an online resource provided by the Biomimicry Institute that showcases biological strategies for human inspiration and problem-solving.") ("entity" +"AskNature.org is a resource platform for biologically inspired innovations. It showcases strategies, organisms and ideas that can be applied to solve human challenges through nature's principles.") +"A component of Biomimicry.org website that asks users to explore and apply natural strategies in their innovations." +"AskNature is an online platform offering knowledge and tools about nature-based solutions and biomimicry, specifically highlighting the strategies of heliotropism in plants." +"AskNature.org is a platform where Lonny Lippsett shared information about the functions of a diverse soil ecosystem, including coordination via self-organization." +"Asknature.org is a website that offers information and resources on various scientific topics, including ecology and evolution."),("entity" + 0a71d2671ba6b6bceb2f13e60122c278,10a8260a1ac5e4f2ab531d67e534b83f,3678ab8d2bad24bba44d0a83fe09f8a6,42b463f5b40c4f86e9338c967c8d5bfa,75be22a096d450ebe20ed42f79da45da,fb3016519d20d8e4fc1d25d5690a550a + + + "PERSON" + "Sam Rivera is a part of an organization working in Saudi Arabia where they are using echolocation for food searching. He is also involved with an Egyptian fruit bat." +"Sam Rivera is a member of an unspecified organization involved in biological research on adhesive mechanisms in nature." +"Sam Rivera is not mentioned in the provided real data.")|("entity" + 777a1482c060a064af315a8488df370a,b01ac6d637b8d31e396081208c8162d0,d99568b2216b6501020a719efe70edaf + + + "ORGANISM" + "A species of frog specifically adapted to living in water-filled tree hollows, utilizing their environment to amplify vocal calls.|) ("entity" + aff4d366caa94978fbabd1021d43d555 + + + "SPECIES" + "Specific types of snakes known for their unique ability to create loud defensive sounds." + 4d6faade61b11859190946a315c34a2e + + + "ACTION" + "Visiting a specific strategy on AskNature for investigation into interactions between vortices and trout. The website provides scientific articles related to the topic." + 8fa82d96bb00621623d0d7c9e9ac5034 + + + "OBJECT" + "Butterfly wings are a natural model that shows how micro-geometrical patterns enhance airflow and facilitate flight through specific scale configurations.") ("entity" + 01117b72383429324254870387eb4aba + + + "BIOLOGICAL STRATEGY" + "The micro-geometry of butterfly wing scales provides insights into designing efficient wind turbines, improved structural stability in tall buildings, and more." + 5bec096731ec31b017777a7aadf747bc + + + "ORGANIZATION" + "The Diving Bell Spider serves as a biological inspiration for technological innovations in air supply and water-resistant materials." ) ("entity" + 81eee876cafa81ab3b11ed19cc045cb6 + + + "PERSON" + "Roger S. Seymour is an author who contributed to the Journal of Experimental Biology in 2011.") ("entity" + eedd4bc29a0007151fb16d1deec2f9eb + + + "ORGANIZATION" + "Spiders use trichobothria for sensing and movement control in hunting and navigating their environment." + 3d22053debaab18c4e321d4cfe15f8af + + + "CONCEPT" + "Trichobothria are sensory structures on spiders’ legs that enhance their sensitivity to touch, vibrations, and motion." + 3d22053debaab18c4e321d4cfe15f8af + + + "EVENT" + "The hypersensitivity provided by trichobothria allows spiders to detect underwater currents or the presence of sea life." + 3d22053debaab18c4e321d4cfe15f8af + + + "CONCEPT" + "Spiders use information from their environment, like the activity of other organisms and environmental cues, for hunting, navigation, and self-defense." + 3d22053debaab18c4e321d4cfe15f8af + + + "ORGANIZATION" + "The concept of integrating spider's sensory capacity into wearable devices or clothing could improve motion detection beyond human vision." + 3d22053debaab18c4e321d4cfe15f8af + + + "WEBSITE" + "Website for the organization Biomimicry Institute, providing information about strategies found in nature and how they can be applied." + 75be22a096d450ebe20ed42f79da45da + + + "PERSON" + "A researcher contributing his expertise in the biological strategy related to spiders and electric currents for biomimetics applications." + 75be22a096d450ebe20ed42f79da45da + + + "PERSON" + "The individual credited with discovering or understanding how certain spiders fly using electrostatic repulsion, possibly contributing knowledge to biomimetic engineering." + 75be22a096d450ebe20ed42f79da45da + + + "PERSON" + "A contributor or researcher who provided insights or evidence supporting the spider flying phenomenon, influencing scientific community." + 75be22a096d450ebe20ed42f79da45da + + + "PERSON" + "A researcher involved in the study that shed light on spiders' use of electrostatic forces for flight, providing significant biological data for biomimetics." + 75be22a096d450ebe20ed42f79da45da + + + "EVENT" + "Spiders were observed to exhibit 'balloon' like flight in low wind conditions due to atmospheric electric fields.") ("entity" + 621c0cd608f4ed99a4dd7a5c25c8e0b5 + + + "PERSON" + "Mary Hoff authored a strategy on AskNature explaining how water striders communicate using vibrations and their legs.") ("entity" + 60d4060427254b2a553815d05dce7fcf + + + "ORGANISM" + "A species of insects that communicate through tapping the water surface and have highly sensitive motion-detecting structures on their legs.") ("entity" + bd3e8fcd1e1991500d9610859ecfabf4 + + + "PERSON" + "Pablo Perez is responsible for inventing devices that provide advanced warning of impending earthquakes or mudslides, possibly inspiring new technology.") + f228fcbbb8f2ec33599ea9a3d5d4e854 + + + "PERSON" + "He created an image for this document under CC BY-SA license.") ("entity" + 1ff6815fa5511debe6f17ad17c1707b1 + + + "ORGANISM" + "Plants use strategies like tropisms (gravitropism, thigmotropism, phototropism, heliotropism) to adapt and respond efficiently to their environment.") ("entity" + c8455055703093614be4105105a67f0e + + + "PERSON" + "Peter Prehn, a contributor to Biomimicry Institute and AskNature.org, explains the underground network strategy of mycorrhizal fungi in a Douglas-fir and pine forest context.") ("entity" + 2defde0504bd9c1a5bdd248980ce1ce1 + + + "ORGANISM" + "Mycorrhizal fungi form mutualistic partnerships with trees and other plants, facilitating nutrient exchange and communication through the Wood Wide Web.") ("entity" + dbf85def96906b82d29e7bcd512b920f + + + "CONCEPT" + "A network formed between the roots of plants and fungi, facilitating resource exchange, information sharing, and mutual support among plant communities.") ("entity" + ac3f4943aac0de17b70d54bf387fe19b + + + "PERSON" + "Lonny Lippsett wrote about biological strategies performed by organisms living in soil ecosystem, particularly focusing on self-organization." + 0a71d2671ba6b6bceb2f13e60122c278 + + + "ORGANIZATION" + "This refers to the diverse ecosystem that works together to break down organic matter and recycle it into nutrients for plants to reuse.")<|"\n"|"Entity" + 17c65307eb89a2d2f26db3e34ba78722 + + + "EVENT" + "AN-Bird Respiration_Final_05-2022 refers to a document that discusses bird respiration process which is being finalized in the month of May 2022.") ("entity" + 03018b77601ad2b2e8345af35fb84450 + + + "CONCEPT" + "It is a system of classification developed by the Biomimicry Institute for organizing biological content on their website AskNature.org. This taxonomy categorizes strategies that organisms and natural systems use to meet functional challenges. The strategies are classified according to functions, which describe what the strategy accomplishes for the organism or living system. This helps users identify potential solutions to similar human challenges by looking at nature's approach to solving issues.") + ff760235e3461c93ff1fa2bee432fdb1 + + + "ORGANIZATION" + "AskNature is an online platform providing access to strategies and insights from natural systems for design solutions." ) ("entity" + e4b6193a4ea13cb8c682998eb02efb6d + + + "BIOMIMICRY TAXONOMY" + "Biomimicry Taxonomy provides a framework for exploring new verbs and related concepts, facilitating innovation through nature-inspired solutions." +"CTU refers to a group or organization that is focused on understanding and managing ecosystems, including their physical state modifications and services provided." +"NC 4.0 refers to a specific organization or program mentioned in the text, possibly related to creative license or collaboration." +"Creative activities refer to the diverse expressions that often incorporate interdisciplinary knowledge as a source of inspiration.")|("entity" +"A database used in bibliometric analysis that helps researchers and academics find relevant publications and analyze academic trends." +"Organization is involved in studying themes related to sustainability.") +"This journal publishes research related to biomimetic design and technologies." +"A scientific organization that publishes research journals including 'Phil.Trans.RoyalSoc.A'.") +"It is a publisher and an academic organization that publishes research articles including those related to engineering sciences.")<|"person" + 170684a57b4848b420032214260ee67b,23c34b74899c04c60dc7b087b88e0137,3b302bec9259fbca0cf68da76392935c,44c8dff86ecf90b601e21ef2335e8c61,6de0fc3cc6011a0ce9267a0584f498b2,84d05d265cebbc1d33e9d523b860d87e,a19c62053cac11a3e022402443eeba83,dd615bbb350414d251cb1083b3142230,fe902bcadf86addbe747f348c1ccc56f + + + "H" + "H could represent any individual within an organization or group dealing with eco-system management, focusing on behaviors optimization, space/material adaptation, and coordination with other groups." + 170684a57b4848b420032214260ee67b + + + "PERSON" + "Alex is the leader of a team attempting first contact with an unknown intelligence, acknowledging the significance of their task." + 2b9b282e75a0a5345cc0cee8f327a2b1 + + + "ORGANIZATION" + "BOHsihana is involved in the process of attempting to communicate with an unknown intelligence through their technological means and research." + 3b8a807b256d918245b0ffb8c88d4c09 + + + "PERSON" + "A biomimetics researcher at the Department of Design, University of Brasília, who has contributed to studying the application and integration of biological knowledge in design.")|("entity" + 7323cecb72b3fa0472a26a5aa37c4131 + + + "PUBLICATION" + "The publication titled 'Biomimetics' with volume number of 8 and issue number 61 from the year 2023.") +"The journal that published a study on the thematic aspects associated with design and biomimicry, including product conception, structural explorations of nature for new materials, use of creative tools in product design, and emphasis on resource savings and sustainability.")|("entity" +"Biomimetics is a journal that discusses the literature on biomimetics in 2023." +"Publication year for a scientific paper or conference on Biomimetics which this article was published in." + 2aee03ca69624bff0ae2d030f6f31e19,7982a2e4054b66ae19457bde8585eaa8,af3fc23c5069edd0bdffd8f9a64d3ab2,b23a7cb845fd949e0baab80bf6f0c4f8 + + + "CONCEPT" + "Biological concepts or ideas that are mimicked by humans in various fields, often for innovation and problem-solving.") ("entity" + 6e87b92e6c843cb54a008ae676d3b416 + + + "CONCEPT" + "Imitative or biomimetic design that draws on concepts found in nature to solve human challenges and promote sustainability.") + a43faaba2ebb888387d5b0f59efb6381 + + + "JOURNAL" + "The publication Biomimetics, in which an analysis on design and architecture topics from the late 1990s is presented.") +"Biomimetics is a field studying ways to model nature’s design solutions for engineering problems.") ("entity" +"Biomimetics is a field of study that draws inspiration from nature's principles to solve complex human problems." +"The field of biomimetics involves the study of natural systems for solving engineering problems, including developing new materials and devices based on biological principles." + 2790f03c21ca0d9a522e2c1276ad4f6e,b3c5de72ae4c784c9fef28c432a247eb,bc8c1b71a9bc00c67a64198dae0f5a42,d1f202cadb144570739c718437dd9c7b + + + "ORGANIZATION" + "The Procedia Social and Behavioral Sciences is an academic journal that published 5 articles.") ("entity" + 17a811ea2375e85ee164ddd52dbe5a80 + + + "EVENT" + "The article discusses the evolution of reaction centers that mimic photosynthesis for fuel production and water conversion processes." + b315f4391fd31deebdefc7e4496ccc53 + + + "AUTHOR" + "Bhushan conducted research emphasizing biomimetic studies at micro and nano scales, focusing on creating designs inspired by biological surfaces and materials.") ("entity" + bc2123b5f86d53a8b6c4f35594131571 + + + "ORGANIZATION" + "An organization that works in a field related to sustainable design and research, focusing on biomimicry." + c16a050b9f05d4adcbe87cd85974f73b + + + "CONCEPT" + "A central theme in the works of 'The St Works Study' which deals with bio-based innovations, specifically biomimicry." + c16a050b9f05d4adcbe87cd85974f73b + + + "CONCEPT" + "The core concept behind both studies and developments led by 'The St Works Study', involving principles extracted from nature to solve problems or create innovations." +"The use of biomimetic characteristics in design inspired by natural processes and forms." + 30c01680c32c27bbf40c2879200bb4ca,c16a050b9f05d4adcbe87cd85974f73b + + + "PERSON" + "E.O. Wilson is known for conceptualizing nature as a model, measure, and mentor agent capable of generating efficient systems. He also encourages transferring natural knowledge to human contexts particularly in dealing with issues like waste management.") ("entity" + 10357a9455875b5f9c5deca2d9871135 + + + "PERSON" + "Pawlyn is associated with work showcasing biomimicry and architecture interconnections, highlighting sustainable and innovative construction methods, particularly for restoration purposes.") ("entity" + b8f2d8b6f8181c950be1341e09d5f6ac + + + "PERSON" + "These authors are responsible for the concept of designing with a focus on effectively having a positive impact on the environment.") ("entity" + 50d87eb794de75e87a2b0897c5432e39 + + + "ORGANIZATION" + "The organization is involved in the research and functional analysis of natural and artificial systems using biomimetic approaches." + ea3022e7c889776437eec7e0ff1e3b2c + + + "ORGANIZATION" + "The organization involved is a research institute or department that focuses on sustainable architecture and design.") + e01fbf716e63081d999f9f22c28e098a + + + "GEO" + "Climate is a subject associated with the adaptation and systems at ecological level, involving technical solutions, especially in the face of climate crisis." + 3cafe8221f0d2b661270f9e33c59993d + + + "PERSON" + "A Researcher who specializes in biomimetics studies different organisms' abilities to identify two words which appear together frequently") + 4c8d34a6cb7efcbac85f88b2fbb3973e + + + "ORGANIZATION" + "Entomology is a field of study which focuses on the organisms, especially insects.")|("entity" + 5bb96e57d4c79ea40feeb5ecb3296afe + + + "GEO" + "This includes various designs and studies across architecture.")|("entity" + 439722d75181e1aa687e95df70e09d63 + + + "OBJECT" + "This represents a map created using data from the Web of Science, covering publications from 2018 to 2021. The map visually represents bibliographic coupling between documents." ) ("entity" + 8d7e6e7209519d7dec8948a364fdbab2 + + + "EVENT" + "An opportunity for redesigning materials, processes, and products that may inherently link with nature through their properties and functionality." + 30c01680c32c27bbf40c2879200bb4ca + + + "ACTION" + "The act of redesigning materials, processes, and products to improve efficiency or sustainability." + 30c01680c32c27bbf40c2879200bb4ca + + + "ASPECT" + "A connection or relationship between the designed elements and natural principles or systems." + 30c01680c32c27bbf40c2879200bb4ca + + + "CONTEXT" + "Environmental changes that influence the functionality of kinetic architectural elements." + 30c01680c32c27bbf40c2879200bb4ca + + + "CONCEPT" + "A model where resources are kept in use for as long as possible, extracting maximum value while minimizing waste."> + 30c01680c32c27bbf40c2879200bb4ca + + + "ORGANIZATION" + "Tate et al. are a team who reviewed relationships of mutualism found in nature and contributed to the recognition of biomimicry as an area useful for strategic planning in companies." + f770903009c82b1aeca7bf9e490877ad + + + "EVENT" + "The introduction of innovative concepts that integrate ecosystem services to support biodiversity and natural environment resilience against climate change.")|("entity" + f5fd896ed0c59d47158db316fad680dc + + + "ORGANIZATION" + "The Web of Science is a comprehensive database used for academic research that may limit the accessibility or dissemination of certain works based on specific criteria." + 916f17bde39ae650dad1b657a1887fa6 + + + "PERSON" + "A.A.M.d.S. is an author who contributed to a study on the application and importance of biomimicry in design.") ("entity" +"A.A.M.d.S is the primary author who conceptualized the study and developed its methodology with co-author D.M.V." + 7982a2e4054b66ae19457bde8585eaa8,f8d611d2f89f42ca1550ee673a05d4dd + + + "PERSON" + "D.M.V contributes to software development, formal analysis of data, validation, investigation, resource gathering, supervision of the project." + 7982a2e4054b66ae19457bde8585eaa8 + + + "CONCEPT" + "A structured description of each authors' contribution to the research process, from conceptualization to final review." + 7982a2e4054b66ae19457bde8585eaa8 + + + "EVENT" + "Planning and ideation phase for the study conducted by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "EVENT" + "Process of planning how experiments or research will be designed and executed, carried out by A.A.M.d.S. and D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TOOL" + "A.A.M.d.S utilized software tools for various tasks during the study's execution." + 7982a2e4054b66ae19457bde8585eaa8 + + + "EVENT" + "The process of confirming the accuracy or truthfulness of research findings, carried out by A.A.M.d.S. and D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TECHNIQUE" + "Careful examination and interpretation of data or concepts using systematic methods" + 7982a2e4054b66ae19457bde8585eaa8 + + + "ACTIVITY" + "Research conducted to gather information, performed by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TOOL" + "Materials or assets used in the study which were collected or provided by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "PROCESS" + "Organization and management of data throughout its lifecycle, responsibility of A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TASK" + "The initial writing phase where the first version of a paper or report is drafted by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "ACTIVITY" + "Process to refine and correct content, undertaken by both A.A.M.d.S. and D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TECHNIQUE" + "Representation of data or concepts through graphical means, performed by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "ROLE" + "Overseeing the research project's progress and ensuring quality control, done by D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + + + "PERSON" + "MacKinnon R.B., J.Oomen, M.P.Zari are authors in the paper 'Promises and Presuppositions of Biomimicry' contributing to the field of biomimetics.")<br>("entity" + ab0129037f27d2a0b3230e695cb66703 + + + "PERSON" + "Cohen is the author who wrote 'Biomimetic Design Method for Innovation and Sustainability' in Springer")|("entity" + 71820a84991aa839263c1542540c3d9a + + + "PERSON" + "Author of the book 'Biomimicry', exploring innovation inspired by nature.")|("entity" + d9c59b517b2e653c7c9cb7efb130c9b0 + + + "ORGANIZATION" + "CrossRef is a not-for-profit membership organization that operates several databases for scholarly journals and books." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Michael Cutkosky is the author of one paper discussing the design and fabrication of multi-material structures for bioinspired robots." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This is a journal published by The Royal Society which features scientific papers in mathematical, physical, engineering sciences, life sciences and information science." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Jorge Mendoza is an author of one paper discussing the integration of backcasting and eco-design for the circular economy using a framework named BECE." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal focuses on issues in environmental sustainability, green business strategies, and sustainable development." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Ben D. Sherman is an author of one paper discussing the evolution of reaction center mimics for systems capable of generating solar fuel." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal publishes scientific papers about photosynthesis and related fields such as biochemistry, genetics, ecology, and physiology of plants and algae." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Samantha N. Sponberg is an author of one paper discussing templates and anchors for antenna-based wall following in cockroaches and robots." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal publishes research articles on robotics theory, experimentation, applications, and design, including topics like autonomous robots and robot systems." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Qingyuan (Q.) Xu is an author of one paper discussing biomimetic self-cleaning surfaces." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Mehrnaz Zari is the author of a paper discussing biomimetic design for climate change adaptation and mitigation." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal covers various scientific fields including architecture, physics, engineering sciences, life sciences, and information science." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Michael Helms is an author of a paper discussing biologically inspired design: process and products." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal publishes academic studies on design including issues related to cultural, social and psychological aspects of designing processes and artifacts." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Mark Pawlyn is the author of a book titled 'Biomimicry in Architecture' which focuses on principles of biomimicry as applied to architectural design." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Amir Chakrabarti is mentioned with his involvement with other researchers in one paper discussed." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Mawson Pawlyn is the author of 'Biomimicry in Architecture', showcasing expertise and insight into architecture that draws inspiration from natural systems.") ("entity" + 70bfef2ab1bf8bc9a6db2cd5ae212340 + + + "PERSON" + "Ying Xing is the author of 'Exploring design principles of biological and living building envelopes: What can we learn from plant cell walls?' in Intell. Build. Int., contributing to discussions on biomimetic design.") ("entity" + 43eb56fd90297c8d3c9e125f8a258552 + + + "PERSON" + "Escobar is the author of 'Designs for the Pluriverse: Radical Interdependence, Autonomy, and the Making of Worlds', a book about radical interdependence and autonomy in making worlds."), ("entity" + 1e4a32f745aa007ef1215f21e5d61f20 + + + "PERSON" + "Dr. Meng F is a researcher who contributed to the study on biomimetics for new smart adhesives based on tree frog adhesion properties.") ("entity" + b1365ab133c6be5ea45465f8f66fde20 + + + "PERSON" + "Longjian Xue contributed research on bioinspired adhesives through tree frog toe pad mimics." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "PERSON" + "W. Jon P. Barnes collaborated in the development of bioinspired adhesive materials and friction-generating devices based on biomimetic principles." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "ORGANIZATION" + "These are specific areas of study that focus on replicating biological features from tree frogs to design artificial adhesives and devices." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "CONCEPT" + "Bioinspiration refers to the process of drawing ideas or innovations from natural phenomena for technological applications." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "EVENT" + "The study involves research on how climbing animals, like tree frogs, adhere to surfaces and applying these principles in artificial materials." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "ORGANIZATION" + "Sun & Bhushan are likely the authors of a recent review, suggesting they have expertise in biomimetics and adhesion mechanisms." + 7393bb6f9d3837d8e11cfbef8c7d7959 + + + "SPECIES" + "The species being discussed is a gliding frog that resides in trees and uses its toe pads for attachment"|>2) ("entity" + 86f10a539a2dae71ed0fb369a39cb0a5 + + + "MATERIAL" + "Description of a material with an elastic modulus of approximately 3 kPa, which might relate to biological tissues like toe pads of frogs and other amphibians." + 1e6b8071c30040b985c9f084d73831fb + + + "TOOL" + "An Atomic Force Microscope (AFM) indenter used for measuring the mechanical properties of materials, such as elasticity." + 1e6b8071c30040b985c9f084d73831fb + + + "SURFACE" + "The outermost layer of a toe pad structure that has been measured to have an elastic modulus significantly higher than internal layers." + 1e6b8071c30040b985c9f084d73831fb + + + "LAYER" + "Layers close to sub-dermal lymph spaces and a capillary network, which are much softer and pliable compared to the external surface of the pad." + 1e6b8071c30040b985c9f084d73831fb + + + "MATERIAL" + "Structures that provide rigidity and strength to various biological tissues including toe pads and other skin components in amphibians." + 1e6b8071c30040b985c9f084d73831fb + + + "ORGANIZATION" + "A team led by Sam Rivera that has conducted research and published findings related to cell structures and their adhesive capabilities." +"An organization referenced for research on adhesion force tested with different velocities and hydrophilic/hydrophobic surfaces.")|("entity" + 65e8dd210ebbbf33013fa2f40f86c71a,b01ac6d637b8d31e396081208c8162d0 + + + "CONCEPT" + "Sam Rivera's work involves complex biological concepts, specifically focusing on the intricate designs of cells and nanopillars as they relate to adhesion." + b01ac6d637b8d31e396081208c8162d0 + + + "EVENT" + "In this context, 'First Contact' refers to Sam Rivera's team understanding new forms of adhesion from studying natural structures such as those found in epithelial cells and nanopillars." + b01ac6d637b8d31e396081208c8162d0 + + + "ORGANIZATION" + "This refers to a group of researchers led by Federle who have conducted studies on water frogs' toe pads." +"A research group referenced as the source of scientific findings about frog mucus properties, involved in studying adhesion mechanisms on surfaces.") ("entity" + 136e4bfffb45ced656433f414fdc6b2f,fa424ca04288f43c5c699afb0d603c44 + + + "PERSON" + "The authors who have studied the adhesion ability of tree frogs to various rough surfaces in their natural habitat.")|("entity" + fffe8fad4dcfa583ff169283eb78ecb3 + + + "GEO" + "The image produced by interference reflection microscopy which helps in estimating the thickness of fluid layer.") + e78095af9990d29b641c393cc4eef335 + + + "EVENT" + "Tree frog adhesion refers to the adhesive capabilities displayed by tree frogs, which is a topic under study with respect to physical principles and forces.") + 7fb26cfacb7049c44680dc8301da770f + + + "ORGANIZATION" + "The document contains equation 2.1, which simplifies to FL = −4 πRγ .") ("entity" + 73f5b09aa4346c6324664d57dd868e8c + + + "EVENT" + "The recent study referred to in the text discusses the forces of adhesion in biological systems." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "Equation (2.4) is used as a comparison point for discussing the extension of adhesive force equations to soft, elastic materials like tree frog toe pads." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "The text discusses how with increasing radius (r), adhesive forces may change from length scaling to area scaling." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "The term effective elastic modulus refers to the material's resistance to deformation, affecting adhesive force predictions." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "Refers to one aspect of how adhesive forces are explained mathematically in relation to geometry and elasticity." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "Referred to as Stefan adhesion, these forces resist plate separation due to fluid flow dynamics." + fa83531962b067f9e048396a31135c9e + + + "ORGANIZATION" + "Tulchinsky & Gat introduced the concept of 'temporary adhesion' by considering only viscous flow and ignoring inertial and capillary effects." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "EVENT" + "Equation (2.9) describes this force, which involves a term with viscosity and radius of the sphere." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "CONCEPT" + "Concept introduced by Tulchinsky & Gat based on elastic deformation and viscous flow interactions." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "ITEM" + "A test subject used in studying adhesion, with forces resisting slip being measured during tests." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "ORGANISM" + "Species capable of climbing using both adhesion and adduction forces on smaller structures." +"Tree frogs, similarly to geckos, provide inspiration for materials development due to their adhesive capabilities though the mechanism is more complex." +"Refers to the animals whose toe pad structure is being studied for wet adhesion properties." +"Tree frogs are known for their remarkable wet adhesion properties." + 48a7645a66fe18b7377a1a842f7242b0,70bb442f494ac5321d4f1d3bc233e919,92dc318eef4563c8f3fa73fb7b3978bc,bc8c1b71a9bc00c67a64198dae0f5a42 + + + "PROPERTY" + "Viscosity of the fluid is several orders of magnitude greater for silicone oil than tree frog mucus, affecting applicability of the viscous-poroelastic adhesion concept." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "EVENT" + "Means by which tree frogs climb on flat surfaces using only adhesive forces." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "ACTIVITY" + "Force used by tree frogs to climb small diameter structures, aiding in climbing with their digits." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "STRUCTURE" + "Components also contributing to climbing abilities alongside adhesion and adduction forces." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "ORGANIZATION" + "Developers of a simple procedure to measure adhesive forces generated by tree frogs." + 82d1d20cbed7dd86fe58e59fed8d44ad + + + "GEO" + "This refers to a graphical representation or diagram, likely used in academic literature." + 1647a94c674950bc1429d956f341aba2 + + + "ORGANIZATION" + "The development team of miniature force plates used in measuring friction and adhesive forces on frog toe pads.") ("entity" + bea216e0fcc7f946f0033c137012a930 + + + "EVENT" + "A procedure conducted to study effects on fluid layer thickness under a pad using interference reflection microscopy." + 0888854b6766d37662902e4d32772d60 + + + "EFFECT" + "Increase observed in the distance between pad and ground as an outcome of the said procedure." + 0888854b6766d37662902e4d32772d60 + + + "EFFECT" + "Diminished adhesion due to changes from viscosity-dependent hydrodynamic forces and van der Waals forces." + 0888854b6766d37662902e4d32772d60 + + + "CONCEPT" + "A significant role for capillary forces in maintaining close contact between pad and ground." + 0888854b6766d37662902e4d32772d60 + + + "CONTEXT" + "The necessity of close contact for the manifestation of other adhesive actions, as suggested by the study." + 0888854b6766d37662902e4d32772d60 + + + "EVENT" + "An experiment involving recording forces exerted by a single pad during horizontal pull." + 0888854b6766d37662902e4d32772d60 + + + "CONCEPT" + "Evidence that toe pads can generate static friction, indicating contact between structures on toe pads and the surface." + 0888854b6766d37662902e4d32772d60 + + + "COMPONENT" + "Structures potentially involved in creating contact with the force plate during toe pad experiments." + 0888854b6766d37662902e4d32772d60 + + + "MEASURE" + "Values measured using miniature force plates for tree frog toe pads." + 0888854b6766d37662902e4d32772d60 + + + "SPECIES" + "A species of gliding frog mentioned in the study, used for calculating adhesive and friction forces." + 0888854b6766d37662902e4d32772d60 + + + "COMPARISON" + "Supporting an argument suggesting toe pads are better developed for friction than adhesion based on observed data." + 0888854b6766d37662902e4d32772d60 + + + "ORGANIZATION" + "Geckos are used in biomimetics studies for their unique abilities related to adhesion which inspire various material developments." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + "PRODUCT" + "Materials or devices that replicate aspects of geckos' adhesion mechanisms, often focusing on van der Waals forces." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + "CONCEPT" + "Force responsible for the adhesion capabilities in gecko-inspired materials, enabling simple pillar structure design and construction." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + "PRODUCT" + "Structured formations made of multiple pillars that mimic natural systems like geckos' toe pads or tree frogs' adhesive mechanisms." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + + + bc8c1b71a9bc00c67a64198dae0f5a42 + + + + + bc8c1b71a9bc00c67a64198dae0f5a42 + + + "PROPERTY" + "E eff allows CNT forests to maximize contacts, increasing adhesion force." + c69e8300c5e976bc2e0c66e470f0371b + + + "MATERIAL" + "Shows shear adhesion of approximately 100 N cm−2, significantly higher than gecko foot-hairs." + c69e8300c5e976bc2e0c66e470f0371b + + + "PROCESS" + "Hinders CNT forest applications due to complexity and durability issues." + c69e8300c5e976bc2e0c66e470f0371b + + + "MATERIAL" + "Has relatively low modulus, used widely for structured adhesives due to ease of handling and commercial availability." + c69e8300c5e976bc2e0c66e470f0371b + + + "TYPE" + "Built using PDMS micropillar arrays, showing remarkable decrease in effective modulus compared to flat surfaces." + c69e8300c5e976bc2e0c66e470f0371b + + + "MEASUREMENT" + "Affects pull-off forces and elastic energy dissipation during contact surface interaction." + c69e8300c5e976bc2e0c66e470f0371b + + + "FACTOR" + "Affects CNT forest applications, influencing adhesion forces based on height-to-side length ratio of pillars." + c69e8300c5e976bc2e0c66e470f0371b + + + "CONFIGURATION" + "Show a decrease in E eff with an increase in AR leading to higher contact and pull-off forces." + c69e8300c5e976bc2e0c66e470f0371b + + + "INSPIRATION" + "Illustrate adhesion dependence on pillar AR, showing potential reduction of force at high ARs due to pillar bending and clustering." + c69e8300c5e976bc2e0c66e470f0371b + + + "APPLICATION" + "Typically exhibit small pillar height and channel width, likely for maximizing adhesive strength." + c69e8300c5e976bc2e0c66e470f0371b + + + "CLASSIFICATION" + "Conventionally described as smooth, but may actually display complex structural features enhancing adhesion." + c69e8300c5e976bc2e0c66e470f0371b + + + + + c69e8300c5e976bc2e0c66e470f0371b + + + + + c69e8300c5e976bc2e0c66e470f0371b + + + + + c69e8300c5e976bc2e0c66e470f0371b + + + "ORGANIZATION" + "Tree frogs and bush-crickets refer to specific animal species which exhibit certain biological features and adhesive mechanisms.")<br>("entity" + 10f68536dac42a1fe1015b64ac551c32 + + + "GEO" + "micro-bulges refer to the structures on pillar tops that contribute to increased friction forces." + c08200d48689acf908730b5b5a937f1a + + + "MATERIAL" + "Polydimethylsiloxane that can be used in microstructures to improve mechanical properties and enhance adhesion." + cfd357f03ebd53bb7b20477337baa849 + + + "ORGANIZATION" + "Chen et al.'s team is involved in the research that examines different patterns of micro and nanostructures for understanding wet adhesion mechanics, as published in journals such as Phil.Trans.R.Soc.A.") + 56de28d5378ea95f859724f171540a25 + + + "PUBLISHING ORGANIZATION" + "This organization operates on the web, contributing to scientific publications and research dissemination." + 7959e16097062f8a4801b98295269a6a + + + "A SPECIFIC EXPERIMENT WAS CONDUCTED BY INCREASING RELATIVE HUMIDITY FOR OBSERVING ITS IMPACT ON SOLID-SOLID CONTACT RESISTANCE." + 5 + 7959e16097062f8a4801b98295269a6a + + + "THE REFERENCE TO A NAMED GROUP SUGGESTS A TEAM OF RESEARCHERS INVOLVED IN DESIGNING AND IMPLEMENTING THE LIQUID BRIDGE FORMING DEVICE." + 6 + 7959e16097062f8a4801b98295269a6a + + + + + 7959e16097062f8a4801b98295269a6a + + + + + 7959e16097062f8a4801b98295269a6a + + + "ORGANIZATION" + "This refers to a specific type of microchannel base bio-inspired patch that is being developed.") ("entity" + 2e431df92f1954d7fdf7449771dac2e1 + + + "PERSON" + "Co-author with Barthlott W, Neinhuis C contributed to the study of purity and contamination issues related to biological surfaces." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Sun J worked on nanomanufacturing bioinspired surfaces as presented in Tribol. Int." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Bhushan B is associated with Sun J's research and the field of nanotechnology." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Karl Autumn authored multiple works related to gecko adhesion, including explanations on structure, function, and applications." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Tobias Endlein contributed a study on wet adhesion in tree frogs which was part of an encyclopedia on nanotechnology." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "W. J.P. Barnes co-authored the work by Endlein on wet adhesion and has expertise in this area." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Wilfred R Hansen, alongside Autumn K, provided evidence for self-cleaning in gecko setae as reported in Proc. Natl Acad. Sci." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Nathaniel Crawford contributed research on self-cleaning mechanisms in tree frog toe pads without the need for grooming, as seen in J. Exp. Biol." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Sun Hu alongside Lopez S and Niewiarowski PH co-authored a paper on dynamic self-cleaning in gecko setae through digital hyperextension." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Co-author with Hu S, Lopez contributed to research on dynamic self-cleaning mechanisms in gecko setae." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Participated alongside Hu S and Lopez S in the study of dynamic self-cleaning processes in gecko setae." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Zeng Xia, together with Hu S et al., explored digital hyperextension mechanisms for self-cleaning in geckos." + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + "ORGANIZATION" + "Research focuses on the toe pads of this species as a source for developing new biomimetically inspired reversible adhesives.")<br>("entity" + 4d8b21398c70d24c39cd26cfa1dba5c0 + + + "PERSON" + "Aino T.'s research is focused on the high deformability of adhesive toe pads in White's tree frog, specifically through light and electron microscopic analyses.")|("entity" + 39bb4090056fa3afa0591e818ff2e48b + + + "ORGANIZATION" + "This system is comprised of 24 separate 3D force plates to study single limb forces in climbing animals on a quasi-cylindrical tower.") ("entity" + a2e84db4531e11bb05a5e5cbdb285bb8 + + + "PERSON" + "Samuel DS contributes to research on metamorphosis and maturation in hylid tree frogs at the Journal of Zoology.") ("entity" + b57944edc55bf9a8ed604f132186cac1 + + + "PERSON" + "Xue L contributed to research on bioinspired orientation-dependent friction as well as effective elastic modulus of structured adhesives.")|("entity" + 8d4a6778098c667728901fd5eb6ae286 + + + "PERSON" + "A is a co-author in the publication 'Microfluidic adhesion induced by subsurface microstructures' published in Science in 2007.") ("entity" + 221b04279ff2633a5d567aa14627c640 + + + "PERSON" + "Author Berg is associated with the publication 'Use of biomimetic hexagonal surface texture in friction against lubricated skin', indicating expertise or contribution to research in this field." + cda9b37513bc2f8036dfff4a389184d7 + + + "TEAM" + "The team of authors includes contributors from various institutions who together have published a paper on 'Highly permeable skin patch with conductive hierarchical architectures inspired by amphibians and octopi for omnidirectionally enhanced wet adhesion', showcasing collaborative research effort." + cda9b37513bc2f8036dfff4a389184d7 + + + "ORGANIZATION" + "The team of authors is associated with the publication in Advanced Functional Materials, suggesting that the paper has undergone peer review and was accepted for publication by this reputable scientific journal." + cda9b37513bc2f8036dfff4a389184d7 + + + + + cda9b37513bc2f8036dfff4a389184d7 + + + 1.0 + "Longjian Xue contributed significantly to bioinspired adhesive development through studying tree frog toe pad structures." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "W. Jon P. Barnes co-developed biomimetic adhesives and friction-generating devices with inspiration from natural climbing mechanisms." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "The primary focus of research in this area involves replicating the complex structures found on tree frogs' toes to enhance material performance." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "Bioinspiration has influenced the development of artificial adhesives and devices by providing natural solutions for their design." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "The study of adhesive mechanisms in nature, especially from climbing animals, serves as a fundamental source of information for bioinspired material advancements." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "Inspired by the biological adhesion properties of geckos, leading to advancements in material science and engineering applications." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + 1.0 + "Young's modulus of different materials influences the effectiveness and stability of pillar array designs used for biomimetic adhesive development." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + 1.0 + "Based on polydimethylsiloxane, a material known for its ease of handling and commercial availability." + c69e8300c5e976bc2e0c66e470f0371b + + + 1.0 + "Affects adhesion forces in hexagonal pillar configurations via AR calculations." + c69e8300c5e976bc2e0c66e470f0371b + + + 1.0 + "publishing organization is responsible for releasing scientific studies or findings like this study on tree frog-inspired adhesion." + 7959e16097062f8a4801b98295269a6a + + + 1.0 + "C was co-author with Barthlott W on work concerning purity and contamination issues related to biological surfaces." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Sun J is an author of the paper on nanomanufacturing bioinspired surfaces in Tribol. Int." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Is associated with Sun J's research and the field of nanotechnology as a co-author or author." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Karl Autumn is an author of works on gecko adhesion, including structure, function, and applications." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Tobias Endlein contributed to the study on wet adhesion in tree frogs as part of a broader work on nanotechnology." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "W. J.P. Barnes co-authored research with Endlein and likely has expertise in biological adhesion mechanisms." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Wilfred Hansen, along with Karl Autumn, provided evidence for self-cleaning gecko setae." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Nathaniel Crawford contributed research on self-cleaning mechanisms in tree frog toe pads as part of J. Exp. Biol." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Sun Hu co-authored the study with Lopez and Niewiarowski on dynamic self-cleaning in gecko setae using digital hyperextension." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Barthlott W contributed to studies on purity and contamination of biological surfaces in Planta." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Author Berg is directly linked to the publication 'Use of biomimetic hexagonal surface texture in friction against lubricated skin', indicating a specific contribution or lead authorship to this research work." + cda9b37513bc2f8036dfff4a389184d7 + + + 1.0 + "The team of authors collectively contributed to the publication 'Highly permeable skin patch with conductive hierarchical architectures inspired by amphibians and octopi for omnidirectionally enhanced wet adhesion', highlighting their collaborative effort in advancing biomimetic research." + cda9b37513bc2f8036dfff4a389184d7 + + + 1.0 + "The publication 'Highly permeable skin patch with conductive hierarchical architectures' was published in this journal, indicating that the research meets high standards for originality and scientific rigor as required by peer-reviewed journals." + cda9b37513bc2f8036dfff4a389184d7 + + + \ No newline at end of file diff --git a/indexing/output/20240722-073448/artifacts/raw_extracted_entities.json b/indexing/output/20240722-073448/artifacts/raw_extracted_entities.json new file mode 100644 index 0000000000000000000000000000000000000000..17537d1f0c9826fae1c85e83466f41202b2290dc --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/raw_extracted_entities.json @@ -0,0 +1,128 @@ +{"id":"4305d6610a2538765dc1ea9aed78ea5e","chunk":"BIOLOGICAL STRATEGY\n\nHow Air Sacs Power\n\nLungs in Birds\u2019\n\nRespiratory System\n\nLIVING SYSTEM:\n\nBirds\n\nAUTHOR:\n\nAskNature Team\n\nImage: Benoit Gauzere \/ CC BY\n\nFUNCTIONS PERFORMED:\n\nStore Gasses\n\nDistribute Gasses\n\nExpel Gasses\n\nOptimize Shape\/Material\n\nThe respiratory system of birds facilitates efficient exchange of carbon dioxide and oxygen by using air sacs to maintain a continuous unidirectional airflow through the lungs.\n\nThe avian respiratory system is notably different air travels down each primary bronchus and\n\nfrom the mammalian respiratory system, in both then divides: some air enters the lungs where gas its structure and its ability to exchange gas as exchange occurs, while the remaining air fills the efficiently as possible.\n\nposterior (rear) air sacs. Then, during the first exhalation, the fresh air in the posterior sacs enters It consists of paired lungs, which contain static the lungs and undergoes gas exchange. The spent structures with surfaces for gas exchange, and air in the lungs is displaced by this incoming air and connected air sacs, which expand and contract flows out the body through the trachea. During causing air to move through the static lungs. A the second inhalation, fresh air again enters both breath of oxygen-rich inhaled air remains in the the posterior sacs and the lungs. Spent air in the respiratory system for two complete inhalation lungs is again displaced by incoming air, but it and exhalation cycles before it is fully spent and cannot exit through the trachea because fresh exhaled out the body.\n\nair is flowing inward. Instead, the spent air from the lungs enters anterior (forward) air sacs. Then, When fresh air is first inhaled through a bird\u2019s nares during the second exhalation, the spent air in the (nostrils), it travels through the trachea (a large anterior sacs and in the lungs flows out through the tube extending from the throat), which splits into trachea, and fresh air in the posterior sacs enters left and right primary bronchi (called mesobronchi, the lungs for gas exchange.\n\nwith each bronchus leading to a lung). The inhaled\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nINHALATION\n\nEXHALATION\n\n\u00a9Biomimicry Institute\n\nWhen a bird inh","chunk_id":"4305d6610a2538765dc1ea9aed78ea5e","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"ASKNATURE TEAM\"","type":"\"ORGANIZATION\"","description":"\"AskNature Team is responsible for creating educational content about living systems, including birds.\")","source_id":"4305d6610a2538765dc1ea9aed78ea5e"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"AskNature Team is responsible for creating educational content about living systems, including birds.\")<\/data> 4305d6610a2538765dc1ea9aed78ea5e<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"a5430820e1ece1dff536ad804e55c798","chunk":" gas exchange.\n\nwith each bronchus leading to a lung). The inhaled\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nINHALATION\n\nEXHALATION\n\n\u00a9Biomimicry Institute\n\nWhen a bird inhales, air enters through the trachea and During exhalation, fresh air from the posterior air sac bronchus and flows into the lungs and posterior air sacs.\n\nmoves into the lungs, while stale air from the anterior air The fresh air moving into the lungs displaces stale air sacs is expelled through the bronchus and trachea.\n\nfrom the previous breath, moving it into the anterior air sacs.\n\nThis pattern of airflow through the respiratory greater surface area, allows a greater proportion system creates unidirectional (one-way) flow of of oxygen from each breath to be exchanged for\n\nfresh air over the gas exchange surfaces in the carbon dioxide from the blood and tissues.\n\nlungs. Furthermore, fresh air passes over the gas exchange surfaces during both inhalation This summary features contributions from Alex Uhrich.\n\nand exhalation, resulting in a constant supply of fresh air enabling the bird to experience a near-Visit this Strategy on AskNature:\n\ncontinuous state of gas exchange within the lungs.\n\nhttps:\/\/asknature.org\/how-birds-breathe\n\nThis contrasts with mammalian lungs, which\n\nexperience bidirectional (two-way) airflow over the gas exchange surfaces.\n\nReferences:\n\nThe efficiency of the avian respiratory system is BOOK\n\nowed in part to its unidirectional nature and in Ornithology. Macmillan. 01\/03\/2007. Gill, Frank B.\n\npart to the structure of its parabronchial system (the smaller passages within the lungs). The air JOURNAL ARTICLE\n\ncapillaries in the walls of the parabronchial system Structure of the avian respiratory tract. Respiration have a much larger overall surface area than that Physiology. 12\/02\/2003. Hans-Rainer Duncker.\n\nfound in the mammalian respiratory system. The\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nBirds That\n\nSurf the Air\n\nLIVING SYSTEM:\n\nPelicans\n\n\n\nAUTHOR:\n\nAndy Carstens\n\nImage: Russ \/ CC BY\n\nFUNCTIONS PERFORMED:\n\nMove Through Gases\n\nWhen pelican wings glide close to water, they","chunk_id":"a5430820e1ece1dff536ad804e55c798","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"GAS EXCHANGE\"","type":"\"PROCESS\"","description":"\"The process by which birds inhale and exhale air through their respiratory system for oxygen intake and carbon dioxide expulsion.\") (\"entity\"","source_id":"a5430820e1ece1dff536ad804e55c798"}],"entity_graph":" \"PROCESS\"<\/data> \"The process by which birds inhale and exhale air through their respiratory system for oxygen intake and carbon dioxide expulsion.\") (\"entity\"<\/data> a5430820e1ece1dff536ad804e55c798<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"8afa448acb86b96422cea043f3fd6749","chunk":" | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nBirds That\n\nSurf the Air\n\nLIVING SYSTEM:\n\nPelicans\n\n\n\nAUTHOR:\n\nAndy Carstens\n\nImage: Russ \/ CC BY\n\nFUNCTIONS PERFORMED:\n\nMove Through Gases\n\nWhen pelican wings glide close to water, they use \u201cground effect\u201d\n\nto minimize drag, maximize lift, and conserve energy.\n\nIt\u2019s low tide and a calm sea early in the morning as a flock of brown pelicans dips low and glides just above the surface of the Atlantic Ocean. The appearance may be graceful, but the real grace is efficiency. These birds are using tricks of physics to catch a nearly free ride over the deep.\n\nThe Strategy\n\nPelicans, skimmers, and other birds save energy when gliding across water because of something called the\n\n\u201cground effect,\u201d which increases lift and reduces drag.\n\n\n\nWhen a bird glides, it stretches its wings outward and rides the wind, saving the energy it would otherwise Image: \u00a9Biomimicry Institute\n\nuse to flap. In this \u201cfixed-wing\u201d mode of flight, some of the air that flows under the wing impacts it and washes As a pelican nears the water surface, the downwash below downward, pushing the wing (and bird) upward. In the wing compresses the air and creates a cushion of addition, the curvature of the wing causes the air above higher\u2011pressure air (yellow arrows). This results in more lift (red arrows). The water also partially blocks the formation it to move faster and drop in pressure, also contributing of vortices, and decreases drag.\n\nto the lift. Near the tips of the wings, the higher-pressure air below is able to push up into the region of lower pressure above and create swirling vortices. Both downwash and the vortices increase drag, adding to the amount of energy required to stay airborne.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nWhen birds fly just above the water, the relative effects Visit this Strategy on AskNature:\n\nof these forces change. Because there is less room for https:\/\/asknature.org\/pelican\u2011ground\u2011\n\ndownwash to disperse, it compresses the air between effect\n\nthe wing and the surface, creating a cushion of even higher pressure that increases lift. There is also less space for vortices to form, decreasing drag.\n\nThe Potential\n\nStudying methods that birds use","chunk_id":"8afa448acb86b96422cea043f3fd6749","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"ANDY CARSTENS\"","type":"\"PERSON\"","description":"\"Andy Carstens is an author who wrote about biological strategy of birds using ground effect to minimize drag and conserve energy when gliding over water.\") (\"entity\"","source_id":"8afa448acb86b96422cea043f3fd6749"}],"entity_graph":" \"PERSON\"<\/data> \"Andy Carstens is an author who wrote about biological strategy of birds using ground effect to minimize drag and conserve energy when gliding over water.\") (\"entity\"<\/data> 8afa448acb86b96422cea043f3fd6749<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"638dc502f70bb90aeb0465be8db1facc","chunk":".org\/pelican\u2011ground\u2011\n\ndownwash to disperse, it compresses the air between effect\n\nthe wing and the surface, creating a cushion of even higher pressure that increases lift. There is also less space for vortices to form, decreasing drag.\n\nThe Potential\n\nStudying methods that birds use to save energy flying References:\n\ncan lead to innovations that help airplanes fly more efficiently, reducing fuel consumption and greenhouse JOURNAL ARTICLE\n\ngas emissions. Flying drones that survey and study Induced Drag Savings From Ground Effect and\n\nwaterways might be designed to glide close to the Formation Flight in Brown Pelicans. Journal water to optimize energy and cover farther distances.\n\nof Experimental Biology. 1988. F. Reed\n\nAnd in the rising development of electric airplanes, it\u2019s Hainsworth.\n\ngoing to be particularly helpful to save as much energy as possible to help battery charges last as long as possible.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nHow Flying Squirrels\n\nControl Their Glide\n\nLIVING SYSTEM:\n\nFlying squirrels\n\nAUTHOR:\n\nAndy Carstens\n\nImage: Christian Collins \/ CC BY-SA\n\nFUNCTIONS PERFORMED:\n\nMove in\/Through Gases\n\nFlying squirrels have membranes and cartilage that help them change lift and drag forces, enabling them to glide more than 100\n\ntimes their body length.\n\nSeveral hours before the sun rises in a conifer forest in Another membrane stretches from each ankle to the Alaska, a northern flying squirrel ( Glaucomys sabrinus) tail.\n\nleaps from a high tree branch. Launching forward, it stretches its arms and legs out as far as possible, Changes in body position allow the squirrel to alter opening parachute-like membranes between them to aerodynamic forces such as lift and drag. When\n\ncatch the wind. The squirrel then glides to a tree 100\n\nresearchers studied the aerodynamics of flying feet (30 meters) away where it hopes to find fungi to squirrels by filming and analyzing their glides in nature, eat.\n\nthey found the squirrels did not glide under equilibrium, but instead continuously changed their velocities and The ability to glide has evolved at least six separate forces throughout three phases of \u201cflight.\u201d During times in mammals, suggesting it gives certain species those phases, the squirrel\u2019s body tilts up, and the net advantages that may include saving the energy from aerodynamic forces rotate from pointing forward to walking and climbing, expanding their foraging","chunk_id":"638dc502f70bb90aeb0465be8db1facc","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"FLYING SQUIRRELS\"","type":"\"ORGANISM\"","description":"\"The Flying squirrels are the subject of study due to their ability to control their glide.\"","source_id":"638dc502f70bb90aeb0465be8db1facc"}],"entity_graph":" \"ORGANISM\"<\/data> \"The Flying squirrels are the subject of study due to their ability to control their glide.\"<\/data> 638dc502f70bb90aeb0465be8db1facc<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"e9161c0416f80b08625e2dcd9f70167f","chunk":" to glide has evolved at least six separate forces throughout three phases of \u201cflight.\u201d During times in mammals, suggesting it gives certain species those phases, the squirrel\u2019s body tilts up, and the net advantages that may include saving the energy from aerodynamic forces rotate from pointing forward to walking and climbing, expanding their foraging range, upward, and then towards the back. This corresponds or avoiding exposure to predators.\n\nto its acceleration increasing, reaching its peak, and decreasing.\n\nThe Strategy\n\nA flying squirrel\u2019s ability to glide comes from two The scientists called the first phase a ballistic dive, anatomical features\u2014membranes and cartilage. It has characterized by the height from which it leaps (its two sets of membranes that are composed of skin and potential energy), the forward momentum it gains muscle. One membrane stretches between each wrist through leaping, and the acceleration it picks up and ankle, forming wing-like flaps. Behind the wrist are because of gravity. During this phase, both lift and drag pieces of cartilage that bend upward like the tips of are small.\n\nairplane wings to improve stability and minimize drag.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nIllustration by Charles Dessalines D\u2019 Orbigny (1806-1876) \/ public domain Next comes the cruising phase, where the squirrel Visit this Strategy on AskNature: deploys its membranes, and the forces of lift and drag https:\/\/asknature.org\/how-flying-increase. In this phase, the squirrel\u2019s body begins to tilt squirrels-glide\n\nfrom horizontal to upright (its head above its tail). As it does so, lift increases to beyond the force of gravity, and the squirrel\u2019s glide path flattens. Now instead of it both falling downward and gliding forward it\u2019s just moving horizontally forward.\n\nIn the final phase, the squirrel\u2019s body position is nearly vertical. Lift increases significantly, and the net aerodynamic force continues to rotate rearward, slowing the squirrel enough so it can land. Just before landing, lift is so high that its glide path curves slightly upward moving the squirrel to a completely vertical position before it grabs on to the tree trunk.\n\nReferences:\n\nJOURNAL ARTICLE\n\nThe Potential\n\nGlide performance and aerodynamics of\n\nUnderstanding how mammals like the northern flying squirrel glide could improve parachute and skydiving non-equilibrium glides in northern flying\n\nsuit designs as well as improve airplane aeronautics.\n\nsquirrels (Glau","chunk_id":"e9161c0416f80b08625e2dcd9f70167f","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"BIOMIMICRY INSTITUTE\"","type":"\"ORGANIZATION\"","description":"\"The organization that provides insight and information on biological strategies for human design, specifically in this case the glide mechanism of flying squirrels. They suggest how understanding such biological performance could be applied to improve various human technologies like parachutes and skydiving suits.\") (\"entity\"","source_id":"e9161c0416f80b08625e2dcd9f70167f"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The organization that provides insight and information on biological strategies for human design, specifically in this case the glide mechanism of flying squirrels. They suggest how understanding such biological performance could be applied to improve various human technologies like parachutes and skydiving suits.\") (\"entity\"<\/data> e9161c0416f80b08625e2dcd9f70167f<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"a3d83dc700d8d01b07a94c2a1180c2b4","chunk":" the tree trunk.\n\nReferences:\n\nJOURNAL ARTICLE\n\nThe Potential\n\nGlide performance and aerodynamics of\n\nUnderstanding how mammals like the northern flying squirrel glide could improve parachute and skydiving non-equilibrium glides in northern flying\n\nsuit designs as well as improve airplane aeronautics.\n\nsquirrels (Glaucomys sabrinus). Journal of\n\nThis could help improve efficiency and reduce\n\nthe Royal Society Interface. 2012. Joseph W.\n\ngreenhouse gas emissions in planes that currently burn Bahlman , Sharon M. Swartz, Daniel K. Riskin,\n\nfossil fuels. In the future, electric planes may need and Kenneth S. Breuer.\n\nmaximum efficiency to help batteries last as long as possible.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nAsymmetric Burrow\n\nOpenings Create\n\nPassive Ventilation\n\nLIVING SYSTEM:\n\nBlack-tailed prairie dog\n\nAUTHOR:\n\nAskNature Team\n\nImage: Dhinakaran Gajavarathan \/ CC BY\n\nFUNCTIONS PERFORMED:\n\nDistribute Gases\n\nDifferences in position and shape of burrow openings of black\u2011tailed prairie dogs create passive ventilation from wind energy by altering air pressure.\n\nPrairie dogs are highly social rodents that build extensive underground burrows in the plains of\n\nNorth America to house their family groups. The burrows can reach 10 m (32 ft) in length, and this size means that diffusion alone is not sufficient to A\n\nB\n\nreplace used air inside the burrow with fresh air.\n\nThe way that a prairie dog builds the openings\n\nto its burrow, however, helps to harness wind\n\nenergy from the windy plains and create passive ventilation through the burrow\u2019s tunnels.\n\nAs air flows across a surface, a gradient in flow speed forms, where air moves more slowly the\n\nAir moves faster the further it is from the ground closer it is to the surface. The prairie dog is able surface. At the mouth of the elevated burrow to take advantage of this gradient by building\n\nopening (A), fast moving winds suck air out of the burrow. At the mouth of the lower opening (B), slower a mound with an elevated opening upwind and\n\nmoving air flow flows in. Image: \u00a9 Morgane Rae, used a mound with a lower opening downwind. Wind\n\nwith permission.\n\nvelocity then is faster over the higher opening than the lower opening. Since an increase in","chunk_id":"a3d83dc700d8d01b07a94c2a1180c2b4","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"ASKNATURE TEAM\"","type":"\"ORGANIZATION\"","description":"\"The entity 'AskNature Team' conducts research and educational programs on biomimicry, looking to nature for solutions in technology, design, and problem solving.\"","source_id":"a3d83dc700d8d01b07a94c2a1180c2b4"},{"name":"\"JOSEPH W. BAHLMAN\", \"SHARON M. SWARTZ\", \"DANIEL K. RISKIN\", \"KENNETH S. BREUER\"","type":"\"PERSON\"","description":"\"This refers to researchers who contributed to a study on gliding performance of mammals, particularly northern flying squirrels (Glaucomys sabrinus).\"","source_id":"a3d83dc700d8d01b07a94c2a1180c2b4"},{"name":"\"BLACK-TAILED PRAIRIE DOG\"","type":"\"ORGANISM\"","description":"\"The Black-tailed prairie dog is an animal that builds extensive burrows in the plains of North America and performs functions like distributing gases.\"","source_id":"a3d83dc700d8d01b07a94c2a1180c2b4"},{"name":"\"DHINAKARAN GAJAVARATHAN\"","type":"\"CREATIVE WORKER\"","description":"\"This refers to a photographer whose image has been used in publications related to nature studies, with permission granted for use.\"","source_id":"a3d83dc700d8d01b07a94c2a1180c2b4"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The entity 'AskNature Team' conducts research and educational programs on biomimicry, looking to nature for solutions in technology, design, and problem solving.\"<\/data> a3d83dc700d8d01b07a94c2a1180c2b4<\/data> <\/node> \"PERSON\"<\/data> \"This refers to researchers who contributed to a study on gliding performance of mammals, particularly northern flying squirrels (Glaucomys sabrinus).\"<\/data> a3d83dc700d8d01b07a94c2a1180c2b4<\/data> <\/node> \"ORGANISM\"<\/data> \"The Black-tailed prairie dog is an animal that builds extensive burrows in the plains of North America and performs functions like distributing gases.\"<\/data> a3d83dc700d8d01b07a94c2a1180c2b4<\/data> <\/node> \"CREATIVE WORKER\"<\/data> \"This refers to a photographer whose image has been used in publications related to nature studies, with permission granted for use.\"<\/data> a3d83dc700d8d01b07a94c2a1180c2b4<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"fb3016519d20d8e4fc1d25d5690a550a","chunk":" mouth of the lower opening (B), slower a mound with an elevated opening upwind and\n\nmoving air flow flows in. Image: \u00a9 Morgane Rae, used a mound with a lower opening downwind. Wind\n\nwith permission.\n\nvelocity then is faster over the higher opening than the lower opening. Since an increase in\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nImage: Ken Lund \/ CC BY-SA\n\nPrairie dogs live in \u201ctowns\u201d that house multiple family groups in a large network of burrows. The varied height and distribution of the burrow openings is evident in this prairie dog town at Theodore Roosevelt National Park, North Dakota, USA.\n\nspeed creates a decrease in pressure (according Visit this Strategy on AskNature:\n\nto what is called \u201cBernoulli\u2019s principle\u201d), the burrow https:\/\/asknature.org\/prairie-dog-air-flow now has openings with two different air pressures on them. The result of this difference is one-way air flow through the burrow as air rushes out\n\nthe higher opening and is drawn in to the lower opening.\n\nReferences:\n\nThe mounds around the burrow openings serve\n\nJOURNAL ARTICLE\n\nadditional functions for the prairie dog, like\n\nWind-induced ventilation of the burrow of the\n\nproviding a perch to watch for predators. Other prairie-dog, Cynomys ludovicianus. Journal of Comparative Biology, 85(1): 1\u201314. 1\/3\/1973.\n\norganisms use a similar arrangement of openings Steven Vogel, Charles P. Ellington, Delbert L.\n\nto generate passive flow, including sea sponges Kilgore.\n\nand limpets.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nOff-Target Clicks Help\n\nFruit Bats Find Food\n\nLIVING SYSTEM:\n\nEgyptian fruit bat\n\nAUTHOR:\n\nMary Hoff\n\nImage: Lithuania Zoological Gardens \/ CC BY-SA FUNCTIONS PERFORMED:\n\nNavigate Through Air\n\nThese fruit-eating bats home in on a meal by aiming sound waves to the side of their intended target, then adjusting their path to reduce the difference in timing between the waves bouncing back.\n\nIt\u2019s a sweltering night in Saudi Arabia. Suddenly, initial calls don\u2019t provide much information about how something the size of a small dog swoops by through the searcher and the searched are moving side to","chunk_id":"fb3016519d20d8e4fc1d25d5690a550a","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"ASKNATURE.ORG\"","type":"\"ORGANIZATION\"","description":"\"AskNature.org is an online resource provided by the Biomimicry Institute that showcases biological strategies for human inspiration and problem-solving.\") (\"entity\"","source_id":"fb3016519d20d8e4fc1d25d5690a550a"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"AskNature.org is an online resource provided by the Biomimicry Institute that showcases biological strategies for human inspiration and problem-solving.\") (\"entity\"<\/data> fb3016519d20d8e4fc1d25d5690a550a<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"d99568b2216b6501020a719efe70edaf","chunk":" side of their intended target, then adjusting their path to reduce the difference in timing between the waves bouncing back.\n\nIt\u2019s a sweltering night in Saudi Arabia. Suddenly, initial calls don\u2019t provide much information about how something the size of a small dog swoops by through the searcher and the searched are moving side to side the air. Is it a bird? A drone? No, it\u2019s an Egyptian fruit relative to each other. As a result, such an approach has bat, in search of overripe figs.\n\nlimited value in helping the animal fine-tune its position as it moves closer to its target.\n\nLike other bats, this outsized flying mammal finds its food by clicking its tongue to produce sound waves Enter the sound waves at the perimeter of the cone.\n\nand observing how they bounce back. At first it aims If the bat aims its clicks to the side of the object, the its clicks widely as it searches for a piece of fruit. Once sound waves that bounce back from the slanted part the returning sound waves reveal food item, however, of the cone of sound contain more information about the search strategy changes. Rather than pointing the the relative movement between the searcher and\n\nsound waves directly the object of its desire, the bat the searched than would those aimed directly at the aims them slightly left and then slightly right of the object. By listening for the bounce back of sound waves target. Although this strategy seems counterintuitive, at the edge of the cone where the difference in timing it improves the accuracy with which the bat can land on is larger, the bat can more easily tell if it\u2019s getting its favored food.\n\n\u201cwarmer\u201d or \u201ccolder\u201d from one click to the next and adjust its trajectory accordingly.\n\nThe Strategy\n\nSound waves travel in an expanding, cone-shaped path This is similar to the effect that we perceive when from their source. The best way for an animal using viewing an object in light that shines nearly parallel echolocation to find an object in the first place is to to a surface, as the sun does at dawn and dusk. In this point its clicks in lots of different directions. But these\n\n\u201craking light,\u201d shadows are greatly extended, making\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\ntiny objects and textures dramatically more noticeable.\n\nThe bats are making use of \u201craking sound.\u201d By angling their high-pitched sounds to either side of an object of interest, the echo comes","chunk_id":"d99568b2216b6501020a719efe70edaf","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"SAM RIVERA\"","type":"\"PERSON\"","description":"\"Sam Rivera is a part of an organization working in Saudi Arabia where they are using echolocation for food searching. He is also involved with an Egyptian fruit bat.\"","source_id":"d99568b2216b6501020a719efe70edaf"}],"entity_graph":" \"PERSON\"<\/data> \"Sam Rivera is a part of an organization working in Saudi Arabia where they are using echolocation for food searching. He is also involved with an Egyptian fruit bat.\"<\/data> d99568b2216b6501020a719efe70edaf<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"74a8b683e829577d39bd3b12018ddee0","chunk":"2 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\ntiny objects and textures dramatically more noticeable.\n\nThe bats are making use of \u201craking sound.\u201d By angling their high-pitched sounds to either side of an object of interest, the echo comes back not as a bright, direct beam, but in steeply angled waves that exaggerate any relative change in position of the object, revealing more information to the bat with every click it makes.\n\nThe Potential\n\nThe \u201csweet spot\u201d the fruit bat has found between maximizing its odds of finding food and maximizing its odds of landing on it accurately is similar to strategies other animals likely use to follow sounds, scents, or other signals from a desired object. This suggests it is broadly beneficial as a \u201choming-in strategy.\u201d Humans might apply a similar strategy to optimizing the search function for drones or other robots that use light, sound, Egyptian fruit bat in flight. Image: Oren Peles \/ CC BY\n\nor scent to track objects. The side-to-side switch-out also could be helpful for keeping aircraft on the straight and narrow during taxiing or flight or improving self-driving vehicles\u2019 ability to stay in their lane with the fine-tuned finesse a skilled driver might use.\n\nVisit this Strategy on AskNature:\n\nhttps:\/\/asknature.org\/\/off-center-\n\nReferences:\n\nechoes\n\nJOURNAL ARTICLE\n\nOptimal localization by pointing off axis. Science.\n\nFebruary 5, 2010. Yossi Yovel, Ben Falk, Cynthia F. Moss, Nachum Ulanovsky.\n\nOTHER\n\n\u2018Zen\u2019 bats hit their target by not aiming at it.\n\nScienceDaily. February 5, 2010. University of Maryland.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nThe Frog That Plays\n\nTree Holes Like\n\na Pipe Organ\n\nLIVING SYSTEM:\n\nBornean tree-hole frog\n\nAUTHOR:\n\nAndy Carstens\n\nImage: Bernard Dupont \/ CC BY-SA\n\nFUNCTIONS PERFORMED:\n\nSend Sound Signals\n\nThe tree\u2011hole frog amplifies the sound of its call by adjusting its pitch to match the resonant frequency of its surroundings.\n\nIn a Malaysian rainforest, a male tree-hole frog example, when the frequency of sound matches the wriggles inside a water-filled tree hollow, getting ready resonant frequency of a wineglass, the glass vibrates so to call a mate. His call","chunk_id":"74a8b683e829577d39bd3b12018ddee0","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"BIOMIMICRY INSTITUTE\"","type":"\"ORGANIZATION\"","description":"\"Biomimicry Institute is an organization that studies and applies principles observed in nature to solve human problems.\"","source_id":"74a8b683e829577d39bd3b12018ddee0"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"Biomimicry Institute is an organization that studies and applies principles observed in nature to solve human problems.\"<\/data> 74a8b683e829577d39bd3b12018ddee0<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"aff4d366caa94978fbabd1021d43d555","chunk":" its pitch to match the resonant frequency of its surroundings.\n\nIn a Malaysian rainforest, a male tree-hole frog example, when the frequency of sound matches the wriggles inside a water-filled tree hollow, getting ready resonant frequency of a wineglass, the glass vibrates so to call a mate. His call is a single-note pulse, and the hard that it breaks.\n\nlouder it sounds, the farther it will reach, increasing the likelihood that a female will hear and respond to it.\n\nPipe organs form a particular note by forcing air through a pipe of a specific diameter and length, which The Strategy\n\ncauses the pipe to vibrate at its resonant frequency.\n\nLike other frogs, the tree-hole frog uses vocal cords If a tree-hole frog sat inside the pipe of a pipe organ and a vocal sac to croak. Instead of expelling exhaled and adjusted his pitch to match the pipe\u2019s resonant air like most other animals do when they make noise, frequency, the pipe would vibrate along with the frog\u2019s frogs pass exhaling air across their vocal cords, then vocal sac, boosting the sound volume. In a sense, a tree-into their vocal sacs. The vocal sac itself is a natural hole frog plays a tree hole like a pipe organ.\n\nsound amplifier, vibrating like the top of a kettle drum to transfer the sound of its call into the air.\n\nOne thing that affects the resonant frequency of a tree hole is the amount of water inside it. When scientists But tree-hole frogs don\u2019t simply rely on their own put a male tree-hole frog in a tube and slowly drained anatomy to amplify sound. They also use their watery water from it, the frog continually tweaked his call to holes as echo chambers. The frogs adjust the pitch of match the changing resonant frequency. Furthermore, their calls until they find the resonant frequency of their when the frog found the resonant frequency, his croaks surroundings.\n\nwere longer in duration with fewer breaks in between, suggesting that when the amplifying effect is found, The resonant frequency is the frequency at which it\u2019s worth the energetic cost to increase the chances of a substance vibrates at its highest amplitude. For finding a mate.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nThe Potential\n\nLearning how tree-hole frogs use their surroundings References:\n\nto boost sound could lead to improved architectural JOURNAL ARTICLE\n\ndesigns that incorporate acoustics. Schools for Tree-hole","chunk_id":"aff4d366caa94978fbabd1021d43d555","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"TREE-HOLE FROG\"","type":"\"ORGANISM\"","description":"\"A species of frog specifically adapted to living in water-filled tree hollows, utilizing their environment to amplify vocal calls.|) (\"entity\"","source_id":"aff4d366caa94978fbabd1021d43d555"}],"entity_graph":" \"ORGANISM\"<\/data> \"A species of frog specifically adapted to living in water-filled tree hollows, utilizing their environment to amplify vocal calls.|) (\"entity\"<\/data> aff4d366caa94978fbabd1021d43d555<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"4d6faade61b11859190946a315c34a2e","chunk":"\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nThe Potential\n\nLearning how tree-hole frogs use their surroundings References:\n\nto boost sound could lead to improved architectural JOURNAL ARTICLE\n\ndesigns that incorporate acoustics. Schools for Tree-hole frogs exploit resonance effects. Nature.\n\nhearing-impaired children could be designed to\n\n2002. Bj\u00f6rn Lardner, Maklarin bin Lakim.\n\nnaturally amplify sound. Electronic devices such as televisions and audio players could be designed to use less energy by amplifying sound based on the resonance of their locations.\n\nVisit this Strategy on AskNature:\n\nhttps:\/\/asknature.org\/tree-frog-call\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nThe Snakes That\n\nBellow Like Bulls\n\nLIVING SYSTEM:\n\nBull snakes and relatives\n\nAUTHOR:\n\nAndy Carstens\n\nImage: Dallas Krentzel \/ CC BY\n\nFUNCTIONS PERFORMED:\n\nSend Sound Signals\n\nWhen bull snakes and their relatives bellow in defense, tissue boosts air flow as it passes over a single vocal cord to create an initial burst of sound.\n\nA snake is slinking across a grassy meadow when a and constant-frequency sound that resembles a hiss.\n\nred-tailed hawk swoops from the sky to try to catch it.\n\nThe researchers found that bull snakes also hiss during In response, the snake lets out a loud bellowing sound their third or fourth exhalation, which resembles the that earns it the name of \u201cbull snake.\u201d\n\nsecond portion of the bellow in its low amplitude and constant frequency.\n\nNo other genus of snake is known to make such a sound.\n\nWhat\u2019s going on?\n\nPituophis snakes have a few unique anatomical features that help create these sounds. For one, these snakes The Strategy\n\nare the only known animals to have a single vocal cord.\n\nWhen a bull snake, gopher snake, or pine snake Other animals have paired vocal cords made of smooth (all members of the genus Pituophis) is attacked or muscle tissue that vibrate and constrict to change the frightened it makes two defensive noises. Both noises pitch of the sounds they make.\n\nresult from when the snake forces air through its larynx while exhaling, similar to how humans can only speak Whereas human vocal cords are paired and vertically while exhaling.\n\noriented, bull snakes and their relatives have a","chunk_id":"4d6faade61b11859190946a315c34a2e","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"BIOMIMICRY INSTITUTE\"","type":"\"ORGANIZATION\"","description":"\"Institute dedicated to fostering innovation inspired by nature, focusing on sustainable design and technology.\"","source_id":"4d6faade61b11859190946a315c34a2e"},{"name":"\"BULL SNAKES\"&\"PITUOPHIS SNAKES\"","type":"\"SPECIES\"","description":"\"Specific types of snakes known for their unique ability to create loud defensive sounds.\"","source_id":"4d6faade61b11859190946a315c34a2e"},{"name":"\"ANDY CARSTENS\"","type":"\"PERSON\"","description":"\"An author who has contributed content related to natural phenomena and innovations inspired by nature.\"","source_id":"4d6faade61b11859190946a315c34a2e"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"Institute dedicated to fostering innovation inspired by nature, focusing on sustainable design and technology.\"<\/data> 4d6faade61b11859190946a315c34a2e<\/data> <\/node> \"SPECIES\"<\/data> \"Specific types of snakes known for their unique ability to create loud defensive sounds.\"<\/data> 4d6faade61b11859190946a315c34a2e<\/data> <\/node> \"PERSON\"<\/data> \"An author who has contributed content related to natural phenomena and innovations inspired by nature.\"<\/data> 4d6faade61b11859190946a315c34a2e<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"42b463f5b40c4f86e9338c967c8d5bfa","chunk":"strict to change the frightened it makes two defensive noises. Both noises pitch of the sounds they make.\n\nresult from when the snake forces air through its larynx while exhaling, similar to how humans can only speak Whereas human vocal cords are paired and vertically while exhaling.\n\noriented, bull snakes and their relatives have a single cord that is oriented horizontally across the top portion Scientists recorded bull snake defensive noises in an of the larynx. The bellowing likely occurs when air flows acoustic chamber and analyzed their characteristics.\n\nover the tensed vocal cord, causing it to vibrate.\n\nThey found that the snakes bellow usually during the first or second exhalation. The bellow is characterized The scientists also found that another piece of tissue, by a high amplitude (louder-sounding) burst of sound called the epiglottal keel, had a minor role in the bellow.\n\nfollowed by a longer period of low-amplitude (quieter) The keel is an oblong and stiff piece of tissue that sits\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nin the path of the air flow and divides it like a boulder might split a river into two streams. When the snakes References:\n\npartially close their mouths, it\u2019s like having a bigger JOURNAL ARTICLE\n\nboulder dividing a river that forces the water (or air Sound production in Pituophis melanoleucus\n\nwith the snakes) down narrower paths. Having more air (Serpentes: Colubridae) with the first\n\npass through partially obstructed paths amplifies the description of a vocal cord in snakes. Journal of sound of the bellow\u2019s initial burst.\n\nExperimental Zoology. 1995. Bruce A. Young, The Potential\n\nStan Sheft, William Yost.\n\nStudying how snakes vocalize and amplify their sound could lead to devices that amplify sound through their structure, as opposed to through electronic means.\n\nWarning systems that alert people to natural disasters might one day use structural elements to efficiently carry sound further. Or perhaps they could lead to a revolution in hearing aid design.\n\nVisit this Strategy on AskNature:\n\nhttps:\/\/asknature.org \/bull-snake-bellow\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nBody Uses Vortices\n\nto Save Energy\n\nLIVING SYSTEM:\n\nRainbow trout\n\nAUTHOR:\n\nAskNature","chunk_id":"42b463f5b40c4f86e9338c967c8d5bfa","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"ASKNATURE.ORG\"","type":"\"ORGANIZATION\"","description":"\"AskNature.org is a resource platform for biologically inspired innovations. It showcases strategies, organisms and ideas that can be applied to solve human challenges through nature's principles.\")","source_id":"42b463f5b40c4f86e9338c967c8d5bfa"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"AskNature.org is a resource platform for biologically inspired innovations. It showcases strategies, organisms and ideas that can be applied to solve human challenges through nature's principles.\")<\/data> 42b463f5b40c4f86e9338c967c8d5bfa<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"891d3f28f888b374a21d9c781295bbf9","chunk":"Nature:\n\nhttps:\/\/asknature.org \/bull-snake-bellow\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nBody Uses Vortices\n\nto Save Energy\n\nLIVING SYSTEM:\n\nRainbow trout\n\nAUTHOR:\n\nAskNature Team\n\n\u00a9 Olexander Kozak \/ Shutterstock\n\nFUNCTIONS PERFORMED:\n\nMove in\/on Liquids\n\nModify Position\n\nThe body of rainbow trout decreases energy required for swimming by interacting with vortices in its fluid environment.\n\nMany fish swim using an undulating motion of their bodies. The muscle activity that bends the body and produces these movements during steady, continuous swimming can cost a significant amount of energy. But some fishes, such as rainbow trout, can adopt a special swimming behavior that likely enables them to save their own energy by extracting energy from nearby water vortices.\n\nIn a fluid environment, vortices are swirls of water or air often released (or \u201cshed\u201d) from stationary objects and other living creatures, including other fish, that are in the path of an oncoming flow.\n\nTrout use water vortices that come their way from upstream sources to their advantage by adjusting their typical swimming behavior to produce a\n\n\u2018slalom\u2019 movement between vortices. Body bends\n\nincrease in amplitude and curvature, and the tail beats at a frequency that matches the frequency at which vortices are shed upstream. The pattern of muscle activity along the body also changes, Image: \u00a9Biomimicry Institute\n\nwhere only muscles close to the head are active.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nThis differs from typical undulating motion where The general concept of taking advantage of muscles contract all along the body, starting altered fluid flows behind other objects to reduce from the head and moving toward the tail to the energetic cost of motion is found in human produce a traveling body wave that pushes the behaviors too, for instance, in cyclists that draft fish forward. Researchers hypothesize that these behind one another to save energy.\n\nchanges in muscle activity and body motion help the trout position its body so that it interacts with Visit this Strategy on AskNature:\n\nthe vortices in a specific way. The exact nature https:\/\/asknature.org\/trout-vortices\n\nof this interaction is still under investigation, but one explanation is that the fish controls the angle of its body so that local flow from the vortices produces","chunk_id":"891d3f28f888b374a21d9c781295bbf9","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"BIOMIMICRY INSTITUTE\"","type":"\"ORGANIZATION\"","description":"\"The organization behind AskNature and its educational content on nature-based solutions and inspirations for human innovation.\"","source_id":"891d3f28f888b374a21d9c781295bbf9"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The organization behind AskNature and its educational content on nature-based solutions and inspirations for human innovation.\"<\/data> 891d3f28f888b374a21d9c781295bbf9<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"8fa82d96bb00621623d0d7c9e9ac5034","chunk":" it interacts with Visit this Strategy on AskNature:\n\nthe vortices in a specific way. The exact nature https:\/\/asknature.org\/trout-vortices\n\nof this interaction is still under investigation, but one explanation is that the fish controls the angle of its body so that local flow from the vortices produces a continuous upstream force on the body. Scientist James Liao uses the analogy, \u201c\u2026we hypothesize that trout use their body like a sail to tack upstream.\u201d\n\nReferences:\n\nJOURNAL ARTICLE\n\nJOURNAL ARTICLE\n\nFish Exploiting Vortices Decrease Muscle Activity.\n\nThe Karman gait: novel body kinematics of rainbow Science. 28\/11\/2003. James C. Liao, David N.\n\ntrout swimming in a vortex street. Journal of Beal, George V. Lauder, Michael S. Triantafyllou.\n\nExperimental Biology. 11\/02\/2003. James C.\n\nLiao, David N. Beal, George V. Lauder, Michael\n\nJOURNAL ARTICLE\n\nS. Triantafyllou\n\nPassive propulsion in vortex wakes. J. Fluid Mech.\n\n08\/02\/2006. D. N. Beal, F. S. Hover, M. S.\n\nTriantafyllou, J. C. Liao, G. V. Lauder.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nTiny Structures Help\n\nButterflies Soar\n\nLIVING SYSTEM:\n\nButterflies\n\nAUTHOR:\n\nMary Hoff\n\nFUNCTIONS PERFORMED:\n\nMove in\/Through Gases\n\nManage Turbulence\n\nMicroscopic scales provide lift to nature\u2019s \u201cflying flowers.\u201d\n\nThe vivid orange, iridescent blues, deep blacks, and Natural observations and experiments have shown that other astounding colors showcased on the wings of with fewer scales, butterflies don\u2019t flap their wings as nature\u2019s flying flowers\u2013\u2013butterflies\u2013\u2013are due to the way fully, and they have a harder time flying upward. Though the hundreds of thousands of microscopic scales that the details are not yet well defined or described, it\u2019s cover the wings reflect light. But it turns out that\u2019s not clear that scales help the butterfly fly by providing lift.\n\nthe only benefit of these shingle-like structures. The configuration of the scales also contributes to flying The organized patterns of bumps created by fish scales efficiency as the butterfly dances and dips its way are known to reduce drag essentially by comb","chunk_id":"8fa82d96bb00621623d0d7c9e9ac5034","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"VISIT THIS STRATEGY ON ASKNATURE\"","type":"\"ACTION\"","description":"\"Visiting a specific strategy on AskNature for investigation into interactions between vortices and trout. The website provides scientific articles related to the topic.\"","source_id":"8fa82d96bb00621623d0d7c9e9ac5034"}],"entity_graph":" \"ACTION\"<\/data> \"Visiting a specific strategy on AskNature for investigation into interactions between vortices and trout. The website provides scientific articles related to the topic.\"<\/data> 8fa82d96bb00621623d0d7c9e9ac5034<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"01117b72383429324254870387eb4aba","chunk":". But it turns out that\u2019s not clear that scales help the butterfly fly by providing lift.\n\nthe only benefit of these shingle-like structures. The configuration of the scales also contributes to flying The organized patterns of bumps created by fish scales efficiency as the butterfly dances and dips its way are known to reduce drag essentially by combing the through the air.\n\npassing water into smooth, orderly layers. Butterfly scales may produce a similar effect. They also can alter The Strategy\n\nthe formation of vortices in certain parts of the wing.\n\nIn animals and inanimate objects alike, four forces make For instance, the bumps created by overlapping scales flight possible: lift, weight, thrust, and drag. When all at the front end of the wings could slow the formation of balance out, the object stays in one position in the air, vortices there and reduce the amount of energy going like a hummingbird or a helicopter. If one or more are into forming the vortices. Since vortices create drag as stronger than the others, the object moves up, down, they spin off the surface, this would decrease drag and forward, or backward.\n\ntherefore increase lift and thrust.\n\nThe surface of a butterfly\u2019s wing is covered with The Potential\n\nhundreds of thousands of overlapping scales, arranged By studying how various configurations of butterfly like shingles on a roof. The size, shape, and orientation wing scales affect flight, designers can get ideas of the scales alters the relative size of the four forces for how to improve the efficiency and versatility of flight by affecting how air flows over the butterfly\u2019s of the flight of conventional aircraft, parachutes, wings and how vortices (air swirls) form.\n\nkites, drones, and other objects traveling through\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\n(L) A close-up view shows how scales are arranged along the surface of a butterfly\u2019s wing. Image: J. MichaD \/ CC BY-SA. (R) The texture created by tiny scales that coat a butterfly\u2019s wing affect airflow and so enhance the ability to fly.\n\nImage captured by scanning electron microscope, 50x magnification. Image: Secret Disc \/ CC BY-SA the air. They might also inform the design of more Visit this Strategy on AskNature:\n\nefficient wind turbines and reduce the materials https:\/\/asknature.org\/butterfly-needed for structural stability in tall buildings. The scales-lift\n\nmicro-geometry of wing scales can","chunk_id":"01117b72383429324254870387eb4aba","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"BUTTERFLY WINGS\"","type":"\"OBJECT\"","description":"\"Butterfly wings are a natural model that shows how micro-geometrical patterns enhance airflow and facilitate flight through specific scale configurations.\") (\"entity\"","source_id":"01117b72383429324254870387eb4aba"}],"entity_graph":" \"OBJECT\"<\/data> \"Butterfly wings are a natural model that shows how micro-geometrical patterns enhance airflow and facilitate flight through specific scale configurations.\") (\"entity\"<\/data> 01117b72383429324254870387eb4aba<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"5bec096731ec31b017777a7aadf747bc","chunk":" magnification. Image: Secret Disc \/ CC BY-SA the air. They might also inform the design of more Visit this Strategy on AskNature:\n\nefficient wind turbines and reduce the materials https:\/\/asknature.org\/butterfly-needed for structural stability in tall buildings. The scales-lift\n\nmicro-geometry of wing scales can provide valuable insights for the design of innovative flying machines that incorporate flapping into their operation and of cars, trains, and other ground vehicles. They also can provide insights into improving the efficiency of cargo ships and other vehicles that travel through water or other media.\n\nReferences:\n\nJOURNAL ARTICLE\n\nBeneficial aerodynamic effect of wing scales on the climbing flight of butterflies. Bioinspiration\n\n& Biomimetics. Jan 30 2017. Nathan Slegers, Michael Heilman, Jacob Cranford, Amy Lang,\n\nJohn Yoder, and Maria Laura Habegger.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nSpider Builds an\n\nUnderwater\n\nBubble House\n\nLIVING SYSTEM:\n\nDiving bell spider\n\nAUTHOR:\n\nMary Hoff\n\nImage: \u00a9 Alamy\n\nFUNCTIONS PERFORMED:\n\nCapture, Absorb, or Filter Gases\n\nStore Gases\n\nThe Eurasian diving bell spider uses silk and goo to make an airy home for itself beneath the surface of a pond.\n\nMost spiders weave webs in open spaces to capture Now it\u2019s time to gather some air. The spider swims to the insects. When the Eurasian diving bell spider weaves surface, sticks the back end of its abdomen up in the a web, however, it\u2019s in a dramatically different setting, air, and spreads its rear legs. The abdomen is covered with a dramatically different function. Stretched with tiny, feather-shaped water-repelling hairs set into between parts of underwater plants, this spider\u2019s web small grooves. As the spider submerges, the hairs trap holds a spider-sized bubble of air beneath the surface air in a glistening bubble, which is held in place with the of a pond. It serves as both home base and a literal help of the legs. The spider carries the bubble beneath breath of fresh air for its weaver.\n\nthe web and releases it. The bubble rises until it reaches the web, but the thread and goo combo prevents it The Strategy\n\nfrom going any farther. The spider goes back for more A diving bell spider begins constructing its home under until eventually it builds up an air chamber big enough the surface","chunk_id":"5bec096731ec31b017777a7aadf747bc","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"BUTTERFLY WING SCALES\"","type":"\"BIOLOGICAL STRATEGY\"","description":"\"The micro-geometry of butterfly wing scales provides insights into designing efficient wind turbines, improved structural stability in tall buildings, and more.\"","source_id":"5bec096731ec31b017777a7aadf747bc"}],"entity_graph":" \"BIOLOGICAL STRATEGY\"<\/data> \"The micro-geometry of butterfly wing scales provides insights into designing efficient wind turbines, improved structural stability in tall buildings, and more.\"<\/data> 5bec096731ec31b017777a7aadf747bc<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"81eee876cafa81ab3b11ed19cc045cb6","chunk":" air for its weaver.\n\nthe web and releases it. The bubble rises until it reaches the web, but the thread and goo combo prevents it The Strategy\n\nfrom going any farther. The spider goes back for more A diving bell spider begins constructing its home under until eventually it builds up an air chamber big enough the surface of a pond or standing water in a wetland to provide the oxygen it needs.\n\nin much the same way land-living spiders build their webs: by extruding silken threads from spinnerets in its As the spider breathes inside its bubble home it uses abdomen and fastening them to plants. It then moves up oxygen. That causes oxygen trapped in the water back and forth between the anchors, first producing around it to diffuse into the bubble, replacing what the parallel strands and then crossing them with others. It spider depleted. Similarly, the high concentration of lightly coats the threads with a protein-based goo it exhaled carbon dioxide inside diffuses out of the bubble also produces from its body. Both the silk and the goo into the surrounding water. If the oxygen concentration are hydrophilic, meaning they attract water. Together, declines more rapidly than diffusion can replenish, the they create a loosely woven sheet of spider material spider simply returns to the surface to grab some more and water that traps air bubbles below instead of bubbles.\n\nletting them rise to the surface.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nImage: \u00a9Biomimicry Institute\n\nThe Potential\n\nVisit this Strategy on AskNature:\n\nThe diving bell spider\u2019s ability to create an air supply https:\/\/asknature.org\/diving-bell-spider\n\nbeneath a silken web underwater offers a variety of inspirations for innovations that benefit humans. The spider\u2019s ability to trap small amounts of air against its body using tiny, water-resistant hairs embedded References:\n\nin grooves offers insights that can be used to develop JOURNAL ARTICLE\n\npainted-on coatings for ships that hold tiny amounts The diving bell and the spider: the physical gill of of air. Such coatings could reduce rusting, make it harder for ship-degrading microorganisms to attach Argyroneta aquatica. Journal of Experimental to the outside of a ship, and provide lubrication to Biology. 2011. Roger S. Seymour and Stefan K.\n\nreduce friction with the water and so make the ship Hetz.\n\nmore energy-efficient.\n\nThe ability to make an airspace that replenishes JOURNAL","chunk_id":"81eee876cafa81ab3b11ed19cc045cb6","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"DIVING BELL SPIDER\"","type":"\"ORGANIZATION\"","description":"\"The Diving Bell Spider serves as a biological inspiration for technological innovations in air supply and water-resistant materials.\" ) (\"entity\"","source_id":"81eee876cafa81ab3b11ed19cc045cb6"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The Diving Bell Spider serves as a biological inspiration for technological innovations in air supply and water-resistant materials.\" ) (\"entity\"<\/data> 81eee876cafa81ab3b11ed19cc045cb6<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"eedd4bc29a0007151fb16d1deec2f9eb","chunk":" Argyroneta aquatica. Journal of Experimental to the outside of a ship, and provide lubrication to Biology. 2011. Roger S. Seymour and Stefan K.\n\nreduce friction with the water and so make the ship Hetz.\n\nmore energy-efficient.\n\nThe ability to make an airspace that replenishes JOURNAL ARTICLE\n\noxygen by drawing it from surrounding water\n\nComposite structure of silken threads and a\n\ncould open the door to allowing humans to spend proteinaceous hydrogel which form the\n\nextended time in oceans, lakes, or rivers for scientific, diving bell wall of the water spider Agyroneta\n\ncommercial, or recreational pursuits. It could even aquatica. SpringerPlus. May 16, 2013. Dietrich provide a useful model for developing living spaces Neumann, Armin Kureck.\n\nbeneath the surface.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nSpiders\u2019 Leg Hairs Help\n\nFind Flying Food\n\nLIVING SYSTEM:\n\nSpiders\n\nAUTHOR:\n\nMary Hoff\n\nImage: Volker Framenau \/ CC BY-NC\n\nFUNCTIONS PERFORMED: Sense Touch and Mechanical Forces Sense Sound and Other Vibrations\n\nSense Motion\n\nTiny leg hairs help spiders sense subtle air movement by conducting it directly to nerve cells.\n\nAll animals eat\u2014but first, they have to find their When an insect flies nearby, it sets the air around food. For predators, that means being able to it in motion. The movement of the air\u2014even the detect the presence, location, and movement of vibrations from sound\u2014sets the hairs moving, their often-elusive prey. Wolves and their kin use too. Since each hair is suspended in a flexible their keen sense of smell. Eagles and other raptors membrane (instead of being held tight at the rely on exceptional eyesight. For bats, it\u2019s all in the base), even the slightest movement is conducted ears.\n\nright to the nerves.\n\nFor hunting spiders, the secret to success is Because of variations in size and location, each touch\u2013\u2013information gathered by hundreds of hairs trichobothrium provides unique information about protruding from their lanky legs.\n\nthe location and movement of the prey in relation to the spider. In a split second, the nervous system The Strategy\n\nis able to combine the information from the many Each of a spider\u2019s legs has at least 20 (and trichobothria into a clear picture of where and potentially more than ","chunk_id":"eedd4bc29a0007151fb16d1deec2f9eb","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"ROGER S. SEYMOUR\"","type":"\"PERSON\"","description":"\"Roger S. Seymour is an author who contributed to the Journal of Experimental Biology in 2011.\") (\"entity\"","source_id":"eedd4bc29a0007151fb16d1deec2f9eb"}],"entity_graph":" \"PERSON\"<\/data> \"Roger S. Seymour is an author who contributed to the Journal of Experimental Biology in 2011.\") (\"entity\"<\/data> eedd4bc29a0007151fb16d1deec2f9eb<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"3d22053debaab18c4e321d4cfe15f8af","chunk":" legs.\n\nthe location and movement of the prey in relation to the spider. In a split second, the nervous system The Strategy\n\nis able to combine the information from the many Each of a spider\u2019s legs has at least 20 (and trichobothria into a clear picture of where and potentially more than 100) sensory structures when the spider needs to strike in order to capture called trichobothria. Each consists of a thin hair its meal.\n\nof varying length and thickness embedded in a membrane at the bottom of a cup-shaped base. The Potential Below the membrane, the hair connects to three\n\nThe hypersensitivity to touch and vibrations or four nerve cells.\n\nmodeled by trichobothria\u2019s system of a long thin\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nMagnified views of a spider\u2019s trichobothria (leg hairs). Images: Janice Carr (photo credit) and Leah Lowrey, Michael Smith (content providers), Centers for Disease Control and Prevention.\n\nreceptor suspended in a flexible membrane could Visit this Strategy on AskNature:\n\nbe emulated at varying scales using different https:\/\/asknature.org\/spider-leg-sensors\n\nmaterials to detect different kinds of signals. At a large scale, they could help analyze underwater currents or detect the presence or activity of sea life. At the micro scale they could provide alternative options for sound detection in a variety of products.\n\nIn addition, a spider\u2019s ability to use information References:\n\ngathered from and synthesized by a network of BOOK\n\nmany sensors to detect the location and motion\n\nA Spider\u2019s World. Trichobothria - the Measurement of an object could be used to improve our ability of Air Movement. Springer. 2002. Barth, F.G.\n\nto do the same. Manned or unmanned aircraft\n\ncould adapt the strategy for greater sensitivity JOURNAL ARTICLE\n\nto environmental clues to avoid collisions with Air motion sensing hairs of arthropods detect\n\nbirds, and ground vehicles could use it to improve high frequencies at near-maximal mechanical\n\nmaneuvers such as parallel parking or backing up.\n\nefficiency. Journal of the Royal Society\n\nThe sensory capacity might be built into wearable Interface. 12\/14\/2011. Brice Bathellier, Thomas devices or clothing to make it possible to detect Steinmann, Friedrich G. Barth, J\u00e9r\u00f4me Casas.\n\nmotion beyond the range of vision.\n\n\u00a92022 Biomimicry Institute","chunk_id":"3d22053debaab18c4e321d4cfe15f8af","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"SPIDER\"","type":"\"ORGANIZATION\"","description":"\"Spiders use trichobothria for sensing and movement control in hunting and navigating their environment.\"","source_id":"3d22053debaab18c4e321d4cfe15f8af"},{"name":"\"TRICHOBOTHRIA\"","type":"\"CONCEPT\"","description":"\"Trichobothria are sensory structures on spiders\u2019 legs that enhance their sensitivity to touch, vibrations, and motion.\"","source_id":"3d22053debaab18c4e321d4cfe15f8af"},{"name":"\"SENSITIVITY\"","type":"\"EVENT\"","description":"\"The hypersensitivity provided by trichobothria allows spiders to detect underwater currents or the presence of sea life.\"","source_id":"3d22053debaab18c4e321d4cfe15f8af"},{"name":"\"ENVIRONMENTAL CLUES\"","type":"\"CONCEPT\"","description":"\"Spiders use information from their environment, like the activity of other organisms and environmental cues, for hunting, navigation, and self-defense.\"","source_id":"3d22053debaab18c4e321d4cfe15f8af"},{"name":"\"WEARABLE DEVICES\"","type":"\"ORGANIZATION\"","description":"\"The concept of integrating spider's sensory capacity into wearable devices or clothing could improve motion detection beyond human vision.\"","source_id":"3d22053debaab18c4e321d4cfe15f8af"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"Spiders use trichobothria for sensing and movement control in hunting and navigating their environment.\"<\/data> 3d22053debaab18c4e321d4cfe15f8af<\/data> <\/node> \"CONCEPT\"<\/data> \"Trichobothria are sensory structures on spiders’ legs that enhance their sensitivity to touch, vibrations, and motion.\"<\/data> 3d22053debaab18c4e321d4cfe15f8af<\/data> <\/node> \"EVENT\"<\/data> \"The hypersensitivity provided by trichobothria allows spiders to detect underwater currents or the presence of sea life.\"<\/data> 3d22053debaab18c4e321d4cfe15f8af<\/data> <\/node> \"CONCEPT\"<\/data> \"Spiders use information from their environment, like the activity of other organisms and environmental cues, for hunting, navigation, and self-defense.\"<\/data> 3d22053debaab18c4e321d4cfe15f8af<\/data> <\/node> \"ORGANIZATION\"<\/data> \"The concept of integrating spider's sensory capacity into wearable devices or clothing could improve motion detection beyond human vision.\"<\/data> 3d22053debaab18c4e321d4cfe15f8af<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"75be22a096d450ebe20ed42f79da45da","chunk":"\n\nThe sensory capacity might be built into wearable Interface. 12\/14\/2011. Brice Bathellier, Thomas devices or clothing to make it possible to detect Steinmann, Friedrich G. Barth, J\u00e9r\u00f4me Casas.\n\nmotion beyond the range of vision.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nSpiders Fly Riding\n\nElectric Currents\n\nLIVING SYSTEM:\n\nSpiders\n\nAUTHOR:\n\nKathryn Krupin\n\nImage: \u00a9Michael Hutchinson, used with permission FUNCTIONS PERFORMED:\n\nMove in\/Through Gases\n\nModify Electric Charge\n\nSense Electricity\/Magnetism\n\nSpiders travel thousands of miles through the air using their silk to ride electrostatic repulsion instead of the wind.\n\nYou may have heard of \u201cjumping\u201d spiders, but did you above us is always positively charged. The ground is know that some spiders have been found over two miles always negatively charged, along with any plants or high in the sky and a thousand miles out to sea?\n\nrocks on it. When a spider crawls to an exposed point, it is essentially putting itself on top of a lightning rod How do they get there? Charles Darwin first mused on (any sharp structure protruding up from an object on this mystery in the early 1800s, but only recently have the ground, such as the leaves on a tree, will cause an scientists found a solid explanation. It turns out that increase in the strength of the surrounding electric an itsy bitsy spider can go up something much more field). Then, as the spider releases its silk, the strands exciting than a water spout.\n\npick up negative charges, and since like charges repel each other, the silk is pushed up and away from the The Strategy\n\nnegatively charged surfaces upon which the spider is To begin its journey, a spider crawls to an exposed point, perched.\n\nraises its abdomen, shoots out a couple strands of silk, and then jets away. For a long time it was thought the This phenomenon was demonstrated magnificently in spider was simply carried off on wind currents. However, a study published in 2018 by scientists at the University the physics just didn\u2019t make sense: spiders \u201cballoon\u201d like of Bristol. Spiders were placed in a closed container this when the wind is low, and light air currents couldn\u2019t that blocked all air flow and atmospheric electricity. An explain the impressive velocity with which they take artificial electric field","chunk_id":"75be22a096d450ebe20ed42f79da45da","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"BIOMIMICRY INSTITUTE\"","type":"\"ORGANIZATION\"","description":"\"The organization responsible for providing biological strategy solutions and information through their website Biomimicry.org.\"","source_id":"75be22a096d450ebe20ed42f79da45da"},{"name":"\"BIOMIMICRY.ORG\"","type":"\"WEBSITE\"","description":"\"Website for the organization Biomimicry Institute, providing information about strategies found in nature and how they can be applied.\"","source_id":"75be22a096d450ebe20ed42f79da45da"},{"name":"\"ASKNATURE.ORG\"","type":"\"WEBSITE\"","description":"\"A component of Biomimicry.org website that asks users to explore and apply natural strategies in their innovations.\"","source_id":"75be22a096d450ebe20ed42f79da45da"},{"name":"\"BRICE BATHELLIER\"","type":"\"PERSON\"","description":"\"A researcher contributing his expertise in the biological strategy related to spiders and electric currents for biomimetics applications.\"","source_id":"75be22a096d450ebe20ed42f79da45da"},{"name":"\"THOMAS STEINMANN\"","type":"\"PERSON\"","description":"\"The individual credited with discovering or understanding how certain spiders fly using electrostatic repulsion, possibly contributing knowledge to biomimetic engineering.\"","source_id":"75be22a096d450ebe20ed42f79da45da"},{"name":"\"FRIEDRICH G. BARTH\"","type":"\"PERSON\"","description":"\"A contributor or researcher who provided insights or evidence supporting the spider flying phenomenon, influencing scientific community.\"","source_id":"75be22a096d450ebe20ed42f79da45da"},{"name":"\"J\u00c9R\u00d4ME CASAS\"","type":"\"PERSON\"","description":"\"A researcher involved in the study that shed light on spiders' use of electrostatic forces for flight, providing significant biological data for biomimetics.\"","source_id":"75be22a096d450ebe20ed42f79da45da"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The organization responsible for providing biological strategy solutions and information through their website Biomimicry.org.\"<\/data> 75be22a096d450ebe20ed42f79da45da<\/data> <\/node> \"WEBSITE\"<\/data> \"Website for the organization Biomimicry Institute, providing information about strategies found in nature and how they can be applied.\"<\/data> 75be22a096d450ebe20ed42f79da45da<\/data> <\/node> \"WEBSITE\"<\/data> \"A component of Biomimicry.org website that asks users to explore and apply natural strategies in their innovations.\"<\/data> 75be22a096d450ebe20ed42f79da45da<\/data> <\/node> \"PERSON\"<\/data> \"A researcher contributing his expertise in the biological strategy related to spiders and electric currents for biomimetics applications.\"<\/data> 75be22a096d450ebe20ed42f79da45da<\/data> <\/node> \"PERSON\"<\/data> \"The individual credited with discovering or understanding how certain spiders fly using electrostatic repulsion, possibly contributing knowledge to biomimetic engineering.\"<\/data> 75be22a096d450ebe20ed42f79da45da<\/data> <\/node> \"PERSON\"<\/data> \"A contributor or researcher who provided insights or evidence supporting the spider flying phenomenon, influencing scientific community.\"<\/data> 75be22a096d450ebe20ed42f79da45da<\/data> <\/node> \"PERSON\"<\/data> \"A researcher involved in the study that shed light on spiders' use of electrostatic forces for flight, providing significant biological data for biomimetics.\"<\/data> 75be22a096d450ebe20ed42f79da45da<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"621c0cd608f4ed99a4dd7a5c25c8e0b5","chunk":" by scientists at the University the physics just didn\u2019t make sense: spiders \u201cballoon\u201d like of Bristol. Spiders were placed in a closed container this when the wind is low, and light air currents couldn\u2019t that blocked all air flow and atmospheric electricity. An explain the impressive velocity with which they take artificial electric field was then generated, and scientists flight. Furthermore, spiders can\u2019t shoot out much silk on observed that tiny sensory hairs on the spiders\u2019 feet, their own; some external force had to be pulling it from called trichobothria, were ruffled by the field. Spiders their spinnerets. Now we know: spiders can sense and then began lifting their abdomens up, and many took surf on electric charges in the Earth\u2019s atmosphere.\n\nflight\u2014again, with zero air flow in the container. When the researchers turned the artificial electric field off, You may only think of electricity in the air when there\u2019s the spiders dropped to the ground. Previously, scientists a thunderstorm, but the atmosphere around and were aware that spiders\u2019 trichobothria were sensitive to\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\n\u00a9 Mesa Schumacher\n\nair flow, but this study provides strong evidence that The Potential\n\nthey also function as electromechanical receptors.\n\nFor most current human flight applications, electric repulsion and attraction aren\u2019t strong enough to Scientists acknowledge that electrostatic forces may overcome the force of the Earth\u2019s gravity. However, be acting in conjunction with light winds to facilitate nanotechnology, 3D printing, and other advances are spider flight, though this research shows that wind is producing sophisticated machinery of remarkably not necessary.\n\nsmall sizes and light weights. On these scales, \u201cflying spider\u201d technology could create exciting opportunities Spiders are likely not the only ones who make use for development.\n\nof electric fields for flight: other arthropods such as caterpillars and spider mites could be traveling using If we think of all the human-designed products\n\nsimilar methods, either to escape predators or to seek that utilize wind, how many could be shrunken and out new territory with more abundant resources. Plant engineered to use electrical currents in the atmosphere?\n\nparts such as dandelion fluff and other seeds and spores could be transported in this way as well, aiding reproduction.\n\nVisit this Strategy on AskNature:\n\nReferences:\n\nhttps:\/\/asknature.org \/siders-surf-electric-JOURNAL ARTICLE\n\nfields\n\nElectric Fields","chunk_id":"621c0cd608f4ed99a4dd7a5c25c8e0b5","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"SPIDER BALLOON FLIGHT\"","type":"\"EVENT\"","description":"\"Spiders were observed to exhibit 'balloon' like flight in low wind conditions due to atmospheric electric fields.\") (\"entity\"","source_id":"621c0cd608f4ed99a4dd7a5c25c8e0b5"}],"entity_graph":" \"EVENT\"<\/data> \"Spiders were observed to exhibit 'balloon' like flight in low wind conditions due to atmospheric electric fields.\") (\"entity\"<\/data> 621c0cd608f4ed99a4dd7a5c25c8e0b5<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"60d4060427254b2a553815d05dce7fcf","chunk":" engineered to use electrical currents in the atmosphere?\n\nparts such as dandelion fluff and other seeds and spores could be transported in this way as well, aiding reproduction.\n\nVisit this Strategy on AskNature:\n\nReferences:\n\nhttps:\/\/asknature.org \/siders-surf-electric-JOURNAL ARTICLE\n\nfields\n\nElectric Fields Elicit Ballooning in Spiders. Current Biology. 7\/23\/2018. E.L. Moreley, D. Robert.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nThe Insect That Uses\n\nWaves to Communicate\n\nLIVING SYSTEM:\n\nWater strider\n\nAUTHOR:\n\nMary Hoff\n\nImage: Alexander \/ CC BY-SA\n\nFUNCTIONS PERFORMED:\n\nSend Vibratory Signals\n\nSense Touch and Mechanical Forces\n\n\n\nSense Sound and Other Vibrations\n\nSense Motion\n\n\n\nTransduce\/Convert Signals\n\nWater striders communicate with each other using body parts that send and sense slight vibrations in the water around them.\n\nInsects of all kinds can use their six legs to walk on solid pierce, the surface of the water \u2013 like a cat\u2019s whiskers surfaces\u2014but water striders have a special twist. The tickling the water in its bowl as it takes a drink.\n\nhairs on the feet of these long-legged bugs contain grooves that hold air bubbles, making it possible for Insects also have a sensory organ called a chordotonal them to walk on the surface of water without breaking organ near their joints that lets them know when their through.\n\njoints move and can also sense other forces. Each is made up of structures called scolopidia. The scolopidia But that\u2019s not their only claim to fame. These insects in turn are made up of three parts: a nerve cell that\u2019s also have specialized structures on their legs and attached to the central nervous system and that undersides that sense minute, fast-moving waves in the includes a long, thin pressure-sensing extension called water around them. This ability allows water striders to a dendrite; a scolopale cell, which serves as a sheath communicate with each other by rapidly moving their around the dendrite; and an attachment cell, which legs up and down, vibrating the surface of the water in connects the rest of the scolopidium to the insect\u2019s skin.\n\na way that other striders\u2019 sense organs can detect.\n\nWater striders have more scolopidia than other bugs, presumably making them","chunk_id":"60d4060427254b2a553815d05dce7fcf","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"MARY HOFF\"","type":"\"PERSON\"","description":"\"Mary Hoff authored a strategy on AskNature explaining how water striders communicate using vibrations and their legs.\") (\"entity\"","source_id":"60d4060427254b2a553815d05dce7fcf"}],"entity_graph":" \"PERSON\"<\/data> \"Mary Hoff authored a strategy on AskNature explaining how water striders communicate using vibrations and their legs.\") (\"entity\"<\/data> 60d4060427254b2a553815d05dce7fcf<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"bd3e8fcd1e1991500d9610859ecfabf4","chunk":"rite; and an attachment cell, which legs up and down, vibrating the surface of the water in connects the rest of the scolopidium to the insect\u2019s skin.\n\na way that other striders\u2019 sense organs can detect.\n\nWater striders have more scolopidia than other bugs, presumably making them super-sensitive to motion.\n\nThe Strategy\n\nLike other insects, water striders have movement-When a neighbor rapidly moves its leg up and down, it sensing hairs called trichobothria on various parts makes tiny waves that travel across the surface. When of their bodies. But water striders have a special these waves reach the legs of another strider, they variation on the theme: They have several extra-long cause them to activate these two sets of extra-sensitive trichobothria sticking out of the ventral side of the end sensory organs and alert the insect\u2019s nervous system of of their legs. These trichobothria just touch, but don\u2019t the motion.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nWater striders communicate with each other by tapping the surface of the water rapidly with their feet, creating ripples that nearby neighbors sense using highly sensitive motion-detecting structures on their legs. Image: Hunter Desportes \/ CC BY\n\nTogether, the activated nerve cells translate the Visit this Strategy on AskNature: movement into information about the vibrations\u2019 https:\/\/asknature.org \/water-strider-frequency and location of origin and so about the vibrations source that sent them. Humans are not water striders, so we\u2019ll likely never be completely sure of what the messages are\u2014but scientists have evidence that they include information about the sex of the sender and also provide warning signals if one strider is venturing too far into another\u2019s personal space.\n\nReferences:\n\nThe Potential\n\nJOURNAL ARTICLE\n\nWater striders\u2019 ability to sense minute vibrations Morphology and neurophysiology of tarsal\n\nwith distinct meanings offers abundant inspiration vibration receptors in the water strider\n\nfor devices humans can use to detect movement and Aquarius paludum (Heteroptera: Gerridae).\n\nconvey information. For instance, it might inspire the Journal of Insect Physiology. 2009. Pablo Perez invention of devices that provide advanced warning of impending earthquakes or mudslides by catching small Goodwyn, Ayako Katsumata-Wada, Koutaroh\n\nwaves of movement traveling through the ground or Okada.\n\nair. It","chunk_id":"bd3e8fcd1e1991500d9610859ecfabf4","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"WATER STRIDERS\"","type":"\"ORGANISM\"","description":"\"A species of insects that communicate through tapping the water surface and have highly sensitive motion-detecting structures on their legs.\") (\"entity\"","source_id":"bd3e8fcd1e1991500d9610859ecfabf4"}],"entity_graph":" \"ORGANISM\"<\/data> \"A species of insects that communicate through tapping the water surface and have highly sensitive motion-detecting structures on their legs.\") (\"entity\"<\/data> bd3e8fcd1e1991500d9610859ecfabf4<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"f228fcbbb8f2ec33599ea9a3d5d4e854","chunk":" instance, it might inspire the Journal of Insect Physiology. 2009. Pablo Perez invention of devices that provide advanced warning of impending earthquakes or mudslides by catching small Goodwyn, Ayako Katsumata-Wada, Koutaroh\n\nwaves of movement traveling through the ground or Okada.\n\nair. It might serve as a model for enhancing structural engineers\u2019 ability to test the resilience of buildings to JOURNAL ARTICLE\n\nvibrations caused by traffic or forces of nature. Or it Ripple communication in aquatic and semiaquatic might lead to the development of ways to communicate between humans, robotic devices, or both, that don\u2019t insects. Ecoscience. 1995. R. Stimson Wilcox.\n\nrely on sight or the audible vibrations we call sound.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nPine Cones Open and\n\nClose in Response\n\nto Weather\n\nLIVING SYSTEM:\n\nPine trees\n\nAUTHOR:\n\nLonny Lippsett\n\nImage: Pilar Mirando \/ public domain\n\nFUNCTIONS PERFORMED:\n\nDisperse Seeds\n\nModify Size\/Shape\/Mass\/Volume\n\nA slight rise in humidity triggers pine cones to curl up their scales to prevent ineffective seed dispersal in wet weather.\n\nSavvy naturalists have long known the old trick of using pine cones to predict the weather. If it\u2019s dry, pine cones on the ground will let down their slender scales and open up like the fingers of an unfurling fist. If rain and humidity are in the air, the scales will clamp up like a castle drawbridge, overlapping one another and sealing the cone into a tight ball.\n\nThe idea is simple\u2014to open and release seeds when conditions are best for winds to carry them far and wide. Wet weather dampens dispersal. But how do they\n\n\u201csense\u201d humidity when pine cones contain no living cells?\n\nAnd how do they move without any muscles or nerves?\n\nThe Strategy\n\nThe secret lies in the structure of their scales. Pine cone scales have multiple layers with different qualities. The outermost side of the scale (which faces downward when the scales are open) is made of a layer of loosely packed, stretchable cells. The inner layer (facing upward when the scales are open) is made of stiff fibers Conceptual diagram showing how the expansion of cells tightly packed like cables.\n\non the underside of a pine cone\u2019s scales will cause the scale to curl upward, thus closing the","chunk_id":"f228fcbbb8f2ec33599ea9a3d5d4e854","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"PABLO PEREZ\"","type":"\"PERSON\"","description":"\"Pablo Perez is responsible for inventing devices that provide advanced warning of impending earthquakes or mudslides, possibly inspiring new technology.\")","source_id":"f228fcbbb8f2ec33599ea9a3d5d4e854"}],"entity_graph":" \"PERSON\"<\/data> \"Pablo Perez is responsible for inventing devices that provide advanced warning of impending earthquakes or mudslides, possibly inspiring new technology.\")<\/data> f228fcbbb8f2ec33599ea9a3d5d4e854<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"7c777850b39440dea33d9b60641e803b","chunk":" made of a layer of loosely packed, stretchable cells. The inner layer (facing upward when the scales are open) is made of stiff fibers Conceptual diagram showing how the expansion of cells tightly packed like cables.\n\non the underside of a pine cone\u2019s scales will cause the scale to curl upward, thus closing the cone. Image: \u00a9 Biomimicry Institute\n\nWhen the scales are open and the air becomes humid, water drops will begin to fall or bead on the upper layer.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nThe water slides down toward the cone\u2019s central stalk and is channeled into the scale\u2019s interior. There, the water fills up the cells and the empty spaces between them. This layer expands and stretches, while the less flexible upper layer stays more taut. The scales bend upward in the middle until they curl completely shut.\n\nWhen humidity levels reach around 20 percent, it takes just a one-percent change in humidity to trigger the scales to close. Then, when the air becomes drier, water in the scales evaporates, the outer layer shrinks back in Image: Leland J. Prater \/ CC BY-NC\n\nsize, and the scales reopen.\n\nExamples of closed (moist) and open (dry) cones.\n\nThe Potential\n\nPine cones\u2019 effective, sensitive, water-driven scheme it more breathable. When conditions dry out, the is inspiring engineers to design mechanisms that can material could revert to its original tight knit weave.\n\nmove and\/or change shape without needing energy input. Such innovations could lead to novel systems Similarly inspired building materials might also to transport water, or on a smaller scale, to serve as respond to changing humidity. In dry, warm midday activation switches for robotics.\n\nair, self-adjusting blinds, for example, might bend to create shade and keep houses cool. At night through Scientists are also exploring new materials that quickly humid early mornings, they would relax and open up respond to environmental changes. \u201cSmart\u201d fabrics again.\n\ncould react automatically to changing temperatures or humidity. When the fabric gets wet from sweat or Visit this Strategy on AskNature:\n\nhumidity, layers in the fabric could open up and make https:\/\/asknature.org\/pine-cones\n\nReferences:\n\nJOURNAL ARTICLE\n\nJOURNAL ARTICLE\n\nJourney of water in pine cones. Scientific Reports.\n\nHygromorphs: from pine cones to biomimetic\n\nMay 6, 2015. Kahye Song","chunk_id":"7c777850b39440dea33d9b60641e803b","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"BIOMIMICRY INSTITUTE\"","type":"\"ORGANIZATION\"","description":"\"The Biomimicry Institute is an organization dedicated to promoting the adoption of nature's problem-solving strategies in design.\"","source_id":"7c777850b39440dea33d9b60641e803b"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The Biomimicry Institute is an organization dedicated to promoting the adoption of nature's problem-solving strategies in design.\"<\/data> 7c777850b39440dea33d9b60641e803b<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"30aa281b7ea0845a9f88c0914df109c3","chunk":" in the fabric could open up and make https:\/\/asknature.org\/pine-cones\n\nReferences:\n\nJOURNAL ARTICLE\n\nJOURNAL ARTICLE\n\nJourney of water in pine cones. Scientific Reports.\n\nHygromorphs: from pine cones to biomimetic\n\nMay 6, 2015. Kahye Song, Eunseop Yeom,\n\nbilayers. Journal of the Royal Society\n\nSeung-Jun Seo, Kiwoong Kim, Hyejeong Kim,\n\nInterface. July 1, 2009. \u00c9tienne Reyssat and Jae-Hong Lim, and Sang Joon Lee.\n\nLakshminarayanan Mahadevan.\n\nJOURNAL ARTICLE\n\nJOURNAL ARTICLE\n\nThe Structural and Mechanical Basis for\n\n4D pine scale: biomimetic 4D printed autonomous Passive-Hydraulic Pine Cone Actuation.\n\nscale and flap structures capable of multi-phase Advanced Science. May 14, 2022. Eger, C. J., movement. Philosophical Transactions of the Horstmann, M., Poppinga, S., Sachse, R., Thierer, Royal Society A. Feb. 3, 2020. David Correa, R., Nestle, N., Bruchmann, B., Speck, T., Bischoff, Simon Poppinga, Max D. Mylo, Anna S.\n\nM., R\u00fche, J.\n\nWestermeier, Bernd Bruchmann, Achim Menges,\n\nand Thomas Speck.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nSpiral Fibers\n\nStrengthen Tree Trunk\n\nLIVING SYSTEM:\n\nPines\n\nAUTHOR:\n\nAskNature Team\n\nImage: John Johnston \/ CC BY-SA\n\nFUNCTIONS PERFORMED:\n\nProtect from Wind\n\nManage Shear\n\nTrunk of pine tree withstands wind and snow via spiral growth.\n\nSome trees, including the Ponderosa pine,\n\nScots pine, and Norway spruce, exhibit\n\na spiral growth pattern in their trunks,\n\nbranches, and stems. Some scientists suggest\n\nthat because spiral-grained materials bend\n\nmore than straight-grained materials,\n\nthis spiral composition may help protect\n\ntrees that grow in areas of high wind from\n\nbreaking. A tree\u2019s ability to bend and twist in strong winds may reduce drag forces on its\n\nlimbs and also allow additional weight (such\n\nas that from snow) to slide off its branches","chunk_id":"30aa281b7ea0845a9f88c0914df109c3","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"ASKNATURE TEAM\"","type":"\"ORGANIZATION\"","description":"\"The AskNature team is responsible for cataloging information about biomimicry and nature, including strategies like 'Spiral Fibers'.\")||(\"entity\"","source_id":"30aa281b7ea0845a9f88c0914df109c3"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The AskNature team is responsible for cataloging information about biomimicry and nature, including strategies like 'Spiral Fibers'.\")||(\"entity\"<\/data> 30aa281b7ea0845a9f88c0914df109c3<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"1ff6815fa5511debe6f17ad17c1707b1","chunk":"more than straight-grained materials,\n\nthis spiral composition may help protect\n\ntrees that grow in areas of high wind from\n\nbreaking. A tree\u2019s ability to bend and twist in strong winds may reduce drag forces on its\n\nlimbs and also allow additional weight (such\n\nas that from snow) to slide off its branches\n\nClose up of a dead pine trunk showing the spiral when they twist in the wind.\n\ngrowth pattern in the grain. Image: Ole Husby CC\n\nBY-SA\n\nWhen tested for the ability to bend before\n\nbreaking, spiral-grained sticks break under\n\nthan straight ones before breaking. Spiral-\n\nthe same force as straight-grained sticks, but\n\ngrained materials deflect (or bend) more\n\nspiral-grained samples performed differently\n\nthan straight-grained materials. During\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\ndeflection of straight-grained materials, the\n\nside nearest the force is compressed while the\n\nReferences:\n\nopposite side is stretched, putting it under\n\nJOURNAL ARTICLE\n\ntension. In contrast, spiral-grained materials\n\nFunction of spiral grain in trees. Trees.\n\ntransfer the compression and tension forces\n\n31\/08\/2004. Hans Kubler.\n\nalong the spiral to the other side, thereby\n\nBOOK\n\nequalizing the stresses.\n\nHow Life Learned to Live: Adaptation in Nature.\n\n01\/01\/1983. Helmut Tributsch.\n\nVisit this Strategy on AskNature:\n\nhttps:\/\/asknature.org\/spiral-tree-\n\ntrunks\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nWater Pressure Helps\n\nFlowers Follow the Sun\n\nLIVING SYSTEM:\n\nPlants\n\nAUTHOR:\n\nAnika Hazra\n\nImage: B\u00f6hringer Friedrich \/ CC BY-SA\n\nFUNCTIONS PERFORMED:\n\nCapture, Absorb, or Filter Energy\n\nModify Size\/Shape\/Mass\/Volume\n\n\n\nSense Light\n\nRespond to Signals\n\nLight intensity concentrates hormones that alter the water levels in cells causing plants to bend toward the light source.\n\nPlants may not seem to lead lives as complex Heliotropism requires some use of energy, but it\u2019s as those of animals, especially since they can\u2019t worth the effort for plants because it helps them move much from the spot where they\u2019ve sprouted.\n\nto get much more of the energy they need to\n\nThey have, however, found many ways around continue growing, maintain","chunk_id":"1ff6815fa5511debe6f17ad17c1707b1","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"OLE HUSBY\"","type":"\"PERSON\"","description":"\"He created an image for this document under CC BY-SA license.\") (\"entity\"","source_id":"1ff6815fa5511debe6f17ad17c1707b1"}],"entity_graph":" \"PERSON\"<\/data> \"He created an image for this document under CC BY-SA license.\") (\"entity\"<\/data> 1ff6815fa5511debe6f17ad17c1707b1<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"c8455055703093614be4105105a67f0e","chunk":"ism requires some use of energy, but it\u2019s as those of animals, especially since they can\u2019t worth the effort for plants because it helps them move much from the spot where they\u2019ve sprouted.\n\nto get much more of the energy they need to\n\nThey have, however, found many ways around continue growing, maintain ideal temperatures, their immobile lifestyle to reproduce, compete and attract pollinators.\n\nwith other plants for resources, adapt to their environment, and avoid or defend themselves The Strategy from herbivores.\n\nTropism of all kinds works because environmental cues trigger a hormonal response that causes the While they cannot relocate, plants can alter plant\u2019s cells to grow or expand \u2013 some faster than their structure in response to changes in their others. The plant redirects itself over time as its environment: this turning of part or all of the tissues respond to these environmental cues.\n\norganism is called tropism. The various types\n\nof tropisms include gravitropism (reacting to Auxins are a class of hormones known to be gravity), thigmotropism (reacting to physical involved in a plant\u2019s response to light. An increase contact), phototropism (reacting to light), and in auxin levels occurs in the part of the plant that heliotropism (growing or changing their shape in receives less light, which results in the elongation response to sunlight specifically). An example of of cells in those areas through a weakening of the this is a flower opening, closing, and\/or orienting rigid cell wall and an increase in the cell\u2019s water itself at different times of the day according to intake. This response reaches the tissue level when when the sun is out and where it is.\n\nmany cells have expanded on the shaded side of\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nAuxin (plant hormones) move away from light (phototropism), thereby making the shoot bend toward the sun. Image: \u00a9 Johannes Fuchs the plant. The plant may continue to orient itself While a plant\u2019s responses to myriad environmental in the direction it is growing, change its orientation cues are difficult to tease apart, what tropism to align with sunlight, or orient itself at an angle comes down to is adapting relatively quickly to to sunlight if there are other aspects of its the environment according to the plant\u2019s needs.\n\nenvironment preventing it from aligning perfectly At large and small scales, that opens countless with the sun.\n\npathways","chunk_id":"c8455055703093614be4105105a67f0e","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"PLANT\"","type":"\"ORGANISM\"","description":"\"Plants use strategies like tropisms (gravitropism, thigmotropism, phototropism, heliotropism) to adapt and respond efficiently to their environment.\") (\"entity\"","source_id":"c8455055703093614be4105105a67f0e"}],"entity_graph":" \"ORGANISM\"<\/data> \"Plants use strategies like tropisms (gravitropism, thigmotropism, phototropism, heliotropism) to adapt and respond efficiently to their environment.\") (\"entity\"<\/data> c8455055703093614be4105105a67f0e<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"10a8260a1ac5e4f2ab531d67e534b83f","chunk":" apart, what tropism to align with sunlight, or orient itself at an angle comes down to is adapting relatively quickly to to sunlight if there are other aspects of its the environment according to the plant\u2019s needs.\n\nenvironment preventing it from aligning perfectly At large and small scales, that opens countless with the sun.\n\npathways for human inspiration.\n\nThe Potential\n\nVisit this Strategy on AskNature:\n\nOur knowledge of heliotropism, along with other https:\/\/asknature.org\/flowers-follow-sun ways plants move and orient themselves, can\n\nserve as a foundation for the development of\n\ncrop management strategies and biomechanical\n\ntechnologies.\n\nTaking inspiration from plant heliotropism can\n\nhelp us to develop more sustainable technologies References:\n\nfor harnessing solar energy, through the ingenious JOURNAL ARTICLE\n\nstrategy of following the sun without uprooting. It The mechanism of floral heliotropism in the snow has already inspired the creation of self-directing buttercup, Ranunculus adoneus. Plant, Cell\n\nsolar panels that use soft robots made of materials and Environment. 12\/03\/2003. R. A. Sherry, that bend and move with changes in water pressure C. Galen.\n\nto face the sun and absorb and store as much light as possible.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nHow Wetland Plants\n\nGet Air to Waterlogged\n\nRoots\n\nLIVING SYSTEM:\n\nCommon reed\n\nAUTHOR:\n\nAndy Carstens\n\nImage: Charles Peterson \/ CC BY-NC\n\nFUNCTIONS PERFORMED:\n\nDistribute Gases\n\nExpel Gases\n\nCommon reeds and other wetland plants transport gases through a network of spaces between their cells.\n\nIn a reedy marshland in spring, the wind rustles through Air enters into common reeds from broken stems or the fronds, dragonflies buzz through the air, and the dead plants that are all connected via underwater strange song of an American bittern booms across the structures called rhizomes. Many wetland plant species land. It is a thriving ecosystem, hosting a wide variety have rhizomes that grow horizontally just below the of plants and animals. The plants in such a wetland, surface of the soil, with many stems growing up and however, face a major challenge\u2014growing in soil so many roots growing down. Air taken in through one waterlogged that it\u2019s harder for oxygen to reach their broken stem or","chunk_id":"10a8260a1ac5e4f2ab531d67e534b83f","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"ASKNATURE.ORG\"","type":"\"ORGANIZATION\"","description":"\"AskNature is an online platform offering knowledge and tools about nature-based solutions and biomimicry, specifically highlighting the strategies of heliotropism in plants.\"","source_id":"10a8260a1ac5e4f2ab531d67e534b83f"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"AskNature is an online platform offering knowledge and tools about nature-based solutions and biomimicry, specifically highlighting the strategies of heliotropism in plants.\"<\/data> 10a8260a1ac5e4f2ab531d67e534b83f<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"809da8a35547ca53620a67d4f1cdb6f5","chunk":" horizontally just below the of plants and animals. The plants in such a wetland, surface of the soil, with many stems growing up and however, face a major challenge\u2014growing in soil so many roots growing down. Air taken in through one waterlogged that it\u2019s harder for oxygen to reach their broken stem or dead plant can reach other healthy roots.\n\nsections through this network.\n\nThe Strategy\n\nThe oxygen-carrying air moves through gaps in the Plants take in carbon dioxide through their leaves and plant\u2019s tissues, called aerenchyma. If glass beads poured use the carbon as material to build their structures. into a cylindrical vase represented the cells inside a But they take in oxygen through their roots to provide plant stem, the space between the beads would be the energy to carry out growth and repair.\n\naerenchyma, which form when cells separate from one another or collapse.\n\nEven though the roots of land plants are buried, they can extract oxygen from air pockets within the soil. Most The aerenchyma spaces rely on pressure gradients of the oxygen enters the roots through diffusion, when to drive the gasses from areas of high pressure to molecules are driven to move from areas with higher areas of low pressure. In some cases, air is drawn into concentrations to areas with lower ones. In very wet living sections of the plant through the stomata (gas-soil, this becomes much more difficult because oxygen exchange holes) of the leaf sheaths, sending oxygen diffusion in water is 10,000 times slower than in air. So from the stems down into the rhizomes (from where it reeds (such as the common reed, Phragmites australis) can diffuse into the roots), and pushing stale air out of have developed another way to breathe that\u2019s very broken stems.\n\nsimilar to using a snorkel.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nImage: \u00a9 Biomimicry Institute\n\nIn other cases, broken stems of different heights or that transport gases, like natural gas, more efficiently.\n\ncreate a passive ventilation system. This is because of When natural disasters such as earthquakes trap people the Bernoulli principle: the faster air moves, the lower below felled buildings, perhaps gas exchange networks its pressure becomes. Since air closer to the ground is could vent carbon dioxide and pump in oxygen to help slower due to friction and turbulence, the air around recovery efforts. Studying aerenchyma","chunk_id":"809da8a35547ca53620a67d4f1cdb6f5","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"BIOMIMICRY INSTITUTE\"","type":"\"ORGANIZATION\"","description":"\"The Biomimicry Institute is an organization that specializes in finding solutions inspired by nature.\"","source_id":"809da8a35547ca53620a67d4f1cdb6f5"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The Biomimicry Institute is an organization that specializes in finding solutions inspired by nature.\"<\/data> 809da8a35547ca53620a67d4f1cdb6f5<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"2defde0504bd9c1a5bdd248980ce1ce1","chunk":" people the Bernoulli principle: the faster air moves, the lower below felled buildings, perhaps gas exchange networks its pressure becomes. Since air closer to the ground is could vent carbon dioxide and pump in oxygen to help slower due to friction and turbulence, the air around recovery efforts. Studying aerenchyma may even lead higher stems is faster, and has lower pressure. This to medical therapies based on the concept of multiple pulls stale air out of the taller broken stems and draws networks of gas flow to deliver oxygen to (or removes oxygen-rich fresh air into the shorter broken stems.\n\ntoxins from) specific bodily tissues to promote healing.\n\nThe removal of stale air can be as important as the Visit this Strategy on AskNature:\n\nintake of fresh air. Gases like carbon dioxide (which roots https:\/\/asknature.org\/stems-move-air\n\nproduce via cellular respiration of oxygen) and ethylene are drawn upward from the roots, into the rhizomes, and eventually out into the air. Though plants form ethylene to act as a kind of hormone that influences growth, research shows that some plant roots thrive under low ethylene concentrations while higher concentrations References:\n\ncan stunt their growth. Therefore, the ability of wetland plants to vent this gas can help them stay healthy and JOURNAL ARTICLE\n\nkeep growing.\n\nLong-distance transport of gases in plants:\n\na perspective on internal aeration and\n\nThe Potential\n\nradial oxygen loss from roots. Plant, Cell, & Understanding how wetlands transport gases could help develop technologies that remove water pollution Environment. 2003. T. D. Colmer.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nUnderground Network\n\nDistributes Resources\n\nLIVING SYSTEM:\n\nMycorrhizal fungi\n\nAUTHOR:\n\nSherry Ritter\n\nPeter Prehn \/ CC BY-NC-ND\n\nFUNCTIONS PERFORMED:\n\nDistribute Solids\n\nDistribute Liquids\n\nProtect from Animals\n\n\n\nSend Chemical Signals\n\nCooperate\/Compete\n\nMycorrhizal network sustains diversity in a forest by transporting nutrients and water.\n\nIn a Douglas-fir and pine forest in North America there are trees of all ages, ranging from tiny\n\nseedlings to giants that are hundreds of years old.\n\nHidden in the soil is a vast network made up of millions of miles of thin threads called mycelium.\n\nMost of the mycelium spread throughout this\n\nforest are mycorrhizal fungi","chunk_id":"2defde0504bd9c1a5bdd248980ce1ce1","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"PETER PREHN\"","type":"\"PERSON\"","description":"\"Peter Prehn, a contributor to Biomimicry Institute and AskNature.org, explains the underground network strategy of mycorrhizal fungi in a Douglas-fir and pine forest context.\") (\"entity\"","source_id":"2defde0504bd9c1a5bdd248980ce1ce1"}],"entity_graph":" \"PERSON\"<\/data> \"Peter Prehn, a contributor to Biomimicry Institute and AskNature.org, explains the underground network strategy of mycorrhizal fungi in a Douglas-fir and pine forest context.\") (\"entity\"<\/data> 2defde0504bd9c1a5bdd248980ce1ce1<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"dbf85def96906b82d29e7bcd512b920f","chunk":" North America there are trees of all ages, ranging from tiny\n\nseedlings to giants that are hundreds of years old.\n\nHidden in the soil is a vast network made up of millions of miles of thin threads called mycelium.\n\nMost of the mycelium spread throughout this\n\nforest are mycorrhizal fungi. These are fungi that live in a mutualistic partnership with trees and other plants.\n\nThe mycelium acts like an internet network but\n\ninstead of moving electronic information around, they transport water and chemicals to keep the\n\ntrees alive and communicating with each other.\n\nThis network has been called the \u201cWood Wide\n\nWeb\u201d.\n\nThe Strategy\n\nOn the internet, nodes are individual computers A top\u2010down view mapping fungi and 67 Douglas\u2010fir and the network moves information among\n\ntrees in a 30\u00d730 m plot. Green shapes are trees. Lines them. Hubs are places that connect lots of nodes illustrate the linkages between tree roots via the fungal together and have a lot of information traveling network. An arrow points to the most highly connected tree, which was linked to 47 other trees. Image Credit: through them, such as Google. The nodes of the\n\nBeiler, et. al.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nWood Wide Web are all the individual trees in the Researchers at a study site in Canada discovered forest. The oldest trees, which are often also the that one tree was connected to 47 others through tallest and largest, are the \u2018hubs\u2019 because they this network. Sixty percent of the tree species in the have the most connections running through them.\n\nworld are associated with these mycorrhizal fungi.\n\nMost trees form symbioses with a wide variety of Mycelia form the connections between all the fungal species (there are more than 5000 of them) nodes in the Wood Wide Web. The mycelia and each species of fungus can have relationships wrap around the fine roots of the hub tree and with a wide variety of trees.\n\nother vegetation, snuggling so close that water, nutrients, and other chemicals can move between Besides sharing nutrients and water, the network the cells of the roots and fungi. A hub tree has also sends warnings. If a tree is attacked by a more access to sunlight than smaller trees because bark beetle, it sends out a chemical signal, called of its size. Sometimes that results in it producing a defense signal. The mycelium","chunk_id":"dbf85def96906b82d29e7bcd512b920f","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"MYCORRHIZAL FUNGI\"","type":"\"ORGANISM\"","description":"\"Mycorrhizal fungi form mutualistic partnerships with trees and other plants, facilitating nutrient exchange and communication through the Wood Wide Web.\") (\"entity\"","source_id":"dbf85def96906b82d29e7bcd512b920f"}],"entity_graph":" \"ORGANISM\"<\/data> \"Mycorrhizal fungi form mutualistic partnerships with trees and other plants, facilitating nutrient exchange and communication through the Wood Wide Web.\") (\"entity\"<\/data> dbf85def96906b82d29e7bcd512b920f<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"ac3f4943aac0de17b70d54bf387fe19b","chunk":" water, the network the cells of the roots and fungi. A hub tree has also sends warnings. If a tree is attacked by a more access to sunlight than smaller trees because bark beetle, it sends out a chemical signal, called of its size. Sometimes that results in it producing a defense signal. The mycelium passes this signal too much sugar through photosynthesis. When along to other nearby trees. When they get the this happens, it sends the sugar out through the signal, they reinforce their chemical defenses, mycelium network to be used by its own seedlings which makes it easier for them to fight off an and even other species of trees. The fungi take attack when it comes.\n\nsome of the sugar as it passes between trees and use it for themselves.\n\nThe Potential\n\nThe Wood Wide Web can show us the value of\n\nWater is also shared among the fungi and plants sharing resources, efficient ways to move them, in the network. The water and nutrients increase and the importance of forming close partnerships.\n\nseedling growth and help other trees survive. At We also can learn how to better manage our another time, if the hub tree is stressed and needs forests to maintain this underground network that water or nutrients, the mycelium and other trees provides mutual support to all partners.\n\ncan send them back to the hub tree.\n\nVisit this Strategy on AskNature:\n\nBut this isn\u2019t just about one hub tree. It\u2019s about a https:\/\/asknature.org\/fungal-hub tree connected to a seedling connected to a network sapling, connected to another hub tree, and so on.\n\nReferences:\n\nMAGAZINE ARTICLE\n\nJOURNAL ARTICLE\n\nThe Wood Wide Web. The Atlantic. April 14, 2016.\n\nArchitecture of the wood\u2010wide web. New\n\nYong E.\n\nPhytologist. October 29, 2009. Beiler KJ, Durall DM, Simard SW, Maxwell SA, Kretzer AM.\n\nJOURNAL ARTICLE\n\nInter\u2011plant communication through mycorrhizal\n\nBOOK SECTION\n\nnetworks mediates complex adaptive behaviour\n\nMycorrhizal networks facilitate tree communication, in plant communities. AoB Plants. May 15, 2015.\n\nlearning, and memory. Memory and Learning in Gorzelak MA, Asay AK, Pickles BJ, Simard SW.\n\nPlants. April 24, 2018. Simard SW.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOG","chunk_id":"ac3f4943aac0de17b70d54bf387fe19b","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"MYCORRHIZAL NETWORK\"","type":"\"CONCEPT\"","description":"\"A network formed between the roots of plants and fungi, facilitating resource exchange, information sharing, and mutual support among plant communities.\") (\"entity\"","source_id":"ac3f4943aac0de17b70d54bf387fe19b"}],"entity_graph":" \"CONCEPT\"<\/data> \"A network formed between the roots of plants and fungi, facilitating resource exchange, information sharing, and mutual support among plant communities.\") (\"entity\"<\/data> ac3f4943aac0de17b70d54bf387fe19b<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"0a71d2671ba6b6bceb2f13e60122c278","chunk":"learning, and memory. Memory and Learning in Gorzelak MA, Asay AK, Pickles BJ, Simard SW.\n\nPlants. April 24, 2018. Simard SW.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nThe World\u2019s Most Diverse\n\nCommunity Lives\n\nin the Soil\n\nLIVING SYSTEM:\n\nSoil ecosystem\n\nAUTHOR:\n\nLonny Lippsett\n\n\u00a9Andrew Linscott \/ Shutterstock\n\nFUNCTIONS PERFORMED:\n\nCoordinate by Self-Organization\n\nA diverse community of organisms interacts to break down and recycle chemicals to maintain soil fertility.\n\nA shovelful of soil from a forest contains far more crucial role, creating tunnels through which air different types of living things at the micro scale and water seep into the soil.\n\nthan the Serengeti Plain in Africa at the macro scale with all its roaming hordes of animals. The top Slightly smaller animals such as mites and 2 to 4 inches (5 to 10 centimeters) of soil contains springtails occupy air-filled pores within soil.\n\nbillions of organisms that are always interacting.\n\nThey, too, are arthropods\u2013\u2013closely related to, but This complex underground community creates\n\ndistinct from, insects. They also help decompose and maintains the substance that plants, trees, organic material and graze on bacteria.\n\nand animals depend on.\n\nWoven into and around plant roots are fungi, in The Strategy\n\na relationship that benefits both. The fungi grow A cubic meter of soil may contain thousands of out in long narrow tendrils that extend the plants\u2019\n\ndifferent species of bacteria and fungi; single-root systems deep into and across the soil and give celled protists and microscopic nematodes plants more access to minerals they need to grow.\n\n(roundworms); and larger animals such as mites, The fungi also provide a sheath that protects springtails, earthworms, ants, termites, lice, and plants from pathogens and toxic metals. In beetles. Each species takes part in breaking down exchange, the fungi receive sugars that the plants leaves, twigs, fruit, animal carcasses, and feces make via photosynthesis.\n\nand recycling them into smaller organic materials that plants use to live and grow. And each species Nematodes and protists living in water in the soil has specific abilities that take advantage of eat organic material and excrete it in particles different niches in the environment.The","chunk_id":"0a71d2671ba6b6bceb2f13e60122c278","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"LONNY LIPPSETT\"","type":"\"PERSON\"","description":"\"Lonny Lippsett wrote about biological strategies performed by organisms living in soil ecosystem, particularly focusing on self-organization.\"","source_id":"0a71d2671ba6b6bceb2f13e60122c278"},{"name":"\"ASKNATURE.ORG\"","type":"\"WEBSITE\"","description":"\"AskNature.org is a platform where Lonny Lippsett shared information about the functions of a diverse soil ecosystem, including coordination via self-organization.\"","source_id":"0a71d2671ba6b6bceb2f13e60122c278"}],"entity_graph":" \"PERSON\"<\/data> \"Lonny Lippsett wrote about biological strategies performed by organisms living in soil ecosystem, particularly focusing on self-organization.\"<\/data> 0a71d2671ba6b6bceb2f13e60122c278<\/data> <\/node> \"WEBSITE\"<\/data> \"AskNature.org is a platform where Lonny Lippsett shared information about the functions of a diverse soil ecosystem, including coordination via self-organization.\"<\/data> 0a71d2671ba6b6bceb2f13e60122c278<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"17c65307eb89a2d2f26db3e34ba78722","chunk":" carcasses, and feces make via photosynthesis.\n\nand recycling them into smaller organic materials that plants use to live and grow. And each species Nematodes and protists living in water in the soil has specific abilities that take advantage of eat organic material and excrete it in particles different niches in the environment.The largest that are smaller and\/or more easily absorbed by decomposers are earthworms, ants, termites, roots. Nematodes also eat bacteria, keeping their millipedes, woodlice, and beetles. They play a populations in balance.\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nBIOLOGICAL STRATEGY\n\nA community of diverse organisms interacts to break down organic matter and recycle it into nutrients for plants to re-use. Image Credit: Milkwood.net \/ CC BY-NC-SA Those bacteria have diverse roles to play as well.\n\nfor helping us to manage our activities on the land Some species convert gaseous nitrogen into solid more sustainably.\n\nnitrates that plants take up for essential chemical functions. Others specialize in decomposing In addition, learning the intricacies of how tough, slow-rotting molecules like cellulose that different organisms break down waste can lead to plants produce to keep stiff and strong.\n\nmore effective and eco-friendly waste treatment systems.\n\nThe Potential\n\nPeople have learned the hard way that radically Visit this Strategy on AskNature:\n\nchanging the landscape above ground can have https:\/\/asknature.org\/soil-dire impacts on the underground ecosystem, community\n\nturning vital soil into infertile dust. Herbicides and insecticides take out segments of the interconnected community that recycle and\n\nreplenish the soil. Farming and clearcutting References:\n\nforests cut the supplies to underground species.\n\nBOOK\n\nHeavy equipment compacts soil too much for\n\nThe Work of Nature: How the Diversity of Life air and water to penetrate. Understanding, maintaining, and working in harmony with the Sustains Us. 1997. Yvonne Baskin.\n\ndiverse community in the soil holds great potential\n\n\u00a92022 Biomimicry Institute\n\nBiomimicry.org | AskNature.org\n\n\n\n\n\nDocument Outline\n\n\nAN-Bird Respiration_Final_05-2022\n\nAN-Bull-Snake-Sound_Final_05-2022\n\nAN-Butterfly-Scales-Lift_Final_05-2022\n\nAN-Diving-Spider_Updated_06-2022\n\nAN-Flying-S","chunk_id":"17c65307eb89a2d2f26db3e34ba78722","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":512,"entities":[{"name":"\"COMMUNITY OF ORGANISMS\"","type":"\"ORGANIZATION\"","description":"\"This refers to the diverse ecosystem that works together to break down organic matter and recycle it into nutrients for plants to reuse.\")<|\"\\n\"|\"Entity\"","source_id":"17c65307eb89a2d2f26db3e34ba78722"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"This refers to the diverse ecosystem that works together to break down organic matter and recycle it into nutrients for plants to reuse.\")<|\"\\n\"|\"Entity\"<\/data> 17c65307eb89a2d2f26db3e34ba78722<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"03018b77601ad2b2e8345af35fb84450","chunk":"Document Outline\n\n\nAN-Bird Respiration_Final_05-2022\n\nAN-Bull-Snake-Sound_Final_05-2022\n\nAN-Butterfly-Scales-Lift_Final_05-2022\n\nAN-Diving-Spider_Updated_06-2022\n\nAN-Flying-Squirrel_Final_05-2022\n\nAN-Frog-Sound-Amplification_Final_05-2022\n\nAN-Fruit-Bats_Ecolocation_Final_05-2022\n\nAN-Pelican-Ground-Effect_Final_05-2022\n\nAN-Prairie_Dog_Ventilation_Final_05-2022\n\nAN-Spider-Legs_Final_05-2022\n\nAN-Spider_Balloon_Final_05-2022\n\nAN-Trout-Vortices\n\nAN-Water-Strider_ Spider_Final_05-2022\n\nAN-Mycorrhizal-Fungi-Network\n\nAN-Pine-Cone_06-2022\n\nAN-Pine-Spiral\n\nAN-Plants_Heliotropism\n\nAN-Soil-Ecosystem\n\nAN-Wetland-Plants-Air_Final_05-2022\n\n\n\n\n\n","chunk_id":"03018b77601ad2b2e8345af35fb84450","document_ids":["0c45c841f585086b2dd0b3ed30b2e795"],"n_tokens":245,"entities":[{"name":"\"AN-BIRD RESPIRATION_FINAL_05-2022\"","type":"\"EVENT\"","description":"\"AN-Bird Respiration_Final_05-2022 refers to a document that discusses bird respiration process which is being finalized in the month of May 2022.\") (\"entity\"","source_id":"03018b77601ad2b2e8345af35fb84450"}],"entity_graph":" \"EVENT\"<\/data> \"AN-Bird Respiration_Final_05-2022 refers to a document that discusses bird respiration process which is being finalized in the month of May 2022.\") (\"entity\"<\/data> 03018b77601ad2b2e8345af35fb84450<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"ff760235e3461c93ff1fa2bee432fdb1","chunk":"THE BIOMIMICRY TAXONOMY:\n\nBiology Organized by Function\n\nWhat is the Biomimicry Taxonomy?\n\nA taxonomy is a system of classification. The Biomimicry Taxonomy is a classification system developed by the Biomimicry Institute to organize biological content on the website AskNature\n\n(AskNature.org). The Taxonomy categorizes the different ways that organisms and natural systems meet functional challenges.\n\nOn AskNature, the ways that organisms and other living systems meet functional challenges are called strategies. The Biomimicry Taxonomy organizes these biological strategies by function, that is, by what the strategy does for the organism or living system. Organizing biological content by function is valuable because it allows How strategies appear on AskNature.\n\nus to look for potential solutions to similar challenges we face as humans.\n\nHere is an example showing how AskNature represents a strategy and a related function within the Biomimicry Taxonomy. In the Taxonomy, functions are organized in a nested hierarchy. The top level, \u201cGroup,\u201d represents a broad function performed in nature, the second level a \u201cSub-Group\u201d\n\nof functions, and the third level a specific \u201cFunction.\u201d In total, the Taxonomy features eight groups comprised of 30 sub-groups that contain more than 160 functions.\n\nOrganism What is the organism?\n\nNamib desert beetle\n\nChallenge What challenge must it Capturing water in a very arid climate address?\n\nStrategy\n\nHow does the organism\n\nThe beetle\u2019s wing covers gather water from the air address this challenge?\n\nusing nanoscale bumps and body position.\n\n(strategy)\n\nView this strategy page on AskNature.\n\nFunction\n\nWhy does the organisms need To capture liquid this strategy?\n\nThis is represented by the Biomimicry Taxonomy as: \u04f9 Group: Get, store, or distribute resources \u04f9 Sub-group: Capture, absorb, or filter resources\n\n\u2022 Function: Capture, absorb, or filter liquids 1\n\nBiomimicry.org | AskNature.org\n\nUsing the Biomimicry Taxonomy on AskNature AskNature and the Biomimicry Taxonomy provide a novel way to approach your innovation challenges.\n\nLook to the Taxonomy as a tool when you first approach your design challenge, using its framework to identify questions you can \u201cask\u201dnature. For example, if you\u2019re trying to make less toxic pigments, \u201cask\u201d\n\nhow nature creates color. If you want to manufacture tough, lightweight building materials without energy-intensive high pressures and temperatures, \u201cask\u201d how","chunk_id":"ff760235e3461c93ff1fa2bee432fdb1","document_ids":["a102cdf19bc35f57dee1ff8698a21683"],"n_tokens":512,"entities":[{"name":"\"THE BIOMIMICRY TAXONOMY\"","type":"\"CONCEPT\"","description":"\"It is a system of classification developed by the Biomimicry Institute for organizing biological content on their website AskNature.org. This taxonomy categorizes strategies that organisms and natural systems use to meet functional challenges. The strategies are classified according to functions, which describe what the strategy accomplishes for the organism or living system. This helps users identify potential solutions to similar human challenges by looking at nature's approach to solving issues.\")","source_id":"ff760235e3461c93ff1fa2bee432fdb1"}],"entity_graph":" \"CONCEPT\"<\/data> \"It is a system of classification developed by the Biomimicry Institute for organizing biological content on their website AskNature.org. This taxonomy categorizes strategies that organisms and natural systems use to meet functional challenges. The strategies are classified according to functions, which describe what the strategy accomplishes for the organism or living system. This helps users identify potential solutions to similar human challenges by looking at nature's approach to solving issues.\")<\/data> ff760235e3461c93ff1fa2bee432fdb1<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"e4b6193a4ea13cb8c682998eb02efb6d","chunk":" you first approach your design challenge, using its framework to identify questions you can \u201cask\u201dnature. For example, if you\u2019re trying to make less toxic pigments, \u201cask\u201d\n\nhow nature creates color. If you want to manufacture tough, lightweight building materials without energy-intensive high pressures and temperatures, \u201cask\u201d how nature manages structural forces.\n\nAskNature offers two ways for you to ask questions of nature: using Search and using the Function menu. Using the Search bar on the home page, you can ask questions like those posed above, for example: \u201cHow does nature stay dry?\u201d Further down on the homepage, links to the top level of the Biomimicry Taxonomy enable you to quickly find strategies by function. Clicking on one of the top level functions will lead you to a page where you can access the whole Taxonomy and the AskNature content that addresses each function.\n\nUsing the Biomimicry Taxonomy as a Critial Thinking Tool The Biomimicry Taxonomy is useful not just because it will help you navigate better on AskNature, but because it provides a framework that may help you understand your challenge differently. Here\u2019s an example of how you could use the Taxonomy to help solve your next innovation challenge.\n\nInnovation Challenge: You\u2019re designing a building in an area of low rainfall. To ensure an adequate water supply, you want your building to capture rainwater and store it for future use.\n\nApproach #1: Identify verbs that directly define your challenge. Use the Biomimicry Taxonomy for ideas that help you shift from predetermined thoughts of how or what you\u2019ll design to why you\u2019re designing (in other words, your design\u2019s purpose or the outcomes it must accomplish). Use verbs that describe functions (such as: move, break down, distribute, etc.). In this example, the questions you pose might be: How does nature\u2026\n\n\u2022 Capture water?\n\n\u2022 Store water?\n\nApproach #2: Consider concepts that go beyond your exact challenge but are related enough to why you\u2019re designing that they may have similar solutions. In this example, you may consider that some organisms (like the Namib beetle) live in areas that experience little to no rain, yet they still get all of the water they need. Use the Biomimicry Taxonomy to spark ideas for new verbs, and also think about related nouns or synonyms. In this example, questions to pose might include: How does nature\u2026\n\n\u2022 Absorb water?\n\n\u2022 Capture fog?\n\n\u2022 Manage humidity?\n\n\u2022 Move water?\n\nApproach #","chunk_id":"e4b6193a4ea13cb8c682998eb02efb6d","document_ids":["a102cdf19bc35f57dee1ff8698a21683"],"n_tokens":512,"entities":[{"name":"\"ASKNATURE\"","type":"\"ORGANIZATION\"","description":"\"AskNature is an online platform providing access to strategies and insights from natural systems for design solutions.\" ) (\"entity\"","source_id":"e4b6193a4ea13cb8c682998eb02efb6d"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"AskNature is an online platform providing access to strategies and insights from natural systems for design solutions.\" ) (\"entity\"<\/data> e4b6193a4ea13cb8c682998eb02efb6d<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"6de0fc3cc6011a0ce9267a0584f498b2","chunk":" of the water they need. Use the Biomimicry Taxonomy to spark ideas for new verbs, and also think about related nouns or synonyms. In this example, questions to pose might include: How does nature\u2026\n\n\u2022 Absorb water?\n\n\u2022 Capture fog?\n\n\u2022 Manage humidity?\n\n\u2022 Move water?\n\nApproach #3: Turn your question completely around. Instead of asking how nature stores water, think about how it protects against excess water or keeps water out. Although counterintuitive, sometimes asking the opposite of your original question can provide new insights to your real challenge. The Biomimicry Taxonomy is a great resource for ideas of verbs that represent opposites. In this example, you might ask: How does nature\u2026\n\n\u2022 Remove water?\n\n\u2022 Stay dry?\n\n2\n\nBiomimicry.org | AskNature.org\n\nind\n\near\n\nes\n\nases\n\nases\n\ns\n\nirt\/solids\n\ns\n\neostasis\n\nical w\n\nlid\n\nh g\n\nuid\n\nicrob\n\nuclear radiation\n\nelting \u2022 Fracture\/rupture\n\nrarily\n\nanently\n\no\n\nicals \u2022 Fire \u2022 Ice\n\nhem\n\np\n\nn so\n\nals \u2022 Plants\n\nal shock\n\nerm\n\nhem\n\naintain hom\n\nnim\n\nFUNCTION\n\near \u2022 C\n\n\u2022 P \u2022 Tem\n\npression\n\n\u2022 In\/o \u2022 In\/on liq \u2022 In\/throug\n\nperature \u2022 N\n\n\u2022 A \u2022 Fungi \u2022 M \u2022 Excess liquids \u2022 W\n\n\u2022 Loss of liquids \u2022 G\n\nation \u2022 Fatigue \u2022 M\n\n\u2022 Loss of gases \u2022 D\n\n\u2022 Light \u2022 C\n\npact \u2022 Tension \u2022 Turbulence\n\nTS\n\n\u2022 Tem\n\nA\n\nechanical w\n\nE\n\n\u2022 Shear \u2022 Therm\n\nR\n\n\n\n\u2022 Im \u2022 M\n\nG\n\n\u2022 Creep \u2022 Com\n\nTH\n\nIN\n\nGIN\n\n\u2022 Reproduction or growth\n\n\u2022 Cel ular processes \u2022 M\n\n-LIV\n\nN\n\nRCES\n\nLIV\n\nO\n\nM\n\nN\n\nL FO\n\nO\n\nM\n\nRA\n\nCESSES\n\nithin the same species \u2022 Cooperate\/compete between dif erent species\n\n\u2022 Coordinate by self-organization \u2022 Activities \u2022 Systems\n\n\u2022 Buckling \u2022 Deform\n\nH\n\nT FR\n\nithin a (eco)system \u2022 Cooperate\/compete between (eco)systems CTU\n\n\u2022 W\n\nC\n\nC\n\nE\n\nT FRO\n\nL. PRO\n\nV\n\nTE\n\nTTA\n\nO\n\nO\n\nTEC\n\nR","chunk_id":"6de0fc3cc6011a0ce9267a0584f498b2","document_ids":["a102cdf19bc35f57dee1ff8698a21683"],"n_tokens":512,"entities":[{"name":"\"ORGANIZATION\"","type":"\"BIOMIMICRY TAXONOMY\"","description":"\"Biomimicry Taxonomy provides a framework for exploring new verbs and related concepts, facilitating innovation through nature-inspired solutions.\"","source_id":"6de0fc3cc6011a0ce9267a0584f498b2"}],"entity_graph":" \"BIOMIMICRY TAXONOMY\"<\/data> \"Biomimicry Taxonomy provides a framework for exploring new verbs and related concepts, facilitating innovation through nature-inspired solutions.\"<\/data> 6de0fc3cc6011a0ce9267a0584f498b2<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"170684a57b4848b420032214260ee67b","chunk":" Buckling \u2022 Deform\n\nH\n\nT FR\n\nithin a (eco)system \u2022 Cooperate\/compete between (eco)systems CTU\n\n\u2022 W\n\nC\n\nC\n\nE\n\nT FRO\n\nL. PRO\n\nV\n\nTE\n\nTTA\n\nO\n\nO\n\nTEC\n\nR\n\nE STRU\n\nSUB-GROUP\n\nREATS\n\nG\n\nA\n\nA\n\nM\n\nN\n\nT\n\nA\n\nTH\n\nP\n\nU\n\nULATE PHYSIO\n\nPRO\n\nPY\n\nM\n\nM\n\nSTAR\n\nRM\n\nA\n\nO\n\nT FRO\n\nE\n\nL H\n\nVO\n\nTEC\n\nGROUP\n\nYSICA\n\nM\n\nPRO PH\n\nMODIFY PHYSICAL STATE\n\nPROVIDE ECOSYSTEM SERVICES\n\nCOOPERATE\n\nCOORDINATE\n\nPREVENT STRUCTURAL FAILURE\n\nREG\n\nMAINTAIN\n\nMODIFY CHEMICAL\/ELECTRICAL\n\nCOMMUNITY\n\nSTATE\n\n\u2022 Adapt behaviors \u2022 Optimize space\/materials\n\n\u2022 Adapt genotype \u2022 Adapt phenotype \u2022 Coevolve\n\n\u2022 Chemical y generate flow of electrons\n\n\u2022 Surface tension \u2022 pH \u2022 Solubility \u2022 Electron transport\n\n\u2022 Oxidation state \u2022 Electric charge \u2022 Conductivity\n\n\u2022 Chemical potential \u2022 Reactivity with water\n\n\u2022 Energy state \u2022 Free radical reactivity \u2022 Concentration\n\n\u2022 Speed \u2022 Position\n\n\u2022 Buoyancy \u2022 Light\/color \u2022 Material characteristics\n\n\u2022 Size\/shape\/mass\/volume \u2022 Pressure \u2022 Density \u2022 Phase\n\n\u2022 Maintain biodiversity \u2022 Biological control of populations, pests, diseases\n\n\u2022 Regulate atmospheric composition \u2022 Regulate climate \u2022 Disperse seeds\n\n\u2022 Control erosion and sediment \u2022 Regulate water storage \u2022 Cycle nutrients\n\n\u2022 Generate soil\/renew fertility \u2022 Detoxification\/purification of air\/water\/waste\n\n\u2022 Manage disturbance in a community \u2022 Regulate hydrological flows \u2022 Pol inate\n\n\u2022 W\n\nMODIFY\n\nADAPT \/ OPTIMIZE\n\n\u2022 Electrical energy \u2022 Magnetic energy TRANSFORM\/CONVERT\n\n\n\nE\n\n\u2022 Ch\n\nN\n\nemi\n\nE\n\ncal e\n\nR\n\nner\n\nG\n\ngy\n\nY\n\n\u2022 Mechanical energy\n\n\u2022 Thermal energy \u2022 Radiant energy (light) M\n\n\n\nA\n\nR\n\nK\n\nEP\n\nE\n\nRODU\n\n\n\nC\n\n\n\nE\n\nPHY\n\n\n\nS\n\n\n\nIC\n\n\u2022\n\nA\n\nS\n\nP\n\nL\n\nel\n\nL\n\nf-\n\nY\n\nrep\n\n\n\nasknature.org\n\n\n\nR\n\nA\n\nlica\n\nS\n\nte\n\nS\n\nI\n\nO\n\nN\n\n\n\nE\n\n\n\nM\n\nC\n\n\n\nB\n\n\n\nL\n\n\n\nE","chunk_id":"170684a57b4848b420032214260ee67b","document_ids":["a102cdf19bc35f57dee1ff8698a21683"],"n_tokens":512,"entities":[{"name":"\"ORGANIZATION\"","type":"\"CTU\"","description":"\"CTU refers to a group or organization that is focused on understanding and managing ecosystems, including their physical state modifications and services provided.\"","source_id":"170684a57b4848b420032214260ee67b"},{"name":"\"PERSON\"","type":"\"H\"","description":"\"H could represent any individual within an organization or group dealing with eco-system management, focusing on behaviors optimization, space\/material adaptation, and coordination with other groups.\"","source_id":"170684a57b4848b420032214260ee67b"}],"entity_graph":" \"CTU\"<\/data> \"CTU refers to a group or organization that is focused on understanding and managing ecosystems, including their physical state modifications and services provided.\"<\/data> 170684a57b4848b420032214260ee67b<\/data> <\/node> \"H\"<\/data> \"H could represent any individual within an organization or group dealing with eco-system management, focusing on behaviors optimization, space\/material adaptation, and coordination with other groups.\"<\/data> 170684a57b4848b420032214260ee67b<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"3678ab8d2bad24bba44d0a83fe09f8a6","chunk":"DU\n\n\n\nC\n\n\n\nE\n\nPHY\n\n\n\nS\n\n\n\nIC\n\n\u2022\n\nA\n\nS\n\nP\n\nL\n\nel\n\nL\n\nf-\n\nY\n\nrep\n\n\n\nasknature.org\n\n\n\nR\n\nA\n\nlica\n\nS\n\nte\n\nS\n\nI\n\nO\n\nN\n\n\n\nE\n\n\n\nM\n\nC\n\n\n\nB\n\n\n\nL\n\n\n\nE\n\nF\n\nE\n\nC\n\n\n\nO\n\nS\n\nHE\n\n\n\nB\n\nS\n\nM\n\n\u2022 S\n\nI\n\nt\n\nC\n\nruc\n\n\n\nR\n\n\n\nA\n\ntu\n\nL\n\nre\n\n\n\nR D G\n\nR\n\nM\n\n\n\nL\n\nE\n\n\n\nY\n\nA\n\n\n\n\n\nA\n\n\n\nE I\n\nE\n\n\n\nSSEM\n\n\n\nA\n\nT\n\n\n\n\u2022\n\nN\n\nB\n\n\n\n\n\nL\n\nP\n\nv. 6.1\n\nS\n\nS\n\nT\n\nI\n\n\n\no\n\n\n\nK\n\nO\n\n\n\nAVI\n\nE\n\n\n\nT\n\n,\n\n\n\nG\n\n\n\nl\n\n\u2022\n\nym\n\n\n\n\n\nO\n\n\n\n\n\nN\n\n\n\nS\n\ners\n\n\n\nA\n\n\u2022\n\n\n\nR\n\nS\n\nD\n\n\n\nSEN\n\nTE\n\n\n\np\n\n\n\n\n\nM\n\n\n\n\u2022\n\ne\n\nU\n\nI\n\nT\n\n\n\n\n\nc\n\ne\n\nO\n\nD\n\nI\n\ni\n\nt\n\n\n\nn\n\nfic st\n\nal-ba\n\n\n\nB\n\n\n\nR\n\nO\n\nPR\n\nS\n\n\n\ne\n\ns\n\nI\n\n\n\no\n\nr\n\ne\n\nW\n\n\n\nG\n\n\u2022\n\nr\n\ne\n\nd\n\nU\n\n\n\nO\n\n\n\no\n\n\n\nA\n\nganic\n\nisom\n\ncomp\n\n\n\n\n\nC\n\nR\n\n\n\n\n\nN\n\nT\n\nN\n\n\n\nS\n\nC\n\nA\n\n\n\n\n\ne\n\no\n\nE\n\n\n\nc\n\nu\n\n\u2022\n\ntt\n\no\n\nrs\n\nn\n\n\n\nE\n\nL\n\n\n\na\n\n\n\nd\n\nS\n\nE\n\nE\n\nS\n\nC\n\nc\n\nm\n\n\u2022\n\ns\n\n\n\nE N\n\nS\n\na\n\nh\n\np\n\nM\n\n\n\n\n\nt\n\na\n\no\n\n\u2022\n\nE\n\n\n\n\n\na\n\n\n\nu\n\nin\n\nM\n\n\n\nS\n\n,\n\nN\n\nS\n\nS\n\nl\n\nf\n\nn\n\ny\n\nu\n\nd\n\ne\n\no\n\n\n\n\n\nV\n\nE\n\nI\n\nz\n\nn\n\ns\n\nra\n\nle\n\n\n\nG\n\ne\n\nc\n\n\n\nl\n\ncu\n\n\n\nO\n\nI\n\n\n\n\n\nt\n\n\n\nc\n\nC\n\nm\n\nio\n\n\u2022\n\nrys\n\nlar\n\n\n\nR\n\nS\n\nN\n\na\n\nn\n\nO\n\nt\n\nd\n\n\n\nO\n\nI\n\nk\n\na\n\nrg\n\nal\n\nev\n\n\n\nO\n\nG\n\nA\n\ni\n\nl\n\ns\n\nn\n\ngro\n\ni\n\nu\n\nanic\n\n\n\nces\n\n\n\nR\n\n\n\nM\n\nN\n\nN\n\nLS\n\n\n\nc\n\n\n\n","chunk_id":"3678ab8d2bad24bba44d0a83fe09f8a6","document_ids":["a102cdf19bc35f57dee1ff8698a21683"],"n_tokens":512,"entities":[{"name":"\"ASKNATURE.ORG\"","type":"\"ORGANIZATION\"","description":"\"Asknature.org is a website that offers information and resources on various scientific topics, including ecology and evolution.\"),(\"entity\"","source_id":"3678ab8d2bad24bba44d0a83fe09f8a6"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"Asknature.org is a website that offers information and resources on various scientific topics, including ecology and evolution.\"),(\"entity\"<\/data> 3678ab8d2bad24bba44d0a83fe09f8a6<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"2b9b282e75a0a5345cc0cee8f327a2b1","chunk":"S\n\nN\n\na\n\nn\n\nO\n\nt\n\nd\n\n\n\nO\n\nI\n\nk\n\na\n\nrg\n\nal\n\nev\n\n\n\nO\n\nG\n\nA\n\ni\n\nl\n\ns\n\nn\n\ngro\n\ni\n\nu\n\nanic\n\n\n\nces\n\n\n\nR\n\n\n\nM\n\nN\n\nN\n\nLS\n\n\n\nc\n\n\n\nM\n\nA\n\n\n\ng\n\np\n\no\n\nP\n\n\u2022\n\no\n\n\n\nm\n\n\n\n\n\nL\n\nT\n\nf\n\n\u2022\n\npo\n\n\n\nC\n\nU\n\nE\n\nS\n\nh\n\nbo\n\nD\n\nu\n\n\n\nr\n\nnds\n\netac\n\nn\n\nT\n\nN\n\n\n\nh\n\nds\n\n\n\n\n\nH\n\nE\n\n\/\n\nT\n\n\n\no\n\n\n\n\n\nE\n\n\n\n\n\na\n\nA\n\n\u2022\n\nugh\n\n\u2022 O\n\n\n\n\n\nn\n\nfun\n\n\n\nc\n\n\n\n\n\nP\n\nM\n\nL\n\nL\n\n\n\n\n\nt\n\n\n\nE\n\n\n\n\n\nL\n\na\n\nd\n\ni\n\n\n\n\n\nC\n\n\u2022\n\ni\n\nir\n\ne\n\non\n\n\n\n\n\nH\n\nIC\n\nA\n\n\n\ng\n\n\n\nm\n\n\n\nU\n\nT\n\n\n\nal\n\n\n\n\n\na h\n\n\u2022\n\nan\n\ng\n\n\n\n\n\nC\n\nY\n\nA\n\nR\n\nE\n\nc t (v\n\n\n\nr\n\ni\n\nThr\n\nd\n\noup\n\n\n\n\n\nS\n\nA\n\nSI\n\nL\n\nN\n\nS\n\n\n\nt\n\ns\n\no\n\nE\n\nL\n\n\n\ni\n\ni\n\nu\n\nD\n\nP\n\nC\n\n\n\n\u2022\n\nc\n\nb\n\ng\n\nT\n\nY\n\n\n\nX\n\n[\n\n\n\nle\n\nle\n\nD\n\n\n\nh\n\nT\n\nA\n\n\n\nE\n\n\u2022\n\n\n\n\n\nI\n\nO\n\nB\n\n\n\nspe\n\nliqu\n\nS\n\nP\n\nT\n\nR\n\nU\n\nL\n\nR\n\nN\/\n\n\n\nif\n\nC\n\nc\n\ni\n\nAXONOMYE\n\nL\n\n\n\nfe\n\nR\n\nr\n\nhe\n\ntru\n\nd\n\nE\n\nD\n\n\u2022\n\nR\n\nE\n\nL\n\nE\n\nY\n\nA\n\nE\n\n\u2022\n\ne\n\nm\n\nm\n\nI\n\n\n\nL\n\n\n\ni\n\nnt\n\nic\n\n)\n\nOv\n\nB\n\n,\n\nBR\n\nK\n\n]C\n\n\u2022\n\ng\n\ni\n\na\n\n\n\ne\n\nA\n\n\n\nO\n\nT\n\nh\n\na\n\n\u2022\n\nU\n\nt\n\nte\n\nl (o\n\nLi\n\nr la\n\nB\n\nE\n\nD\n\nD\n\n\u2022\n\no\n\n\n\n\n\nd\n\ng\n\nn\n\nT\n\nA\n\nO\n\n\n\n(\n\ns\n\nd\n\nE\n\n\u2022 S u\n\nv\n\nig\n\no\n\nht\n\n\n\nE\n\nS\n\nW\n\n\n\nc\n\ni\n\nr\n\n\n\n\n\nK\n\nB o\n\nh\n\nsi\n\nna\n\n, t\n\n(n\n\n\u2022 T\n\nO\n\nY T\n\n\n\na","chunk_id":"2b9b282e75a0a5345cc0cee8f327a2b1","document_ids":["a102cdf19bc35f57dee1ff8698a21683"],"n_tokens":512,"entities":[{"name":"\"ALEX\"","type":"\"PERSON\"","description":"\"Alex is the leader of a team attempting first contact with an unknown intelligence, acknowledging the significance of their task.\"","source_id":"2b9b282e75a0a5345cc0cee8f327a2b1"}],"entity_graph":" \"PERSON\"<\/data> \"Alex is the leader of a team attempting first contact with an unknown intelligence, acknowledging the significance of their task.\"<\/data> 2b9b282e75a0a5345cc0cee8f327a2b1<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"3b8a807b256d918245b0ffb8c88d4c09","chunk":"n\n\nT\n\nA\n\nO\n\n\n\n(\n\ns\n\nd\n\nE\n\n\u2022 S u\n\nv\n\nig\n\no\n\nht\n\n\n\nE\n\nS\n\nW\n\n\n\nc\n\ni\n\nr\n\n\n\n\n\nK\n\nB o\n\nh\n\nsi\n\nna\n\n, t\n\n(n\n\n\u2022 T\n\nO\n\nY T\n\n\n\na u\n\na\n\nb\n\nl\n\nas\n\non\n\nh\n\nD\n\nN\n\nl n\n\nl\n\n\n\nr\n\nR\n\na d\n\nn\n\ne\n\nfr\n\nte\n\n-v\n\nou\n\nO\n\nn\n\nd\n\ns\n\no\n\n,\n\nis\n\ng\n\nB\n\nc a\n\nm p\n\nm\n\ne\n\nib\n\nh\n\n,\n\nW\n\ne n\n\ne\n\nn\n\ntc\n\nle\n\nso\n\n\n\n\/ d\n\nec ctr\n\no\n\n)\n\nsp\n\nlid\n\nO\n\nN\n\n\n\no\n\nh\n\nu\n\nis\n\n\u2022\n\ns\n\n\n\nor th a\n\ne\n\nn\n\nm\n\ne\n\nVi\n\nct\n\nR\n\n\u2022\n\nie\n\n\n\nb\n\nr\n\n\n\nC\n\nn\n\ner\n\n)\n\nF\n\n\n\nica \u2022\n\n\u2022 T\n\nrat\n\num\n\nI\n\n\u2022\n\nl\n\nta\n\nvib l f L\n\nra\n\nory\n\n) \u2022\n\nLT\n\n\u2022\n\nC\n\nea\n\ntio\n\nr\n\ni\n\na\n\nor\n\ngh\n\nnsd\n\n\u2022\n\nSo\n\nE\n\n\n\n\n\nle\n\nv\n\nn\n\nc\n\nt\n\n\n\nu\n\nR\n\n\u2022\n\nI\n\nt\n\ne\n\n\n\nu\n\nE\n\n\u2022 O no a\n\nn\n\nv e\n\ni\n\n\u2022\n\non s\n\n(no\n\nce\/\n\nlec\n\nd\n\n\n\nC r rg e he\n\nS\n\ns\n\n\u2022\n\nn\n\nco\n\ntri\n\n\n\ng\n\n\n\nh\n\n\n\nC\n\n-v\n\nn\n\nca\n\n\u2022\n\na\n\nh\n\na\n\n\u2022\n\nh\n\nv\n\n\u2022\n\na\n\ni\n\nl\n\nN\n\nt\n\nv\n\na\n\n\n\ns\n\n\/\n\na an n\n\ne\n\ni\n\nal\n\ny\n\np\n\nT\n\ne\n\ne\n\nem\n\nib\n\nrt\n\nma\n\n\n\n\n\ni\n\nc\n\no\n\nm\n\nm\n\nle\n\ns\n\ng\n\n\n\nLi o\n\nly c c g\n\nan p\n\nica\n\ns\n\nig\n\nne\n\n.6.1\n\n\n\nn\n\nz\n\ne\n\ne\n\np\n\nn\n\nt\n\n\u2022 \u2022\n\nvi -\n\ne co o\n\ne\n\nm\n\nn\n\nta\n\nd\n\nra\n\nls\n\nec\n\nal\n\nic\n\n\n\n\u2022 O\n\nn\n\nli\n\nb m\n\ns\n\nl\n\np\n\nt\n\n(o\n\n","chunk_id":"3b8a807b256d918245b0ffb8c88d4c09","document_ids":["a102cdf19bc35f57dee1ff8698a21683"],"n_tokens":512,"entities":[{"name":"\"BOHSIHANA\"","type":"\"ORGANIZATION\"","description":"\"BOHsihana is involved in the process of attempting to communicate with an unknown intelligence through their technological means and research.\"","source_id":"3b8a807b256d918245b0ffb8c88d4c09"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"BOHsihana is involved in the process of attempting to communicate with an unknown intelligence through their technological means and research.\"<\/data> 3b8a807b256d918245b0ffb8c88d4c09<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"a19c62053cac11a3e022402443eeba83","chunk":"\n\n\n\nn\n\nz\n\ne\n\ne\n\np\n\nn\n\nt\n\n\u2022 \u2022\n\nvi -\n\ne co o\n\ne\n\nm\n\nn\n\nta\n\nd\n\nra\n\nls\n\nec\n\nal\n\nic\n\n\n\n\u2022 O\n\nn\n\nli\n\nb m\n\ns\n\nl\n\np\n\nt\n\n(o\n\nt\n\ns\n\n\n\n\n\nG\n\ng\n\nvi\n\nr\n\np\n\nf\n\ns\n\na\n\nur\n\nd\n\nru\n\n\u2022\n\n-NC 4.0\n\n\n\n\n\n\u2022\n\nC\n\nr\n\n\n\nn\n\ne\n\np\n\no\n\nr\n\nf\n\ntt\n\ne\n\no\n\nm\n\nR\n\n\u2022 \u2022\n\n\n\n\n\n\u2022 \u2022\n\na\n\ng\n\nm\n\no\n\nr\n\ne\n\n\n\nr,\n\ne\n\n\u2022\n\n\n\n\u2022 \u2022 \u2022\n\n\n\nS\n\nh\n\ns\n\na\n\ng\n\na\n\no\n\nu\n\nm\n\no\n\nr\n\n\u2022\n\nt\n\n)\n\ns\n\nG L\n\n\u2022\n\nC G\n\ns\n\na\n\n\n\nk\n\nu\n\nn\n\nm\n\nn\n\n\n\na\n\n\u2022\n\np\n\nS\n\nE G L S\n\no\n\nem e ni\n\nte m\n\nin n\n\nd\n\no\n\n\n\n\n\nM\n\nst\n\nEl\n\non\n\na\n\niq o\n\nn\n\ni o\n\nh a\n\nli\n\ns\n\ns\n\nr\n\na\n\ng\n\nd\n\ns\n\nrg\n\nor\n\n\u2022\n\not\n\ne,\n\nec\n\nd\n\ns\n\nu\n\nli\n\ne a q\n\nl\n\ne se d\n\nic m\n\nia te\n\no s\n\n\n\na\n\ng\n\nTi\n\nio\n\net\n\ntr\n\nto\n\nBIOMIMICRe i d r s u id m s\n\n\u2022\n\ns\n\n\u2022\n\nn\n\na\n\nm\n\nn\n\nc\n\nic\n\ns\n\ns\n\nd\n\ns\n\ng e\n\nid s\n\ns\n\na\n\nl\n\n\n\ni\n\n\n\n\n\nl\n\nE\n\ns\n\nri\n\nf\n\nP\n\nic\n\nn\n\ne\n\n\u2022\n\n.)\n\nity\n\nign\n\ns\n\ny\n\ns\n\ns\n\nc\n\n\n\n\n\na\n\nb\n\ni\n\n\n\n\n\na\n\n\u2022\n\n\u2022\n\ne\n\nn\n\n\u2022\n\nls\n\no\n\no\n\nc\n\nc\n\nan\n\nP\n\n\u2022 A\n\n\/m\n\nal\n\nl\n\n\n\n\n\nn\n\nl\n\no\n\nc\n\na\n\ns\n\n\n\nE\n\nL\n\ne\n\nS\n\nn\n\ny\n\no\n\nd\n\nin\n\nt\n\na\n\ne\n\nm\n\nm\n\n\n\nm\n\ng\n\nn\n\ni\n\nt\n\nr\n\no\n\nd\n\nm\n\nd\n\n\n\nn\n\nn\n\nq\n\ni\n\ng","chunk_id":"a19c62053cac11a3e022402443eeba83","document_ids":["a102cdf19bc35f57dee1ff8698a21683"],"n_tokens":512,"entities":[{"name":"\"ORGANIZATION\"","type":"\"NC 4.0\"","description":"\"NC 4.0 refers to a specific organization or program mentioned in the text, possibly related to creative license or collaboration.\"","source_id":"a19c62053cac11a3e022402443eeba83"}],"entity_graph":" \"NC 4.0\"<\/data> \"NC 4.0 refers to a specific organization or program mentioned in the text, possibly related to creative license or collaboration.\"<\/data> a19c62053cac11a3e022402443eeba83<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"90ede7f9f06fa68f01d8528ec2495d4b","chunk":"\n\nc\n\na\n\ns\n\n\n\nE\n\nL\n\ne\n\nS\n\nn\n\ny\n\no\n\nd\n\nin\n\nt\n\na\n\ne\n\nm\n\nm\n\n\n\nm\n\ng\n\nn\n\ni\n\nt\n\nr\n\no\n\nd\n\nm\n\nd\n\n\n\nn\n\nn\n\nq\n\ni\n\ng\n\na\n\n\u2022\n\no\n\ne\n\ne\n\nt\n\nli\n\ns\n\ne\n\np\n\np\n\n\n\ns\n\nt\n\nt\n\nu\n\nie\n\ny\n\nd\n\nr\n\no\n\ny\n\nB\n\np\n\ni\n\ni\n\nr\n\ns\n\no\n\nl\n\no\n\ns\n\nt\n\ng\n\nid\n\ns\n\ns\n\nu\n\nu\n\ne\n\nd\n\nh\n\nm\n\neative Commons BY\n\ni\n\n\n\nn\n\ne\n\n\n\ne\n\ny\n\ns\n\n\u2022\n\nnd\n\nn\n\ng\n\ny\n\nric\n\n\u2022\n\nCr\n\ns\n\n\n\n\n\nd\n\nt\n\na\n\n\n\n\n\nL\n\ns\n\ns\n\nh\n\nw\n\nc\n\nD\n\ni\n\no\n\ni\n\nq\n\nar\n\nn\n\nse\n\nu\n\nen\n\nd\n\nas\n\ni\n\nit\n\ne\n\nd\n\nes\n\nio\n\ns\n\ns\n\nns\n\n\u00a9 2008-2017 Biomimicry Institute, v\n\n\u00a9 2008-2017 Biomimicry Institute, Creative Commons BY-NC 4.0 | Biomimicry.org\n\n\n\n\n\n","chunk_id":"90ede7f9f06fa68f01d8528ec2495d4b","document_ids":["a102cdf19bc35f57dee1ff8698a21683"],"n_tokens":285,"entities":[{"name":"\"BIOMIMICRY INSTITUTE\"","type":"\"ORGANIZATION\"","description":"\"The Biomimicry Institute is a copyright holder of the material and operates in the field of biomimicry.\"","source_id":"90ede7f9f06fa68f01d8528ec2495d4b"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The Biomimicry Institute is a copyright holder of the material and operates in the field of biomimicry.\"<\/data> 90ede7f9f06fa68f01d8528ec2495d4b<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"7323cecb72b3fa0472a26a5aa37c4131","chunk":"biomimetics\n\nArticle\n\nDesign and Biomimicry: A Review of Interconnections and\n\nCreative Potentials\n\nAlice Araujo Marques de S\u00e1 1, *\n\nand Dianne Magalh\u00e3es Viana 2\n\n1\n\nDepartment of Design, Institute of Arts, University of Bras\u00edlia, Bras\u00edlia 70910-900, Brazil 2\n\nDepartment of Mechanical Engineering, Faculty of Technology, University of Bras\u00edlia, Bras\u00edlia 70910-900, Brazil\n\n*\n\nCorrespondence: alicearaujoms@gmail.com\n\nAbstract: The study and application of biological knowledge favor the creation of innovative projects in several areas, so it is necessary to better understand the use of these resources specifically in the field of design. Thus, a systematic review was undertaken to identify, describe, and analyze the contributions of biomimicry to design. For this purpose, the integrative systematic review model, called the Theory of Consolidated Meta-Analytical Approach, was used, carrying out a search on the Web of Science with the descriptors \u201cdesign\u201d and \u201cbiomimicry\u201d. For the period from 1991 to 2021, 196 publications were retrieved. The results were organized according to areas of knowledge, countries, journals, institutions, authors, and years. Citation, co-citation, and bibliographic coupling analyses were also performed. The investigation highlighted the following research emphases: the conception of products, buildings, and environments; the exploration of natural structures and systems to create materials and technologies; the use of biomimetic creative tools in product design; and projects focused on saving resources and implementing sustainability. It was noted that there was a tendency for authors to adopt a problem-based approach. It was concluded that the study of biomimicry can stimulate the development of multiple skills in design, improving creativity, and enhancing the potential integration of sustainability into production cycles.\n\nKeywords: design; biomimicry; biomimetic design; systematic review; bio-inspiration; bionics; bio-inspired design; nature-inspired design; bio-informed design; sustainability Citation: S\u00e1, A.A.M.d.; Viana, D.M.\n\nDesign and Biomimicry: A Review of\n\nInterconnections and Creative\n\n1. Introduction\n\nPotentials. Biomimetics 2023, 8, 61.\n\nCreative activities, in their most varied manifestations, often adopt interdisciplinary\n\nhttps:\/\/doi.org\/10.3390\/\n\nknowledge as a reference for their performance. Thus, from","chunk_id":"7323cecb72b3fa0472a26a5aa37c4131","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"ALICE ARAUJO MARQUES DE S\u00c1\"","type":"\"PERSON\"","description":"\"A biomimetics researcher at the Department of Design, University of Bras\u00edlia, who has contributed to studying the application and integration of biological knowledge in design.\")|(\"entity\"","source_id":"7323cecb72b3fa0472a26a5aa37c4131"}],"entity_graph":" \"PERSON\"<\/data> \"A biomimetics researcher at the Department of Design, University of Brasília, who has contributed to studying the application and integration of biological knowledge in design.\")|(\"entity\"<\/data> 7323cecb72b3fa0472a26a5aa37c4131<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"23c34b74899c04c60dc7b087b88e0137","chunk":": A Review of\n\nInterconnections and Creative\n\n1. Introduction\n\nPotentials. Biomimetics 2023, 8, 61.\n\nCreative activities, in their most varied manifestations, often adopt interdisciplinary\n\nhttps:\/\/doi.org\/10.3390\/\n\nknowledge as a reference for their performance. Thus, from this diversified and integrative\n\nbiomimetics8010061\n\napproach, the interconnections between the multiple spheres of knowledge are promoted, Academic Editor: Stanislav N. Gorb\n\nproviding opportunities for innovation. In the opinion of Cardoso [1], the adoption of this type of approach in the processes of teaching, learning, and practice, is essential Received: 18 November 2022\n\nto expand the range of resources available to designers. It should be noted that, based Revised: 26 January 2023\n\non the conception of authors such as Bonsiepe [2], Munari [3], and Flusser [4], design Accepted: 26 January 2023\n\nconsists of envisioning and planning functional creations through the combination of art Published: 2 February 2023\n\nand technique, giving rise to new forms of culture and expression. Design professionals constantly search for guidelines and methods that enable proposals for products and services that are better adapted to the demands of society. Faced with these enduring Copyright: \u00a9 2023 by the authors.\n\nchallenges, it is essential to explore possibilities and alternatives, such as those that can be Licensee MDPI, Basel, Switzerland.\n\noffered by biomimicry [5,6].\n\nThis article is an open access article\n\nIt is worth mentioning that biomimicry is defined in ISO Standard 18458:2015 as a set distributed under the terms and\n\nof interdisciplinary philosophical and creative approaches that consider nature as a model conditions of the Creative Commons\n\nto guide the development of projects, including aspects related to environmental, social, Attribution (CC BY) license (https:\/\/\n\nand economic sustainability. In this field, it is understood that the outcomes implemented\n\ncreativecommons.org\/licenses\/by\/\n\nby nature provide possible answers to questions of function or practice, simultaneously 4.0\/).\n\nBiomimetics 2023, 8, 61. https:\/\/doi.org\/10.3390\/biomimetics8010061\n\nhttps:\/\/www.mdpi.com\/journal\/biomimetics\n\nBiomimetics 2023, 8, 61\n\n2 of 16\n\nallowing choices","chunk_id":"23c34b74899c04c60dc7b087b88e0137","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"ORGANIZATION\"","type":"\"CREATIVE ACTIVITIES\"","description":"\"Creative activities refer to the diverse expressions that often incorporate interdisciplinary knowledge as a source of inspiration.\")|(\"entity\"","source_id":"23c34b74899c04c60dc7b087b88e0137"}],"entity_graph":" \"CREATIVE ACTIVITIES\"<\/data> \"Creative activities refer to the diverse expressions that often incorporate interdisciplinary knowledge as a source of inspiration.\")|(\"entity\"<\/data> 23c34b74899c04c60dc7b087b88e0137<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"2aee03ca69624bff0ae2d030f6f31e19","chunk":"imetics 2023, 8, 61. https:\/\/doi.org\/10.3390\/biomimetics8010061\n\nhttps:\/\/www.mdpi.com\/journal\/biomimetics\n\nBiomimetics 2023, 8, 61\n\n2 of 16\n\nallowing choices appropriate to the goals of a project. In this way, by observing organisms, biological processes, and ecosystems, solutions can be developed to meet the needs and challenges of the various spheres of human activity, such as in the design of products, environments, services, and digital technologies [6\u20138].\n\nGiven the scope of the present work, it is necessary to remark on the persistent im-passes regarding the use of terminologies by scholars and professionals involved in creative activities inspired by nature. Some authors adopt the bio-derived terms interchange-ably [9]. That is, in a given publication, they globally adopt some bio-derived expressions, which does not allow to sufficiently distinguish the understanding they possessed from the conceptual point of view when structuring and carrying out their studies. Other researchers rely on the specific conceptualization of terms, in line with the ISO 18458:2015\n\nStandard [10,11]. However, for some biomimicry researchers\u2014such as Iouguina et al. [12]\n\nand Speck et al. [13]\u2014this field of inspiration in nature has been expanding rapidly, and it is increasingly necessary to differentiate even more clearly and objectively several basic notions, such as biomimicry, biomimetics, bionics, and bioinspiration. For authors who share this concern, even though there are already different understandings of these terms, they are still insufficient. This happens because many authors use different nomenclatures, but, depending on the specific contexts in which each researcher or professional is inserted, these words may reflect cultural factors and aspects of their specializations, which need to be clarified to enhance future work and research. In other words, more theoretical and empirical studies are needed to better delimit the concepts underlying biomimicry. In this sense, review works are very important, despite the advances already achieved. In summary, a close examination of the area reveals that certain biomimetic concepts can be understood as equivalent by certain authors, while, for others, they are perceived as different or complementary [12\u201314]. In view of the above, it is essential to explain that, in the present work, the word \u201cbiomimicry\u201d was adopted due to","chunk_id":"2aee03ca69624bff0ae2d030f6f31e19","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"BIOMIMETICS 2023\"","type":"\"PUBLICATION\"","description":"\"The publication titled 'Biomimetics' with volume number of 8 and issue number 61 from the year 2023.\")","source_id":"2aee03ca69624bff0ae2d030f6f31e19"}],"entity_graph":" \"PUBLICATION\"<\/data> \"The publication titled 'Biomimetics' with volume number of 8 and issue number 61 from the year 2023.\")<\/data> 2aee03ca69624bff0ae2d030f6f31e19<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"6e87b92e6c843cb54a008ae676d3b416","chunk":" reveals that certain biomimetic concepts can be understood as equivalent by certain authors, while, for others, they are perceived as different or complementary [12\u201314]. In view of the above, it is essential to explain that, in the present work, the word \u201cbiomimicry\u201d was adopted due to the advantages that still exist when opting for a comprehensive term with wide dissemination. Furthermore, as evidenced by Iouguina et al. [12] and Gamage and Hyde [15], this nomenclature refers to a theoretical and technical framework that can be considered more accessible, in addition to being closely associated with the disciplines of design, architecture, and philosophy.\n\nAdditionally, to support the bibliographical research that was undertaken, which will be presented and discussed later, it is worth remembering that a survey of the specialized literature constitutes an essential approach for the systematization of knowledge already gathered, in addition to allowing the identification of trends and to suggesting an agenda for future research, especially in the case of emerging areas of knowledge. Indeed, many review techniques are available (e.g., narrative, integrative, systematic, meta-analyses) [16\u201318].\n\nAmong these possibilities is the integrative systematic review model called the Theory of Consolidated Meta-Analytical Approach (TEMAC). This resource, based on bibliometric laws, helps in the development of: research preparation; presentation and interrelation of data; integrative model and validation by evidences. TEMAC is a multilingual model that enables research in various databases, such as the Web of Science, Scopus, and Google Scholar, for reviewing international literature in different areas of knowledge. Furthermore, this resource recommends the adoption of free software such as VOSViewer and TagCrowd for processing and visualization of data. Through TEMAC, it is possible to obtain an overview of the works and productions of an area, to elaborate integrative models, and to carry out comparisons between publications, institutions, and countries [19].\n\nIn summary, as the study and application of biological knowledge enables the realization of creative projects in several areas, it is necessary to better understand the use of these resources specifically in design. Thus, in this work, emphasis was given to biomimetic design, also understood as biomimicry-based design, that could be defined as the creative implementation of biologically-inspired concepts, ideas, and strategies into functional products to solve human challenges, that may have the potential to meet the current needs of sustainability in design. This definition is based on the perspectives of authors","chunk_id":"6e87b92e6c843cb54a008ae676d3b416","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"BIOMIMETIC CONCEPTS\"","type":"\"CONCEPT\"","description":"\"Biological concepts or ideas that are mimicked by humans in various fields, often for innovation and problem-solving.\") (\"entity\"","source_id":"6e87b92e6c843cb54a008ae676d3b416"}],"entity_graph":" \"CONCEPT\"<\/data> \"Biological concepts or ideas that are mimicked by humans in various fields, often for innovation and problem-solving.\") (\"entity\"<\/data> 6e87b92e6c843cb54a008ae676d3b416<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"a43faaba2ebb888387d5b0f59efb6381","chunk":"imetic design, also understood as biomimicry-based design, that could be defined as the creative implementation of biologically-inspired concepts, ideas, and strategies into functional products to solve human challenges, that may have the potential to meet the current needs of sustainability in design. This definition is based on the perspectives of authors such as Gamage and Hyde [15]; Hsiao and Chou [20]; Volstad and Boks [21]. Aiming, therefore, to\n\n\n\n\n\nBiomimetics 2023, 8, 61\n\n3 of 16\n\naid the grounding, guiding, planning, creation, and evaluation of biomimetic productions in this field, the general objective of this article was to identify, describe and analyze the contributions of biomimicry to design based on a survey of publications indexed in the Web of Science database.\n\n2. Materials and Methods\n\nThe investigation was carried out in the Web of Science database, using the descriptors biomimicry and design. The period between 1991 and 2021 was configured as the time range for the searches, totaling three decades. It should be noted that the first decade of this interval coincides with the publication of the work by Benyus, Biomimicry: Innovation Inspired by Nature, which contributed to the dissemination of the term \u201cbiomimicry\u201d [22].\n\nTo carry out the systematic review, the Theory of Consolidated Meta-Analytical Approach (TEMAC) integrative model was adopted. This resource recommends organizing the information collected in the database according to areas of knowledge, countries, journals, institutions, authors, and years. In addition, TEMAC guides the performance of citation, co-citation, coupling, co-occurrence, and word cloud analyses with the generation of images, such as heat maps and network or line maps. For this purpose, the VOSViewer and TagCrowd platforms were used [23].\n\nIt is worth clarifying that citation analysis is one of the means of measuring the impact of authors\u2019 production based on the number of citations listed in the database. Evidently, it is important not to mistake the popularity of an author or publication with the relevance of the scientific work developed, but it is an interesting comparative parameter. The co-citation analysis corresponds to works that are frequently cited together by other publications.\n\nThe greater the number of co-citations of a document, the greater its prominence in the literature, and the more likely its semantic relationship with the other two documents will be. Coupling establishes","chunk_id":"a43faaba2ebb888387d5b0f59efb6381","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"IMETIC DESIGN\"","type":"\"CONCEPT\"","description":"\"Imitative or biomimetic design that draws on concepts found in nature to solve human challenges and promote sustainability.\")","source_id":"a43faaba2ebb888387d5b0f59efb6381"}],"entity_graph":" \"CONCEPT\"<\/data> \"Imitative or biomimetic design that draws on concepts found in nature to solve human challenges and promote sustainability.\")<\/data> a43faaba2ebb888387d5b0f59efb6381<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"fe902bcadf86addbe747f348c1ccc56f","chunk":", but it is an interesting comparative parameter. The co-citation analysis corresponds to works that are frequently cited together by other publications.\n\nThe greater the number of co-citations of a document, the greater its prominence in the literature, and the more likely its semantic relationship with the other two documents will be. Coupling establishes that when two documents cite the same third publication in their bibliographies, this is an indicator that these works have similarities [19, 23].\n\nIn TEMAC, it is common to delimit longer periods for co-citation than for coupling, since the first type of analysis is adopted to highlight the most-used thematic approaches in the study of a given topic (comprehensive panorama), while the second type, focuses on reduced intervals and, therefore, tends to show the main fronts of contemporary research [19, 23,24]. Therefore, in the present work, co-citation covered the period from 1991 to 2021, and coupling comprised the years from 2018 to 2021. Bearing in mind these methodological guidelines, interrelationships were established between the data obtained with the help of TEMAC and the content of the identified works.\n\n3. Results\n\nPreliminarily, 633 documents were obtained. It is considered essential to point out that, as biomimicry is a recent area\u2014especially when associated with the field of design\u2014various types of documents were examined in the present literature review, including articles, publications in proceedings of events, and books. The research of such works is pertinent because they represent important sources of information and can contain and record discoveries in emerging areas.\n\nThe oldest work found on the Web of Science was the article by Li et al. (1995), in which the authors explored structural applications of synthetic composites and natural bamboo fibers [25]. The material produced showed mechanical behavior similar to resistant structures present in nature. Considering this pioneering study with a biomimetic approach, it is pertinent to highlight that the initial works on the subject were directed mainly at the study of materials from an engineering perspective (especially at microscopic and nanoscopic scales), including physicochemical and structural investigations. With regard to pioneering efforts and research, it should be noted that studies and applications, more clearly related to the areas of design and architecture, followed in greater numbers after the publication of the book by Janine Benyus (1997), that is, from the end of the 1990s [22].\n\nBiomimetics 2023, 8, 61\n\n4 of","chunk_id":"fe902bcadf86addbe747f348c1ccc56f","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"ORGANIZATION\"","type":"\"WEB OF SCIENCE\"","description":"\"A database used in bibliometric analysis that helps researchers and academics find relevant publications and analyze academic trends.\"","source_id":"fe902bcadf86addbe747f348c1ccc56f"}],"entity_graph":" \"WEB OF SCIENCE\"<\/data> \"A database used in bibliometric analysis that helps researchers and academics find relevant publications and analyze academic trends.\"<\/data> fe902bcadf86addbe747f348c1ccc56f<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"d1f202cadb144570739c718437dd9c7b","chunk":" applications, more clearly related to the areas of design and architecture, followed in greater numbers after the publication of the book by Janine Benyus (1997), that is, from the end of the 1990s [22].\n\nBiomimetics 2023, 8, 61\n\n4 of 16\n\nBased on the examination of previous evidence, a filter according to knowledge areas was implemented in the subsequent step of the review. Thus, divergent categories were excluded (e.g., agriculture, medicine, dentistry, physics, chemistry, biochemistry, materials science, electrical engineering, computer science, mathematics, nanoscience, nanotechnology, pharmacy, and neurosciences). This reduced the number of selected works to n = 196. Table 1 presents the analysis categories used to process the information and the respective quantitative data obtained from the search on the Web of Science. In this set of documents, it was noted that the areas of knowledge with the highest number of contributions, in descending order, were: engineering (n = 64), the science of technology (n = 41), environmental sciences, and ecology (n = 31), and architecture (n = 24). It is vital to mention that the Web of Science does not have a specific category for filtering documents published exclusively in the domain of design, unlike other areas of knowledge.\n\nThis limitation impacts the investigation and means that works of interest in this field are obtained only in related areas.\n\nTable 1. Classification of information collected in the Web of Science database, distributed quantitatively into categories. Source: the authors.\n\nCategories\n\nData from Web of Science\n\nEngineering (n = 64)\n\nScience of Technology (n = 41)\n\nKnowledge areas with the highest number of contributions\n\nEnvironmental Sciences and Ecology (n = 31)\n\nArchitecture (n = 24)\n\nUnited States (n = 68)\n\nCountries with the highest number of publications\n\nUnited Kingdom (n = 19)\n\nTurkey (n = 15)\n\nWIT Transactions on Ecology and the Environment (n = 9)\n\nScientific Reports (n = 6)\n\nJournals that published the most works\n\nArchitectural Science Review (n = 5)\n\nProcedia Social and Behavioral Sciences (n = 5)\n\nUniversity of California System (n = 8)\n\nVictoria University of Wellington (n = 8)\n\nInstitutions that published the most works\n\nUniversity System of Georgia (n = 7)\n\nDelft University of Technology and University of Akron (n =","chunk_id":"d1f202cadb144570739c718437dd9c7b","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"BIOMIMETICS\"","type":"\"JOURNAL\"","description":"\"The publication Biomimetics, in which an analysis on design and architecture topics from the late 1990s is presented.\")","source_id":"d1f202cadb144570739c718437dd9c7b"}],"entity_graph":" \"JOURNAL\"<\/data> \"The publication Biomimetics, in which an analysis on design and architecture topics from the late 1990s is presented.\")<\/data> d1f202cadb144570739c718437dd9c7b<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"17a811ea2375e85ee164ddd52dbe5a80","chunk":"Procedia Social and Behavioral Sciences (n = 5)\n\nUniversity of California System (n = 8)\n\nVictoria University of Wellington (n = 8)\n\nInstitutions that published the most works\n\nUniversity System of Georgia (n = 7)\n\nDelft University of Technology and University of Akron (n = 6)\n\nMaibritt Pedersen Zari (n = 8)\n\nAuthors who published the most works\n\nDonnison, Faludi, Jones, Niewiarowski and Pauw (n = 3)\n\n2019 (n = 27)\n\nYears with the highest number of publications\n\n2016 (n = 26)\n\n2020 (n = 24)\n\nThe three countries with the highest number of publications were, respectively: United States (n = 68), United Kingdom (n = 19), and Turkey (n = 15). The following journals published the highest number of works on the subject: WIT Transactions on Ecology and the Environment (n = 9), Scientific Reports (n = 6), Architectural Science Review (n = 5), and Procedia Social and Behavioral Sciences (n = 5). Regarding the institutions associated with publications about interconnections between design and biomimicry, the following stood out: University of California System (n = 8), Victoria University of Wellington (n = 8), University System of Georgia (n = 7), Delft University of Technology (n = 6), University of Akron (n = 6). It was also found that Maibritt Pedersen Zari was the author with the most published works (n = 8), followed by Donnison, Faludi, Jones, Niewiarowski, and Pauw (n = 3). The years with the greatest profusion of works were: 2019 (n = 27), 2016 (n = 26), and 2020 (n = 24).\n\nIn order to provide an overview of the bibliographic production regarding design and biomimicry analyzed in the review reported here, Table 2 presents a summary of publications that showed 35 or more citations in the Web of Science between 1991 and 2021.\n\nBiomimetics 2023, 8, 61\n\n5 of 16\n\nTable 2. Synthesis of works with 35 or more citations registered in the Web of Science. Source: the authors.\n\nTitle\n\nCitations\n\nMain Contributions of the Author(s","chunk_id":"17a811ea2375e85ee164ddd52dbe5a80","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"PROCEDIA SOCIAL AND BEHAVIORAL SCIENCES\"","type":"\"ORGANIZATION\"","description":"\"The Procedia Social and Behavioral Sciences is an academic journal that published 5 articles.\") (\"entity\"","source_id":"17a811ea2375e85ee164ddd52dbe5a80"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The Procedia Social and Behavioral Sciences is an academic journal that published 5 articles.\") (\"entity\"<\/data> 17a811ea2375e85ee164ddd52dbe5a80<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"b3c5de72ae4c784c9fef28c432a247eb","chunk":" 1991 and 2021.\n\nBiomimetics 2023, 8, 61\n\n5 of 16\n\nTable 2. Synthesis of works with 35 or more citations registered in the Web of Science. Source: the authors.\n\nTitle\n\nCitations\n\nMain Contributions of the Author(s)\n\nBiomimetic approaches on a microscopic scale, inspired by morphological and\n\n\u201cBiomimetics: lessons from\n\nphysicochemical properties for the development of materials, devices, and 691\n\nnature\u2014an overview\u201d [26]\n\nsurfaces were identified. The authors gathered a set of inspiring natural elements and pointed out applications in products.\n\nCharacteristics of nature relevant to the field of bio-inspired textile design\n\n\u201cBiomimicry in textiles: past,\n\nwere highlighted: fiber diversity (strength, structure); functional surfaces present and potential\n\n81\n\n(adhesion, hydrophobicity); thermal insulation and optical systems (structural\n\n\u2014an overview\u201d [27]\n\ncolors and photonic materials).\n\nApplications based on the defensive strategies of the species Erethizon dorsatum\n\n\u201cMicrostructured barbs on the\n\n(pointed and sharp dorsal structures) were examined. The findings North American porcupine quill\n\n69\n\ndemonstrated good adherence and reduced the force required for penetration enable easy tissue penetration\n\ninto tissues, which could be adopted in the design of hospital products and difficult removal\u201d [28]\n\n(e.g., needles).\n\nMulti-material rapid prototyping processes were studied for biomimetic robot\n\n\u201cDesign and fabrication of\n\ndesign. Uses of stiff and flexible materials and the incorporation of sensors multi-material structures for\n\n63\n\nwere discussed, in which nature-based configurations demanded less active bioinspired robots\u201d [29]\n\ncontrol compared to traditional procedures.\n\nThe authors underlined which aspects of the circular economy can mitigate the\n\n\u201cIntegrating backcasting and\n\nimpacts of environmental degradation and presented the framework eco-design for the circular\n\n61\n\nBackcasting and Eco-Design for the Circular Economy. Investigations on economy the BECE framework\u201d\n\nnature-based notions and areas were identified (biomimicry, cradle-to-cradle,\n\n[30]\n\nnatural capitalism, regenerative design).\n\n\u201cEvolution of reaction center\n\nArtificial reactions based on photosynthesis to produce fuels through mimics to systems capable of\n\n51\n\nphotochemical processes were mapped. Research on photoelectric systems generating solar fuel\u201d [31]\n\ncapable of converting water into oxygen and hydrogen was evidenced.\n\nThe authors highlighted that natural factors stimulate innovations","chunk_id":"b3c5de72ae4c784c9fef28c432a247eb","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"BIOMIMETICS\"","type":"\"FIELD_OF_STUDY\"","description":"\"Biomimetics is a field studying ways to model nature\u2019s design solutions for engineering problems.\") (\"entity\"","source_id":"b3c5de72ae4c784c9fef28c432a247eb"}],"entity_graph":" \"FIELD_OF_STUDY\"<\/data> \"Biomimetics is a field studying ways to model nature’s design solutions for engineering problems.\") (\"entity\"<\/data> b3c5de72ae4c784c9fef28c432a247eb<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"b315f4391fd31deebdefc7e4496ccc53","chunk":"Evolution of reaction center\n\nArtificial reactions based on photosynthesis to produce fuels through mimics to systems capable of\n\n51\n\nphotochemical processes were mapped. Research on photoelectric systems generating solar fuel\u201d [31]\n\ncapable of converting water into oxygen and hydrogen was evidenced.\n\nThe authors highlighted that natural factors stimulate innovations in robot\n\n\u201cTemplates and anchors for\n\ndesign and neuromechanics. An antenna project for task control (guiding the antenna-based wall following in\n\n46\n\nangulation of robots in relation to walls), based on the spatial navigation of the cockroaches and robots\u201d [32]\n\nPeriplaneta americana species, was illustrated.\n\nThe study focused on the self-cleaning capacity of organisms by classifying\n\n\u201cBiomimetic self-cleaning\n\nthem based on the use or the absence of water. It was found that new design surfaces: synthesis, mechanism\n\n43\n\nprojects inspired by these characteristics can be applied in: medicine, and applications\u201d [33]\n\naerospace construction, solar energy production, and water treatment.\n\nSystems-level regenerative and biomimetic design to mitigate the causes and\n\n\u201cBiomimetic design for climate\n\neffects of climate change was examined. The importance of renewable energies, change adaptation and\n\n39\n\nresponsive systems, local context adaptation, feedback loops, and autonomy mitigation\u201d [34]\n\nwas noted. Uses of biomimetic principles, in short, medium, and long-term projects were mentioned.\n\nThe study measured and summarized biomimicry applications in\n\n\u201cA model based on Biomimicry\n\nenvironmental preservation projects in design and architecture. The following to enhance ecologically\n\n35\n\ntools were explored: BioTRIZ, Typological Analysis, Nature Studies Analysis, sustainable design\u201d [15]\n\nand Biomimetic Spirals (Biomimicry Thinking Design Lens).\n\nExamining the table, it is possible to observe that the article \u201cBiomimetics: lessons from nature\u2014an overview\u201d [26] was significantly more cited (n = 691) than \u201cBiomimicry in textiles: past, present, and potential\u2014an overview\u201d [27], the work with the second highest number of citations (n = 81). It should be noted that the work of Bhushan (2009) highlighted the field of biomimetic research at a microscopic and nanoscopic scale to generate creations inspired by biological surfaces and materials. The author presented sets of inspiring natural elements addressing possible applications in products, considering aspects of: superhydrophobicity","chunk_id":"b315f4391fd31deebdefc7e4496ccc53","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"EVOLUTION OF REACTION CENTER\"","type":"\"EVENT\"","description":"\"The article discusses the evolution of reaction centers that mimic photosynthesis for fuel production and water conversion processes.\"","source_id":"b315f4391fd31deebdefc7e4496ccc53"}],"entity_graph":" \"EVENT\"<\/data> \"The article discusses the evolution of reaction centers that mimic photosynthesis for fuel production and water conversion processes.\"<\/data> b315f4391fd31deebdefc7e4496ccc53<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"bc2123b5f86d53a8b6c4f35594131571","chunk":"). It should be noted that the work of Bhushan (2009) highlighted the field of biomimetic research at a microscopic and nanoscopic scale to generate creations inspired by biological surfaces and materials. The author presented sets of inspiring natural elements addressing possible applications in products, considering aspects of: superhydrophobicity, self-cleaning, fluid flow, drag reduction, adhesion, aerodynamics, structural coloration, thermal insulation, and mechanical strength.\n\nTo identify the main thematic emphases adopted in Biomimicry research and projects oriented toward design, a heat map of co-citations was prepared. This analysis determines which documents are frequently cited together to identify the highest-density nuclei that\n\n\n\nBiomimetics 2023, 8, x FOR PEER REVIEW\n\n6 of 16\n\n\n\n\u201cTemplates and anchors\n\nThe authors highlighted that natural factors stimulate innovations in robot for antenna-based wall fol-design and neuromechanics. An antenna project for task control (guiding 46\n\nlowing in cockroaches and\n\nthe angulation of robots in relation to walls), based on the spatial naviga-robots\u201d [32]\n\ntion of the Periplaneta americana species, was illustrated.\n\n\u201cBiomimetic self-cleaning\n\nThe study focused on the self-cleaning capacity of organisms by classifying surfaces: synthesis, mecha-them based on the use or the absence of water. It was found that new design 43\n\nnism and applications\u201d\n\nprojects inspired by these characteristics can be applied in: medicine, aero-\n\n[33]\n\nspace construction, solar energy production, and water treatment.\n\nSystems-level regenerative and biomimetic design to mitigate the causes\n\n\u201cBiomimetic design for cli-\n\nand effects of climate change was examined. The importance of renewable Biomimetics\n\nmate\n\n2023\n\nchan , 8\n\nge , 61\n\nadaptation\n\n39\n\nenergies, responsive systems, local context adaptation, feedback lo 6 of 16\n\nops, and\n\nand mitigation\u201d [34]\n\nautonomy was noted. Uses of biomimetic principles, in short, medium, and long-term projects were mentioned.\n\n\u201cA model based on Bio-\n\nhighlight authors and\n\nThe st works\n\nudy me with\n\nasured similar\n\nand su lines\n\nmmariof\n\nze resear\n\nd bi\n\nch. Thus,\n\nomimicry ap it is\n\nplicatpossible\n\nions in e to\n\nn\n\nmap\n\nviron-\n\nmimicry to enhance eco","chunk_id":"bc2123b5f86d53a8b6c4f35594131571","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"BHUSHAN (2009)\"","type":"\"AUTHOR\"","description":"\"Bhushan conducted research emphasizing biomimetic studies at micro and nano scales, focusing on creating designs inspired by biological surfaces and materials.\") (\"entity\"","source_id":"bc2123b5f86d53a8b6c4f35594131571"}],"entity_graph":" \"AUTHOR\"<\/data> \"Bhushan conducted research emphasizing biomimetic studies at micro and nano scales, focusing on creating designs inspired by biological surfaces and materials.\") (\"entity\"<\/data> bc2123b5f86d53a8b6c4f35594131571<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"c16a050b9f05d4adcbe87cd85974f73b","chunk":" and\n\nThe st works\n\nudy me with\n\nasured similar\n\nand su lines\n\nmmariof\n\nze resear\n\nd bi\n\nch. Thus,\n\nomimicry ap it is\n\nplicatpossible\n\nions in e to\n\nn\n\nmap\n\nviron-\n\nmimicry to enhance eco-\n\nthe proximity of studies\n\nmental pr and\n\neser ascertain their\n\nvation projec\n\nthematic\n\nts in design and\n\nand a theor\n\nrchit etical\n\necture appr\n\n. The oaches\n\nfollowin[19\n\ng ]. In\n\ntools\n\n35\n\nlogically sustainable de-\n\nFigure 1, the larger the typeface\n\nwere explored\n\nsize\n\n: BioT of the\n\nRIZ, names and\n\nTypologica\n\nthe\n\nl Ana r\n\nl edder\n\nysis , the\n\nNa\n\nareas\n\nture St wher\n\nud\n\ne they\n\nies Analysar\n\nis e\n\n,\n\nsign\u201d [15]\n\ninscribed, the greater\n\nand Bi the concentration\n\nomimetic Spirals of\n\n(Bi each\n\no\n\nnucleus.\n\nmimicry Thinking Design Lens).\n\n\n\nFigure 1. Co-citation map generated from data obtained in the Web of Science, covering the period Figure 1. Co-citation map generated from data obtained in the Web of Science, covering the period from 1991 to 2021. Source: the authors.\n\nfrom 1991 to 2021. Source: the authors.\n\nThe layout of the co-citation map reveals that the cluster encompassing Benyus (1997) The layout of the co-citation map reveals that the cluster encompassing Benyus (1997) shows the greatest convergence [22]. This was an expected result since this work consti-shows the greatest convergence [22]. This was an expected result since this work constitutes tutes one of the fundamental publications on biomimicry and contributed to consolidating one of the fundamental publications on biomimicry and contributed to consolidating the the subject as a field of research. As is widely known, in her work, Benyus conceptualized subject as a field of research. As is widely known, in her work, Benyus conceptualized nature as the \u201cmodel, measure and mentor\u201d agent, capable of generating complex systems nature as the \u201cmodel, measure and mentor\u201d agent, capable of generating complex systems of high efficiency and economy, encouraging the discovery of solutions based on the of high efficiency and economy,","chunk_id":"c16a050b9f05d4adcbe87cd85974f73b","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"THE ST WORKS STUDY\"","type":"\"ORGANIZATION\"","description":"\"An organization that works in a field related to sustainable design and research, focusing on biomimicry.\"","source_id":"c16a050b9f05d4adcbe87cd85974f73b"},{"name":"\"BIOTECHNOLOGY\"","type":"\"CONCEPT\"","description":"\"A central theme in the works of 'The St Works Study' which deals with bio-based innovations, specifically biomimicry.\"","source_id":"c16a050b9f05d4adcbe87cd85974f73b"},{"name":"\"MIMICRY\"","type":"\"CONCEPT\"","description":"\"The core concept behind both studies and developments led by 'The St Works Study', involving principles extracted from nature to solve problems or create innovations.\"","source_id":"c16a050b9f05d4adcbe87cd85974f73b"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"An organization that works in a field related to sustainable design and research, focusing on biomimicry.\"<\/data> c16a050b9f05d4adcbe87cd85974f73b<\/data> <\/node> \"CONCEPT\"<\/data> \"A central theme in the works of 'The St Works Study' which deals with bio-based innovations, specifically biomimicry.\"<\/data> c16a050b9f05d4adcbe87cd85974f73b<\/data> <\/node> \"CONCEPT\"<\/data> \"The core concept behind both studies and developments led by 'The St Works Study', involving principles extracted from nature to solve problems or create innovations.\"<\/data> c16a050b9f05d4adcbe87cd85974f73b<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"10357a9455875b5f9c5deca2d9871135","chunk":", in her work, Benyus conceptualized nature as the \u201cmodel, measure and mentor\u201d agent, capable of generating complex systems nature as the \u201cmodel, measure and mentor\u201d agent, capable of generating complex systems of high efficiency and economy, encouraging the discovery of solutions based on the of high efficiency and economy, encouraging the discovery of solutions based on the transfer transfer of natural knowledge to the human context, especially for the challenges related of natural knowledge to the human context, especially for the challenges related to material to material disposal, circulation of energy, resource-saving and problem management.\n\ndisposal, circulation of energy, resource-saving and problem management.\n\nIn Figure 1, another significant nucleus revolves around Vincent et al. [9]. In the aforementioned article, the authors emphasized that biomimicry requires specific tools and processes. One possibility highlighted by Vincent et al. is the use of the TRIZ heuristic matrix, which can be adapted for biologically-inspired projects in the BioTRIZ tool. In it, notions obtained from natural systems are used, transferring configurations to conceive innovations in the creation of technological systems and projects, mainly with the inclusion of energetic and structural aspects based on nature.\n\nThe publication by Helms, Vattam, and Goel [35] about the naturally inspired approaches that integrate analogy systems to develop solutions in product design lies in this same cluster. This study featured the two main approaches adopted in biomimetic projects: one centered on the design problem (known as design for biology or problem-based approach) and another, which starts directly from the study of a natural aspect (known as biology to design or solution-driven approach). This article also cautioned against common mistakes in biomimetic design practices, that should be avoided throughout the creation\n\nBiomimetics 2023, 8, 61\n\n7 of 16\n\nprocess, such as: a vague and overly broad definition of design problems; the inappropriate combination of design proposal and selection of the biological element; the use of superfi-cial natural analogies; the inappropriate simplification of complex biological functions; the use of pre-formulated solutions without examining the project context; and preference for the first solution found, without analyzing alternatives, either for biological inspiration or for detailed design proposals.\n\nNext to this group of works is the publication by Pawlyn [36], which showcased the interconnections between biomimicry and architecture, seeking technological projects of sustainable and innovative construction that may also have a restorative character for environments, based on conscious and systemic initiatives. Supported by various examples and","chunk_id":"10357a9455875b5f9c5deca2d9871135","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"E.O. WILSON\"","type":"\"PERSON\"","description":"\"E.O. Wilson is known for conceptualizing nature as a model, measure, and mentor agent capable of generating efficient systems. He also encourages transferring natural knowledge to human contexts particularly in dealing with issues like waste management.\") (\"entity\"","source_id":"10357a9455875b5f9c5deca2d9871135"}],"entity_graph":" \"PERSON\"<\/data> \"E.O. Wilson is known for conceptualizing nature as a model, measure, and mentor agent capable of generating efficient systems. He also encourages transferring natural knowledge to human contexts particularly in dealing with issues like waste management.\") (\"entity\"<\/data> 10357a9455875b5f9c5deca2d9871135<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"b8f2d8b6f8181c950be1341e09d5f6ac","chunk":" for detailed design proposals.\n\nNext to this group of works is the publication by Pawlyn [36], which showcased the interconnections between biomimicry and architecture, seeking technological projects of sustainable and innovative construction that may also have a restorative character for environments, based on conscious and systemic initiatives. Supported by various examples and cases, the author emphasized the importance of considering: structural efficiency; mindful use of resources; understanding manufacturing processes; analysis and implementation of zero-waste systems; clean energy generation; and water saving.\n\nIn the lower central portion of the co-citation map are Chakrabarti et al. [37], whose article presented the GEMS of SAPPhIRE Model of Causality tool, which contributes to the functional comprehension and definition in biomimetic design projects. This model enabled the development of a computational tool and a database that help designers find solutions for their projects based on analogies of natural and artificial systems (IDEA-INSPIRE). The authors concluded that natural systems have been insufficiently adopted as a source of inspiration for design projects, unlike artificial systems. Thus, their proposal is very relevant to the field of biomimetic product design and the systematization of idea generation.\n\nOther publications, shown in Figure 1, are also worth mentioning. Located in the lower left part of the co-citation map, is the Biomimicry Resource Handbook manual by Baumeister et al. [38], which provides the essentials of biomimicry, including guidelines for applying biomimetic methods, approaches, and tools to conduct creative projects (e.g., Biomimicry Thinking Design Lens, Challenge to Biology and Biology to Design approaches, Biomimicry Taxonomy Chart, Life\u2019s Principles Diagram).\n\nAnother interesting work found on the map is Cradle to Cradle by Braungart and McDonough [39], which is positioned in the upper left portion of the map. This publication proposes reinventing the life cycle of products and processes. In their work, the authors emphasized the integration of design and science to favor lasting social benefits, stimulating the regeneration of the natural realm and the improvement of human quality of life.\n\nThey also advocated the use of safe materials, water, and energy in the context of the circular economy, eliminating the concepts of waste and disposal. Therefore, according to Braungart and McDonough, design can be reconfigured with a view to effectively having a positive impact.\n\nIn view of what was previously presented, through the analysis of the co-citation map, it became possible to verify the","chunk_id":"b8f2d8b6f8181c950be1341e09d5f6ac","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"PAWLYN\"","type":"\"PERSON\"","description":"\"Pawlyn is associated with work showcasing biomimicry and architecture interconnections, highlighting sustainable and innovative construction methods, particularly for restoration purposes.\") (\"entity\"","source_id":"b8f2d8b6f8181c950be1341e09d5f6ac"}],"entity_graph":" \"PERSON\"<\/data> \"Pawlyn is associated with work showcasing biomimicry and architecture interconnections, highlighting sustainable and innovative construction methods, particularly for restoration purposes.\") (\"entity\"<\/data> b8f2d8b6f8181c950be1341e09d5f6ac<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"50d87eb794de75e87a2b0897c5432e39","chunk":" context of the circular economy, eliminating the concepts of waste and disposal. Therefore, according to Braungart and McDonough, design can be reconfigured with a view to effectively having a positive impact.\n\nIn view of what was previously presented, through the analysis of the co-citation map, it became possible to verify the thematic emphases of publications in the period between 1991 and 2021. As expected, the main nucleus was concentrated around the work of Benyus, which was a crucial work in the dissemination of knowledge about biomimicry. In addition, it was found that, the central area of the map contained nuclei related to the development of biomimetic design works in which the authors present field theories and project cases that exemplify the use of biomimicry principles. It is interesting to mention that, on the map, there was also a highlight on clusters whose publications evidenced specifications of technical aspects, including development stages and processes of biomimetic design.\n\nThis was carried out through the presentation of tools, models, approaches or processes, and guidelines for projects. Some of the works of this group are directed toward the research and functional analysis of natural and artificial systems. Finally, smaller nuclei, whose works discuss issues of circularity and sustainability, which are often related to biomimicry-based design, are visible.\n\nIt is worth mentioning that a predominance of the problem-based biomimetic approach was found in the works of multiple authors located in the center of the map. Such an approach begins with a design challenge and the functional requirements of a project, and\n\n\n\nBiomimetics 2023, 8, x FOR PEER REVIEW\n\n8 of 16\n\n\n\nof Benyus, which was a crucial work in the dissemination of knowledge about biomimicry. In addition, it was found that, the central area of the map contained nuclei related to the development of biomimetic design works in which the authors present field theories and project cases that exemplify the use of biomimicry principles. It is interesting to mention that, on the map, there was also a highlight on clusters whose publications evidenced specifications of technical aspects, including development stages and processes of biomimetic design. This was carried out through the presentation of tools, models, approaches or processes, and guidelines for projects. Some of the works of this group are directed toward the research and functional analysis of natural and artificial systems. Finally, smaller nuclei, whose works discuss issues of circularity and sustainability, which are often related to biomim","chunk_id":"50d87eb794de75e87a2b0897c5432e39","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"BRAUNGART AND MCDONOUGH\"","type":"\"PERSON\"","description":"\"These authors are responsible for the concept of designing with a focus on effectively having a positive impact on the environment.\") (\"entity\"","source_id":"50d87eb794de75e87a2b0897c5432e39"}],"entity_graph":" \"PERSON\"<\/data> \"These authors are responsible for the concept of designing with a focus on effectively having a positive impact on the environment.\") (\"entity\"<\/data> 50d87eb794de75e87a2b0897c5432e39<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"ea3022e7c889776437eec7e0ff1e3b2c","chunk":" This was carried out through the presentation of tools, models, approaches or processes, and guidelines for projects. Some of the works of this group are directed toward the research and functional analysis of natural and artificial systems. Finally, smaller nuclei, whose works discuss issues of circularity and sustainability, which are often related to biomimicry-based design, are visible.\n\nIt is worth mentioning that a predominance of the problem-based biomimetic ap-Biomimetics 2023, 8, 61\n\n8 of 16\n\nproach was found in the works of multiple authors located in the center of the map. Such an approach begins with a design challenge and the functional requirements of a project, and only in the following steps of the creative and research processes are investigated only in the following steps of the creative and research processes are investigated biological biological aspects relevant to each context. As previously stated, some of these authors aspects relevant to each context. As previously stated, some of these authors have also have also proposed and made available processes and tools to stimulate biomimetic de-proposed and made available processes and tools to stimulate biomimetic design projects sign projects that are primarily problem-based.\n\nthat are primarily problem-based.\n\nAfter performing the co-citation analysis, a word cloud was generated (Figure 2) After performing the co-citation analysis, a word cloud was generated (Figure 2)\n\ncomposed of the fifty most frequent words from the set of works published in the period composed of the fifty most frequent words from the set of works published in the period from 1991 to 2021 ( n = 196).\n\nfrom 1991 to 2021 (n = 196).\n\n\n\nFigure 2. Word cloud generated from data obtained in the Web of Science, covering the period from Figure 2. Word cloud generated from data obtained in the Web of Science, covering the period from 1991 to 2021. Source: the authors.\n\n1991 to 2021. Source: the authors.\n\nIn this illustration, it can be seen that, in addition to the descriptors used in the pre-In this illustration, it can be seen that, in addition to the descriptors used in the present sent re\n\nr\n\nse\n\nesear arch, the most\n\nch, the most fr frequen\n\nequently tly mentioned ke\n\nmentioned\n\nywo\n\nkeywor r\n\nds ds were, r\n\nwere, r\n\nespectively:\n\nespectively:\n\n\u201csustain\n\n\u201csustai\n\nabil-\n\nnability","chunk_id":"ea3022e7c889776437eec7e0ff1e3b2c","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"RESEARCH GROUP\"","type":"\"ORGANIZATION\"","description":"\"The organization is involved in the research and functional analysis of natural and artificial systems using biomimetic approaches.\"","source_id":"ea3022e7c889776437eec7e0ff1e3b2c"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The organization is involved in the research and functional analysis of natural and artificial systems using biomimetic approaches.\"<\/data> ea3022e7c889776437eec7e0ff1e3b2c<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"e01fbf716e63081d999f9f22c28e098a","chunk":"se\n\nesear arch, the most\n\nch, the most fr frequen\n\nequently tly mentioned ke\n\nmentioned\n\nywo\n\nkeywor r\n\nds ds were, r\n\nwere, r\n\nespectively:\n\nespectively:\n\n\u201csustain\n\n\u201csustai\n\nabil-\n\nnability\u201d\n\nity\n\n( \u201d\n\nn ( n\n\n= = 58\n\n58), ), \u201ca\n\n\u201car rchitecture\n\nchitecture\u201d \u201d (( n\n\nn = 25\n\n=\n\n), \u201cec\n\n25),\n\nology\u201d (\n\n\u201cecology\u201d n = 2\n\n(n 3\n\n= ), \u201cp\n\n23), roduc\n\n\u201cpr t\u201d ( n = 21\n\noduct\u201d (n ), \u201cs\n\n=\n\nyst\n\n21), ems\u201d ( n =\n\n\u201csystems\u201d\n\n20\n\n( ),\n\nn and\n\n=\n\n\u201c\n\n20), urban\u201d\n\nand\n\n( n = 20).\n\n\u201curban\u201d ( Thus,\n\nn =\n\nsustain\n\n20).\n\na\n\nThus, bility would seem\n\nsustainability\n\nto be o\n\nwould\n\nne of\n\nseem to the m\n\nbe\n\na\n\none in rese\n\nof the arch\n\nmain\n\nthemes\n\nresear in\n\nch design\n\nthemes and\n\nin\n\nbiom\n\ndesign imicry\n\nand\n\n, whether\n\nbiomimicry, for the\n\nwhether development\n\nfor the\n\nof prod\n\ndevelopment uct\n\nof\n\ns\n\npr , build\n\noducts, ings,\n\nbuild-\n\nor citie\n\nings, s.\n\nor In addi\n\ncities.\n\ntion to th\n\nIn addition ese\n\nto word\n\nthese s, it\n\nwor is\n\nds, e\n\nitssen\n\nis\n\ntial to\n\nessentialreflec\n\nto r t on th\n\neflect on e entire im\n\nthe entire age, which\n\nimage, which\n\nincludes term\n\nincludes\n\ns such\n\nterms\n\nas\n\nsuch\n\n\u201cad\n\nas\n\naptation\u201d, \u201c\n\n\u201cadaptation\u201d, systems\u201d, \u201cne\n\n\u201csystems\u201d,\n\ntworks\u201d, \u201c\n\n\u201cnetworks\u201d, ecology\u201d, \u201cenv\n\n\u201cecology\u201d,\n\niro\n\n\u201cenvirnment\u201d,\n\nonment\u201d,\n\n\u201cclimate\u201d, an\n\n\u201cclimate\u201d,\n\nd \u201cchan\n\nand\n\nge\u201d, which are\n\n\u201cchange\u201d, which ar ass\n\ne\n\nociated wi\n\nassociated th t\n\nwith he adap\n\nthe\n\ntive a\n\nadaptive pproach a\n\napproach t a\n\n","chunk_id":"e01fbf716e63081d999f9f22c28e098a","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"SEAR ARCH\"","type":"\"ORGANIZATION\"","description":"\"The organization involved is a research institute or department that focuses on sustainable architecture and design.\")","source_id":"e01fbf716e63081d999f9f22c28e098a"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The organization involved is a research institute or department that focuses on sustainable architecture and design.\")<\/data> e01fbf716e63081d999f9f22c28e098a<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"3cafe8221f0d2b661270f9e33c59993d","chunk":"\u201d,\n\nonment\u201d,\n\n\u201cclimate\u201d, an\n\n\u201cclimate\u201d,\n\nd \u201cchan\n\nand\n\nge\u201d, which are\n\n\u201cchange\u201d, which ar ass\n\ne\n\nociated wi\n\nassociated th t\n\nwith he adap\n\nthe\n\ntive a\n\nadaptive pproach a\n\napproach t a\n\nat sys\n\na\n\ntem\n\nsyst ic\n\nemic\n\nlevel, th\n\nlevel, at in\n\nthat\n\nturn c\n\nin turn an rev\n\ncan r eal im\n\neveal\n\nportant techni\n\nimportant\n\ncal sol\n\ntechnical\n\nutions, e\n\nsolutions, specially in\n\nespecially\n\nthe\n\nin\n\nfa\n\nthe ce of the\n\nface of\n\n\n\nthe\n\nclimate cri\n\nclimate sis, contr\n\ncrisis,\n\nibuting to\n\ncontributing the g\n\nto the eneration of connec\n\ngeneration of\n\nted, adap\n\nconnected,\n\nted, and r\n\nadapted, andesilient\n\nresi\n\nprojects.\n\nlient pr\n\n\n\nojects.\n\nThe words\n\nThe wor \u201ce\n\nds ducation\u201d, \u201c\n\n\u201ceducation\u201d, methodology\u201d, \u201cm\n\n\u201cmethodology\u201d,\n\nethods\u201d, \u201cp\n\n\u201cmethods\u201d, er\n\n\u201cp formance\u201d, \u201cp\n\nerformance\u201d, rod\n\n\u201cpr uct\u201d, an\n\noduct\u201d, d \u201cop\n\nand\n\n-\n\n\u201cop-\n\ntimization\u201d are\n\ntimization\u201d ar also included, and den\n\ne also included, and\n\note co\n\ndenote ncerns about the\n\nconcerns about\n\ne\n\nthe fficiency and functional\n\nefficiency and functional\n\nimprovements\n\nimpr\n\nin\n\novements the\n\nin t cr\n\nhe eation\n\ncr\n\nof\n\neation bi\n\nof omimetic prod\n\nbiomimetic pr ucts, incl\n\noducts,\n\nuding res\n\nincluding r ources\n\nesour asso\n\nces\n\nciated wi\n\nassociated th\n\nwith\n\nits p\n\nits ractice an\n\npractice d te\n\nand aching.\n\nteaching.\n\nExamining th\n\nExamining e im\n\nthe\n\nage a\n\nimage gain, i\n\nagain, t is\n\nit poss\n\nis\n\nible to\n\npossible iden\n\nto\n\ntify wo\n\nidentify\n\nrds\n\nwor th\n\nds at, at\n\nthat, f\n\natirst gl\n\nfirst ance, ap\n\nglance, pear\n\nappear\n\nto b\n\nto e di\n\nbe stant f\n\ndistantrom\n\n","chunk_id":"3cafe8221f0d2b661270f9e33c59993d","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"THE CLIMATE\"","type":"\"GEO\"","description":"\"Climate is a subject associated with the adaptation and systems at ecological level, involving technical solutions, especially in the face of climate crisis.\"","source_id":"3cafe8221f0d2b661270f9e33c59993d"}],"entity_graph":" \"GEO\"<\/data> \"Climate is a subject associated with the adaptation and systems at ecological level, involving technical solutions, especially in the face of climate crisis.\"<\/data> 3cafe8221f0d2b661270f9e33c59993d<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"4c8d34a6cb7efcbac85f88b2fbb3973e","chunk":"is\n\nible to\n\npossible iden\n\nto\n\ntify wo\n\nidentify\n\nrds\n\nwor th\n\nds at, at\n\nthat, f\n\natirst gl\n\nfirst ance, ap\n\nglance, pear\n\nappear\n\nto b\n\nto e di\n\nbe stant f\n\ndistantrom\n\nfr the oth\n\nom the\n\ner group\n\nother gr\n\ns o\n\noups f te\n\nof rms, such\n\nterms,\n\nas\n\nsuch : \u201c\n\nas: insect\u201d, \u201cw\n\n\u201cinsect\u201d,\n\nater\u201d, \u201clo\n\n\u201cwater\u201d,\n\ncomotion\u201d, and\n\n\u201clocomotion\u201d, and\n\n\u201cadhesion\u201d. S\n\n\u201cadhesion\u201d. uch res\n\nSuch r ults p\n\nesults robably come\n\nprobably\n\nfrom\n\ncome fr\n\nrese\n\nom r arc\n\nesearh that emphasizes\n\nch that\n\nthe mor\n\nemphasizes the\n\nphology\n\nmorphology\n\nand movement of organisms, especially in the field of entomology. The water environment is also an interesting result as it can be associated both with new hydrodynamic, hydrophilic, or hydrophobic products, such as surfaces and vehicles, for example; and also, with products for water harvesting, or with the study of aquatic organisms and their characteristics. The term \u201cadhesion\u201d represents another specific focus of research in biomimicry, directed toward the creation of new materials and surfaces with bioinspired properties at the microscopic and nanoscopic levels.\n\nThe next step was the co-occurrence analysis, carried out with the words of the group of publications corresponding to the period from 1991 to 2021 (n = 196). The VOSViewer software, used to generate Figure 3, automatically assigned different colors to distinguish each thematic grouping of words. The interconnections between words and groups are established through the interweaving of colored lines. The closer to the center of the diagram and the larger the typeface size, the stronger the connections between groups and terms and the greater the prominence in the researched literature.\n\n\n\nBiomimetics 2023, 8, x FOR PEER REVIEW\n\n9 of 16\n\n\n\nand movement of organisms, especially in the field of entomology. The water environment is also an interesting result as it can be associated both with new hydrodynamic, hydrophilic, or hydrophobic products, such as surfaces and vehicles, for example; and also, with products for water harvesting, or with the study of aquatic","chunk_id":"4c8d34a6cb7efcbac85f88b2fbb3973e","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"RESEARCHER\"","type":"\"PERSON\"","description":"\"A Researcher who specializes in biomimetics studies different organisms' abilities to identify two words which appear together frequently\")","source_id":"4c8d34a6cb7efcbac85f88b2fbb3973e"}],"entity_graph":" \"PERSON\"<\/data> \"A Researcher who specializes in biomimetics studies different organisms' abilities to identify two words which appear together frequently\")<\/data> 4c8d34a6cb7efcbac85f88b2fbb3973e<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"5bb96e57d4c79ea40feeb5ecb3296afe","chunk":" organisms, especially in the field of entomology. The water environment is also an interesting result as it can be associated both with new hydrodynamic, hydrophilic, or hydrophobic products, such as surfaces and vehicles, for example; and also, with products for water harvesting, or with the study of aquatic organisms and their characteristics. The term \u201cadhesion\u201d represents another specific focus of research in biomimicry, directed toward the creation of new materials and surfaces with bioinspired properties at the microscopic and nanoscopic levels.\n\nThe next step was the co-occurrence analysis, carried out with the words of the group of publications corresponding to the period from 1991 to 2021 ( n = 196). The VOSViewer software, used to generate Figure 3, automatically assigned different colors to distinguish each thematic grouping of words. The interconnections between words and groups are established through the interweaving of colored lines. The closer to the center of the dia-Biomimetics 2023, 8, 61\n\ngram and the larger the typeface size, the stronger the connections between gr 9 of 16\n\noups and\n\nterms and the greater the prominence in the researched literature.\n\n\n\nFigure 3.\n\nFigure Co-o\n\n3.\n\nccurrence map generated from data from\n\nCo-occurrence map generated from data fr the Web of Scien\n\nom the Web of\n\nce platform, co\n\nScience platform, vering th\n\ncovering e\n\nthe\n\nperiod from 1991 to 2021.\n\nperiod from 1991 to\n\nInsp\n\n2021.\n\necting the colored set\n\nInspecting the colored s, it\n\nsets, is possible\n\nit is p\n\nto identify\n\nossible to\n\na total of\n\nidentify a total nine\n\nof\n\ndifferent\n\nnine different\n\ngrou\n\ngr ps. Sou\n\noups. rce: th\n\nSource: e au\n\nthe thors.\n\nauthors.\n\nIt was\n\nIt\n\nfound\n\nwas\n\ntha\n\nfound t, si\n\nthat, milarly to wha\n\nsimilarly to\n\nt w\n\nwhat as exposed by\n\nwas exposed the word clo\n\nby the word ud an\n\ncloud alysis, the\n\nanalysis,\n\nthe\n\nterms \u201cs\n\nterms ustainability\u201d, \u201csu\n\n\u201csustainability\u201d, stainable des\n\n\u201csustainable ign\u201d, and\n\ndesign\u201d, \u201carc\n\nand hitec\n\n\u201car ture\u201d are\n\nchitectur in ev\n\ne\u201d are id","chunk_id":"5bb96e57d4c79ea40feeb5ecb3296afe","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"ENTOMOLOGY\"","type":"\"ORGANIZATION\"","description":"\"Entomology is a field of study which focuses on the organisms, especially insects.\")|(\"entity\"","source_id":"5bb96e57d4c79ea40feeb5ecb3296afe"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"Entomology is a field of study which focuses on the organisms, especially insects.\")|(\"entity\"<\/data> 5bb96e57d4c79ea40feeb5ecb3296afe<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"84d05d265cebbc1d33e9d523b860d87e","chunk":" alysis, the\n\nanalysis,\n\nthe\n\nterms \u201cs\n\nterms ustainability\u201d, \u201csu\n\n\u201csustainability\u201d, stainable des\n\n\u201csustainable ign\u201d, and\n\ndesign\u201d, \u201carc\n\nand hitec\n\n\u201car ture\u201d are\n\nchitectur in ev\n\ne\u201d are idence\n\nin\n\nat the cen\n\nevidence at -the\n\nter of the\n\ncenter the\n\nof mat\n\nthe ic clusters\n\nthematic , in proxim\n\nclusters, in ity\n\npr to the descr\n\noximity to iptors o\n\nthe\n\nf this r\n\ndescriptorsesearch. The r\n\nof this r\n\ned group\n\nesearch. The -red\n\ning emph\n\ngr\n\nas\n\noupingizes sustaina\n\nemphasizes bility; promotio\n\nsustainability; n of we\n\npr\n\nll-bein\n\nomotion of g and health\n\nwell-being\n\nassociated w\n\nand health\n\nith natur\n\nassociated e-\n\nwith\n\ninspired in\n\nnatur\n\nitiati\n\ne-inspirves\n\ned and biophilic con\n\ninitiatives and\n\nfigurat\n\nbiophilic ions. It also incl\n\nconfigurations. ude\n\nIt s issues\n\nalso\n\nrelated t\n\nincludes\n\no clim\n\nissues r ate\n\nelated\n\nchange\n\nto\n\nand e\n\nclimate cosystem se\n\nchange andrvices. In the g\n\necosystem\n\nreen gro\n\nservices.\n\nu\n\nInp, there ar\n\nthe gr\n\ne wor\n\neen gr\n\nds abo\n\noup,\n\nu\n\nther t b\n\ne\n\nu\n\nar ilding mod\n\ne words\n\n-\n\nabout\n\nels and innov\n\nbuilding\n\native propos\n\nmodels and\n\nals based\n\ninnovative on n\n\npr\n\natur\n\noposals al aspects an\n\nbased on\n\nd eco\n\nnatural\n\nlogical design, in\n\naspects and ecol\n\nclud\n\nogical ing\n\ndesign,\n\nbiodiversity\n\nincluding concerns. In b\n\nbiodiversity\n\noth blue\n\nconcerns. gro\n\nIn\n\nups,\n\nboth\n\nthe\n\nblue ar\n\ngr eas of\n\noups, de\n\nthe sign an\n\nareas d architec\n\nof design\n\ntur\n\nand e\n\narare evi-\n\nchitecture\n\ndenced,\n\nare\n\nas well as\n\nevidenced, the exp\n\nas well loration of biotec\n\nas the\n\nhnolo\n\nexploration of gies and the stud\n\nbi","chunk_id":"84d05d265cebbc1d33e9d523b860d87e","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"ORGANIZATION\"","type":"\"SUSTAINABILITY STUDIES\"","description":"\"Organization is involved in studying themes related to sustainability.\")","source_id":"84d05d265cebbc1d33e9d523b860d87e"}],"entity_graph":" \"SUSTAINABILITY STUDIES\"<\/data> \"Organization is involved in studying themes related to sustainability.\")<\/data> 84d05d265cebbc1d33e9d523b860d87e<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"439722d75181e1aa687e95df70e09d63","chunk":" an\n\nareas d architec\n\nof design\n\ntur\n\nand e\n\narare evi-\n\nchitecture\n\ndenced,\n\nare\n\nas well as\n\nevidenced, the exp\n\nas well loration of biotec\n\nas the\n\nhnolo\n\nexploration of gies and the stud\n\nbiotechnologies\n\ny of ener\n\nand the\n\ngy e\n\nstudyfficienc\n\nof\n\ny\n\nener gy\n\nand m\n\nef\n\naterial\n\nficiency s such\n\nand\n\nas\n\nmatefiber\n\nrials s. The p\n\nsuch\n\ni\n\nas nk set i\n\nfibers. llust\n\nThe rates\n\npinka concern for\n\nset\n\nt\n\nillustrates he fu\n\na\n\nture and\n\nconcern\n\nthe nee\n\nfor the\n\nd\n\nfuture\n\nand the need to integrate adaptive criteria into projects. In orange, words focused on principles and practices of sustainable development, waste management, and circular economy stand out. The brown cluster refers to the morphological study of animals such as geckos and beetles. The group in yellow is directed toward investigations on materials and surfaces (e.g., adhesion properties, locomotion). In the purple group, themes linked to the exploration of design methodologies and processes interconnected with sustainability factors, eco-design, bio-inspired design, and the use of creative analogies can be found.\n\nIt is interesting to note that terms related to sustainability were distributed in more than one colored group. It can be inferred that this topic is one of the notable potentials of biomimicry creations and technologies. As such, it permeates many different subjects related to research and production of biomimetic design including a diversity of application scales (city level, construction, object, materials, and surface properties).\n\nOnce the citation, co-citation, co-occurrence, and word cloud prospecting stages were completed\u2014all referring to the period from 1991 to 2021\u2014another temporal filter was used to carry out the bibliographic coupling analysis (years from 2018 to 2021), obtaining a total of 78 publications. It is important to recall that TEMAC recommends the performance of\n\n\n\nBiomimetics 2023, 8, x FOR PEER REVIEW\n\n10 of 16\n\n\n\nto integrate adaptive criteria into projects. In orange, words focused on principles and practices of sustainable development, waste management, and circular economy stand out. The brown cluster refers to the morphological study of animals such as geckos and beetles. The group","chunk_id":"439722d75181e1aa687e95df70e09d63","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"AN AREAS D ARCHITECTURE\"","type":"\"GEO\"","description":"\"This includes various designs and studies across architecture.\")|(\"entity\"","source_id":"439722d75181e1aa687e95df70e09d63"}],"entity_graph":" \"GEO\"<\/data> \"This includes various designs and studies across architecture.\")|(\"entity\"<\/data> 439722d75181e1aa687e95df70e09d63<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"44c8dff86ecf90b601e21ef2335e8c61","chunk":"8, x FOR PEER REVIEW\n\n10 of 16\n\n\n\nto integrate adaptive criteria into projects. In orange, words focused on principles and practices of sustainable development, waste management, and circular economy stand out. The brown cluster refers to the morphological study of animals such as geckos and beetles. The group in yellow is directed toward investigations on materials and surfaces (e.g., adhesion properties, locomotion). In the purple group, themes linked to the exploration of design methodologies and processes interconnected with sustainability factors, eco-design, bio-inspired design, and the use of creative analogies can be found.\n\nIt is interesting to note that terms related to sustainability were distributed in more than one colored group. It can be inferred that this topic is one of the notable potentials of biomimicry creations and technologies. As such, it permeates many different subjects related to research and production of biomimetic design including a diversity of application scales (city level, construction, object, materials, and surface properties).\n\nOnce the citation, co-citation, co-occurrence, and word cloud prospecting stages were Biomimetics 2023, 8, 61\n\n10 of 16\n\ncompleted\u2014all referring to the period from 1991 to 2021\u2014another temporal filter was used to carry out the bibliographic coupling analysis (years from 2018 to 2021), obtaining a total of 78 publications. It is important to recall that TEMAC recommends the perfor-coupling\n\nmance o analysis\n\nf coup\n\nto\n\nling investigate\n\nanalysis to recent\n\ninvestig r\n\naesear\n\nte re ch fr\n\ncent onts\n\nrese [19,\n\narch 23].\n\nfron Below\n\nts [19, , Figur\n\n23]. Bele 4 shows\n\now, Figu a\n\nre 4\n\nrepresentative\n\nshows a repr heat map\n\nesentative of\n\nhe this assessment,\n\nat map of this\n\nin\n\nasse which\n\nssmen resear\n\nt, in\n\nch emphases\n\nwhich research can be observed\n\nemphases can be\n\nduring the defined\n\nobserved during period.\n\nthe defined period.\n\n\n\nFigure 4. Bibliographic coupling map created from data obtained in the Web of Science, covering Figure 4. Bibliographic coupling map created from data obtained in the Web of Science, covering the the period from 2018 to 2021. Source: the authors.\n\nperiod from 2018 to 2021. Source: the authors.\n\nOn","chunk_id":"44c8dff86ecf90b601e21ef2335e8c61","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"ORGANIZATION\"","type":"\"BIOMIMETICS JOURNAL\"","description":"\"This journal publishes research related to biomimetic design and technologies.\"","source_id":"44c8dff86ecf90b601e21ef2335e8c61"}],"entity_graph":" \"BIOMIMETICS JOURNAL\"<\/data> \"This journal publishes research related to biomimetic design and technologies.\"<\/data> 44c8dff86ecf90b601e21ef2335e8c61<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"8d7e6e7209519d7dec8948a364fdbab2","chunk":" map created from data obtained in the Web of Science, covering Figure 4. Bibliographic coupling map created from data obtained in the Web of Science, covering the the period from 2018 to 2021. Source: the authors.\n\nperiod from 2018 to 2021. Source: the authors.\n\nOn th\n\nOn\n\ne\n\nthe l lef\n\neft t of\n\nof th\n\nthe e coupling\n\ncoupling map,\n\nmap,\n\ninin\n\na a high-concentrati\n\nhigh-concentrationon nucle\n\nnucleus,us\n\nis, is\n\nthethe publicat\n\npublication ion\n\nby\n\nby Perer\n\nPerera\n\na an\n\nand\n\nd Co\n\nCoppe pp\n\nns e\n\n[ ns [4\n\n40]. 0]. The au\n\nThe\n\ntho\n\nauthors\n\nrs investigate\n\ninvestigated\n\nd new design\n\nnew design\n\npossibilities\n\npossibilities thr through\n\nough the\n\nthe lens o\n\nlens of\n\nf bioinspir\n\nbioinspired ed materials\n\nmaterials and and ch\n\nchem emical\n\nical\n\nengineering. Some o\n\nengineering. Some of\n\nf\n\nthe the\n\npr presen\n\nesented ted mate-\n\nmaterials\n\nrials we\n\nwere\n\nre based on the\n\nbased on the str structur\n\nucture ofe of moth\n\nmother er-of-pearl\n\n-of-pearl;\n\n; o\n\non n the s\n\nthe str trong\n\nong, , r\n\nr eusable\n\neusable adhesives\n\nadhesives that\n\nthat\n\nmimic\n\nmimic gecko\n\ngecko toe-pads;\n\ntoe-pads; and\n\nand on\n\non the\n\nthe antibacterial su\n\nantibacterial\n\nrfaces\n\nsurfaces based\n\nbased on\n\non shark\n\nshark skin.\n\nskin. Perera\n\nPerera and\n\nand\n\nCoppens em\n\nCoppens\n\nphasized\n\nemphasized that\n\nthat seeking\n\nseeking inspiration\n\ninspiration in\n\nin natural\n\nnatural patte\n\npatte rns a\n\nrns\n\nnd mi\n\nand\n\ncrostructures\n\nmicrostructures\n\nprovides\n\nprovides an\n\nan opportunity\n\nopportunity for rede\n\nfor r\n\nsigning mater\n\nedesigning\n\nials,\n\nmaterials, processes,\n\nprocesses, and produc\n\nand pr\n\nts w\n\noducts\n\nhich may\n\nwhich may\n\nresu\n\nr\n\nlt\n\nesult in cre\n\nin cr","chunk_id":"8d7e6e7209519d7dec8948a364fdbab2","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"MAP\"","type":"\"OBJECT\"","description":"\"This represents a map created using data from the Web of Science, covering publications from 2018 to 2021. The map visually represents bibliographic coupling between documents.\" ) (\"entity\"","source_id":"8d7e6e7209519d7dec8948a364fdbab2"}],"entity_graph":" \"OBJECT\"<\/data> \"This represents a map created using data from the Web of Science, covering publications from 2018 to 2021. The map visually represents bibliographic coupling between documents.\" ) (\"entity\"<\/data> 8d7e6e7209519d7dec8948a364fdbab2<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"30c01680c32c27bbf40c2879200bb4ca","chunk":"\n\nan opportunity\n\nopportunity for rede\n\nfor r\n\nsigning mater\n\nedesigning\n\nials,\n\nmaterials, processes,\n\nprocesses, and produc\n\nand pr\n\nts w\n\noducts\n\nhich may\n\nwhich may\n\nresu\n\nr\n\nlt\n\nesult in cre\n\nin cr\n\nation\n\neations s that\n\nthat, , ev\n\nevenen witho\n\nwithout ut\n\ndir direc\n\nectly trly resemb\n\nesemblingling\n\nthe the mimi\n\nmimickedcked or\n\nor\n\nga\n\nganism,nism\n\nwill , will\n\nhave\n\nhave an inherent link\n\nan inherent link with with\n\nnatur nature in the\n\ne in their pr ir proper\n\noperties\n\nties and functionality\n\nand functionality.\n\n.\n\nThe red-co\n\nThe red-c\n\nlor\n\nolor ed are\n\ned ar\n\na\n\nea, , in th\n\nin the e center o\n\ncenter of f th\n\nthe e map, gro\n\nmap, gr\n\nu\n\noups ps the wor\n\nthe works k\n\nbys by Hossein\n\nHosseini et i et al.\n\nal. [41],\n\n[41]\n\nTate , Tate e\n\net al. [ t al. [\n\n42], 42], X\n\nXing i\n\net ng e\n\nal. [t al.\n\n43], [43], an\n\nand\n\nd Amer [\n\nAmer [41]. 41]. Hossein\n\nHosseini et i e\n\nal. t al. [\n\n[41] 41] ga\n\ngatherthered l\n\ned\n\nitera\n\nliteratur tur\n\ne\n\ne\n\non\n\nkinetic and adaptive architectural fa\u00e7ades that act as permeable complex interfaces between indoor and outdoor environments. The authors analyzed the ability of these elements to function as a protective layer responsive to climatic variations. They proposed a design process to guide the construction of kinetic fa\u00e7ades from a morphological and interdisciplinary approach, in which biomimetic characteristics are combined with parametric and energy efficiency technologies.\n\nTate et al. [42] studied the interaction between biomimicry and the circular economy based on ecosystem analogies. They called attention to the flows of energy and matter in nature, primarily based on recycling and reuse between the different trophic levels.\n\nTate et al. exemplified their concepts by reviewing relationships of mutualism found in nature. In the authors\u2019 opinion, the insertion of biomimetic knowledge and principles into new economic and","chunk_id":"30c01680c32c27bbf40c2879200bb4ca","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"OPPORTUNITY\"","type":"\"EVENT\"","description":"\"An opportunity for redesigning materials, processes, and products that may inherently link with nature through their properties and functionality.\"","source_id":"30c01680c32c27bbf40c2879200bb4ca"},{"name":"\"REDESIGN\"","type":"\"ACTION\"","description":"\"The act of redesigning materials, processes, and products to improve efficiency or sustainability.\"","source_id":"30c01680c32c27bbf40c2879200bb4ca"},{"name":"\"NATURE LINK\"","type":"\"ASPECT\"","description":"\"A connection or relationship between the designed elements and natural principles or systems.\"","source_id":"30c01680c32c27bbf40c2879200bb4ca"},{"name":"\"MIMICRY\"","type":"\"CONCEPT\"","description":"\"The use of biomimetic characteristics in design inspired by natural processes and forms.\"","source_id":"30c01680c32c27bbf40c2879200bb4ca"},{"name":"\"CLIMATIC VARIATIONS\"","type":"\"CONTEXT\"","description":"\"Environmental changes that influence the functionality of kinetic architectural elements.\"","source_id":"30c01680c32c27bbf40c2879200bb4ca"},{"name":"\"CIRCULAR ECONOMY\"","type":"\"CONCEPT\"","description":"\"A model where resources are kept in use for as long as possible, extracting maximum value while minimizing waste.\">","source_id":"30c01680c32c27bbf40c2879200bb4ca"}],"entity_graph":" \"EVENT\"<\/data> \"An opportunity for redesigning materials, processes, and products that may inherently link with nature through their properties and functionality.\"<\/data> 30c01680c32c27bbf40c2879200bb4ca<\/data> <\/node> \"ACTION\"<\/data> \"The act of redesigning materials, processes, and products to improve efficiency or sustainability.\"<\/data> 30c01680c32c27bbf40c2879200bb4ca<\/data> <\/node> \"ASPECT\"<\/data> \"A connection or relationship between the designed elements and natural principles or systems.\"<\/data> 30c01680c32c27bbf40c2879200bb4ca<\/data> <\/node> \"CONCEPT\"<\/data> \"The use of biomimetic characteristics in design inspired by natural processes and forms.\"<\/data> 30c01680c32c27bbf40c2879200bb4ca<\/data> <\/node> \"CONTEXT\"<\/data> \"Environmental changes that influence the functionality of kinetic architectural elements.\"<\/data> 30c01680c32c27bbf40c2879200bb4ca<\/data> <\/node> \"CONCEPT\"<\/data> \"A model where resources are kept in use for as long as possible, extracting maximum value while minimizing waste.\"><\/data> 30c01680c32c27bbf40c2879200bb4ca<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"f770903009c82b1aeca7bf9e490877ad","chunk":" called attention to the flows of energy and matter in nature, primarily based on recycling and reuse between the different trophic levels.\n\nTate et al. exemplified their concepts by reviewing relationships of mutualism found in nature. In the authors\u2019 opinion, the insertion of biomimetic knowledge and principles into new economic and business approaches can promote innovation in the organizational sphere. In fact, this work contributed to the recognition of biomimicry as an area from which knowledge can be useful in the strategic, administrative, and organizational plans of companies.\n\nXing et al. [43] combined the study of plants, more specifically plant cells, with the development of fa\u00e7ade design and technologies for building cladding, resulting in a con-\n\n\n\n\n\nBiomimetics 2023, 8, 61\n\n11 of 16\n\nceptual proposal for a biodome, with improvements in thermal insulation and energy efficiency. The authors prioritized the study of plant-based analogies to generate constructive proposals, due to the sessile character of plants, which requires them to adapt to the surrounding conditions (as they fixed in a single location, a characteristic also associated with buildings). Xing et al. generated a framework for the design process of biomimetic projects.\n\nAmer [44] incorporated biomimetic notions into the syllabus of a university course, covering the following topics: interrelationships between biomimicry and building design; project methodology; natural lighting management; and plant-inspired fa\u00e7ades; as well as research activities, design, parametric digital prototyping (with Rhinoceros and Grasshopper software), and the use of the biomimetic design concept generation matrix.\n\nAccording to the author, the students realized the importance of the responsibility inherent in professional practice regarding the preservation of the health of human communities and those of other species.\n\nAdditionally, in Figure 4, two more nuclei can be observed, with the works of Clark [45]\n\nand Zari [46]. The first publication researched marine biomineralization for monitoring and forecasting the impacts of climate change and for the design of new biocomposite materials [45]. In the second publication, Zari [46] endeavored to analyze how the urban environment can insert new proposals into its design that incorporate ecosystem services committed to the regeneration of biodiversity and the resilience of natural environments faced with climate change.\n\nIn summary, an examination of the results from the coupling analysis allowed verifica-tion that the themes of recent research in biomimicry and design include, on one hand, the investigation","chunk_id":"f770903009c82b1aeca7bf9e490877ad","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"TATE ET AL.\"","type":"\"ORGANIZATION\"","description":"\"Tate et al. are a team who reviewed relationships of mutualism found in nature and contributed to the recognition of biomimicry as an area useful for strategic planning in companies.\"","source_id":"f770903009c82b1aeca7bf9e490877ad"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"Tate et al. are a team who reviewed relationships of mutualism found in nature and contributed to the recognition of biomimicry as an area useful for strategic planning in companies.\"<\/data> f770903009c82b1aeca7bf9e490877ad<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"f5fd896ed0c59d47158db316fad680dc","chunk":" insert new proposals into its design that incorporate ecosystem services committed to the regeneration of biodiversity and the resilience of natural environments faced with climate change.\n\nIn summary, an examination of the results from the coupling analysis allowed verifica-tion that the themes of recent research in biomimicry and design include, on one hand, the investigation of the physicochemical properties of materials and microstructures, mainly biological structures of reptiles and marine animals. On the other hand, there is a focus on the design of components, coatings, and finishes for application in architecture, including bioclimatic factors (e.g., local context, energy, and resource savings) and environmental responsiveness. This enables envisaging the creation of adaptable buildings that operate similarly to living organisms. In this scope, the authors mainly investigated plant elements as a source of inspiration. Among the highlighted works, there were also many proposals for creative tools, frameworks, and parametric software that aim to assist in the search for biological solutions and the transfer of such natural characteristics to the conceptual development in design. Another research emphasis focused on sustainability, including aspects of ecosystems and interspecific ecological relationships that demonstrate the potential to inspire a multiplicity of projects, such as the design of products and even strategic design. In addition, in the present study, there were research perspectives that addressed, respectively, the importance of supporting ecosystem services in the urban environment and the development of materials such as biocomposites.\n\nGiven what is presented above, it is possible to infer that the coupling analysis highlighted initiatives in biomimetic design that demonstrate a remarkable capacity to generate innovations to solve emerging challenges in several fields of human activity. Finally, it should be stressed that, once again, the authors highlighted in the densest cluster produced research and projects guided by the problem-based approach.\n\n4. Discussion\n\nThe results of this systematic review allowed establishing connections and making conjectures about the scenarios of publications indexed by the Web of Science. It is be-lieved that the panorama of productions showcased in the present research encompasses contributions that may assist researchers and designers in their endeavors, as the main themes and emphases of projects and research were identified in the investigated literature, representing possible paths for new creations and studies.\n\nThe analysis of the data obtained through this survey indicated that the works involving design and biomimicry are associated with the following thematic aspects: (a) the conception of products, buildings, and environments; (b) the exploration of structural and\n\nBiomimetics 2023, 8, 61\n\n12 of 16\n\nsystemic conform","chunk_id":"f5fd896ed0c59d47158db316fad680dc","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"NEW PROPOSALS\"","type":"\"EVENT\"","description":"\"The introduction of innovative concepts that integrate ecosystem services to support biodiversity and natural environment resilience against climate change.\")|(\"entity\"","source_id":"f5fd896ed0c59d47158db316fad680dc"}],"entity_graph":" \"EVENT\"<\/data> \"The introduction of innovative concepts that integrate ecosystem services to support biodiversity and natural environment resilience against climate change.\")|(\"entity\"<\/data> f5fd896ed0c59d47158db316fad680dc<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"af3fc23c5069edd0bdffd8f9a64d3ab2","chunk":" survey indicated that the works involving design and biomimicry are associated with the following thematic aspects: (a) the conception of products, buildings, and environments; (b) the exploration of structural and\n\nBiomimetics 2023, 8, 61\n\n12 of 16\n\nsystemic conformations of nature for the production of new materials and technologies; (c) the use of biomimetic creative tools to guide idea generation in product design; and (d) biomimetic creations with an emphasis on resource savings and sustainability.\n\nIt was also noted that innovations which correlate design and biomimicry have been applied in different domains, namely: health (e.g., new equipment); textiles (e.g., fibers and fabrics); robotics (e.g., programming and navigation); materials science (e.g., adhesives and self-cleaning materials); construction (e.g., kinetic fa\u00e7ades and structures); and environmental science and ecology (e.g., ecosystem services, regeneration of biodiversity). In this sense, it is pertinent to mention that the publications, which were listed and organized in this review, reflect development in several areas of cutting-edge technology, which is consistent with the innovative tendency intrinsic to the field of biomimicry.\n\nHowever, it is relevant to underscore that there is still a scarcity of works oriented toward the development and use of everyday objects and in the field of services, given that these are two areas of great importance in the design domain. In view of this finding, it is reasonable to assume that more efforts and investments are required in design projects that clearly and consistently recognize their foundation in the principles of biomimicry.\n\nThus, it is crucial to more frequently adopt a biomimicry perspective to research and develop products intended for the daily lives of consumers, in order to guarantee a better quality of life for the users of these objects (e.g., bio-inspired functional and technological improvements of products). This limitation is even more alarming upon verifying that most of the publications retrieved from the Web of Science originate from engineering and architecture schools and departments. As a result, there are not enough projects produced by teams from schools and departments associated exclusively with the field of design. It is possible to assume that the absence of the \u2018design\u2019 filter when searching the Web of Science may constitute a restriction for specific dissemination of works.\n\nAnother trend observed in the present review, highlighted by the analysis of the heat maps, concerns which type of biomimicry-based approach the authors adopted in their projects and research. The results indicated that","chunk_id":"af3fc23c5069edd0bdffd8f9a64d3ab2","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"BIOMIMETICS 2023\"","type":"\"JOURNAL\"","description":"\"The journal that published a study on the thematic aspects associated with design and biomimicry, including product conception, structural explorations of nature for new materials, use of creative tools in product design, and emphasis on resource savings and sustainability.\")|(\"entity\"","source_id":"af3fc23c5069edd0bdffd8f9a64d3ab2"}],"entity_graph":" \"JOURNAL\"<\/data> \"The journal that published a study on the thematic aspects associated with design and biomimicry, including product conception, structural explorations of nature for new materials, use of creative tools in product design, and emphasis on resource savings and sustainability.\")|(\"entity\"<\/data> af3fc23c5069edd0bdffd8f9a64d3ab2<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"916f17bde39ae650dad1b657a1887fa6","chunk":" the absence of the \u2018design\u2019 filter when searching the Web of Science may constitute a restriction for specific dissemination of works.\n\nAnother trend observed in the present review, highlighted by the analysis of the heat maps, concerns which type of biomimicry-based approach the authors adopted in their projects and research. The results indicated that many of them started by addressing the problem and the required function (problem-based approach) instead of beginning directly from the investigation of natural aspects (solution-driven approach). It should be clarified that this could be expected since the survey encompassed the field of design, an area where projects and creative processes commonly begin with the definition of a problem or a challenge associated with human activity. However, supporting the development of more projects and research in design based on the solution-driven approach can also be of great interest, as it can contribute to enhancing and refining creative skills. In addition, this approach contributes to establishing connections with specialists from other areas (e.g., biologists) and may also help bring designers closer to field research in nature.\n\nRegarding design processes, efforts were made to provide information about biomimetic tools that assist in the planning and execution of creative proposals (e.g., Biomimicry Thinking Design Lens, Biomimicry Taxonomy Chart, BioTRIZ, GEMS of SAPPhIRE, IDEA-INSPIRE, BECE-Framework) [9,15, 30,35,37,38]. Such instruments, connected to the problem-based approach, mainly focus on the conceptual development phase of the project, supporting the investigation of characteristics of nature in their transposition into the design domain. In addition, various digital resources were explored by the authors to generate complex shapes and patterns for models and products (e.g., parametric software and rapid prototyping). The use of biomimetic tools in creative design processes, reported in the analyzed literature, can still be considered restricted, given that there was not enough detail on the application of such instruments. Consequently, it was not possible to verify, in this review, whether the authors resorted to other resources or documents, or if they deliberately chose not to include this information in the communication of their works.\n\nThe TEMAC model contributed to the identification of the main themes, approaches, and trends in the literature. Through it, it was possible to infer which areas are expanding and which deserve to be further investigated. The tool also allowed comparisons to be made between the works and production of different authors, countries, and institutions.\n\nBiomimetics 2023, 8,","chunk_id":"916f17bde39ae650dad1b657a1887fa6","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"WEB OF SCIENCE\"","type":"\"ORGANIZATION\"","description":"\"The Web of Science is a comprehensive database used for academic research that may limit the accessibility or dissemination of certain works based on specific criteria.\"","source_id":"916f17bde39ae650dad1b657a1887fa6"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The Web of Science is a comprehensive database used for academic research that may limit the accessibility or dissemination of certain works based on specific criteria.\"<\/data> 916f17bde39ae650dad1b657a1887fa6<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"b23a7cb845fd949e0baab80bf6f0c4f8","chunk":" main themes, approaches, and trends in the literature. Through it, it was possible to infer which areas are expanding and which deserve to be further investigated. The tool also allowed comparisons to be made between the works and production of different authors, countries, and institutions.\n\nBiomimetics 2023, 8, 61\n\n13 of 16\n\nIn addition, the recommendation of TEMAC to adopt software, such as VOSViewer and TagCrowd, enabled the graphical representation of the results (e.g., heat maps and line maps), which facilitated carrying out the analyses, in addition to illustrating them satis-factorily. However, like any procedure for surveying and analyzing the literature, it is crucial to understand that, from the moment specifications are established for the research themes, descriptors, software, databases, and filters that will be used, it is inevitable that certain works will not be captured by the selected criteria, which can limit the scope of the contributions of a review such as the present work.\n\nThe chosen database for this research (Web of Science) is one of the main multidisci-plinary repositories, having an excellent temporal coverage of publications, in addition to ensuring a frequent update of indexed works, including complementary materials such as conference proceedings [19]. Nevertheless, the Web of Science mainly covers content published in English and, as discussed earlier, there is no specific filtering function for the field of design. Thus, the investigation of other multilingual repositories, such as Scopus, Google Scholar, EBSCO, ProQuest [19, 47] is recommended. Furthermore, when analyzing other systematic reviews, it is noticeable that other software and platforms, in addition to those employed in the present review, have been used by authors to organize and facilitate data processing. Some examples are: MAXQDA, CiteSpace, Publish or Perish, San-keyMATIc, Bibexcel, Gephi, Pajek, Ucinet, and Science of Science (Sci2) [47\u201349].\n\nThe adoption of the descriptors biomimicry and design was sufficient to achieve the objectives proposed in the scope of this research. However, considering that only two descriptors were used, it is suggested that more terms be incorporated in future surveys, such as: bioinspiration, biomimetics, bionics, biodesign, biomimetic design, bioinspired design, bionic design, nature-based design, nature-inspired design, biologically-inspired design, and bio-informed design. Thus, it will be possible","chunk_id":"b23a7cb845fd949e0baab80bf6f0c4f8","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"BIOMIMETICS 2023\"","type":"\"PUBLICATION\"","description":"\"Biomimetics is a journal that discusses the literature on biomimetics in 2023.\"","source_id":"b23a7cb845fd949e0baab80bf6f0c4f8"}],"entity_graph":" \"PUBLICATION\"<\/data> \"Biomimetics is a journal that discusses the literature on biomimetics in 2023.\"<\/data> b23a7cb845fd949e0baab80bf6f0c4f8<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"f8d611d2f89f42ca1550ee673a05d4dd","chunk":" be incorporated in future surveys, such as: bioinspiration, biomimetics, bionics, biodesign, biomimetic design, bioinspired design, bionic design, nature-based design, nature-inspired design, biologically-inspired design, and bio-informed design. Thus, it will be possible to cover an even greater number of works, which may lead to relevant developments for the scientific and professional communities.\n\nIn summary, with this review, it is necessary to emphasize the importance of adopting interdisciplinary knowledge in the field of design to expand the creative perspectives of professionals and to diversify theories, approaches, and resources. In this sense, biomimicry has shown itself to be an area of great potential for projects in design. In this work, the expression \u201cbiomimetic design\u201d was generically adopted when analyzing publications from the intersection between the design and biomimicry domains. However, it is necessary to understand that further efforts are needed in favor of more \u2018genuinely\u2019 biomimetic designs, developed in the specific field of design, in which, throughout the entire creative process of products and services, the concepts, principles, and creative tools of biomimicry are effectively integrated.\n\nUnlike technologies that require specific procedures, authorizations, investments, and monetization for access, nature is an extensive (and more accessible) repository of resources that can be investigated and interpreted by human beings, which can complement and expand current practices in design. Furthermore, as evidenced by several authors, the field of design is plural and interdisciplinary, as it seeks to enable creations for different areas of human endeavor [1\u20134, 50\u201355]. Including the perspective of biomimicry in teaching and professional practice scenarios in design can expand creative horizons, allowing the creation of innovative solutions that are more efficient, economical, and better adapted to consumer needs and environmental diversity [6, 55,56].\n\nFinally, as the study of aspects of biomimicry in design can enhance the development of multiple skills (such as creative and conceptual generation, observation and research, study of materials, graphic expression, and three-dimensional conception and digital modeling), it is important to recognize that understanding nature and knowing how to explore its resources are indispensable requirements for contemporary professional training, since they can encourage creativity as well as the integration of ecological and sustainable factors in production cycles.\n\nBiomimetics 2023, 8, 61\n\n14 of 16\n\nAuthor Contributions: Conceptualization, A.A.M.d.S.; methodology,","chunk_id":"f8d611d2f89f42ca1550ee673a05d4dd","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"A.A.M.D.S.\"","type":"\"PERSON\"","description":"\"A.A.M.d.S. is an author who contributed to a study on the application and importance of biomimicry in design.\") (\"entity\"","source_id":"f8d611d2f89f42ca1550ee673a05d4dd"}],"entity_graph":" \"PERSON\"<\/data> \"A.A.M.d.S. is an author who contributed to a study on the application and importance of biomimicry in design.\") (\"entity\"<\/data> f8d611d2f89f42ca1550ee673a05d4dd<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"7982a2e4054b66ae19457bde8585eaa8","chunk":" explore its resources are indispensable requirements for contemporary professional training, since they can encourage creativity as well as the integration of ecological and sustainable factors in production cycles.\n\nBiomimetics 2023, 8, 61\n\n14 of 16\n\nAuthor Contributions: Conceptualization, A.A.M.d.S.; methodology, A.A.M.d.S. and D.M.V.; software, A.A.M.d.S.; validation, A.A.M.d.S. and D.M.V.; formal analysis, A.A.M.d.S.; investigation A.A.M.d.S.; resources A.A.M.d.S.; data curation, A.A.M.d.S.; writing\u2014original draft, A.A.M.d.S.; writing\u2014review and editing, A.A.M.d.S. and D.M.V.; visualization, A.A.M.d.S.; supervision, D.M.V.\n\nAll authors have read and agreed to the published version of the manuscript.\n\nFunding: This research received no external funding.\n\nInstitutional Review Board Statement: Not applicable.\n\nData Availability Statement: Not applicable.\n\nConflicts of Interest: The authors declare no conflict of interest.\n\nReferences\n\n1.\n\nCardoso, R. Design for a Complex World; Cosac Naify: S\u00e3o Paulo, Brazil, 2012; ISBN 9788540500983.\n\n2.\n\nBonsiepe, G. Design, Culture and Society; Blucher: S\u00e3o Paulo, Brazil, 2011; ISBN 978-8521205326.\n\n3.\n\nMunari, B. Design as Art; Penguin Modern Classics: London, UK, 2008; ISBN 978-0141035819.\n\n4.\n\nFlusser, V. The Codified World: Towards a Philosophy of Design and Communication; Cosac Naify: S\u00e3o Paulo, Brazil, 2007; ISBN 9788575035931.\n\n5.\n\nS\u00e1, A.A.M. Biomimicry Tools in Design: Contributions of Nature to the Creative Practice. Master\u2019s Thesis, University of Bras\u00edlia, Bras\u00edlia, Brazil, December 2021.\n\n6.\n\nArruda, A.J.V. Methods and Processes in Bionics and Biomimicry: The Technological Revolution by Nature; Blucher: S\u00e3o Paulo, Brazil, 2018; ISBN 9788580393491.\n\n7.\n\nMacKinnon, R.B.; Oomen, J.; Zari, M.P. Promises and Presuppositions of Biomimicry. Biomimetics 2020, 5, 33","chunk_id":"7982a2e4054b66ae19457bde8585eaa8","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"A.A.M.D.S.\"","type":"\"PERSON\"","description":"\"A.A.M.d.S is the primary author who conceptualized the study and developed its methodology with co-author D.M.V.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"D.M.V.\"","type":"\"PERSON\"","description":"\"D.M.V contributes to software development, formal analysis of data, validation, investigation, resource gathering, supervision of the project.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"BIOMIMETICS 2023\"","type":"\"EVENT\"","description":"\"Publication year for a scientific paper or conference on Biomimetics which this article was published in.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"AUTHOR CONTRIBUTIONS\"","type":"\"CONCEPT\"","description":"\"A structured description of each authors' contribution to the research process, from conceptualization to final review.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"CONCEPTUALIZATION\"","type":"\"EVENT\"","description":"\"Planning and ideation phase for the study conducted by A.A.M.d.S.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"METHODOLOGY\"","type":"\"EVENT\"","description":"\"Process of planning how experiments or research will be designed and executed, carried out by A.A.M.d.S. and D.M.V.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"SOFTWARE\"","type":"\"TOOL\"","description":"\"A.A.M.d.S utilized software tools for various tasks during the study's execution.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"VALIDATION\"","type":"\"EVENT\"","description":"\"The process of confirming the accuracy or truthfulness of research findings, carried out by A.A.M.d.S. and D.M.V.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"FORMAL ANALYSIS\"","type":"\"TECHNIQUE\"","description":"\"Careful examination and interpretation of data or concepts using systematic methods\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"INVESTIGATION\"","type":"\"ACTIVITY\"","description":"\"Research conducted to gather information, performed by A.A.M.d.S.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"RESOURCES\"","type":"\"TOOL\"","description":"\"Materials or assets used in the study which were collected or provided by A.A.M.d.S.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"DATA CURATION\"","type":"\"PROCESS\"","description":"\"Organization and management of data throughout its lifecycle, responsibility of A.A.M.d.S.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"WRITING\u2014ORIGINAL DRAFT\"","type":"\"TASK\"","description":"\"The initial writing phase where the first version of a paper or report is drafted by A.A.M.d.S.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"WRITING\u2014REVIEW AND EDITING\"","type":"\"ACTIVITY\"","description":"\"Process to refine and correct content, undertaken by both A.A.M.d.S. and D.M.V.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"VISUALIZATION\"","type":"\"TECHNIQUE\"","description":"\"Representation of data or concepts through graphical means, performed by A.A.M.d.S.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"},{"name":"\"SUPERVISION\"","type":"\"ROLE\"","description":"\"Overseeing the research project's progress and ensuring quality control, done by D.M.V.\"","source_id":"7982a2e4054b66ae19457bde8585eaa8"}],"entity_graph":" \"PERSON\"<\/data> \"A.A.M.d.S is the primary author who conceptualized the study and developed its methodology with co-author D.M.V.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"PERSON\"<\/data> \"D.M.V contributes to software development, formal analysis of data, validation, investigation, resource gathering, supervision of the project.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"EVENT\"<\/data> \"Publication year for a scientific paper or conference on Biomimetics which this article was published in.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"CONCEPT\"<\/data> \"A structured description of each authors' contribution to the research process, from conceptualization to final review.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"EVENT\"<\/data> \"Planning and ideation phase for the study conducted by A.A.M.d.S.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"EVENT\"<\/data> \"Process of planning how experiments or research will be designed and executed, carried out by A.A.M.d.S. and D.M.V.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"TOOL\"<\/data> \"A.A.M.d.S utilized software tools for various tasks during the study's execution.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"EVENT\"<\/data> \"The process of confirming the accuracy or truthfulness of research findings, carried out by A.A.M.d.S. and D.M.V.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"TECHNIQUE\"<\/data> \"Careful examination and interpretation of data or concepts using systematic methods\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"ACTIVITY\"<\/data> \"Research conducted to gather information, performed by A.A.M.d.S.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"TOOL\"<\/data> \"Materials or assets used in the study which were collected or provided by A.A.M.d.S.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"PROCESS\"<\/data> \"Organization and management of data throughout its lifecycle, responsibility of A.A.M.d.S.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"TASK\"<\/data> \"The initial writing phase where the first version of a paper or report is drafted by A.A.M.d.S.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"ACTIVITY\"<\/data> \"Process to refine and correct content, undertaken by both A.A.M.d.S. and D.M.V.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"TECHNIQUE\"<\/data> \"Representation of data or concepts through graphical means, performed by A.A.M.d.S.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> \"ROLE\"<\/data> \"Overseeing the research project's progress and ensuring quality control, done by D.M.V.\"<\/data> 7982a2e4054b66ae19457bde8585eaa8<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"ab0129037f27d2a0b3230e695cb66703","chunk":"ucher: S\u00e3o Paulo, Brazil, 2018; ISBN 9788580393491.\n\n7.\n\nMacKinnon, R.B.; Oomen, J.; Zari, M.P. Promises and Presuppositions of Biomimicry. Biomimetics 2020, 5, 33. [CrossRef] [PubMed]\n\n8.\n\nISO Online Browsing Platform. ISO 18458:2015(en) Biomimetics\u2014Terminology, Concepts and Methodology. Available online:\n\nhttps:\/\/www.iso.org\/obp\/ui\/#iso:std:iso:18458:ed-1:v1:en (accessed on 15 January 2023).\n\n9.\n\nVincent, J.F.; Bogatyreva, O.A.; Bogatyrev, N.R.; Bowyer, A.; Pahl, A.K. Biomimetics: Its practice and theory. J. R. Soc. Interface 2006, 3, 471\u2013482. [CrossRef]\n\n10.\n\nWanieck, K.; Beismann, H. Perception and role of standards in the world of biomimetics. Bioinspired. Biomim. Nanobiomater. 2021, 10, 8\u201315. [CrossRef]\n\n11.\n\nKamps, T.; Gralow, M.; Schlick, G.; Reinhart, G. Systematic Biomimetic Part Design for Additive Manufacturing. Procedia CIRP\n\n2017, 65, 259\u2013266. [CrossRef]\n\n12.\n\nIouguina, A.; Dawson, J.; Hallgr\u00edmsson, B.; Smart, G. Biologically informed disciplines: A comparative analysis of bionics, biomimetics, biomimicry, and bio-inspiration among others. Int. J. Des. Nat. Ecodyn. 2014, 9, 197\u2013205. [CrossRef]\n\n13.\n\nSpeck, O.; Speck, D.; Horn, R.; Gantner, J.; Sedlbauer, K.P. Biomimetic bio-inspired biomorph sustainable? An attempt to classify and clarify biology-derived technical developments. Bioinspir. Biomim. 2017, 12, 011004. [CrossRef] [PubMed]\n\n14.\n\nCohen, Y.H.; Reich, Y. Biomimetic Design Method for Innovation and Sustainability; Springer: New York, NY, USA, 2016; ISBN ","chunk_id":"ab0129037f27d2a0b3230e695cb66703","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"MACKINNON\"","type":"\"PERSON\"","description":"\"MacKinnon R.B., J.Oomen, M.P.Zari are authors in the paper 'Promises and Presuppositions of Biomimicry' contributing to the field of biomimetics.\")
(\"entity\"","source_id":"ab0129037f27d2a0b3230e695cb66703"}],"entity_graph":" \"PERSON\"<\/data> \"MacKinnon R.B., J.Oomen, M.P.Zari are authors in the paper 'Promises and Presuppositions of Biomimicry' contributing to the field of biomimetics.\")<br>(\"entity\"<\/data> ab0129037f27d2a0b3230e695cb66703<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"71820a84991aa839263c1542540c3d9a","chunk":" developments. Bioinspir. Biomim. 2017, 12, 011004. [CrossRef] [PubMed]\n\n14.\n\nCohen, Y.H.; Reich, Y. Biomimetic Design Method for Innovation and Sustainability; Springer: New York, NY, USA, 2016; ISBN 978-3-319-33997-9.\n\n15.\n\nGamage, A.; Hyde, R. A model based on Biomimicry to enhance ecologically sustainable design. Arch. Sci. Rev. 2012, 55, 224\u2013235.\n\n[CrossRef]\n\n16.\n\nSnyder, H. Literature review as a research methodology: An overview and guidelines. J. Bus. Res. 2019, 104, 333\u2013339. [CrossRef]\n\n17.\n\nGrant, M.J.; Booth, A. A typology of reviews: An analysis of 14 review types and associated methodologies. Health Inf. Libr. J.\n\n2009, 26, 91\u2013108. [CrossRef]\n\n18.\n\nCreswell, J.W. Research Design: Qualitative, Quantitative, and Mixed Methods Approaches; Sage Publication: Los Angeles, CA, USA, 2013; ISBN 978-1452226101.\n\n19.\n\nMariano, A.M.; Rocha, M.S. Literature review: Presentation of an integrative approach. In Proceedings of the AEDM International Conference\u2014Economy, Business and Uncertainty: Ideas for a European and Mediterranean Industrial Policy, Reggio Calabria, Italy, 4\u20135 September 2017; pp. 427\u2013443, ISBN 978-84-697-5592-1.\n\n20.\n\nHsiao, H.C.; Chou, W.C. Using biomimetic design in a product design course. World Trans. Eng. Technol. Educ. 2007, 6, 31\u201335.\n\n21.\n\nVolstad, N.L.; Boks, C. On the use of Biomimicry as a Useful Tool for the Industrial Designer. Sustain. Dev. 2012, 20, 189\u2013199.\n\n[CrossRef]\n\n22.\n\nBenyus, J.M. Biomimicry: Innovation Inspired by Nature; William Morrow and Company: New York, NY, USA, 1997; ISBN 9780060533229.\n\nBiomimetics 2023, 8, 61\n\n15 of 16\n\n","chunk_id":"71820a84991aa839263c1542540c3d9a","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"Y.H. COHEN\"","type":"\"PERSON\"","description":"\"Cohen is the author who wrote 'Biomimetic Design Method for Innovation and Sustainability' in Springer\")|(\"entity\"","source_id":"71820a84991aa839263c1542540c3d9a"}],"entity_graph":" \"PERSON\"<\/data> \"Cohen is the author who wrote 'Biomimetic Design Method for Innovation and Sustainability' in Springer\")|(\"entity\"<\/data> 71820a84991aa839263c1542540c3d9a<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"d9c59b517b2e653c7c9cb7efb130c9b0","chunk":"Ref]\n\n22.\n\nBenyus, J.M. Biomimicry: Innovation Inspired by Nature; William Morrow and Company: New York, NY, USA, 1997; ISBN 9780060533229.\n\nBiomimetics 2023, 8, 61\n\n15 of 16\n\n23.\n\nMariano, A.M. Learn to Use TEMAC. Available online: https:\/\/www.pesquisatemac.com\/aprenda-a-usar-o-temac (accessed on 15 January 2023).\n\n24.\n\nBoyack, K.W.; Klavans, R. Co-citation analysis, bibliographic coupling, and direct citation: Which citation approach represents the research front most accurately? J. Am. Soc. Inf. Sci. Technol. 2010, 61, 2389\u20132404. [CrossRef]\n\n25.\n\nLi, S.; Zeng, Q.; Xiao, Y.; Fu, S.Y.; Zhou, B. Biomimicry of bamboo bast fiber with engineering composite materials. Mater. Sci. Eng.\n\nC 1995, 3, 125\u2013130. [CrossRef]\n\n26.\n\nBhushan, B. Biomimetics: Lessons from nature\u2013an overview. Philos. Trans. R. Soc. A Math. Phys. Eng. Sci. 2009, 367, 1445\u20131486.\n\n[CrossRef] [PubMed]\n\n27.\n\nEadie, L.; Ghosh, T.K. Biomimicry in textiles: Past, present and potential. An overview. J. R. Soc. Interface 2011, 8, 761\u2013775.\n\n[CrossRef] [PubMed]\n\n28.\n\nCho, W.K.; Ankrum, J.A.; Guo, D.; Chester, S.A.; Yang, S.Y.; Kashyap, A.; Campbell, G.A.; Wood, R.J.; Rijal, R.K.; Karnik, R.; et al.\n\nMicrostructured barbs on the North American porcupine quill enable easy tissue penetration and difficult removal. Proc. Natl.\n\nAcad. Sci. USA 2012, 109, 21289\u201321294. [CrossRef]\n\n29.\n\nCutkosky, M.R.; Kim, S. Design and fabrication of multi-material structures for bioinspired robots. Philos. Trans. R. Soc. A Math.\n\nPhys. Eng. Sci. 2009","chunk_id":"d9c59b517b2e653c7c9cb7efb130c9b0","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"BENYUS\"","type":"\"PERSON\"","description":"\"Author of the book 'Biomimicry', exploring innovation inspired by nature.\")|(\"entity\"","source_id":"d9c59b517b2e653c7c9cb7efb130c9b0"}],"entity_graph":" \"PERSON\"<\/data> \"Author of the book 'Biomimicry', exploring innovation inspired by nature.\")|(\"entity\"<\/data> d9c59b517b2e653c7c9cb7efb130c9b0<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"d41313a8b0e699443363728cc7ec56b7","chunk":"2012, 109, 21289\u201321294. [CrossRef]\n\n29.\n\nCutkosky, M.R.; Kim, S. Design and fabrication of multi-material structures for bioinspired robots. Philos. Trans. R. Soc. A Math.\n\nPhys. Eng. Sci. 2009, 367, 1799\u20131813. [CrossRef]\n\n30.\n\nMendoza, J.M.F.; Sharmina, M.; Gallego-Schmid, A.; Heyes, G.; Azapagic, A. Integrating Backcasting and Eco-Design for the Circular Economy: The BECE Framework. J. Ind. Ecol. 2017, 21, 526\u2013544. [CrossRef]\n\n31.\n\nSherman, B.D.; Vaughn, M.D.; Bergkamp, J.; Gust, D.; Moore, A.L.; Moore, T.A. Evolution of reaction center mimics to systems capable of generating solar fuel. Photosynth. Res. 2013, 120, 59\u201370. [CrossRef]\n\n32.\n\nLee, J.; Sponberg, S.N.; Loh, O.Y.; Lamperski, A.G.; Full, R.J.; Cowan, N.J. Templates and Anchors for Antenna-Based Wall Following in Cockroaches and Robots. IEEE Trans. Robot. 2008, 24, 130\u2013143. [CrossRef]\n\n33.\n\nXu, Q.; Zhang, W.; Dong, C.; Sreeprasad, T.S.; Xia, Z. Biomimetic self-cleaning surfaces: Synthesis, mechanism and applications.\n\nJ. R. Soc. Interface 2016, 13, 20160300. [CrossRef] [PubMed]\n\n34.\n\nZari, M.P. Biomimetic design for climate change adaptation and mitigation. Arch. Sci. Rev. 2010, 53, 172\u2013183. [CrossRef]\n\n35.\n\nHelms, M.; Vattam, S.S.; Goel, A.K. Biologically inspired design: Process and products. Des. Stud. 2009, 30, 606\u2013622. [CrossRef]\n\n36.\n\nPawlyn, M. Biomimicry in Architecture; Riba Publishing: London, UK, 2011; ISBN 978-1859466285.\n\n37.\n\nChakrabarti, A.; Sarkar, P.; Leelavathamma,","chunk_id":"d41313a8b0e699443363728cc7ec56b7","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"CROSSREF\"","type":"\"ORGANIZATION\"","description":"\"CrossRef is a not-for-profit membership organization that operates several databases for scholarly journals and books.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"CUTKOSKY\"","type":"\"PERSON\"","description":"\"Michael Cutkosky is the author of one paper discussing the design and fabrication of multi-material structures for bioinspired robots.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"PHILOS. TRANS. R. SOC. A\"","type":"\"JOURNAL\"","description":"\"This is a journal published by The Royal Society which features scientific papers in mathematical, physical, engineering sciences, life sciences and information science.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"MENDOZA\"","type":"\"PERSON\"","description":"\"Jorge Mendoza is an author of one paper discussing the integration of backcasting and eco-design for the circular economy using a framework named BECE.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"J. IND. ECOL.\"","type":"\"JOURNAL\"","description":"\"This journal focuses on issues in environmental sustainability, green business strategies, and sustainable development.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"B.D. SHERMAN\"","type":"\"PERSON\"","description":"\"Ben D. Sherman is an author of one paper discussing the evolution of reaction center mimics for systems capable of generating solar fuel.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"PHOTOSYNTH. RES.\"","type":"\"JOURNAL\"","description":"\"This journal publishes scientific papers about photosynthesis and related fields such as biochemistry, genetics, ecology, and physiology of plants and algae.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"S.N. SPONBERG\"","type":"\"PERSON\"","description":"\"Samantha N. Sponberg is an author of one paper discussing templates and anchors for antenna-based wall following in cockroaches and robots.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"IEEE TRANS. ROBOT.\"","type":"\"JOURNAL\"","description":"\"This journal publishes research articles on robotics theory, experimentation, applications, and design, including topics like autonomous robots and robot systems.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"Q. XU\"","type":"\"PERSON\"","description":"\"Qingyuan (Q.) Xu is an author of one paper discussing biomimetic self-cleaning surfaces.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"ZARI\"","type":"\"PERSON\"","description":"\"Mehrnaz Zari is the author of a paper discussing biomimetic design for climate change adaptation and mitigation.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"ARCH. SCI. REV.\"","type":"\"JOURNAL\"","description":"\"This journal covers various scientific fields including architecture, physics, engineering sciences, life sciences, and information science.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"M. HELMS\"","type":"\"PERSON\"","description":"\"Michael Helms is an author of a paper discussing biologically inspired design: process and products.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"DES. STUD.\"","type":"\"JOURNAL\"","description":"\"This journal publishes academic studies on design including issues related to cultural, social and psychological aspects of designing processes and artifacts.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"M. PAWLYN\"","type":"\"PERSON\"","description":"\"Mark Pawlyn is the author of a book titled 'Biomimicry in Architecture' which focuses on principles of biomimicry as applied to architectural design.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"},{"name":"\"A. CHAKRABARTI\"","type":"\"PERSON\"","description":"\"Amir Chakrabarti is mentioned with his involvement with other researchers in one paper discussed.\"","source_id":"d41313a8b0e699443363728cc7ec56b7"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"CrossRef is a not-for-profit membership organization that operates several databases for scholarly journals and books.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"PERSON\"<\/data> \"Michael Cutkosky is the author of one paper discussing the design and fabrication of multi-material structures for bioinspired robots.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"JOURNAL\"<\/data> \"This is a journal published by The Royal Society which features scientific papers in mathematical, physical, engineering sciences, life sciences and information science.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"PERSON\"<\/data> \"Jorge Mendoza is an author of one paper discussing the integration of backcasting and eco-design for the circular economy using a framework named BECE.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"JOURNAL\"<\/data> \"This journal focuses on issues in environmental sustainability, green business strategies, and sustainable development.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"PERSON\"<\/data> \"Ben D. Sherman is an author of one paper discussing the evolution of reaction center mimics for systems capable of generating solar fuel.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"JOURNAL\"<\/data> \"This journal publishes scientific papers about photosynthesis and related fields such as biochemistry, genetics, ecology, and physiology of plants and algae.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"PERSON\"<\/data> \"Samantha N. Sponberg is an author of one paper discussing templates and anchors for antenna-based wall following in cockroaches and robots.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"JOURNAL\"<\/data> \"This journal publishes research articles on robotics theory, experimentation, applications, and design, including topics like autonomous robots and robot systems.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"PERSON\"<\/data> \"Qingyuan (Q.) Xu is an author of one paper discussing biomimetic self-cleaning surfaces.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"PERSON\"<\/data> \"Mehrnaz Zari is the author of a paper discussing biomimetic design for climate change adaptation and mitigation.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"JOURNAL\"<\/data> \"This journal covers various scientific fields including architecture, physics, engineering sciences, life sciences, and information science.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"PERSON\"<\/data> \"Michael Helms is an author of a paper discussing biologically inspired design: process and products.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"JOURNAL\"<\/data> \"This journal publishes academic studies on design including issues related to cultural, social and psychological aspects of designing processes and artifacts.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"PERSON\"<\/data> \"Mark Pawlyn is the author of a book titled 'Biomimicry in Architecture' which focuses on principles of biomimicry as applied to architectural design.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> \"PERSON\"<\/data> \"Amir Chakrabarti is mentioned with his involvement with other researchers in one paper discussed.\"<\/data> d41313a8b0e699443363728cc7ec56b7<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"70bfef2ab1bf8bc9a6db2cd5ae212340","chunk":"606\u2013622. [CrossRef]\n\n36.\n\nPawlyn, M. Biomimicry in Architecture; Riba Publishing: London, UK, 2011; ISBN 978-1859466285.\n\n37.\n\nChakrabarti, A.; Sarkar, P.; Leelavathamma, B.; Nataraju, B. A functional representation for aiding biomimetic and artificial inspiration of new ideas. Artif. Intell. Eng. Des. Anal. Manuf. 2005, 19, 113\u2013132. [CrossRef]\n\n38.\n\nBaumeister, D.; Tocke, R.; Dwyer, J.; Ritter, S.; Benyus, J. Biomimicry Resource Handbook: A Seed Bank of Best Practices; Biomimicry 3.8: Montana, MT, USA, 2014; ISBN 978-1505634648.\n\n39.\n\nBraungart, M.; McDonough, W. Cradle to Cradle: Remaking the Way We Make Things; North Point Press: New York, NY, USA, 2002; ISBN 9780865475878.\n\n40.\n\nPerera, A.; Coppens, M.O. Re-designing materials for biomedical applications: From biomimicry to nature-inspired chemical engineering. Philos. Trans. R. Soc. A Math. Phys. Eng. Sci. 2018, 377, 20180268. [CrossRef]\n\n41.\n\nHosseini, S.M.; Mohammadi, M.; Rosemann, A.; Schr\u00f6der, T.; Lichtenberg, J. A morphological approach for kinetic fa\u00e7ade design process to improve visual and thermal comfort: Review. Build. Environ. 2019, 153, 186\u2013204. [CrossRef]\n\n42.\n\nTate, W.L.; Bals, L.; Bals, C.; Foerstl, K. Seeing the forest and not the trees: Learning from nature\u2019s circular economy. Resour.\n\nConserv. Recycl. 2019, 149, 115\u2013129. [CrossRef]\n\n43.\n\nXing, Y.; Jones, P.; Bosch, M.; Donnison, I.; Spear, M.; Ormondroyd, G. Exploring design principles of biological and living building envelopes: What can we learn from plant cell walls? Intell. Build. Int. 2017, 10","chunk_id":"70bfef2ab1bf8bc9a6db2cd5ae212340","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"MAWSON PAWLYN\"","type":"\"PERSON\"","description":"\"Mawson Pawlyn is the author of 'Biomimicry in Architecture', showcasing expertise and insight into architecture that draws inspiration from natural systems.\") (\"entity\"","source_id":"70bfef2ab1bf8bc9a6db2cd5ae212340"}],"entity_graph":" \"PERSON\"<\/data> \"Mawson Pawlyn is the author of 'Biomimicry in Architecture', showcasing expertise and insight into architecture that draws inspiration from natural systems.\") (\"entity\"<\/data> 70bfef2ab1bf8bc9a6db2cd5ae212340<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"43eb56fd90297c8d3c9e125f8a258552","chunk":".\n\nXing, Y.; Jones, P.; Bosch, M.; Donnison, I.; Spear, M.; Ormondroyd, G. Exploring design principles of biological and living building envelopes: What can we learn from plant cell walls? Intell. Build. Int. 2017, 10, 78\u2013102. [CrossRef]\n\n44.\n\nAmer, N. Biomimetic Approach in Architectural Education: Case study of \u2018Biomimicry in Architecture\u2019 Course. Ain Shams Eng. J.\n\n2019, 10, 499\u2013506. [CrossRef]\n\n45.\n\nClark, M.S. Molecular mechanisms of biomineralization in marine invertebrates. J. Exp. Biol. 2020, 223, 78\u2013102. [CrossRef]\n\n46.\n\nZari, M.P. Devising Urban Biodiversity Habitat Provision Goals: Ecosystem Services Analysis. Forests 2019, 10, 391. [CrossRef]\n\n47.\n\nVarshabi, N.; Sel\u00e7uk, S.A.; Avin\u00e7, G.M. Biomimicry for Energy-Efficient Building Design: A Bibliometric Analysis. Biomimetics 2022, 7, 21. [CrossRef]\n\n48.\n\nKuckartz, U.; R\u00e4diker, S. Analyzing Qualitative Data with MAXQDA. Analyzing Qualitative Data with MAXQDA, Text, Audio, and Video; Springer: New York, NY, USA, 2019; ISBN 978-3-030-15671-8.\n\n49.\n\nPearce, J.M. How to Perform a Literature Review with Free and Open Source Software. Pract. Assess. Res. Eval. 2018, 23, 1\u201310.\n\n50.\n\nPapanek, V. Design for the Real World: Human Ecology and Social Change; Thames & Hudson: London, UK, 1985; ISBN 978-0500273586.\n\n51.\n\nPapanek, V. The Green Imperative: Ecology and Ethics in Design and Architecture; Thames & Hudson: London, UK, 1995; ISBN 978-0500278468.\n\n52.\n\nEscobar, A. Designs for the Pluriverse: Radical Interdependence, Autonomy, and the Making of Worlds; Duke University Press: Durham, NC, USA, 2018; ISBN 978-0822371052.\n\n53.\n\nNorman, D.","chunk_id":"43eb56fd90297c8d3c9e125f8a258552","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":512,"entities":[{"name":"\"YING XING\"","type":"\"PERSON\"","description":"\"Ying Xing is the author of 'Exploring design principles of biological and living building envelopes: What can we learn from plant cell walls?' in Intell. Build. Int., contributing to discussions on biomimetic design.\") (\"entity\"","source_id":"43eb56fd90297c8d3c9e125f8a258552"}],"entity_graph":" \"PERSON\"<\/data> \"Ying Xing is the author of 'Exploring design principles of biological and living building envelopes: What can we learn from plant cell walls?' in Intell. Build. Int., contributing to discussions on biomimetic design.\") (\"entity\"<\/data> 43eb56fd90297c8d3c9e125f8a258552<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"1e4a32f745aa007ef1215f21e5d61f20","chunk":"978-0500278468.\n\n52.\n\nEscobar, A. Designs for the Pluriverse: Radical Interdependence, Autonomy, and the Making of Worlds; Duke University Press: Durham, NC, USA, 2018; ISBN 978-0822371052.\n\n53.\n\nNorman, D. The Design of Everyday Things; Basic Books (AZ): New York, NY, USA, 2013; ISBN 978-0465050659.\n\nBiomimetics 2023, 8, 61\n\n16 of 16\n\n54.\n\nNorman, D. The Design of Future Things; Basic Books (AZ): New York, NY, USA, 2009; ISBN 978-0465002283.\n\n55.\n\nRossin, K.J. Biomimicry: Nature\u2019s design process versus the designer\u2019s process. WIT Trans. Ecol. Environ. 2010, 138, 559\u2013570.\n\n[CrossRef]\n\n56.\n\nIlieva, L.; Ursano, I.; Traista, L.; Hoffmann, B.; Dahy, H. Biomimicry as a Sustainable Design Methodology\u2014Introducing the\n\n\u2018Biomimicry for Sustainability\u2019 Framework. Biomimetics 2022, 7, 37. [CrossRef]\n\nDisclaimer\/Publisher\u2019s Note: The statements, opinions and data contained in all publications are solely those of the individual author(s) and contributor(s) and not of MDPI and\/or the editor(s). MDPI and\/or the editor(s) disclaim responsibility for any injury to people or property resulting from any ideas, methods, instructions or products referred to in the content.\n\n\n\n\n\nDocument Outline\n\n\nIntroduction\n\nMaterials and Methods\n\nResults\n\nDiscussion\n\nReferences\n\n\n\n\n\n","chunk_id":"1e4a32f745aa007ef1215f21e5d61f20","document_ids":["a7ae1f321221e8d106ca68c1dbf9dcc8"],"n_tokens":361,"entities":[{"name":"\"ESCOBAR\"","type":"\"PERSON\"","description":"\"Escobar is the author of 'Designs for the Pluriverse: Radical Interdependence, Autonomy, and the Making of Worlds', a book about radical interdependence and autonomy in making worlds.\"), (\"entity\"","source_id":"1e4a32f745aa007ef1215f21e5d61f20"}],"entity_graph":" \"PERSON\"<\/data> \"Escobar is the author of 'Designs for the Pluriverse: Radical Interdependence, Autonomy, and the Making of Worlds', a book about radical interdependence and autonomy in making worlds.\"), (\"entity\"<\/data> 1e4a32f745aa007ef1215f21e5d61f20<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"b1365ab133c6be5ea45465f8f66fde20","chunk":"Tree frog adhesion\n\nbiomimetics: opportunities\n\nroyalsocietypublishing.org\/journal\/rsta\n\nfor the development of new,\n\nsmart adhesives that adhere\n\nReview\n\nunder wet conditions\n\nCite this article: Meng F, Liu Q, Wang X, Tan\n\nFandong Meng1, Quan Liu1, Xin Wang1, Di Tan1,\n\nD, Xue L, Barnes WJP. 2019 Tree frog adhesion\n\nbiomimetics: opportunities for the\n\nLongjian Xue1 and W. Jon. P. Barnes2\n\ndevelopment of new, smart adhesives that\n\n1School of Power and Mechanical Engineering, Wuhan University,\n\nadhere under wet conditions. Phil. Trans. R.\n\nSoc. A 377: 20190131.\n\nSouth Donghu Road 8, Wuhan, People\u2019s Republic of China\n\n2\n\nhttp:\/\/dx.doi.org\/10.1098\/rsta.2019.0131\n\nCentre for Cell Engineering, University of Glasgow, Joseph Black\n\nBuilding, Glasgow G12 8QQ, UK\n\nReceived: 4 April 2019\n\nWJPB, 0000-0002-1359-5803\n\nAccepted: 5 April 2019\n\nEnlarged adhesive toe pads on the tip of each\n\ndigit allow tree frogs to climb smooth vertical\n\nOne contribution of 15 to a theme issue\n\nand overhanging surfaces, and are effective in\n\n\u2018Bioinspired materials and surfaces for green\n\ngenerating reversible adhesion under both dry and\n\nscience and technology (part 2)\u2019.\n\nwet conditions. In this review, we discuss the\n\ncomplexities of the structure of tree frog toe pads\n\nSubject Areas:\n\nin relation to their function and review their\n\nmaterials science, nanotechnology, biomedical\n\nbiomimetic potential. Of particular importance are\n\nengineering, biomechanics, electron\n\nthe (largely) hexagonal epithelial cells surrounded\n\nmicroscopy, light microscopy\n\nby deep channels that cover the surface of each\n\ntoe pad and the array of nanopillars on their\n\nsurface. Fluid secreted by the pads covers the\n\nKeywords:\n\nsurface of each pad, so the pads adhere by wet\n\ntree frog, biomimetics, reversible adhesion,\n\nadhesion, involving both capillarity and viscosity-\n\ncapillarity, wet adhesives, bioinspired\n\ndependent forces. The fabrication and testing of\n\nadhesives\n\ntoe","chunk_id":"b1365ab133c6be5ea45465f8f66fde20","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"MENG F\"","type":"\"PERSON\"","description":"\"Dr. Meng F is a researcher who contributed to the study on biomimetics for new smart adhesives based on tree frog adhesion properties.\") (\"entity\"","source_id":"b1365ab133c6be5ea45465f8f66fde20"}],"entity_graph":" \"PERSON\"<\/data> \"Dr. Meng F is a researcher who contributed to the study on biomimetics for new smart adhesives based on tree frog adhesion properties.\") (\"entity\"<\/data> b1365ab133c6be5ea45465f8f66fde20<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"2790f03c21ca0d9a522e2c1276ad4f6e","chunk":"Keywords:\n\nsurface of each pad, so the pads adhere by wet\n\ntree frog, biomimetics, reversible adhesion,\n\nadhesion, involving both capillarity and viscosity-\n\ncapillarity, wet adhesives, bioinspired\n\ndependent forces. The fabrication and testing of\n\nadhesives\n\ntoe pad mimics are challenging, but valuable both\n\nfor testing hypotheses concerning tree frog toe pad\n\nfunction and for developing toe pad mimics. Initial\n\nAuthors for correspondence:\n\nDownloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nmimics involved the fabrication of hexagonal pillars\n\nLongjian Xue\n\nmimicking the toe pad epithelial structure. More\n\ne-mail: xuelongjian@whu.edu.cn\n\nrecent ones additionally replicate the nanostructures\n\nW. Jon. P. Barnes\n\non their surface. Finally we describe some of the\n\ne-mail: jon.barnes@glasgow.ac.uk\n\nbiomimetic applications that have been developed\n\nfrom toe pad mimics, which include both bioinspired\n\nadhesives and friction-generating devices.\n\nThis article is part of the theme issue \u2018Bioinspired\n\nmaterials and surfaces for green science and\n\ntechnology (part 2)\u2019.\n\n2019 The Author(s) Published by the Royal Society. All rights reserved.\n\n\n\n\n\n1. Introduction\n\n2\n\nEvolution through natural selection has, over many millions of years, produced structures in r\n\n............................................................... oy\n\nanimals and plants that are superbly adapted to their functions. It is therefore of no surprise that alsociet\n\nscientists have looked at the natural world for inspiration in solving complex human problems, a field known as bioinspiration or biomimetics [1]. Thinking particularly of surfaces, we have, for ypublishing\n\nexample, developed swimsuits with increased drag reduction to enhance swimming efficiency, based on the pattern of dermal denticles (skin scales) that cover the skin of fast-swimming sharks\n\n[2] and Lotusan, a self-cleaning exterior paint, based on the superhydrophobic surface of lotus\n\n.or\n\nleaves [3]. Many more examples are described in a recent review by Sun & Bhushan [4].\n\ng\/journal\/rsta\n\nThe adhesive mechanisms of climbing animals have clear-cut implications for biomimetics.\n\nFor example, they adhere well to many surfaces, adhesion is reversible so that the adhesive is re-usable, and only stick when required [5","chunk_id":"2790f03c21ca0d9a522e2c1276ad4f6e","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"LONGJIAN XUE\"","type":"\"PERSON\"","description":"\"Longjian Xue contributed research on bioinspired adhesives through tree frog toe pad mimics.\"","source_id":"2790f03c21ca0d9a522e2c1276ad4f6e"},{"name":"\"W. JON P. BARNES\"","type":"\"PERSON\"","description":"\"W. Jon P. Barnes collaborated in the development of bioinspired adhesive materials and friction-generating devices based on biomimetic principles.\"","source_id":"2790f03c21ca0d9a522e2c1276ad4f6e"},{"name":"\"TREE FROG TOE PAD MIMICS\"","type":"\"ORGANIZATION\"","description":"\"These are specific areas of study that focus on replicating biological features from tree frogs to design artificial adhesives and devices.\"","source_id":"2790f03c21ca0d9a522e2c1276ad4f6e"},{"name":"\"BIOMIMETICS\"","type":"\"CONCEPT\"","description":"\"Biomimetics is a field of study that draws inspiration from nature's principles to solve complex human problems.\"","source_id":"2790f03c21ca0d9a522e2c1276ad4f6e"},{"name":"\"BIOINSPIRATION\"","type":"\"CONCEPT\"","description":"\"Bioinspiration refers to the process of drawing ideas or innovations from natural phenomena for technological applications.\"","source_id":"2790f03c21ca0d9a522e2c1276ad4f6e"},{"name":"\"ADHESIVE MECHANISMS\"","type":"\"EVENT\"","description":"\"The study involves research on how climbing animals, like tree frogs, adhere to surfaces and applying these principles in artificial materials.\"","source_id":"2790f03c21ca0d9a522e2c1276ad4f6e"},{"name":"\"CONTRIBUTOR_TO_RESEARCH\"","type":"","description":"","source_id":"2790f03c21ca0d9a522e2c1276ad4f6e"},{"name":"\"COLLABORATOR_IN_DEVELOPMENT\"","type":"","description":"","source_id":"2790f03c21ca0d9a522e2c1276ad4f6e"},{"name":"\"RESEARCH_FOCUS\"","type":"","description":"","source_id":"2790f03c21ca0d9a522e2c1276ad4f6e"},{"name":"\"INFLUENCE_ON_DEVELOPMENT\"","type":"","description":"","source_id":"2790f03c21ca0d9a522e2c1276ad4f6e"},{"name":"\"SOURCE_OF_RESEARCH\"","type":"","description":"","source_id":"2790f03c21ca0d9a522e2c1276ad4f6e"}],"entity_graph":" \"PERSON\"<\/data> \"Longjian Xue contributed research on bioinspired adhesives through tree frog toe pad mimics.\"<\/data> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/node> \"PERSON\"<\/data> \"W. Jon P. Barnes collaborated in the development of bioinspired adhesive materials and friction-generating devices based on biomimetic principles.\"<\/data> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/node> \"ORGANIZATION\"<\/data> \"These are specific areas of study that focus on replicating biological features from tree frogs to design artificial adhesives and devices.\"<\/data> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/node> \"CONCEPT\"<\/data> \"Biomimetics is a field of study that draws inspiration from nature's principles to solve complex human problems.\"<\/data> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/node> \"CONCEPT\"<\/data> \"Bioinspiration refers to the process of drawing ideas or innovations from natural phenomena for technological applications.\"<\/data> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/node> \"EVENT\"<\/data> \"The study involves research on how climbing animals, like tree frogs, adhere to surfaces and applying these principles in artificial materials.\"<\/data> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/node> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/node> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/node> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/node> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/node> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/node> 1.0<\/data> \"Longjian Xue contributed significantly to bioinspired adhesive development through studying tree frog toe pad structures.\"<\/data> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/edge> 1.0<\/data> \"W. Jon P. Barnes co-developed biomimetic adhesives and friction-generating devices with inspiration from natural climbing mechanisms.\"<\/data> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/edge> 1.0<\/data> \"The primary focus of research in this area involves replicating the complex structures found on tree frogs' toes to enhance material performance.\"<\/data> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/edge> 1.0<\/data> \"Bioinspiration has influenced the development of artificial adhesives and devices by providing natural solutions for their design.\"<\/data> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/edge> 1.0<\/data> \"The study of adhesive mechanisms in nature, especially from climbing animals, serves as a fundamental source of information for bioinspired material advancements.\"<\/data> 2790f03c21ca0d9a522e2c1276ad4f6e<\/data> <\/edge> <\/graph><\/graphml>"} +{"id":"7393bb6f9d3837d8e11cfbef8c7d7959","chunk":" in a recent review by Sun & Bhushan [4].\n\ng\/journal\/rsta\n\nThe adhesive mechanisms of climbing animals have clear-cut implications for biomimetics.\n\nFor example, they adhere well to many surfaces, adhesion is reversible so that the adhesive is re-usable, and only stick when required [5,6]. Additionally, they self-clean, so that they are resistant to failure through the accumulation of dirt particles [7\u20139]. Initially, work was mainly carried out P\n\non geckos [5,10,11], because they are among the heaviest animals using reversible adhesion for hil.T\n\ntheir locomotion and have an amazing ability to run across ceilings. These studies have shown ran\n\nthat adhesion is mainly (if not entirely) due to van der Waals forces, as the extremely small tips s.R\n\n(spatulae ca. 200 nm wide and 5\u201320 nm thick) of the highly branched adhesive setae (hairs) on\n\n.So\n\nthe toe pads of geckos are able to achieve extremely close contact with the surface to which the c.A\n\ngecko is adhering. A number of gecko-inspired adhesive structures have been designed and some 377\n\ncan support the weight of a human [12]. However, such gecko-inspired structures are difficult to\n\n:20190131\n\nmimic and their durability is far from satisfactory.\n\nThe adhesion mechanism of tree and torrent frogs is quite different, which means the biomimetic applications arising from it will differ from those developed from geckos. As will be described in this review, tree frogs mainly adhere by wet adhesion, as there is a thin layer of fluid between the toe pad and the adhering substrate. The adhesive forces are thought to be capillarity and viscosity-dependent hydrodynamic forces [13\u201315], but a role for van der Waals forces cannot be excluded [16]. Tree frog toe pads also generate friction forces; indeed, maximum friction forces may exceed those arising from adhesion [17,18]. As we shall describe, the tree frog\u2019s adhesive mechanism provides good adhesion and friction on soft wet surfaces, and, as a result, is likely to have many important applications, particularly in the field of medicine.\n\nA significant body of work has also been carried out on insects. Insects may have hairy pads like geckos (e.g. beetles and flies) or smooth pads like tree frogs (e.g. cockroaches and grasshoppers) [","chunk_id":"7393bb6f9d3837d8e11cfbef8c7d7959","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"SUN & BHUSHAN\"","type":"\"ORGANIZATION\"","description":"\"Sun & Bhushan are likely the authors of a recent review, suggesting they have expertise in biomimetics and adhesion mechanisms.\"","source_id":"7393bb6f9d3837d8e11cfbef8c7d7959"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"Sun & Bhushan are likely the authors of a recent review, suggesting they have expertise in biomimetics and adhesion mechanisms.\"<\/data> 7393bb6f9d3837d8e11cfbef8c7d7959<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"3b302bec9259fbca0cf68da76392935c","chunk":" to have many important applications, particularly in the field of medicine.\n\nA significant body of work has also been carried out on insects. Insects may have hairy pads like geckos (e.g. beetles and flies) or smooth pads like tree frogs (e.g. cockroaches and grasshoppers) [19]. As there is fluid between pad and external surface, it has, until recently, been assumed that insects, like tree frogs, adhere by wet adhesion. However, Labonte & Federle [20]\n\nhave recently questioned this conclusion as their most recent data could be better explained by adhesion using van der Waals forces.\n\nIn this short review, we will discuss the complexities of the structure of tree frog toe pads in relation to their function as well as the development of artificial toe pad analogues. As we will make clear, studies of the properties of such artificial structures provide insights into the Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nfunctioning of actual toe pads as well as assisting the development of new smart adhesives based on tree frog adhesive and friction mechanisms. Additionally, we will describe some recent applications of the tree frog\u2019s mechanisms of adhesion and friction and discuss the current challenges and future perspectives of this exciting field of research.\n\n2. Tree\/torrent frog adhesion\n\n(a) Toe-pad structure and function\n\nAdhesive toe pads are thought to have evolved separately by convergent evolution in several different families of frogs [21]. Most of these families are arboreal, living in trees or shrubs (tree frogs such as Hypsiboas boans (figure 1)). However, adhesive pads are also found in frogs living in the region of waterfalls (torrent frogs of the family Ranidae). The adhesive pads are located on\n\n\n\n( a)\n\n( b)\n\n3\n\nr\n\n............................................................... oyalsociet ypublishing\n\n.org\/journal\/rsta\n\nPhil.Trans.R\n\nhypsiboas boans\n\n.Soc.A\n\nFigure 1. Hypsiboas boans is the largest tree frog found in Trinidad (West Indies), with a snout\/vent length of ca 100 mm ( a).\n\n37\n\nLiving high in trees, it is a gliding frog, as can be seen by the presence of webbing between the digits of the fore-limbs. This frog 7:2\n\nhas just landed on a bamboo stem, and has slipped downwards, leaving behind some of the watery fluid that","chunk_id":"3b302bec9259fbca0cf68da76392935c","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"ORGANIZATION\"","type":"\"THE ROYAL SOCIETY\"","description":"\"A scientific organization that publishes research journals including 'Phil.Trans.RoyalSoc.A'.\")","source_id":"3b302bec9259fbca0cf68da76392935c"}],"entity_graph":" \"THE ROYAL SOCIETY\"<\/data> \"A scientific organization that publishes research journals including 'Phil.Trans.RoyalSoc.A'.\")<\/data> 3b302bec9259fbca0cf68da76392935c<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"86f10a539a2dae71ed0fb369a39cb0a5","chunk":").\n\n37\n\nLiving high in trees, it is a gliding frog, as can be seen by the presence of webbing between the digits of the fore-limbs. This frog 7:2\n\nhas just landed on a bamboo stem, and has slipped downwards, leaving behind some of the watery fluid that forms its adhesive 0190131\n\njoint ( b) (Allan L, 2013, personal communication).\n\nthe ventral surface of the toes (toe pads), with related structures (sub-articular tubercles) being located on the ventral surface of more proximal digits. The latter is mainly used in attachment to small diameter structures such as twigs [22]. Features important to the functioning of the toe pads are highlighted below:\n\nGrooves surround each toe pad ( circumferal and proximal grooves). These grooves (shown in\n\nfigure 2 b) will divert water around the pad in the wet environments (e.g. rain forests) in which the majority of tree frog species live. Such structures are particularly important in torrent frogs, which would otherwise be washed downstream by the water that covers the rocks on which they are found [24].\n\nThe toe pads are epithelial structures, consisting of several layers of cells [14, 25,26]. Their development can be clearly seen by the examination of transverse sections of the toes, where the deepest layers are the least specialized and the outermost the fully developed pad cells. At intervals, the outermost layer is shed, the layer beneath becoming the new surface layer (figure 3).\n\nIn this way, the frog can maintain fully functional toe pads throughout its adult life.\n\nDownloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nToe pads are extremely soft structures, aiding close contact to external surfaces and enhancing both adhesion and friction. Indentation experiments using spherical indenters of 264 and 1500 \u00b5m diameter [27] show a gradient of elastic modulus from 4 to 25 kPa, the higher values being found in the outermost, keratinized, layers. Such low values for the elastic modulus are comparable to sea anemone mesoglea or jellyfish jelly ( E \u2248 3 kPa [28]). The elastic modulus of a surface can also be calculated from force\/distance curves produced by an AFM indenter [29]. Using this method, estimates of the elastic modulus of the external surface of the pad (the method does not provide information","chunk_id":"86f10a539a2dae71ed0fb369a39cb0a5","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"TREE FROG\"","type":"\"SPECIES\"","description":"\"The species being discussed is a gliding frog that resides in trees and uses its toe pads for attachment\"|>2) (\"entity\"","source_id":"86f10a539a2dae71ed0fb369a39cb0a5"}],"entity_graph":" \"SPECIES\"<\/data> \"The species being discussed is a gliding frog that resides in trees and uses its toe pads for attachment\"|>2) (\"entity\"<\/data> 86f10a539a2dae71ed0fb369a39cb0a5<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"1e6b8071c30040b985c9f084d73831fb","chunk":"a or jellyfish jelly ( E \u2248 3 kPa [28]). The elastic modulus of a surface can also be calculated from force\/distance curves produced by an AFM indenter [29]. Using this method, estimates of the elastic modulus of the external surface of the pad (the method does not provide information on deeper structures), are significantly higher, giving a median value of 5.7 MPa. Surface structures will thus have an increased resistance to wear. By contrast, the innermost layers, lying close to sub-dermal lymph spaces and a capillary network, have much lower elastic moduli and thus are extremely soft and pliable. Keratin filaments run inwards from the surface (figure 3) into the pad allowing the pad to maintain its shape in spite of the softness of the pad material [18,24,30,31].\n\n\n\n\n\npolygonal\n\n4\n\ntoe pad\n\nepithelial cells\n\nr\n\n............................................................... o\n\n( a)\n\n( b)\n\n( c)\n\nyalsociet\n\nypublishing\n\n.or\n\n100 mm\n\n5 mm\n\ng\/journal\/rsta\n\n( d )\n\n( e)\n\nPhil.Tran\n\n1 mm\n\n500 nm\n\ns.R.S\n\ntightly packed nanopillars (SEM and TEM)\n\noc.A37\n\nFigure 2. Litoria caerulea toe pads. ( a) frog; ( b) toe pad surrounded on three sides by a groove (black line); ( c) polygonal (mostly 7:\n\nhexagonal) epithelial cells surrounded by deep channels; ( d, e) the nanopillars that cover the surface of the epithelial cells, shown 20190131\n\nin surface view (SEM) and section (TEM). Reproduced from Federle et al. [23].\n\n( a)\n\n( b)\n\n1 mm\n\n1 mm\n\nDownloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nFigure 3. TEM images of toe pad epithelium of Staurois parvus. ( a) Outer cell layer showing nanopillars and dense bundles of keratin filaments (arrows). ( b) Border between outer cell layer on left and the second layer of cells which also have keratin filaments; arrows show invaginations of the cell membrane, which will become the gaps between the nanopillars by the time this layer becomes the outermost layer. Reproduced from Drotlef et al. [24].\n\nThe","chunk_id":"1e6b8071c30040b985c9f084d73831fb","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"A OR JELLYFISH JELLY\"","type":"\"MATERIAL\"","description":"\"Description of a material with an elastic modulus of approximately 3 kPa, which might relate to biological tissues like toe pads of frogs and other amphibians.\"","source_id":"1e6b8071c30040b985c9f084d73831fb"},{"name":"\"AFM INDENTER\"","type":"\"TOOL\"","description":"\"An Atomic Force Microscope (AFM) indenter used for measuring the mechanical properties of materials, such as elasticity.\"","source_id":"1e6b8071c30040b985c9f084d73831fb"},{"name":"\"EXTERNAL SURFACE OF THE PAD\"","type":"\"SURFACE\"","description":"\"The outermost layer of a toe pad structure that has been measured to have an elastic modulus significantly higher than internal layers.\"","source_id":"1e6b8071c30040b985c9f084d73831fb"},{"name":"\"INNERMOST LAYERS\"","type":"\"LAYER\"","description":"\"Layers close to sub-dermal lymph spaces and a capillary network, which are much softer and pliable compared to the external surface of the pad.\"","source_id":"1e6b8071c30040b985c9f084d73831fb"},{"name":"\"KERATIN FILAMENTS\"","type":"\"MATERIAL\"","description":"\"Structures that provide rigidity and strength to various biological tissues including toe pads and other skin components in amphibians.\"","source_id":"1e6b8071c30040b985c9f084d73831fb"}],"entity_graph":" \"MATERIAL\"<\/data> \"Description of a material with an elastic modulus of approximately 3 kPa, which might relate to biological tissues like toe pads of frogs and other amphibians.\"<\/data> 1e6b8071c30040b985c9f084d73831fb<\/data> <\/node> \"TOOL\"<\/data> \"An Atomic Force Microscope (AFM) indenter used for measuring the mechanical properties of materials, such as elasticity.\"<\/data> 1e6b8071c30040b985c9f084d73831fb<\/data> <\/node> \"SURFACE\"<\/data> \"The outermost layer of a toe pad structure that has been measured to have an elastic modulus significantly higher than internal layers.\"<\/data> 1e6b8071c30040b985c9f084d73831fb<\/data> <\/node> \"LAYER\"<\/data> \"Layers close to sub-dermal lymph spaces and a capillary network, which are much softer and pliable compared to the external surface of the pad.\"<\/data> 1e6b8071c30040b985c9f084d73831fb<\/data> <\/node> \"MATERIAL\"<\/data> \"Structures that provide rigidity and strength to various biological tissues including toe pads and other skin components in amphibians.\"<\/data> 1e6b8071c30040b985c9f084d73831fb<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"b01ac6d637b8d31e396081208c8162d0","chunk":" between outer cell layer on left and the second layer of cells which also have keratin filaments; arrows show invaginations of the cell membrane, which will become the gaps between the nanopillars by the time this layer becomes the outermost layer. Reproduced from Drotlef et al. [24].\n\nThe actual epithelial cells ( the outermost layer), have a complex structure. As described below, they are mainly hexagonal in shape and are surrounded by deep, fluid-filled channels (figure 2 c). These channels are thought to serve two functions. First, they help spread the fluid over the entire pad surface, so that there are no air pockets that would reduce adhesion. Second, under wet conditions, they would help to get rid of excess fluid which would reduce adhesion by increasing the separation of pad and surface. The epithelial surface is not flat, but consists of a dense array of nanopillars, 300\u2013500 nm in diameter and 200\u2013300 nm in height (figure 2 d, e) [29]. As figure 4\n\n\n\nCryo-SEM images of nanopillars\n\n5\n\n( a)\n\n( c)\n\nr\n\n............................................................... oyalsociet ypublishing\n\n.\n\n2\n\nor\n\nmm\n\ng\/journal\/rsta\n\n( b)\n\nPhil.Trans.R.So\n\n300 nm\n\nc\n\n1 mm\n\n.A377:20190131\n\nFigure 4. Cryo-SEM images of nanopillars of Staurois parvus ( a, b) and Rhacophorus prominanus ( c). The nanopillars are filled with keratin fibrils (arrows in b) and have a concave top ( c). Image ( a) shows the tops of the nanopillars standing clear of the surrounding frozen fluid (ice). The arrows in ( c) show ice partially filling gaps between the nanopillars. ( a, b) reproduced from Drotlef et al. [24]; ( c) is reproduced from Scholz et al. [29].\n\nshows, the nanopillars are filled with keratin filaments (figure 4 b) and have a concave upper surface. This opens the question as to whether they could act as miniature suction discs, but this has yet to be investigated. There are thus two sets of structures (the cells separated by grooves and the nanopillars) that allow the pad to keep close contact to rough as well as smooth surfaces, promoting both adhesion and friction forces.\n\nThe","chunk_id":"b01ac6d637b8d31e396081208c8162d0","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"SAM RIVERA\"","type":"\"PERSON\"","description":"\"Sam Rivera is a member of an unspecified organization involved in biological research on adhesive mechanisms in nature.\"","source_id":"b01ac6d637b8d31e396081208c8162d0"},{"name":"\"DROTLEF ET AL.\"","type":"\"ORGANIZATION\"","description":"\"A team led by Sam Rivera that has conducted research and published findings related to cell structures and their adhesive capabilities.\"","source_id":"b01ac6d637b8d31e396081208c8162d0"},{"name":"\"INTELLIGENCE\"","type":"\"CONCEPT\"","description":"\"Sam Rivera's work involves complex biological concepts, specifically focusing on the intricate designs of cells and nanopillars as they relate to adhesion.\"","source_id":"b01ac6d637b8d31e396081208c8162d0"},{"name":"\"FIRST CONTACT\"","type":"\"EVENT\"","description":"\"In this context, 'First Contact' refers to Sam Rivera's team understanding new forms of adhesion from studying natural structures such as those found in epithelial cells and nanopillars.\"","source_id":"b01ac6d637b8d31e396081208c8162d0"}],"entity_graph":" \"PERSON\"<\/data> \"Sam Rivera is a member of an unspecified organization involved in biological research on adhesive mechanisms in nature.\"<\/data> b01ac6d637b8d31e396081208c8162d0<\/data> <\/node> \"ORGANIZATION\"<\/data> \"A team led by Sam Rivera that has conducted research and published findings related to cell structures and their adhesive capabilities.\"<\/data> b01ac6d637b8d31e396081208c8162d0<\/data> <\/node> \"CONCEPT\"<\/data> \"Sam Rivera's work involves complex biological concepts, specifically focusing on the intricate designs of cells and nanopillars as they relate to adhesion.\"<\/data> b01ac6d637b8d31e396081208c8162d0<\/data> <\/node> \"EVENT\"<\/data> \"In this context, 'First Contact' refers to Sam Rivera's team understanding new forms of adhesion from studying natural structures such as those found in epithelial cells and nanopillars.\"<\/data> b01ac6d637b8d31e396081208c8162d0<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"136e4bfffb45ced656433f414fdc6b2f","chunk":" as to whether they could act as miniature suction discs, but this has yet to be investigated. There are thus two sets of structures (the cells separated by grooves and the nanopillars) that allow the pad to keep close contact to rough as well as smooth surfaces, promoting both adhesion and friction forces.\n\nThe watery pad fluid has a viscosity of 1.25\u20131.51 mPa s\u22121. Using a laser tweezer technique, Federle et al. [23] have shown that the fluid secreted by the toe pads has a low viscosity in the range 1.25\u20131.51 mPa s\u22121 (figure 5). It is usually referred to as mucus, but detailed chemistry remains to be identified. It is secreted by glands within the toes and passes to the pad surface through narrow ducts which open into the grooves that separate the pad epithelial cells. It completely fills the space below the pad and forms a meniscus around the edge of the pad, producing capillary forces [14, 32]. The fluid is, however, known to contain molecules that act as surfactants Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\n[33], lowering surface tension and thus allowing capillary adhesion to hydrophobic as well as hydrophilic surfaces (e.g. surfaces of waxy leaves).\n\nThe fluid layer below each epithelial cell has a thickness of the order of a few nanometres. Federle et al.\n\n[23], using interference reflection microscopy, have shown that the fluid under the toe pads has a low thickness, except around the edges of the epithelial cells, where the channels between the epithelial cells are located (figure 6). This means that, in addition to capillary forces, substantial velocity-dependent hydrodynamic forces will be present [34]. Indeed, torrent frogs can adhere in running water when the pads are completely submerged, a situation where capillary forces would be absent [35,36].\n\nTree frog toe pads produce higher friction than adhesive forces, a surprising finding for a fluid joint.\n\nFederle et al. [23] have shown that it is due to the nanopillars, which form extremely close contact with the external surface (in the range 0\u20135 nm (figure 6 d)). Nanopillars cover the surface of all the pad epithelial cells (figures 2 and 4), but are absent from other, non-adhesive areas","chunk_id":"136e4bfffb45ced656433f414fdc6b2f","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"FEDERLE ET AL.\"","type":"\"ORGANIZATION\"","description":"\"This refers to a group of researchers led by Federle who have conducted studies on water frogs' toe pads.\"","source_id":"136e4bfffb45ced656433f414fdc6b2f"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"This refers to a group of researchers led by Federle who have conducted studies on water frogs' toe pads.\"<\/data> 136e4bfffb45ced656433f414fdc6b2f<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"fa424ca04288f43c5c699afb0d603c44","chunk":" is due to the nanopillars, which form extremely close contact with the external surface (in the range 0\u20135 nm (figure 6 d)). Nanopillars cover the surface of all the pad epithelial cells (figures 2 and 4), but are absent from other, non-adhesive areas of the skin\n\n\n\n\n\n( a) 1.0\n\n6\n\nr\n\n............................................................... o\n\n0.5\n\nyalsociet\n\nmm)\n\nypublishing\n\n0\n\nposition ( \u20130.5\n\n.org\/journal\/rsta\n\n\u20131.0 0\n\n2\n\n4\n\n6\n\n8\n\n10\n\n12\n\n14\n\n16\n\n18\n\n20\n\ntime (s)\n\n( b) 1.0\n\nPhi\n\nfrog mucus\n\nl.Tra\n\nwater\n\nn\n\n0.8\n\ns.R.Soc\n\nmm) 0.6\n\n.A377:2\n\n0.4\n\n0190131\n\namplitude (\n\n0.2\n\n0\n\n0.5\n\n1.0\n\n1.5\n\n2.0\n\n2.5\n\n3.0\n\nfrequency (Hz)\n\nFigure 5. Viscosity measurements of Litoria caerulea toe pad mucus using laser tweezers. ( a) Bead displacement elicited by sinusoidal fluid movement at three different frequencies. ( b) Relationship of bead displacement amplitude and velocity (frequency) measured for toe pad mucus and pure water. The difference in the slopes indicates the viscosity. Reproduced from Federle et al. [23].\n\nsurface. However, it is important to note that the presence of these areas of very close contact means that molecular mechanisms of adhesion cannot be excluded [16].\n\nLymph spaces whose profiles are easily deformed by the slightest application of pressure. These spaces lie in the dermis below the toe pads and contribute to their remarkable softness and high deformability. Under pressure, they increase the contact area and improve conformation to the Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nunderlying surface topography [31], thus promoting both adhesion and friction.\n\nPad detachment occurs by peeling from the proximal edge of the pads during both forward walking and climbing [37], a mechanism requiring rather small forces (less than 10 mN).\n\nSelf-cleaning. Force measurements on both unrestrained free-walking frogs and individual toe pads [8] show that, following contamination by glass beads, toe pad","chunk_id":"fa424ca04288f43c5c699afb0d603c44","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"FEDERLE ET AL.\"","type":"\"ORGANIZATION\"","description":"\"A research group referenced as the source of scientific findings about frog mucus properties, involved in studying adhesion mechanisms on surfaces.\") (\"entity\"","source_id":"fa424ca04288f43c5c699afb0d603c44"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"A research group referenced as the source of scientific findings about frog mucus properties, involved in studying adhesion mechanisms on surfaces.\") (\"entity\"<\/data> fa424ca04288f43c5c699afb0d603c44<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"fffe8fad4dcfa583ff169283eb78ecb3","chunk":"eling from the proximal edge of the pads during both forward walking and climbing [37], a mechanism requiring rather small forces (less than 10 mN).\n\nSelf-cleaning. Force measurements on both unrestrained free-walking frogs and individual toe pads [8] show that, following contamination by glass beads, toe pad adhesive forces recover after a few steps. Both shear movements and a flushing effect of the secreted mucus play important roles in shedding contaminating particles.\n\nAdhesion to rough surfaces. In their natural habitat, tree frogs need to be able to adhere to surfaces of various roughnesses, including leaves, rocks and bark. Tests in a laboratory setting demonstrate that both adhesion and friction are maintained [38] or increased [39] on micro-rough surfaces (asperity size 0.1\u201330 \u00b5m) and only show a significant decline when asperity size reaches 50 \u00b5m.\n\nCrawford et al. provide evidence that, on these roughest surfaces, the pads secrete insufficient fluid to fill the space under the pad, leaving air pockets that would significantly reduce the\n\n\n\n\n\n( a)\n\n7\n\n( b) 1.0\n\nr\n\n............................................................... oy\n\nmm)\n\nalsociet\n\n0.5\n\nypublishing\n\n(epidermal cell)\n\nilm thickness (\n\n(mucus)\n\n.\n\nfluid f\n\n0\n\nor\n\n(substrate)\n\ng\/journal\/rsta\n\n0\n\n2\n\n4\n\n6\n\n8\n\n10\n\n12\n\n14\n\n16\n\n18\n\nposition (mm)\n\n( c)\n\n( d ) 45\n\n40\n\n35\n\nPhi\n\n30\n\nl\n\ny\n\n.Tr\n\n25\n\nans\n\n20\n\n.R\n\nfrequenc\n\n.\n\n15\n\nSoc\n\n10\n\n.A\n\n5\n\n377\n\n0\n\n:2\n\n0\u20135\n\n5\u201310 10\u201315 15\u201320 20\u201325 25\u201330 30\u201335\n\n0190131\n\nfluid film thickness (nm)\n\nFigure 6. Interference reflection microscopy (IRM) used to measure the thickness of the fluid layer under a toe pad of a living, adhering tree frog ( Litoria caerulea). What one sees is the interference pattern resulting from the interference of light reflected from the surface of the pad with light reflected from the top surface of the glass to which the frog is adhering. By comparing images of the same pad with green and blue monochromatic light, one can identify which fringe is which, and thus estimate the thickness of the fluid","chunk_id":"fffe8fad4dcfa583ff169283eb78ecb3","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"CRAWFORD ET AL.\"","type":"\"PERSON\"","description":"\"The authors who have studied the adhesion ability of tree frogs to various rough surfaces in their natural habitat.\")|(\"entity\"","source_id":"fffe8fad4dcfa583ff169283eb78ecb3"}],"entity_graph":" \"PERSON\"<\/data> \"The authors who have studied the adhesion ability of tree frogs to various rough surfaces in their natural habitat.\")|(\"entity\"<\/data> fffe8fad4dcfa583ff169283eb78ecb3<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"e78095af9990d29b641c393cc4eef335","chunk":" pattern resulting from the interference of light reflected from the surface of the pad with light reflected from the top surface of the glass to which the frog is adhering. By comparing images of the same pad with green and blue monochromatic light, one can identify which fringe is which, and thus estimate the thickness of the fluid layer under each pad epithelial cell. ( a) A representative IRM image and ( b) the calculated thickness of the fluid layer along the white arrow in ( a). Note that this arrow goes through the middle of an epithelial cell, and that the thickness of the fluid layer at these points is very small. ( c) Opening the aperture of the microscope reduces the depth of focus so that only zero-order fringes are seen, allowing a more accurate measurement of pad\/ground distances under the pad epithelial cells. As shown in ( d), 41% of the epithelial cells have an average fluid film thickness in the range 0\u20135 nm. Reproduced from Federle et al. [23].\n\nLaplace pressure component of capillarity [39]. However, the conflicting results on the lower roughnesses leave unanswered the question of whether the low elastic modulus of the toe pads allows them to mould themselves to the contours of all but the largest asperities. However, as Crawford et al., using interference reflection microscopy, were able to observe that small glass Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nbeads (less than 5 \u00b5m diameter) could become lodged in the channels between the cells, it is clear that the nature of the epithelium (cells surrounded by channels) allows interdigitation of asperities on the external surface and the toe pad epithelium.\n\nSimilarity of toe pad structure in different families of tree frogs. There are extraordinary similarities between the structure of toe pads in different frog families (hylid and rhacophorid frogs have been compared in detail by Barnes et al. [30]). They have important implications for biomimetics, for such convergent evolution suggests a good starting point for attempts to develop adhesives that will function in wet conditions.\n\n(b) Mechanisms of adhesion and friction and the forces they produce: physical principles Although the dominant force in tree frog adhesion is thought to be capillarity, viscosity-dependent hydrodynamic forces are also considered to play a role. Additionally, since the\n\n\n\n8\n\nr\n\n............................................................... oyalsociet R\n\nyp","chunk_id":"e78095af9990d29b641c393cc4eef335","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"IRM IMAGE\"","type":"\"GEO\"","description":"\"The image produced by interference reflection microscopy which helps in estimating the thickness of fluid layer.\")","source_id":"e78095af9990d29b641c393cc4eef335"}],"entity_graph":" \"GEO\"<\/data> \"The image produced by interference reflection microscopy which helps in estimating the thickness of fluid layer.\")<\/data> e78095af9990d29b641c393cc4eef335<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"7fb26cfacb7049c44680dc8301da770f","chunk":" Mechanisms of adhesion and friction and the forces they produce: physical principles Although the dominant force in tree frog adhesion is thought to be capillarity, viscosity-dependent hydrodynamic forces are also considered to play a role. Additionally, since the\n\n\n\n8\n\nr\n\n............................................................... oyalsociet R\n\nypublishing\n\nq 2 q\n\n.\n\n1\n\norg\/journal\/rsta\n\nFigure 7. Capillarity model of sphere on a plane surface connected by a drop of fluid. Redrawn from Endlein & Barnes [6].\n\nPh\n\n(Online version in colour.)\n\nil.Trans.R.S\n\nthickness of the fluid layer under each toe pad epithelial cell is less than 35 nm [23], it is likely oc.A\n\nthat there is actual contact between nanopillars on the pad surface and asperities on the substrate.\n\n37\n\nThus, van der Waals forces will also be involved, but to what extent is unknown. The physical 7:2\n\nprinciples underlying capillarity and hydrodynamic forces are outlined below.\n\n0190131\n\nWet adhesion\u2014capillary forces. A common model that has been used for quantifying capillary forces consists of a sphere on a plane surface, connected by a drop of liquid (figure 7). In this model, appropriate as toe pads are slightly domed, the surface tension of the meniscus results in a pressure difference, where the pressure inside the liquid is lower than it is outside, so long as the meniscus is concave. This pressure difference, the Laplace pressure, will resist the separation of the two surfaces. The attractive Laplace force for a macroscopic, perfectly smooth and homogeneous sphere in contact with a plane is given by\n\nFL = \u22122 \u03c0R\u03b3 (cos \u03b8 1 + cos \u03b8 2),\n\n(2.1)\n\nwhere R is the radius of the sphere, \u03b3 is the surface tension of the liquid, and \u03b8 1 and \u03b8 2 are the contact angles of the liquid with the plane surface and sphere, respectively. If the liquid completely wets both surfaces (i.e. \u03b8 1 and \u03b8 2 both equal 0), equation (2.1) simplifies to FL = \u22124 \u03c0R\u03b3 .\n\n(2.2)\n\nAn alternative model examines capillary forces between two rigid plates, separated by a thin layer of fluid (figure 8). This model produces substantial forces if the radius ( r) of the area of contact","chunk_id":"7fb26cfacb7049c44680dc8301da770f","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"TREE FROG ADHESION\"","type":"\"EVENT\"","description":"\"Tree frog adhesion refers to the adhesive capabilities displayed by tree frogs, which is a topic under study with respect to physical principles and forces.\")","source_id":"7fb26cfacb7049c44680dc8301da770f"}],"entity_graph":" \"EVENT\"<\/data> \"Tree frog adhesion refers to the adhesive capabilities displayed by tree frogs, which is a topic under study with respect to physical principles and forces.\")<\/data> 7fb26cfacb7049c44680dc8301da770f<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"73f5b09aa4346c6324664d57dd868e8c","chunk":"0), equation (2.1) simplifies to FL = \u22124 \u03c0R\u03b3 .\n\n(2.2)\n\nAn alternative model examines capillary forces between two rigid plates, separated by a thin layer of fluid (figure 8). This model produces substantial forces if the radius ( r) of the area of contact is large and the separation distance of the plates ( h) is small, according to the following Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nequation:\n\nFL = \u03c0r 2 \u03b3 [ r\u22121 \u2212 (cos \u03b8 1 + cos \u03b8 2) h\u22121].\n\n(2.3)\n\nIn a large flat meniscus where r h and \u03b8 1 = \u03b8 2 = 0, equation (2.3) approximates to equation (2.4), namely\n\nFL \u2248 \u2212 2 \u03c0r 2 \u03b3 .\n\n(2.4)\n\nh\n\nA second component of the adhesive force is the tensile force of the meniscus (figure 9). In the rigid plate model, this surface tension force is\n\nFT = \u22122 \u03c0r\u03b3 .\n\n(2.5)\n\n\n\n\n\n9\n\nr\n\n............................................................... oya\n\nq\n\nq\n\n2\n\n2\n\nlsociet\n\nh\n\nq\n\nq\n\n1\n\n1\n\nypublishing\n\n.org\/journal\/rsta\n\n2 r\n\nFigure 8. Capillarity model of two flat, rigid surfaces separated by a small volume of fluid. Redrawn from Endlein & Barnes [6].\n\n(Online version in colour.)\n\nPhil.Trans.R.Soc.A37\n\nh\n\n7:20190131\n\nr\n\nFv\n\nFigure 9. Viscous force model of two flat rigid plates, fully immersed in a fluid, subject to an external force. Redrawn from Endlein & Barnes [6]. (Online version in colour.)\n\nThe total meniscal force ( FM) is the sum of FL and FT\n\nFM = FL + FT,\n\n(2.6)\n\nwhere FT is negligible in any single large meniscus (e.g. ones with a radius of 0.5\u20133 mm as occur in tree frog toe pads), but would dominate adhesive forces in a fly\u2019s adhesive pad where you have Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nlarge numbers of microscopic menisci (radii of ca 1 \u00b5m).\n\nIn a","chunk_id":"73f5b09aa4346c6324664d57dd868e8c","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"EQUATION 2.1\"","type":"\"ORGANIZATION\"","description":"\"The document contains equation 2.1, which simplifies to FL = \u22124 \u03c0R\u03b3 .\") (\"entity\"","source_id":"73f5b09aa4346c6324664d57dd868e8c"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The document contains equation 2.1, which simplifies to FL = −4 πRγ .\") (\"entity\"<\/data> 73f5b09aa4346c6324664d57dd868e8c<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"fa83531962b067f9e048396a31135c9e","chunk":"3 mm as occur in tree frog toe pads), but would dominate adhesive forces in a fly\u2019s adhesive pad where you have Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nlarge numbers of microscopic menisci (radii of ca 1 \u00b5m).\n\nIn a recent study [40], equation (2.4) has been extended from hard, undeformable surfaces and spheres to soft, elastic materials, such as the toe pad of a tree frog. The mathematical equations relate the capillary attraction between the bodies to their elastic repulsion. Although they do not lend themselves to any easy calculation of the adhesive force, they are of interest in that they predict that FM scaling will gradually change from length scaling to area scaling with increasing r, this change occurring more rapidly for materials with a lower effective elastic modulus ( E eff).\n\nFor instance, in equation (2.7) which deals with the Laplace pressure component of adhesion, the first term is proportional to r and is identical to the force with a hard sphere (equation (2.4)), while the second term is proportional to r 2. It is negligible for high Young\u2019s moduli, but becomes significant for soft materials.\n\n\u03c0\u03b3 3\n\nFL = \u22124 \u03c0r\u03b3 \u2212\n\n\u00b7 2 r 2 ,\n\n(2.7)\n\n2 r\n\n3( E eff)2\n\nwhere r is the radius of curvature of the meniscus.\n\n10\n\nWet adhesion\u2014viscous forces. The second component of wet adhesion is provided by viscosity-r\n\ndependent hydrodynamic forces, usually referred to as Stefan adhesion. Consider two rigid plates\n\n............................................................... oya\n\nfully submersed in a fluid (figure 9). Separating the plates involves fluid flowing into the gap lsociet\n\nbetween them, so that separation is resisted by a viscous force until the fluid movements are ypublishing\n\ncomplete. This hydrodynamic force ( FV) will be greater for more viscous fluids and for smaller values of h. As equation (2.8) indicates, FV scales with area squared.\n\n3 \u03c0\u03b7r 4\n\n.\n\nFV = \u2212 d h .\n\n,\n\n(2.8)\n\nor\n\nd t\n\n2 h 3\n\ng\/journal\/rsta\n\nwhere \u03b7 is the viscosity of the liquid and t is the time needed to separate the two plates. For completeness, the equation for the hydrodynamic force between a sphere and a plate","chunk_id":"fa83531962b067f9e048396a31135c9e","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"STUDY\"","type":"\"EVENT\"","description":"\"The recent study referred to in the text discusses the forces of adhesion in biological systems.\"","source_id":"fa83531962b067f9e048396a31135c9e"},{"name":"\"HARD SPHERE EQUATION\"","type":"\"CONCEPT\"","description":"\"Equation (2.4) is used as a comparison point for discussing the extension of adhesive force equations to soft, elastic materials like tree frog toe pads.\"","source_id":"fa83531962b067f9e048396a31135c9e"},{"name":"\"LENGTH SCALING AND AREA SCALING\"","type":"\"CONCEPT\"","description":"\"The text discusses how with increasing radius (r), adhesive forces may change from length scaling to area scaling.\"","source_id":"fa83531962b067f9e048396a31135c9e"},{"name":"\"EFFECTIVE ELASTIC MODULUS E_EFF\"","type":"\"CONCEPT\"","description":"\"The term effective elastic modulus refers to the material's resistance to deformation, affecting adhesive force predictions.\"","source_id":"fa83531962b067f9e048396a31135c9e"},{"name":"\"LAPLACE PRESSURE COMPONENT OF ADHESION\"","type":"\"CONCEPT\"","description":"\"Refers to one aspect of how adhesive forces are explained mathematically in relation to geometry and elasticity.\"","source_id":"fa83531962b067f9e048396a31135c9e"},{"name":"\"VISCOSITY-DEPENDENT HYDRODYNAMIC FORCES\"","type":"\"CONCEPT\"","description":"\"Referred to as Stefan adhesion, these forces resist plate separation due to fluid flow dynamics.\"","source_id":"fa83531962b067f9e048396a31135c9e"}],"entity_graph":" \"EVENT\"<\/data> \"The recent study referred to in the text discusses the forces of adhesion in biological systems.\"<\/data> fa83531962b067f9e048396a31135c9e<\/data> <\/node> \"CONCEPT\"<\/data> \"Equation (2.4) is used as a comparison point for discussing the extension of adhesive force equations to soft, elastic materials like tree frog toe pads.\"<\/data> fa83531962b067f9e048396a31135c9e<\/data> <\/node> \"CONCEPT\"<\/data> \"The text discusses how with increasing radius (r), adhesive forces may change from length scaling to area scaling.\"<\/data> fa83531962b067f9e048396a31135c9e<\/data> <\/node> \"CONCEPT\"<\/data> \"The term effective elastic modulus refers to the material's resistance to deformation, affecting adhesive force predictions.\"<\/data> fa83531962b067f9e048396a31135c9e<\/data> <\/node> \"CONCEPT\"<\/data> \"Refers to one aspect of how adhesive forces are explained mathematically in relation to geometry and elasticity.\"<\/data> fa83531962b067f9e048396a31135c9e<\/data> <\/node> \"CONCEPT\"<\/data> \"Referred to as Stefan adhesion, these forces resist plate separation due to fluid flow dynamics.\"<\/data> fa83531962b067f9e048396a31135c9e<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"92dc318eef4563c8f3fa73fb7b3978bc","chunk":" = \u2212 d h .\n\n,\n\n(2.8)\n\nor\n\nd t\n\n2 h 3\n\ng\/journal\/rsta\n\nwhere \u03b7 is the viscosity of the liquid and t is the time needed to separate the two plates. For completeness, the equation for the hydrodynamic force between a sphere and a plate (equation (2.9)) is also included.\n\nd h\n\n\n\nPh\n\nFV = \u22126 \u03c0\u03b7r\n\n1 + r ,\n\n(2.9)\n\nil\n\nd t\n\nh\n\n.Tran\n\nwhen the sphere touches the plate, as in figure 1, h = 0.\n\ns.R\n\nViscous-poroelastic adhesion. Recently, Tulchinsky & Gat [41] have introduced the new concept of\n\n.So\n\n\u2018temporary adhesion\u2019 by ignoring inertial and capillary effects, based on the interaction between c.A37\n\nelastic deformation and viscous flow. During tests on a \u2018model toe pad\u2019, the pad generated forces 7\n\nthat resisted slip for periods in excess of 200 s. This is fine for a moving frog, but could present\n\n:20190131\n\nproblems for a frog at rest. Also, as the fluid used in the model toe pad (silicone oil) had a viscosity several orders of magnitude greater than tree frog mucus, it remains unclear whether the mechanism is applicable to frogs.\n\nToe pad adhesion and friction forces. Tree frogs are good climbers, many tropical species being found high in the canopy of rain forests. On effectively flat surfaces (e.g. smooth tree trunks), adhesion is the only means by which tree frogs can climb without falling, but on smaller diameter structures (e.g. small stems\/twigs), they can additionally climb using adduction forces by grasping around these structures with their digits [22]. Indeed, as Hill et al. describe, climbing is rapid on small diameter smooth surfaces because adduction and adhesion act together, and the subarticular tubercles are also brought into play. Unlike geckos, tree frogs cannot run across a ceiling, but they can climb vertical and overhanging surfaces, and a small tree frog can hang on to an inverted glass plate using just its toe pads [32]. At rest, thigh and belly skin aid adhesion.\n\nQuantitative measurements of the adhesive forces that can be generated by tree frogs have been made by a simple procedure first developed by Emerson & Diehl [14]. Frogs are weighed and then placed \u2018head-up\u2019 on a smooth","chunk_id":"92dc318eef4563c8f3fa73fb7b3978bc","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"TULCHINSKY & GAT\"","type":"\"ORGANIZATION\"","description":"\"Tulchinsky & Gat introduced the concept of 'temporary adhesion' by considering only viscous flow and ignoring inertial and capillary effects.\"","source_id":"92dc318eef4563c8f3fa73fb7b3978bc"},{"name":"\"HYDRODYNAMIC FORCE BETWEEN SPHERE AND PLATE\"","type":"\"EVENT\"","description":"\"Equation (2.9) describes this force, which involves a term with viscosity and radius of the sphere.\"","source_id":"92dc318eef4563c8f3fa73fb7b3978bc"},{"name":"\"VISCOUS-POROELASTIC ADHESION\"","type":"\"CONCEPT\"","description":"\"Concept introduced by Tulchinsky & Gat based on elastic deformation and viscous flow interactions.\"","source_id":"92dc318eef4563c8f3fa73fb7b3978bc"},{"name":"\"MODEL TOE PAD\"","type":"\"ITEM\"","description":"\"A test subject used in studying adhesion, with forces resisting slip being measured during tests.\"","source_id":"92dc318eef4563c8f3fa73fb7b3978bc"},{"name":"\"TREE FROGS\"","type":"\"ORGANISM\"","description":"\"Species capable of climbing using both adhesion and adduction forces on smaller structures.\"","source_id":"92dc318eef4563c8f3fa73fb7b3978bc"},{"name":"\"VISCOSITY\"","type":"\"PROPERTY\"","description":"\"Viscosity of the fluid is several orders of magnitude greater for silicone oil than tree frog mucus, affecting applicability of the viscous-poroelastic adhesion concept.\"","source_id":"92dc318eef4563c8f3fa73fb7b3978bc"},{"name":"\"ADHESION\"","type":"\"EVENT\"","description":"\"Means by which tree frogs climb on flat surfaces using only adhesive forces.\"","source_id":"92dc318eef4563c8f3fa73fb7b3978bc"},{"name":"\"ADDUCTION FORCES\"","type":"\"ACTIVITY\"","description":"\"Force used by tree frogs to climb small diameter structures, aiding in climbing with their digits.\"","source_id":"92dc318eef4563c8f3fa73fb7b3978bc"},{"name":"\"SUBARTICULAR TUBERCLES\"","type":"\"STRUCTURE\"","description":"\"Components also contributing to climbing abilities alongside adhesion and adduction forces.\"","source_id":"92dc318eef4563c8f3fa73fb7b3978bc"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"Tulchinsky & Gat introduced the concept of 'temporary adhesion' by considering only viscous flow and ignoring inertial and capillary effects.\"<\/data> 92dc318eef4563c8f3fa73fb7b3978bc<\/data> <\/node> \"EVENT\"<\/data> \"Equation (2.9) describes this force, which involves a term with viscosity and radius of the sphere.\"<\/data> 92dc318eef4563c8f3fa73fb7b3978bc<\/data> <\/node> \"CONCEPT\"<\/data> \"Concept introduced by Tulchinsky & Gat based on elastic deformation and viscous flow interactions.\"<\/data> 92dc318eef4563c8f3fa73fb7b3978bc<\/data> <\/node> \"ITEM\"<\/data> \"A test subject used in studying adhesion, with forces resisting slip being measured during tests.\"<\/data> 92dc318eef4563c8f3fa73fb7b3978bc<\/data> <\/node> \"ORGANISM\"<\/data> \"Species capable of climbing using both adhesion and adduction forces on smaller structures.\"<\/data> 92dc318eef4563c8f3fa73fb7b3978bc<\/data> <\/node> \"PROPERTY\"<\/data> \"Viscosity of the fluid is several orders of magnitude greater for silicone oil than tree frog mucus, affecting applicability of the viscous-poroelastic adhesion concept.\"<\/data> 92dc318eef4563c8f3fa73fb7b3978bc<\/data> <\/node> \"EVENT\"<\/data> \"Means by which tree frogs climb on flat surfaces using only adhesive forces.\"<\/data> 92dc318eef4563c8f3fa73fb7b3978bc<\/data> <\/node> \"ACTIVITY\"<\/data> \"Force used by tree frogs to climb small diameter structures, aiding in climbing with their digits.\"<\/data> 92dc318eef4563c8f3fa73fb7b3978bc<\/data> <\/node> \"STRUCTURE\"<\/data> \"Components also contributing to climbing abilities alongside adhesion and adduction forces.\"<\/data> 92dc318eef4563c8f3fa73fb7b3978bc<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"82d1d20cbed7dd86fe58e59fed8d44ad","chunk":" using just its toe pads [32]. At rest, thigh and belly skin aid adhesion.\n\nQuantitative measurements of the adhesive forces that can be generated by tree frogs have been made by a simple procedure first developed by Emerson & Diehl [14]. Frogs are weighed and then placed \u2018head-up\u2019 on a smooth surface on a rotation platform that is rotated slowly from 0\u00b0\n\n(horizontal), through 90\u00b0 (vertical) to 180\u00b0 (upside-down). The angles at which the frog falls from the surface (fall angle) are recorded. These fall angles are used to calculate maximum adhesive forces by simple trigonometry [32]. If the total toe pad area is also measured, these values can be converted to the force per unit area that toe pads can generate. Figure 10 a shows the masses of Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\n14 different frog species (12 of which were hylids). Measured total toe pad areas of these same frogs appear in figure 10 b, while angles of fall from the rotation platform for these 14 frog species (means of 10 measurements for each frog) are plotted in figure 11 c. Since frogs have an area-based adhesive system (the toe pads), it is unsurprising that larger (and hence heavier) species fall from the platform at lower angles. From this information, the force per unit area of these toe pads can be calculated (figure 11 d). The positive slope of the line of best fit, though small, is statistically significant ( r = 0.68; d.f. = 11; p < 0.05), and reflects the fact that larger tree frogs have more efficient toe pads. A similar study, but looking at the effects of growth on adhesion of these same species [43], shows similar effects, toe pads becoming more structurally complex as the frogs grow. Close examination of the behaviour of tree frogs during such tilting experiments [42,44]\n\ndemonstrates that tree frogs have evolved special strategies to maintain adhesion on overhanging surfaces. As the angle of tilt increases, tree frogs spread their limbs out sideways, and to a more limited extent, forwards or backwards as well. As figure 11 shows, this reduces the angle of\n\n\n\n\n\n( a)\n\n( b)\n\n100\n\n1000\n\n11\n\n)2\n\nr\n\n............................................................... oya\n\n10\n\n100\n\nlsociet\n\nypublishing\n\nmass (g","chunk_id":"82d1d20cbed7dd86fe58e59fed8d44ad","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"EMERSON & DIEHL\"","type":"\"ORGANIZATION\"","description":"\"Developers of a simple procedure to measure adhesive forces generated by tree frogs.\"","source_id":"82d1d20cbed7dd86fe58e59fed8d44ad"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"Developers of a simple procedure to measure adhesive forces generated by tree frogs.\"<\/data> 82d1d20cbed7dd86fe58e59fed8d44ad<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"1647a94c674950bc1429d956f341aba2","chunk":" and to a more limited extent, forwards or backwards as well. As figure 11 shows, this reduces the angle of\n\n\n\n\n\n( a)\n\n( b)\n\n100\n\n1000\n\n11\n\n)2\n\nr\n\n............................................................... oya\n\n10\n\n100\n\nlsociet\n\nypublishing\n\nmass (g)\n\n1\n\n10\n\ntoe-pad area (mm\n\n0.1\n\n1\n\n.or\n\n10\n\n100\n\n10\n\n100\n\ng\/journal\/rsta\n\nSVL (mm)\n\nSVL (mm)\n\n( c)\n\n( d )\n\n)\n\n180\n\n10\n\n\u20132\n\n135\n\nPhil.Tra\n\n90\n\n1\n\nns.R\n\nfall angle (\u00ba)\n\n.S\n\n45\n\noc.A37\n\n0\n\nforce\/unit area (mN mm 0.1\n\n7\n\n10\n\n100\n\n10\n\n100\n\n:20190131\n\nSVL (mm)\n\nSVL (mm)\n\nFigure 10. Allometric relationships of 13 hylid species (open circles) and two non-hylids (filled triangles) plotted against snout\u2013\n\nvent length (SVL). ( a, b) Morphometric relationships between frog mass, toe pad area and length (log : log plots). ( c) Fall angle against length (log : linear plot). ( d) Force per unit area plotted against length (log : log plot). Modified from Barnes et al. [32].\n\n( a)\n\n( b)\n\na\n\nb\n\ngravity\n\nboth toes and legs are extended to reduce\n\nangles a and b and thus reduce the chances\n\nDownloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nof peeling\n\nb\n\na, leg\/substrate angle; b, toe\/substrate angle\n\nFigure 11. ( a) Video-image of ventral view of a tree frog ( Hypsiboas boans) clinging to an overhanging translucent surface, with both fore and hind limbs stretched out sideways. Only areas in contact with the surface are in sharp focus. Scale: large squares are 10 mm across. From Barnes et al. [42]. ( b) Explanatory model.\n\ncontact between pad and surface, reducing the tendency to peel as the mass of the frog is now supported by friction as well as adhesive forces.\n\nIn recent years, the development of miniature force plates that can measure friction and adhesive forces from single toe pads have allowed many interesting findings. As well as providing direct measurements of the friction and adhesive forces that","chunk_id":"1647a94c674950bc1429d956f341aba2","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"FIGURE 11\"","type":"\"GEO\"","description":"\"This refers to a graphical representation or diagram, likely used in academic literature.\"","source_id":"1647a94c674950bc1429d956f341aba2"}],"entity_graph":" \"GEO\"<\/data> \"This refers to a graphical representation or diagram, likely used in academic literature.\"<\/data> 1647a94c674950bc1429d956f341aba2<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"bea216e0fcc7f946f0033c137012a930","chunk":" surface, reducing the tendency to peel as the mass of the frog is now supported by friction as well as adhesive forces.\n\nIn recent years, the development of miniature force plates that can measure friction and adhesive forces from single toe pads have allowed many interesting findings. As well as providing direct measurements of the friction and adhesive forces that toe pads can produce (see\n\n\n\n60 N values 25\n\n25\n\n33\n\n33 (4 frogs)\n\n12\n\nr\n\n50\n\n............................................................... oyalsociet 40\n\nypublishing\n\n30\n\n.\n\nforce (mN)\n\nor\n\n20\n\ng\/journal\/rsta\n\n10\n\n0\n\nPhi\n\nadh-normal frict-normal\n\nadh-H O\n\nfrict-H O\n\nl.T\n\n2\n\n2\n\nr\n\ndrop\n\ndrop\n\nans.R\n\nFigure 12. Single pad adhesion and friction forces in the tree frog,\n\n.\n\nLitoria caerulea, before and after adding a drop of water to\n\nSoc\n\nthe pad. This abolished the meniscus around the edge of the toe pad and resulted in a small increase in pad\/ground distance.\n\n.A37\n\nHence the reduction in both adhesive and friction forces. Typical pad forces were of the order of 1 mN mm\u22122. Barnes WJP & 7:\n\nFederle W, 2006.\n\n20190131\n\nbelow), experiments can be carried out that test different possible mechanisms by which toe pads can adhere.\n\nFigure 12 shows the results of a simple experiment designed to examine the role\/importance of capillarity in tree frog adhesion (Barnes WJP & Federle W, 2006). Both friction and adhesion components of the resultant force are shown for a 70\u00b0 pull-off, which followed a short initial slide, designed to ensure good initial contact of pad and force plate. A drop of water was then gently added, covering the pad in such a way that the meniscus around the edge of the pad was abolished. As expected, adhesive forces fell to low levels, but recovered following removal of the water (not shown). What was not expected was that friction forces declined as well. The only possible conclusion, supported by subsequent experiments examining the effects of the procedure on the thickness of the fluid layer under the pad using interference reflection microscopy, was that this simple procedure had increased the pad\u2013ground distance. Such a change would of course also have reduced adhesion from viscosity-dependent hydrodynamic forces, and also molecular interactions (e.g. van der Waals forces","chunk_id":"bea216e0fcc7f946f0033c137012a930","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"WJP BARNES\"&\"W FEDERLE\"","type":"\"ORGANIZATION\"","description":"\"The development team of miniature force plates used in measuring friction and adhesive forces on frog toe pads.\") (\"entity\"","source_id":"bea216e0fcc7f946f0033c137012a930"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"The development team of miniature force plates used in measuring friction and adhesive forces on frog toe pads.\") (\"entity\"<\/data> bea216e0fcc7f946f0033c137012a930<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"0888854b6766d37662902e4d32772d60","chunk":" the effects of the procedure on the thickness of the fluid layer under the pad using interference reflection microscopy, was that this simple procedure had increased the pad\u2013ground distance. Such a change would of course also have reduced adhesion from viscosity-dependent hydrodynamic forces, and also molecular interactions (e.g. van der Waals forces) that depended on close contact of pad and surface. The experiment is, however, interesting, even though it did not confirm the dominant role of capillarity that it was intended to test. This is because it demonstrates another, equally Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nimportant role for capillary forces in holding the pad close enough to the ground to allow the other forces to exert their adhesive action.\n\nA second interesting result resulting from single pad force recordings comes from the work of Federle et al. [23] in which friction forces were recorded during a short horizontal pull.\n\nSince friction forces developed before the pad began to slide and, additionally, there was a\n\n\u2018remaining\u2019 friction force 2 min after the slide was completed, it is clear that toe pads can generate static friction, strongly suggesting that, during such times, there is actual contact between structures on the toe pads (presumably the nanopillars) and the force plate.\n\nFinally, as has been made clear from the above, these miniature force plates are particularly suitable for measuring the maximum adhesive and friction forces that tree frog toe pads can produce, since both the maximum force and the area of contact are easy to measure. In the gliding frog, Rhacophorus dennysi, the calculated values were 1.45 \u00b1 1.14 mN mm\u22122 ( N = 33) for adhesive force and 6.21 \u00b1 5.11 mN mm\u22122 ( N = 24) for friction [17]. This result supports one of the main\n\n\n\n\n\nconclusions of Langowski et al. [16], that toe pads are optimally developed for friction rather than 13\n\nadhesion.\n\nr\n\n............................................................... oyalsociet 3. Biomimetics of tree frog adhesion and friction\n\nypublishing\n\nLearning from biology to develop new materials and devices, aiming to solve problems in daily life, medical, industry, etc., comes along with human history, though the word \u2018biomimetics\u2019 is a relatively new word, coined by Otto Schmitt in 1957. The mimicking of the clinging abilities of geckos","chunk_id":"0888854b6766d37662902e4d32772d60","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"PROCEDURE\"","type":"\"EVENT\"","description":"\"A procedure conducted to study effects on fluid layer thickness under a pad using interference reflection microscopy.\"","source_id":"0888854b6766d37662902e4d32772d60"},{"name":"\"INCREASE IN PAD-GROUND DISTANCE\"","type":"\"EFFECT\"","description":"\"Increase observed in the distance between pad and ground as an outcome of the said procedure.\"","source_id":"0888854b6766d37662902e4d32772d60"},{"name":"\"REDUCTION OF ADHESION\"","type":"\"EFFECT\"","description":"\"Diminished adhesion due to changes from viscosity-dependent hydrodynamic forces and van der Waals forces.\"","source_id":"0888854b6766d37662902e4d32772d60"},{"name":"\"CAPILLARY FORCES\"","type":"\"CONCEPT\"","description":"\"A significant role for capillary forces in maintaining close contact between pad and ground.\"","source_id":"0888854b6766d37662902e4d32772d60"},{"name":"\"FURTHER ADHESIVE ACTION\"","type":"\"CONTEXT\"","description":"\"The necessity of close contact for the manifestation of other adhesive actions, as suggested by the study.\"","source_id":"0888854b6766d37662902e4d32772d60"},{"name":"\"SINGLE PAD FORCE RECORDINGS\"","type":"\"EVENT\"","description":"\"An experiment involving recording forces exerted by a single pad during horizontal pull.\"","source_id":"0888854b6766d37662902e4d32772d60"},{"name":"\"STATIC FRICTION\"","type":"\"CONCEPT\"","description":"\"Evidence that toe pads can generate static friction, indicating contact between structures on toe pads and the surface.\"","source_id":"0888854b6766d37662902e4d32772d60"},{"name":"\"TOE PAD NANOPILLARS\"","type":"\"COMPONENT\"","description":"\"Structures potentially involved in creating contact with the force plate during toe pad experiments.\"","source_id":"0888854b6766d37662902e4d32772d60"},{"name":"\"MAXIMUM ADHESIVE AND FRICTION FORCES\"","type":"\"MEASURE\"","description":"\"Values measured using miniature force plates for tree frog toe pads.\"","source_id":"0888854b6766d37662902e4d32772d60"},{"name":"\"RHACOPHORUS DENNYSI\"","type":"\"SPECIES\"","description":"\"A species of gliding frog mentioned in the study, used for calculating adhesive and friction forces.\"","source_id":"0888854b6766d37662902e4d32772d60"},{"name":"\"ADHESION VERSUS FRICTION\"","type":"\"COMPARISON\"","description":"\"Supporting an argument suggesting toe pads are better developed for friction than adhesion based on observed data.\"","source_id":"0888854b6766d37662902e4d32772d60"}],"entity_graph":" \"EVENT\"<\/data> \"A procedure conducted to study effects on fluid layer thickness under a pad using interference reflection microscopy.\"<\/data> 0888854b6766d37662902e4d32772d60<\/data> <\/node> \"EFFECT\"<\/data> \"Increase observed in the distance between pad and ground as an outcome of the said procedure.\"<\/data> 0888854b6766d37662902e4d32772d60<\/data> <\/node> \"EFFECT\"<\/data> \"Diminished adhesion due to changes from viscosity-dependent hydrodynamic forces and van der Waals forces.\"<\/data> 0888854b6766d37662902e4d32772d60<\/data> <\/node> \"CONCEPT\"<\/data> \"A significant role for capillary forces in maintaining close contact between pad and ground.\"<\/data> 0888854b6766d37662902e4d32772d60<\/data> <\/node> \"CONTEXT\"<\/data> \"The necessity of close contact for the manifestation of other adhesive actions, as suggested by the study.\"<\/data> 0888854b6766d37662902e4d32772d60<\/data> <\/node> \"EVENT\"<\/data> \"An experiment involving recording forces exerted by a single pad during horizontal pull.\"<\/data> 0888854b6766d37662902e4d32772d60<\/data> <\/node> \"CONCEPT\"<\/data> \"Evidence that toe pads can generate static friction, indicating contact between structures on toe pads and the surface.\"<\/data> 0888854b6766d37662902e4d32772d60<\/data> <\/node> \"COMPONENT\"<\/data> \"Structures potentially involved in creating contact with the force plate during toe pad experiments.\"<\/data> 0888854b6766d37662902e4d32772d60<\/data> <\/node> \"MEASURE\"<\/data> \"Values measured using miniature force plates for tree frog toe pads.\"<\/data> 0888854b6766d37662902e4d32772d60<\/data> <\/node> \"SPECIES\"<\/data> \"A species of gliding frog mentioned in the study, used for calculating adhesive and friction forces.\"<\/data> 0888854b6766d37662902e4d32772d60<\/data> <\/node> \"COMPARISON\"<\/data> \"Supporting an argument suggesting toe pads are better developed for friction than adhesion based on observed data.\"<\/data> 0888854b6766d37662902e4d32772d60<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"bc8c1b71a9bc00c67a64198dae0f5a42","chunk":" biology to develop new materials and devices, aiming to solve problems in daily life, medical, industry, etc., comes along with human history, though the word \u2018biomimetics\u2019 is a relatively new word, coined by Otto Schmitt in 1957. The mimicking of the clinging abilities of geckos and tree-frogs are always attractive for people, so that animal-inspired adhesives have\n\n.org\/journal\/rsta\n\naroused more and more attention in recent years. However, gecko-inspired materials\/devices have caught most of the attention because the origin of gecko adhesion is considered mainly to be due to van der Waals forces so that gecko-mimicking can simply focus on the design and construction of pillar-like structures with various materials and dimensions. Though simple hexagonal structures are present on the toe pads of tree frogs, they are covered by an array of Ph\n\nnanopillars and the mechanism of its adhesion is much more complicated, as described above.\n\nil.T\n\nThough the toe pads of tree frogs look quite different from the hairy gecko pads (figure 2 a), rans\n\nthey both can be considered as pillar arrays [45]. A variety of manufacturing technologies [4]\n\n.R.\n\nhave been developed to construct pillar arrays in materials with Young\u2019s moduli ranging from Soc\n\n1TPa to several MPa (for instance, 1TPa of carbon nanotube (CNT) [46], several GPa of polymers\n\n.A37\n\nlike polyurethane (PU) [47], polystyrene [48], polystyrene-block-poly(vinyl-2-pyridine) (PS-b-7:\n\nP2VP) [49] and 1\u20133 MPa of polydimethylsiloxane (PDMS) [50]). Because of the huge difference in 20190131\n\nYoung\u2019s modulus, pillar arrays with different materials can produce different aspect ratios (AR), which is vital for the stability and adhesion performance of pillar arrays.\n\n(a) Influences of aspect ratio of pillar\n\nThough CNT possesses a large Young\u2019s modulus of 1TPa, the CNT forest shows a much smaller effective modulus ( E eff), which allows CNT forests to maximize contacts, increasing the adhesion force [51]. CNT-based adhesives showed shear adhesion of approximately 100 N cm\u22122, 10 times higher than that of gecko foot-hairs [46]. The complicated fabrication process and the poor","chunk_id":"bc8c1b71a9bc00c67a64198dae0f5a42","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"BIOMIMETICS\"","type":"\"CONCEPT\"","description":"\"The field of biomimetics involves the study of natural systems for solving engineering problems, including developing new materials and devices based on biological principles.\"","source_id":"bc8c1b71a9bc00c67a64198dae0f5a42"},{"name":"\"GECKOS\"","type":"\"ORGANIZATION\"","description":"\"Geckos are used in biomimetics studies for their unique abilities related to adhesion which inspire various material developments.\"","source_id":"bc8c1b71a9bc00c67a64198dae0f5a42"},{"name":"\"TREE FROGS\"","type":"\"ORGANIZATION\"","description":"\"Tree frogs, similarly to geckos, provide inspiration for materials development due to their adhesive capabilities though the mechanism is more complex.\"","source_id":"bc8c1b71a9bc00c67a64198dae0f5a42"},{"name":"\"GECKO-INSPIRED MATERIALS\/DEVICES\"","type":"\"PRODUCT\"","description":"\"Materials or devices that replicate aspects of geckos' adhesion mechanisms, often focusing on van der Waals forces.\"","source_id":"bc8c1b71a9bc00c67a64198dae0f5a42"},{"name":"\"VAN DER WAALS FORCES\"","type":"\"CONCEPT\"","description":"\"Force responsible for the adhesion capabilities in gecko-inspired materials, enabling simple pillar structure design and construction.\"","source_id":"bc8c1b71a9bc00c67a64198dae0f5a42"},{"name":"\"PILLAR ARRAYS\"","type":"\"PRODUCT\"","description":"\"Structured formations made of multiple pillars that mimic natural systems like geckos' toe pads or tree frogs' adhesive mechanisms.\"","source_id":"bc8c1b71a9bc00c67a64198dae0f5a42"},{"name":"\"DERIVED FROM\"","type":"","description":"","source_id":"bc8c1b71a9bc00c67a64198dae0f5a42"},{"name":"\"AFFECTED BY\"","type":"","description":"","source_id":"bc8c1b71a9bc00c67a64198dae0f5a42"}],"entity_graph":" \"CONCEPT\"<\/data> \"The field of biomimetics involves the study of natural systems for solving engineering problems, including developing new materials and devices based on biological principles.\"<\/data> bc8c1b71a9bc00c67a64198dae0f5a42<\/data> <\/node> \"ORGANIZATION\"<\/data> \"Geckos are used in biomimetics studies for their unique abilities related to adhesion which inspire various material developments.\"<\/data> bc8c1b71a9bc00c67a64198dae0f5a42<\/data> <\/node> \"ORGANIZATION\"<\/data> \"Tree frogs, similarly to geckos, provide inspiration for materials development due to their adhesive capabilities though the mechanism is more complex.\"<\/data> bc8c1b71a9bc00c67a64198dae0f5a42<\/data> <\/node> \"PRODUCT\"<\/data> \"Materials or devices that replicate aspects of geckos' adhesion mechanisms, often focusing on van der Waals forces.\"<\/data> bc8c1b71a9bc00c67a64198dae0f5a42<\/data> <\/node> \"CONCEPT\"<\/data> \"Force responsible for the adhesion capabilities in gecko-inspired materials, enabling simple pillar structure design and construction.\"<\/data> bc8c1b71a9bc00c67a64198dae0f5a42<\/data> <\/node> \"PRODUCT\"<\/data> \"Structured formations made of multiple pillars that mimic natural systems like geckos' toe pads or tree frogs' adhesive mechanisms.\"<\/data> bc8c1b71a9bc00c67a64198dae0f5a42<\/data> <\/node> bc8c1b71a9bc00c67a64198dae0f5a42<\/data> <\/node> bc8c1b71a9bc00c67a64198dae0f5a42<\/data> <\/node> 1.0<\/data> \"Inspired by the biological adhesion properties of geckos, leading to advancements in material science and engineering applications.\"<\/data> bc8c1b71a9bc00c67a64198dae0f5a42<\/data> <\/edge> 1.0<\/data> \"Young's modulus of different materials influences the effectiveness and stability of pillar array designs used for biomimetic adhesive development.\"<\/data> bc8c1b71a9bc00c67a64198dae0f5a42<\/data> <\/edge> <\/graph><\/graphml>"} +{"id":"c69e8300c5e976bc2e0c66e470f0371b","chunk":" effective modulus ( E eff), which allows CNT forests to maximize contacts, increasing the adhesion force [51]. CNT-based adhesives showed shear adhesion of approximately 100 N cm\u22122, 10 times higher than that of gecko foot-hairs [46]. The complicated fabrication process and the poor durability of CNT forest, however, hinder its future applications. By contrast, polydimethylsiloxane (PDMS), which has a relatively low modulus, has been widely used to construct structured adhesives due to its handling simplicity and commercial availability.\n\nCompared to the flat surface, PDMS micropillar arrays showed a remarkable decrease in E eff, so that a larger AR results in a smaller E eff (figure 13 a, b). The decreased E eff results in a higher compliance to the contact surface, causing a higher elastic energy dissipation during pull-off from the surface [52]. For instance, increasing the AR of PDMS micropillar arrays from 0.5 to 4 increased pull-off forces by a factor of 3 [53]. It is worth mentioning that measurement of the E eff of a pillar array with a small AR (e.g. 0.5) could be influenced by its backing material. However, higher ARs are not always beneficial for adhesion enhancement. In the case of frog-inspired hexagonal pillars Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nwith height of H and side length of L (figure 13 c), the adhesion force was found to decrease when H\/ L was increased from 0.75 to approximately 1.9 (figure 13 d) [54]. Similar adhesion dependence on the pillar AR was also reported by Iturri [55]. It was explained that the pillars tend to bend and cluster at a high AR, due to the small gap between pillars. The bending and clustering may contribute to the adhesion reduction in two possible ways: (1) the bending of pillars offers the pillar edge for contact, reducing the effective contact area; (2) the clustering of pillars may form a continuous area for contact, reducing the effect of contact splitting. Moreover, the contact density will be reduced by increasing the channel width W, resulting in a smaller adhesive force. This may explain why tree frog toe pads have a small pillar height and a small channel width.\n\nThough the adhesive toe pads on tree frogs and bush-crickets are normally called smooth adhesive pads,","chunk_id":"c69e8300c5e976bc2e0c66e470f0371b","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"EFFECTIVE MODULUS ( E EFF)\"","type":"\"PROPERTY\"","description":"\"E eff allows CNT forests to maximize contacts, increasing adhesion force.\"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"},{"name":"\"CNT-BASED ADHESIVES\"","type":"\"MATERIAL\"","description":"\"Shows shear adhesion of approximately 100 N cm\u22122, significantly higher than gecko foot-hairs.\"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"},{"name":"\"FABRICATION PROCESS\"","type":"\"PROCESS\"","description":"\"Hinders CNT forest applications due to complexity and durability issues.\"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"},{"name":"\"POLYDIMETHYLSILOXANE (PDMS)\"","type":"\"MATERIAL\"","description":"\"Has relatively low modulus, used widely for structured adhesives due to ease of handling and commercial availability.\"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"},{"name":"\"STRUCTURED ADHESIVES\"","type":"\"TYPE\"","description":"\"Built using PDMS micropillar arrays, showing remarkable decrease in effective modulus compared to flat surfaces.\"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"},{"name":"\"E EFF (EFFECTIVE MODULUS)\"","type":"\"MEASUREMENT\"","description":"\"Affects pull-off forces and elastic energy dissipation during contact surface interaction.\"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"},{"name":"\"AR (ASPECT RATIO)\"","type":"\"FACTOR\"","description":"\"Affects CNT forest applications, influencing adhesion forces based on height-to-side length ratio of pillars.\"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"},{"name":"\"PDMS MICROPILLAR ARRAYS\"","type":"\"CONFIGURATION\"","description":"\"Show a decrease in E eff with an increase in AR leading to higher contact and pull-off forces.\"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"},{"name":"\"FROGS INSPIRED HEXAGONAL PILLARS\"","type":"\"INSPIRATION\"","description":"\"Illustrate adhesion dependence on pillar AR, showing potential reduction of force at high ARs due to pillar bending and clustering.\"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"},{"name":"\"TREE FROG TOE PADS\"","type":"\"APPLICATION\"","description":"\"Typically exhibit small pillar height and channel width, likely for maximizing adhesive strength.\"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"},{"name":"\"SMOOTH ADHESIVE PADS\"","type":"\"CLASSIFICATION\"","description":"\"Conventionally described as smooth, but may actually display complex structural features enhancing adhesion.\"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"},{"name":"\"FABRICATION\"","type":"","description":"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"},{"name":"\"HEIGHT (H) AND SIDE LENGTH (L)\"","type":"","description":"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"},{"name":"\"DIMENSION\"","type":"","description":"","source_id":"c69e8300c5e976bc2e0c66e470f0371b"}],"entity_graph":" \"PROPERTY\"<\/data> \"E eff allows CNT forests to maximize contacts, increasing adhesion force.\"<\/data> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> \"MATERIAL\"<\/data> \"Shows shear adhesion of approximately 100 N cm−2, significantly higher than gecko foot-hairs.\"<\/data> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> \"PROCESS\"<\/data> \"Hinders CNT forest applications due to complexity and durability issues.\"<\/data> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> \"MATERIAL\"<\/data> \"Has relatively low modulus, used widely for structured adhesives due to ease of handling and commercial availability.\"<\/data> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> \"TYPE\"<\/data> \"Built using PDMS micropillar arrays, showing remarkable decrease in effective modulus compared to flat surfaces.\"<\/data> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> \"MEASUREMENT\"<\/data> \"Affects pull-off forces and elastic energy dissipation during contact surface interaction.\"<\/data> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> \"FACTOR\"<\/data> \"Affects CNT forest applications, influencing adhesion forces based on height-to-side length ratio of pillars.\"<\/data> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> \"CONFIGURATION\"<\/data> \"Show a decrease in E eff with an increase in AR leading to higher contact and pull-off forces.\"<\/data> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> \"INSPIRATION\"<\/data> \"Illustrate adhesion dependence on pillar AR, showing potential reduction of force at high ARs due to pillar bending and clustering.\"<\/data> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> \"APPLICATION\"<\/data> \"Typically exhibit small pillar height and channel width, likely for maximizing adhesive strength.\"<\/data> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> \"CLASSIFICATION\"<\/data> \"Conventionally described as smooth, but may actually display complex structural features enhancing adhesion.\"<\/data> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/node> 1.0<\/data> \"Based on polydimethylsiloxane, a material known for its ease of handling and commercial availability.\"<\/data> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/edge> 1.0<\/data> \"Affects adhesion forces in hexagonal pillar configurations via AR calculations.\"<\/data> c69e8300c5e976bc2e0c66e470f0371b<\/data> <\/edge> <\/graph><\/graphml>"} +{"id":"10f68536dac42a1fe1015b64ac551c32","chunk":" contact splitting. Moreover, the contact density will be reduced by increasing the channel width W, resulting in a smaller adhesive force. This may explain why tree frog toe pads have a small pillar height and a small channel width.\n\nThough the adhesive toe pads on tree frogs and bush-crickets are normally called smooth adhesive pads, the pillar tops are never smooth. As described above, concave nanostructures have been found on the toe pads of tree frogs (figure 4), and peg-structures have also been reported in bush-crickets [56]. Li et al. [57] reported the hexagonal micropillars with\n\n\n\n\n\n( a)\n\n( b)\n\n14\n\n1.5\n\nr\n\n............................................................... oyalsociet moduluss a) 1.0\n\nypublishing\n\noung\u2019\n\n* (MP\n\ne Y\n\nE 0.5\n\nflat\n\nv\n\nr = 2.5 mm\n\nr = 5 mm\n\nr = 10 mm\n\n.or\n\n10 mm\n\nfecti\n\nr = 25 mm\n\ng\/journal\/rsta\n\nef\n\n0\n\n0\n\n1\n\n2\n\n3\n\n4\n\n5\n\npillar aspect ratio l (\u2013)\n\n( c)\n\n( d ) 24\n\n22\n\nW = 214 mm\n\nW = 100 mm\n\n20\n\nP\n\nW = 71 mm\n\nh\n\nW\n\ni\n\n18\n\nW = 50\n\nl\n\n1\n\nmm\n\n.T\n\n16\n\nW = 33 mm\n\nr\n\nL\n\na\n\n1\n\nn\n\n14\n\ns.R\n\n12\n\n.S\n\n10\n\noc\n\n8\n\n.A37\n\n6\n\nadhesion force (mN)\n\n7\n\n100 mm\n\n4\n\n:2\n\n2\n\n0190131\n\n0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0\n\nheight\/length H\/L\n\nFigure 13. ( a) SEM image of pillar arrays. ( b) The dependence of effective elastic modulus of PDMS micropillars on the AR.\n\n( c) Image of hexagonal pillars in top view. ( d) The dependence of the wet adhesion force on the height-to-length H\/L. ( a, b) reproduced from Greiner et al. [52]; ( c, d) are reproduced from Wang et al. [53].\n\nmicro-bulges on pillar top prepared by combining hemispheric crater arrays on","chunk_id":"10f68536dac42a1fe1015b64ac551c32","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"TREE FROGS\"&\"BUSH-CRICKETS\"","type":"\"ORGANIZATION\"","description":"\"Tree frogs and bush-crickets refer to specific animal species which exhibit certain biological features and adhesive mechanisms.\")
(\"entity\"","source_id":"10f68536dac42a1fe1015b64ac551c32"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"Tree frogs and bush-crickets refer to specific animal species which exhibit certain biological features and adhesive mechanisms.\")<br>(\"entity\"<\/data> 10f68536dac42a1fe1015b64ac551c32<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"c08200d48689acf908730b5b5a937f1a","chunk":" d) The dependence of the wet adhesion force on the height-to-length H\/L. ( a, b) reproduced from Greiner et al. [52]; ( c, d) are reproduced from Wang et al. [53].\n\nmicro-bulges on pillar top prepared by combining hemispheric crater arrays on SiO2 wafer and conventional photolithography. The increased friction force of this hierarchical hexagonal structure, especially in the hydrophilic state, demonstrated the importance of nanostructures on toe pads of tree frogs (figure 14 b). Moreover, concave, spatular, T-shape and spherical micropillar tops were also constructed to investigate the adhesion properties. T-shape pillars, prepared by conventional moulding [59] and inking\u2013printing\u2013curing (IPC) methods, exhibited maximum adhesion strength, both in wet [60] and dry [48, 61] conditions. Both the higher compliance and comparatively large contact area contribute to the outstanding performance. Furthermore, the crack initiation tends to start from the centre during the detachment [62], which results in a suction effect, contributing positively to the adhesion [59].\n\nDownloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\n(b) Influences of micro- and nanostructure\n\nInspired by the existence of nanopillars in toe pad of tree frogs, we fabricated a composite structure with aligned polystyrene (PS) nanopillars embedded in soft PDMS hexagonal micropillars [63]. Both adhesion and friction forces were greatly enhanced compared to the structure with pure PDMS. The finite-element simulation suggests that the embedded nanopillars could regulate the stress distribution across the contact interface, with the stress maximum being distributed on top of a row of nanopillars close to the micropillar perimeter (but not at the centre of contact area or at the very edge of the pillar; figure 14 d). This is similar to the T-shape pillars inspired by gecko setae, which can also shift the stress maximum to the centre of the contact area, inhibiting the crack initiation during pulling. However, the composite structure should possess a much higher stability and durability since the nanopillars are embedded.\n\n\n\n\n\n1.5\n\n( b)\n\n( a)\n\nhydrophobic\n\n15\n\nhydrophilic\n\nload: in; flood\n\nr\n\n1.0\n\n............................................................... oyalsociet 0.5\n\nypublishing\n\nfriction force","chunk_id":"c08200d48689acf908730b5b5a937f1a","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"MICRO-BULGES\"","type":"\"GEO\"","description":"\"micro-bulges refer to the structures on pillar tops that contribute to increased friction forces.\"","source_id":"c08200d48689acf908730b5b5a937f1a"}],"entity_graph":" \"GEO\"<\/data> \"micro-bulges refer to the structures on pillar tops that contribute to increased friction forces.\"<\/data> c08200d48689acf908730b5b5a937f1a<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"dd615bbb350414d251cb1083b3142230","chunk":" much higher stability and durability since the nanopillars are embedded.\n\n\n\n\n\n1.5\n\n( b)\n\n( a)\n\nhydrophobic\n\n15\n\nhydrophilic\n\nload: in; flood\n\nr\n\n1.0\n\n............................................................... oyalsociet 0.5\n\nypublishing\n\nfriction force (N)\n\n0\n\nflat hexagon 10%\n\n20%\n\n30%\n\n40%\n\narea density of pillars ( l)\n\n.org\/journal\/rsta\n\nS \/ S\n\n33\n\n33-avg\n\n( c)\n\n( d )\n\n1.99\n\n1.85\n\n1.71\n\n1.58\n\n1.44\n\n1.30\n\n1.16\n\n1.03\n\n0.89\n\n0.75\n\n0.61\n\nP\n\n0.47\n\nh\n\n0.34\n\nil.Trans.R.Soc.A\n\n( e)\n\n( f )\n\ncore\n\nshell\n\n\/ R = 5\/6\n\n37\n\nt\/ R = 0.1 Ri\n\n7\n\nE , v\n\nc\n\nc\n\nE , v\n\n:\n\ns\n\ns\n\n0.4\n\n2\n\n2\n\n0190131\n\n0.7\n\nz\n\nH\n\nR\n\n\/ s avg-\n\ni\n\ns z 1\n\ncontrol\n\nt\n\nR\n\n0\n\n0.5\n\n1.0\n\nFigure 14. ( a) SEM images of hierarchical structure. ( b) Plot of different microstructures on friction force. ( c) Illustration of composite posts with an internal aligned-PS nanopillars. ( d) Simulated stress distribution on composite miacropillar during detachment. ( e) Schematic of core\u2013shell post with a stiff core and compliant shell. ( f ) Distribution of normal stress along the adhered interface of the post with Ri\/R = 5\/6. ( a, b) Reproduced from Li et al. [57]; ( e, f ) are reproduced from Minsky & Turner\n\n[58].\n\nMore interestingly, this kind of stress-maximum shifting ability was also realized in a much simpler core\u2013shell structure, which is composed of a rigid core of polyetheretherketone and a thin layer of PDMS [58, 64] (figure 14 e). It was found that a thinner layer of PDMS on the pillar end is Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nmore efficient in reducing the stress at the pillar edge, contributing to the ad","chunk_id":"dd615bbb350414d251cb1083b3142230","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"ORGANIZATION\"","type":"\"ROYALSOCIETYPUBLISHING.ORG\"","description":"\"It is a publisher and an academic organization that publishes research articles including those related to engineering sciences.\")<|\"person\"","source_id":"dd615bbb350414d251cb1083b3142230"}],"entity_graph":" \"ROYALSOCIETYPUBLISHING.ORG\"<\/data> \"It is a publisher and an academic organization that publishes research articles including those related to engineering sciences.\")<|\"person\"<\/data> dd615bbb350414d251cb1083b3142230<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"cfd357f03ebd53bb7b20477337baa849","chunk":" [58, 64] (figure 14 e). It was found that a thinner layer of PDMS on the pillar end is Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nmore efficient in reducing the stress at the pillar edge, contributing to the adhesion enhancement.\n\nSimilarly, by coating a thin layer of PDMS onto the gecko-inspired T-shaped micropillar made of polyurethane acrylate (PUA) could sharply enhance the shear adhesion as compared the same structure but composed of either PDMS or PUA [65]. If the core is composed of a polymer material whose stiffness significant decreases by applying an electric current, dynamic tuning of adhesion was successfully realized by the modulation of subsurface stiffness [66].\n\n(c) Adhesion with liquid at interface\n\nThere is mucus on the toe pads of tree frogs, so that a thin layer of liquid is always present at the contact interface. Therefore, tree frog adhesion is considered as wet adhesion, compared to the dry adhesion of geckos. To mimic wet adhesion, spreading a layer of liquid on the structured surface is widely employed [60, 67,68]. The wet adhesion strength is therefore profoundly influenced\n\n\n\nmicrostructured\n\nflat\n\n( a)\n\n( b)\n\n5\n\n50\n\n200\n\n5\n\n50\n\n200 mms\u20131\n\n16\n\nwet\n\ndry\n\nr\n\n............................................................... oy\n\n2\n\nalsociet\n\npolymer-coating\n\nypublishing\n\n1\n\nheat\n\nlow\n\nhigh\n\nadhesion force (mN)\n\nadhesion\n\nadhesion\n\nO\n\nO\n\nO\n\nO\n\nO\n\nO\n\ncool\n\n2\n\n2\n\n2\n\n2\n\n2\n\n2\n\nglycerol 99%\n\nglycerol 87%\n\nH\n\nglycerol 99%\n\nglycerol 87%\n\nH\n\nglycerol 99%\n\nglycerol 87%\n\nH\n\nglycerol 99%\n\nglycerol 87%\n\nH\n\nglycerol 99%\n\nglycerol 87%\n\nH\n\nglycerol 99%\n\nglycerol 87%\n\nH\n\n0\n\n.org\/journal\/rsta\n\nFigure 15. ( a) Adhesion force tested with different velocity on hydrophilic flat and structured surfaces. ( b) Illustration of PDMS\n\npillars coated with a responsive copolymer, realizing switchable adhesion under water. ( a) Reproduced from Drotlef et","chunk_id":"cfd357f03ebd53bb7b20477337baa849","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"PDMS\"","type":"\"MATERIAL\"","description":"\"Polydimethylsiloxane that can be used in microstructures to improve mechanical properties and enhance adhesion.\"","source_id":"cfd357f03ebd53bb7b20477337baa849"}],"entity_graph":" \"MATERIAL\"<\/data> \"Polydimethylsiloxane that can be used in microstructures to improve mechanical properties and enhance adhesion.\"<\/data> cfd357f03ebd53bb7b20477337baa849<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"65e8dd210ebbbf33013fa2f40f86c71a","chunk":"ournal\/rsta\n\nFigure 15. ( a) Adhesion force tested with different velocity on hydrophilic flat and structured surfaces. ( b) Illustration of PDMS\n\npillars coated with a responsive copolymer, realizing switchable adhesion under water. ( a) Reproduced from Drotlef et al. [60];\n\n( b) is reproduced from Ma et al. [71].\n\nPhil.T\n\nby the surface wettability [35, 60]. By applying glycerol (which is polar and does not evaporate ran\n\nat room temperature) to the interface, the adhesion of structured PDMS against a ruby sphere s.R\n\nwas evaluated [60]. It was found that, in the main, short-range attractive forces dominate\n\n.So\n\nadhesion when the PDMS surface is hydrophobic, as the glycerol may be squeezed out from c.A37\n\nthe contact area forming direct contacts. It therefore behaves like gecko-inspired structured 7\n\nadhesive, showing a strong dependence on the contact geometry [60]. By contrast, long-range\n\n:20190131\n\nattractive forces associated with capillarity dominate when the surface is hydrophilic. In this situation, capillary force dominates the adhesion strength, independent of the microstructures on the surface. It was suggested that the adhesion enhancement in the presence of fluid could be the result of crack arresting by liquid, in addition to the capillary forces [69]. It should be noted that excessive liquid will produce a lubrication region, leading to a reduction in adhesion and friction [69,70]. Since the surface wettability has a strong influence on wet adhesion, the switching of a surface between hydrophilic and hydrophobic, e.g. by temperature, could therefore regulate the wet adhesion. By coating a layer of temperature responsive copolymer poly(dopamine methacrylamide-co-methoxyethyl acrylate-co-isopropyl acrylamide) (p(DMA-co-MEA-coNIPAAm) on PDMS micropillars, switching of underwater adhesion was successfully achieved by simply adjusting the temperature of the water bath (figure 15 b) [71].\n\nThe microstructure of the toe pads of animals like tree frogs is considered to play a very important role in wet adhesion. It is suggested that the microchannels between pillars can effectively drain liquid out from the contact area, maximizing the effective solid\u2013solid contact\n\n[55, 67,72","chunk_id":"65e8dd210ebbbf33013fa2f40f86c71a","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"DROTLEF ET AL.\"","type":"\"ORGANIZATION\"","description":"\"An organization referenced for research on adhesion force tested with different velocities and hydrophilic\/hydrophobic surfaces.\")|(\"entity\"","source_id":"65e8dd210ebbbf33013fa2f40f86c71a"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"An organization referenced for research on adhesion force tested with different velocities and hydrophilic\/hydrophobic surfaces.\")|(\"entity\"<\/data> 65e8dd210ebbbf33013fa2f40f86c71a<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"70bb442f494ac5321d4f1d3bc233e919","chunk":" b) [71].\n\nThe microstructure of the toe pads of animals like tree frogs is considered to play a very important role in wet adhesion. It is suggested that the microchannels between pillars can effectively drain liquid out from the contact area, maximizing the effective solid\u2013solid contact\n\n[55, 67,72,73]. Due to the polygonal nature of frog-inspired micropatterns, shear adhesion (friction) shows orientation dependence. In our previous work, wet friction was found to be the highest along the direction of side-sliding (figure 16 a) [55]. Moreover, elongated hexagonal micropillars show an even higher friction at the same orientation. The effective arresting of cracks increases following the edge density per unit length along the friction direction, contributing to friction Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nenhancement. The theory was demonstrated by a macroscopic experiment, where the frog-inspired patterns were mounted on metal pieces and allowed to slide on a rotating surface covered with water (figure 16 c). However, Cheng et al. reported a contradictory result that the wet friction of corner-sliding was higher in both hexagonal and rhomboid pillar arrays [74]. Using Chinese ink as the indicator, the liquid squeezing out of the contact interface was found to be more effective in the direction of corner-sliding (figure 16 a). In the direction of side-sliding, liquid may flow into the contact interface due to the tilting of pillars and the flow pattern, resulting in decreased friction [74]. Recently, distinctive arch-shaped structures (figure 16 b) were reported to provide even larger wet friction force than tree frog-inspired hexagonal patterns, due to their optimal drainage effect and the high stiffness of the patterns [75]. This offers new possibilities for the design of wet adhesives in future.\n\nRecently, it was reported that the bioinspired wet adhesive exhibits better performance on rough than smooth substrates [76,77]. The introduced trace amounts of fluid result in capillary\n\n\n\n\n\n( a)\n\n( b)\n\n17\n\nliquid\n\narch I\n\ncorner-sliding\n\nr\n\n............................................................... oyalsociet 50 mm\n\nypublishing\n\nside-sliding\n\nliquid\n\narch II\n\n.\n\n100 mm\n\norg\/journal\/rsta\n\n50 mm\n\n( c)\n\nflat\n\nhexagon\n\nPhil.Trans.R.\n\n50 mm\n\nSoc.A\n\n35\u00ba\n\n43\u00ba\n\n58\u00ba\n\n377:\n\nFigure 16.","chunk_id":"70bb442f494ac5321d4f1d3bc233e919","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"TREE FROGS\"","type":"\"ORGANIZATION\"","description":"\"Refers to the animals whose toe pad structure is being studied for wet adhesion properties.\"","source_id":"70bb442f494ac5321d4f1d3bc233e919"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"Refers to the animals whose toe pad structure is being studied for wet adhesion properties.\"<\/data> 70bb442f494ac5321d4f1d3bc233e919<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"56de28d5378ea95f859724f171540a25","chunk":" 50 mm\n\nypublishing\n\nside-sliding\n\nliquid\n\narch II\n\n.\n\n100 mm\n\norg\/journal\/rsta\n\n50 mm\n\n( c)\n\nflat\n\nhexagon\n\nPhil.Trans.R.\n\n50 mm\n\nSoc.A\n\n35\u00ba\n\n43\u00ba\n\n58\u00ba\n\n377:\n\nFigure 16. ( a) SEM image of hexagonal pillars with a different sliding direction for friction. Image on right shows the route 20190131\n\nfor flowing water. ( b) SEM images of different pattern (arch I, arch II and hexagon). ( c) Image shows the angles at which flat and micro-patterned hydrophilic samples (regular and elongated hexagonal pillars) slide on a slant terrace flooded with water.\n\n( a) Reproduced from Chen et al. [74]; ( b) Reproduced from Ko et al. [75]. ( c) Reproduced from Iturri et al. [55].\n\nbridges, raising the effective contact area [78] in a way analogous to a thin layer of soft material on top of micropillars [79]. This means that capillary force may serve as the major contributor to wet adhesion on a rough surface [77]. Moreover, structured adhesives could effectively slow down the evaporation of liquid on the rough substrates, which is quite important for tree frogs and other animals using wet adhesion in their natural environment [38].\n\nWhile most studies of wet adhesion on artificial materials involved coating a thin layer of liquid on the structured surface, a few reported the delivery of liquid to the contact area mimicking the secretion of animals [49, 80]. Making use of the microphase separation of block copolymer poly(styrene- b-2-vinylpyridine) (PS2VP), nanopillars with 98 nm internal channels were designed to deliver liquid to the contact area, mimicking the dynamic secretion of animals.\n\nThe combination of material softening in high humidity and the transportation of mineral oil to the contact interface greatly increased the adhesion force by two orders of magnitude. The comparison of work of adhesion at different humidities suggests that the contribution of liquid Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nbridges remained the same, while direct solid\u2013solid contact was 30 times higher when the relative humidity increased from 25 to 90% (figure 17 c). Interestingly, Vogel et al. [80] have designed a device","chunk_id":"56de28d5378ea95f859724f171540a25","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"CHEN ET AL.\"","type":"\"ORGANIZATION\"","description":"\"Chen et al.'s team is involved in the research that examines different patterns of micro and nanostructures for understanding wet adhesion mechanics, as published in journals such as Phil.Trans.R.Soc.A.\")","source_id":"56de28d5378ea95f859724f171540a25"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"Chen et al.'s team is involved in the research that examines different patterns of micro and nanostructures for understanding wet adhesion mechanics, as published in journals such as Phil.Trans.R.Soc.A.\")<\/data> 56de28d5378ea95f859724f171540a25<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"7959e16097062f8a4801b98295269a6a","chunk":"ocietypublishing.org\/ on 09 July 2023\n\nbridges remained the same, while direct solid\u2013solid contact was 30 times higher when the relative humidity increased from 25 to 90% (figure 17 c). Interestingly, Vogel et al. [80] have designed a device with a plate full of holes. Water can be pumped into the holes via channels beneath the plate and form droplet arrays on the plate (figure 17 a). Each droplet can therefore form a liquid bridge with a contacting surface, creating an adhesion force at the interface. Indeed, with all the liquid droplets acting together, the device can generate a substantial adhesion force.\n\n4. Applications\n\nAlthough the mimicking of tree frog-inspired wet adhesion is still in its infancy, there are already some attempts to make use of it in the area of bionic robots [81], soft tissue engineering [82], etc.\n\nFor instance, Tsipenyuk prepared a variety of polyvinylsiloxane (PVS) hexagonal patterns as the stretching unit for disposable safety razors [82]. During the process of sliding against lubricated\n\n\n\n\n\n( a)\n\n( b)\n\n18\n\n20\n\nr\n\n............................................................... oya\n\nJ)\n\n15\n\nlsociet\n\n\u201310\n\nW ad,S\n\n(10\n\n10\n\nypublishing\n\nW ad,C\n\nad,90%\n\n5\n\nW\n\n.\n\n0.5 mm\n\nor\n\n0\n\ng\/journal\/rsta\n\n200\n\n300\n\n400\n\nF (mN)\n\nL\n\n( c)\n\nPhil.Trans.R\n\n1 mm\n\n.Soc.A37\n\nFigure 17. ( a) Image shows large number of liquid bridges were quickly formed by electronic control. ( b) SEM image of 7:2\n\ncontinuous porous pillars. ( c) Dependence of W\n\n0190131\n\nad,S and W ad,C on FL at RH about 90%. ( c) Reproduced from Vogel et al. [80].\n\nrelieving unit\n\n( a)\n\nblades\n\n( c)\n\nstretching unit\n\noctopus-like\n\nconvex cup\n\nbase\n\n(1)\n\namphibian-like\n\nhexegonal array\n\n(2)\n\n(3) PVS\n\nbase\n\ntemplate\n\nstretching unit\n\n(4)\n\nbase\n\ndrainable\n\n(5)\n\nPVS\n\nmicrochannel\n\nbase\n\nbio-inspired patch\n\n120\n\n( b)\n\n60\n\nwith hierarchial architectures\n\n840\n\nbioinspired patch\n\n630","chunk_id":"7959e16097062f8a4801b98295269a6a","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"OCIETYPUBLISHING.ORG\"\/\"ORGANIZATION\"","type":"\"PUBLISHING ORGANIZATION\"","description":"\"This organization operates on the web, contributing to scientific publications and research dissemination.\"","source_id":"7959e16097062f8a4801b98295269a6a"},{"name":"\"BRIDGES\"\/\"EVENT\"\/\"SCIENTIFIC EXPERIMENT\"","type":"\"A SPECIFIC EXPERIMENT WAS CONDUCTED BY INCREASING RELATIVE HUMIDITY FOR OBSERVING ITS IMPACT ON SOLID-SOLID CONTACT RESISTANCE.\"","description":"5","source_id":"7959e16097062f8a4801b98295269a6a"},{"name":"\"VOGEL ET AL.\"\/\"PERSON\"\/\"RESEARCH TEAM\"","type":"\"THE REFERENCE TO A NAMED GROUP SUGGESTS A TEAM OF RESEARCHERS INVOLVED IN DESIGNING AND IMPLEMENTING THE LIQUID BRIDGE FORMING DEVICE.\"","description":"6","source_id":"7959e16097062f8a4801b98295269a6a"},{"name":"\"OCIETYPUBLISHING.ORG\"","type":"","description":"","source_id":"7959e16097062f8a4801b98295269a6a"},{"name":"\"PUBLISHES\"","type":"","description":"","source_id":"7959e16097062f8a4801b98295269a6a"}],"entity_graph":" \"PUBLISHING ORGANIZATION\"<\/data> \"This organization operates on the web, contributing to scientific publications and research dissemination.\"<\/data> 7959e16097062f8a4801b98295269a6a<\/data> <\/node> \"A SPECIFIC EXPERIMENT WAS CONDUCTED BY INCREASING RELATIVE HUMIDITY FOR OBSERVING ITS IMPACT ON SOLID-SOLID CONTACT RESISTANCE.\"<\/data> 5<\/data> 7959e16097062f8a4801b98295269a6a<\/data> <\/node> \"THE REFERENCE TO A NAMED GROUP SUGGESTS A TEAM OF RESEARCHERS INVOLVED IN DESIGNING AND IMPLEMENTING THE LIQUID BRIDGE FORMING DEVICE.\"<\/data> 6<\/data> 7959e16097062f8a4801b98295269a6a<\/data> <\/node> 7959e16097062f8a4801b98295269a6a<\/data> <\/node> 7959e16097062f8a4801b98295269a6a<\/data> <\/node> 1.0<\/data> \"publishing organization is responsible for releasing scientific studies or findings like this study on tree frog-inspired adhesion.\"<\/data> 7959e16097062f8a4801b98295269a6a<\/data> <\/edge> <\/graph><\/graphml>"} +{"id":"2e431df92f1954d7fdf7449771dac2e1","chunk":" array\n\n(2)\n\n(3) PVS\n\nbase\n\ntemplate\n\nstretching unit\n\n(4)\n\nbase\n\ndrainable\n\n(5)\n\nPVS\n\nmicrochannel\n\nbase\n\nbio-inspired patch\n\n120\n\n( b)\n\n60\n\nwith hierarchial architectures\n\n840\n\nbioinspired patch\n\n630\n\nwith conductive architectures\n\n420\n\nz\n\nR\n\n210\n\n120\n\nT\n\nP\n\n50 mm\n\n0\n\nx\n\num\n\n0\n\n210\n\n420\n\n630\n\n840\n\nQ S\n\nDownloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nFigure 18. ( a) Schematic illustration of the preparation process of the commercial safety razor cartridge with hexagonal surface.\n\n( b) Pig liver was deformed by using a normal force of 10 N. ( c) Schematic illustration of bioinspired patch for detecting ECG\n\nsignals. ( a) Reproduced from Tsipenyuk et al. [82]. ( b) Reproduced from Chen et al. [74]. ( c) Reproduced from Kim et al. [83].\n\nhuman skin, the hexagonal surface could increase the effective contact with the skin by draining excessive liquid through the channels. Thus, the friction force was double that of commercial products and stretched the moist skin much better. Also, Chen et al. prepared PDMS polygonal arrays and applied them to the gripping surface of surgical graspers (figure 18 b). Compared to the traditional tooth-textured surgical grasper, the new design can greatly reduce the gripping force, reducing damage to soft tissue [74]. More recently, a biomimetic skin patch inspired by the hexagonal pattern of tree frog toe pads and the convex cup of octopus suckers has been reported\n\n(figure 18 c) [83]. The patch exhibited outstanding adhesion performance on human skin, even in\n\n\n\n\n\na water flowing environment. In addition, following coating with reduced graphene oxide, the 19\n\npatch could serve as a flexible electrode, sensitive enough to receive bio-signals on a wet skin, r\n\neven under motion.\n\n............................................................... oyalsociet 5. Conclusion and outlook\n\nypublishing\n\nIt is clear that tree frogs exhibit outstanding wet adhesion properties. Significant progress has been made in recent years, both in our understanding of how tree frogs adhere and in the development of tree frog-inspired wet adhesives. But many questions remain unanswered. For instance, while\n\n.or\n\nmost of the tree frog","chunk_id":"2e431df92f1954d7fdf7449771dac2e1","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"PVS MICROCHANNEL BASE BIO-INSPIRED PATCH\"","type":"\"ORGANIZATION\"","description":"\"This refers to a specific type of microchannel base bio-inspired patch that is being developed.\") (\"entity\"","source_id":"2e431df92f1954d7fdf7449771dac2e1"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"This refers to a specific type of microchannel base bio-inspired patch that is being developed.\") (\"entity\"<\/data> 2e431df92f1954d7fdf7449771dac2e1<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"48a7645a66fe18b7377a1a842f7242b0","chunk":"ing\n\nIt is clear that tree frogs exhibit outstanding wet adhesion properties. Significant progress has been made in recent years, both in our understanding of how tree frogs adhere and in the development of tree frog-inspired wet adhesives. But many questions remain unanswered. For instance, while\n\n.or\n\nmost of the tree frog-mimicking studies have focused on the micropattern on the toe pad, more g\/journal\/rsta\n\nattention should be given to forming a better understanding of the role of the nanostructures.\n\nCould there be synergistic interactions between the micro- and nanostructures and the mucus?\n\nMoreover, since the animals keep secreting all the time, the liquid volume at the contacting interface should change accordingly. How will this dynamic process contribute to adhesion and P\n\nfriction during the locomotion of animals? And can we make use of the dynamic process? The hil.T\n\nanswers to these questions could deepen our understanding of the adhesion of tree frogs and ran\n\nspeed the development of applications of bioinspired wet adhesion.\n\ns.R.\n\nData accessibility. The article has no additional data.\n\nSoc\n\nAuthors\u2019 contributions. L.X. and W.J.P.B. conceived and designed the study. All authors drafted the manuscript.\n\n.A\n\nCompeting interests. The authors declare that they have no competing interests.\n\n377\n\nFunding. This work was supported the National Key R&D Program of China (2018YFB1105100) and National\n\n:20190131\n\nNatural Science Foundation of China (51503156).\n\nAcknowledgements. W.J.P.B. thank Ross McAuley for his assistance with formatting the figures.\n\nReferences\n\n1. Vincent JF, Bogatyreva OA, Bogatyrev NR, Bowyer A, Pahl AK. 2006 Biomimetics: its practice and theory. J. R. Soc. Interface 3, 471\u2013482. (doi:10.1098\/rsif.2006.0127)\n\n2. Dean B, Bhushan B. 2010 Shark-skin surfaces for fluid-drag reduction in turbulent flow: a review. Phil. Trans. R. Soc. A 368, 4775\u20134806. (doi:10.1098\/rsta.2010.0201)\n\n3. Barthlott W, Neinhuis C. 1997 Purity of the sacred lotus, or escape from contamination in biological surfaces. Planta 202, 1\u20138. (doi:10","chunk_id":"48a7645a66fe18b7377a1a842f7242b0","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"TREE FROGS\"","type":"\"SPECIES\"","description":"\"Tree frogs are known for their remarkable wet adhesion properties.\"","source_id":"48a7645a66fe18b7377a1a842f7242b0"}],"entity_graph":" \"SPECIES\"<\/data> \"Tree frogs are known for their remarkable wet adhesion properties.\"<\/data> 48a7645a66fe18b7377a1a842f7242b0<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"e8c373a905cc6ee3e696c2eb69267455","chunk":"4806. (doi:10.1098\/rsta.2010.0201)\n\n3. Barthlott W, Neinhuis C. 1997 Purity of the sacred lotus, or escape from contamination in biological surfaces. Planta 202, 1\u20138. (doi:10.2307\/23384993)\n\n4. Sun J, Bhushan B. 2019 Nanomanufacturing of bioinspired surfaces. Tribol. Int. 129, 67\u201374.\n\n(doi:10.1016\/j.triboint.2018.08.007)\n\n5. Autumn K. 2007 Gecko adhesion: structure, function, and applications. MRS Bull. 32, 473\u2013478.\n\n(doi:10.1557\/mrs2007.80)\n\n6. Endlein T, Barnes WJP. 2015 Wet adhesion in tree and torrent frogs. In Encyclopedia of nanotechnology, 2nd edn (ed. B Bhushan). Dordrecht, The Netherlands: Springer Science.\n\n7. Hansen WR, Autumn K. 2005 Evidence for self-cleaning in gecko setae. Proc. Natl Acad. Sci.\n\nUSA 102, 385\u2013389. (doi:10.1073\/pnas.0408304102)\n\n8. Crawford N, Endlein T., Barnes WJP. 2012 Self-cleaning in tree frog toe pads; a mechanism for recovering from contamination without the need for grooming. J. Exp. Biol. 215, 3965\u20133972.\n\nDownloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\n(doi:10.1242\/jeb.073809)\n\n9. Hu S, Lopez S, Niewiarowski PH, Xia Z. 2012 Dynamic self-cleaning in gecko setae via digital hyperextension. J. R. Soc. Interface 9, 2781\u20132790. (doi:10.1098\/rsif.2012.0108)\n\n10. Autumn K, Liang YA, Hsieh ST, Zesch W, Chan WP, Kenny TW, Fearing R. 2000 Adhesive force of a single gecko foot-hair. Nature 405, 681\u2013685. (doi:10.1038\/35015073)\n\n11. Autumn, K, Sitti M, Liang YA, Peatt","chunk_id":"e8c373a905cc6ee3e696c2eb69267455","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"NEINHUIS C\"","type":"\"PERSON\"","description":"\"Co-author with Barthlott W, Neinhuis C contributed to the study of purity and contamination issues related to biological surfaces.\"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"SUN J\"","type":"\"PERSON\"","description":"\"Sun J worked on nanomanufacturing bioinspired surfaces as presented in Tribol. Int.\"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"BHUSHAN B\"","type":"\"PERSON\"","description":"\"Bhushan B is associated with Sun J's research and the field of nanotechnology.\"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"AUTUMN K\"","type":"\"PERSON\"","description":"\"Karl Autumn authored multiple works related to gecko adhesion, including explanations on structure, function, and applications.\"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"ENDLEIN T\"","type":"\"PERSON\"","description":"\"Tobias Endlein contributed a study on wet adhesion in tree frogs which was part of an encyclopedia on nanotechnology.\"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"BARNES WJP\"","type":"\"PERSON\"","description":"\"W. J.P. Barnes co-authored the work by Endlein on wet adhesion and has expertise in this area.\"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"HANSEN WR\"","type":"\"PERSON\"","description":"\"Wilfred R Hansen, alongside Autumn K, provided evidence for self-cleaning in gecko setae as reported in Proc. Natl Acad. Sci.\"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"CRAWFORD N\"","type":"\"PERSON\"","description":"\"Nathaniel Crawford contributed research on self-cleaning mechanisms in tree frog toe pads without the need for grooming, as seen in J. Exp. Biol.\"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"HU S\"","type":"\"PERSON\"","description":"\"Sun Hu alongside Lopez S and Niewiarowski PH co-authored a paper on dynamic self-cleaning in gecko setae through digital hyperextension.\"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"LOPEZ S\"","type":"\"PERSON\"","description":"\"Co-author with Hu S, Lopez contributed to research on dynamic self-cleaning mechanisms in gecko setae.\"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"NIEWIAROWSKI PH\"","type":"\"PERSON\"","description":"\"Participated alongside Hu S and Lopez S in the study of dynamic self-cleaning processes in gecko setae.\"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"XIA Z\"","type":"\"PERSON\"","description":"\"Zeng Xia, together with Hu S et al., explored digital hyperextension mechanisms for self-cleaning in geckos.\"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"BARTHLOTT W\"","type":"","description":"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"WORK\"","type":"","description":"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"CO-AUTHORSHIP\"","type":"","description":"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"AUTHORSHIP\"","type":"","description":"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"AUTHORSHIP\/CO-AUTHORSHIP\"","type":"","description":"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"CO-AUTHORSHIP\/CONTRIBUTOR\"","type":"","description":"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"CO-AUTHORSHIP\/EXPERTISE\"","type":"","description":"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"COLLABORATION\/","type":"","description":"","source_id":"e8c373a905cc6ee3e696c2eb69267455"},{"name":"\"CONTRIBUTOR\/RESEARCH\"","type":"","description":"","source_id":"e8c373a905cc6ee3e696c2eb69267455"}],"entity_graph":" \"PERSON\"<\/data> \"Co-author with Barthlott W, Neinhuis C contributed to the study of purity and contamination issues related to biological surfaces.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> \"PERSON\"<\/data> \"Sun J worked on nanomanufacturing bioinspired surfaces as presented in Tribol. Int.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> \"PERSON\"<\/data> \"Bhushan B is associated with Sun J's research and the field of nanotechnology.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> \"PERSON\"<\/data> \"Karl Autumn authored multiple works related to gecko adhesion, including explanations on structure, function, and applications.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> \"PERSON\"<\/data> \"Tobias Endlein contributed a study on wet adhesion in tree frogs which was part of an encyclopedia on nanotechnology.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> \"PERSON\"<\/data> \"W. J.P. Barnes co-authored the work by Endlein on wet adhesion and has expertise in this area.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> \"PERSON\"<\/data> \"Wilfred R Hansen, alongside Autumn K, provided evidence for self-cleaning in gecko setae as reported in Proc. Natl Acad. Sci.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> \"PERSON\"<\/data> \"Nathaniel Crawford contributed research on self-cleaning mechanisms in tree frog toe pads without the need for grooming, as seen in J. Exp. Biol.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> \"PERSON\"<\/data> \"Sun Hu alongside Lopez S and Niewiarowski PH co-authored a paper on dynamic self-cleaning in gecko setae through digital hyperextension.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> \"PERSON\"<\/data> \"Co-author with Hu S, Lopez contributed to research on dynamic self-cleaning mechanisms in gecko setae.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> \"PERSON\"<\/data> \"Participated alongside Hu S and Lopez S in the study of dynamic self-cleaning processes in gecko setae.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> \"PERSON\"<\/data> \"Zeng Xia, together with Hu S et al., explored digital hyperextension mechanisms for self-cleaning in geckos.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/node> 1.0<\/data> \"C was co-author with Barthlott W on work concerning purity and contamination issues related to biological surfaces.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/edge> 1.0<\/data> \"Sun J is an author of the paper on nanomanufacturing bioinspired surfaces in Tribol. Int.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/edge> 1.0<\/data> \"Is associated with Sun J's research and the field of nanotechnology as a co-author or author.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/edge> 1.0<\/data> \"Karl Autumn is an author of works on gecko adhesion, including structure, function, and applications.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/edge> 1.0<\/data> \"Tobias Endlein contributed to the study on wet adhesion in tree frogs as part of a broader work on nanotechnology.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/edge> 1.0<\/data> \"W. J.P. Barnes co-authored research with Endlein and likely has expertise in biological adhesion mechanisms.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/edge> 1.0<\/data> \"Wilfred Hansen, along with Karl Autumn, provided evidence for self-cleaning gecko setae.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/edge> 1.0<\/data> \"Nathaniel Crawford contributed research on self-cleaning mechanisms in tree frog toe pads as part of J. Exp. Biol.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/edge> 1.0<\/data> \"Sun Hu co-authored the study with Lopez and Niewiarowski on dynamic self-cleaning in gecko setae using digital hyperextension.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/edge> 1.0<\/data> \"Barthlott W contributed to studies on purity and contamination of biological surfaces in Planta.\"<\/data> e8c373a905cc6ee3e696c2eb69267455<\/data> <\/edge> <\/graph><\/graphml>"} +{"id":"b0d8a0ab9b482ef83c81415c6fcb22c9","chunk":" W, Chan WP, Kenny TW, Fearing R. 2000 Adhesive force of a single gecko foot-hair. Nature 405, 681\u2013685. (doi:10.1038\/35015073)\n\n11. Autumn, K, Sitti M, Liang YA, Peattie AM, Hansen WR, Sponberg S. 2002 Evidence for van der Waals adhesion in gecko setae. Proc. Natl Acad. Sci. USA 99, 12 252\u201312 256.\n\n(doi:10.1073\/pnas.192252799)\n\n12. Hawkes EW, Eason EV, Christensen DL, Cutkosky MR. 2015 Human climbing\n\nwith efficiently scaled gecko-inspired dry adhesives. J. R. Soc. Interface 12, 20140675.\n\n(doi:10.1098\/rsif.2014.0675)\n\n13. Nachtigall W. 1974 Biological mechanisms of attachment. Berlin, Germany: Springer.\n\n14. Emerson SB, Diehl D. 1980 Toe pad morphology and mechanisms of sticking in frogs. Biol. J.\n\nLinn. Soc. 13, 199\u2013216. (doi:10.1111\/j.1095-8312.1980.tb00082.x)\n\n15. Hanna G, Barnes WJP. 1991 Adhesion and detachment of the toe pads of tree frogs. J. Exp.\n\n20\n\nBiol. 155, 103\u2013125.\n\n16. Langowski JKA, Dodou D, Kamperman M, van Leeuwen JL. 2018 Tree frog attachment: r\n\n............................................................... oy\n\nmechanisms, challenges, and perspectives. Front. Zool. 2018, 15\u201332. (doi:10.1186\/\n\nalsociet\n\ns12983-018-0273-x)\n\n17. Endlein T, Ji A, Yuan S, Hill I, Wang H, Barnes WJP, Dai Z, Sitti M. 2017 The use of clamping ypublishing\n\ngrips and friction pads by tree frogs for climbing curved surfaces. Proc. R. Soc. B 284, 20162867.\n\n(doi:10.1098\/rspb.2016.2867)\n\n18. Langowski JKA, Schipper H, Blij A, van den Berg FT, Gussekloo SWS, van Lee","chunk_id":"b0d8a0ab9b482ef83c81415c6fcb22c9","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[],"entity_graph":" <\/graphml>"} +{"id":"777a1482c060a064af315a8488df370a","chunk":" climbing curved surfaces. Proc. R. Soc. B 284, 20162867.\n\n(doi:10.1098\/rspb.2016.2867)\n\n18. Langowski JKA, Schipper H, Blij A, van den Berg FT, Gussekloo SWS, van Leeuwen JL. 2018\n\nForce-transmitting structures in the digital pads of the tree frog Hyla cinerea: a functional\n\n.org\/journal\/rsta\n\ninterpretation. J. Anat. 233, 478\u2013495. (doi:10.1111\/joa.12860)\n\n19. Gorb S. 2001 Attachment devices of insect cuticle. Dordrecht, The Netherlands: Kluwer Academic Publishers.\n\n20. Labonte D, Federle W. 2015 Rate-dependence of \u2018wet\u2019 biological adhesives and the function of the pad secretion in insects. Soft Matter 11, 8661\u20138673. (doi:10.1039\/C5SM01496D)\n\nP\n\n21. Duellman WE, Trueb L. 1994 Biology of amphibians. Baltimore, MD: John Hopkins University hil.T\n\nPress.\n\nra\n\n22. Hill IDC, Dong B, Barnes WJP, Ji A, Endlein T. 2018 The biomechanics of tree frogs ns.R\n\nclimbing curved surfaces: a gripping problem. J. Exp. Biol. 221, jeb.168179. (doi:10.1242\/jeb.\n\n.S\n\n168179)\n\noc.A\n\n23. Federle W, Barnes WJP, Baumgartner W, Drechsler P, Smith JM. 2006 Wet but not 37\n\nslippery: boundary friction in tree frog adhesive toe pads. J. R. Soc. Interface 3, 689\u2013697.\n\n7:\n\n(doi:10.1098\/rsif.2006.0135)\n\n20190131\n\n24. Drotlef DM, Appel E, Peisker H, Dening K, del Campo A, Gorb SN, Barnes WJP. 2014\n\nMorphological studies of the toe pads of the rock frog, Staurois parvus (family: Ranidae) and their relevance to the development of new biomimetically inspired reversible adhesives.\n\nInterface Focus 5, 20140036. (doi:10.1098\/rsfs.2014.003","chunk_id":"777a1482c060a064af315a8488df370a","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"SAM RIVERA\"","type":"\"PERSON\"","description":"\"Sam Rivera is not mentioned in the provided real data.\")|(\"entity\"","source_id":"777a1482c060a064af315a8488df370a"}],"entity_graph":" \"PERSON\"<\/data> \"Sam Rivera is not mentioned in the provided real data.\")|(\"entity\"<\/data> 777a1482c060a064af315a8488df370a<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"4d8b21398c70d24c39cd26cfa1dba5c0","chunk":" studies of the toe pads of the rock frog, Staurois parvus (family: Ranidae) and their relevance to the development of new biomimetically inspired reversible adhesives.\n\nInterface Focus 5, 20140036. (doi:10.1098\/rsfs.2014.0036)\n\n25. Green DM. 1979 Treefrog toe pads: comparative surface morphology using scanning electron microscopy. Can. J. Zool. 57, 2033\u20132046. (doi:10.1139\/z79-268)\n\n26. Smith JM, Barnes WJP, Downie JR, Ruxton GD. 2006 Structural correlates of increased adhesive efficiency with adult size in the toe pads of hylid tree frogs. J. Comp. Physiol. A 192, 1193\u20131204. (doi:10.1111\/j.1469-7998.2006.00145.x)\n\n27. Barnes WJP, Perez Goodwyn PJ, Nokhbatolfoghahai M, Gorb SN. 2011 Elastic modulus of tree frog adhesive toe pads. J. Comp. Physiol. A 197, 969\u2013978. (doi:10.1007\/s00359-011-0658-1)\n\n28. Alexander RM. 1968 Animal mechanics. London, UK: Sidgwick and Jackson.\n\n29. Scholz I, Barnes WJP, Smith JM, Baumgartner W. 2009 Ultrastructure and physical properties of an adhesive surface, the toe pad epithelium of the tree frog, Litoria caerulea White. J. Exp.\n\nBiol. 212, 155\u2013162. (doi:10.1242\/jeb.019232)\n\n30. Barnes WJP, Baum M, Peisker H, Gorb SN. 2013 Comparative cryo-SEM and AFM studies of hylid and rhacophorid tree frog toe pads. J. Morphol. 274, 1384\u20131396. (doi:10.1002\/jmor.\n\n20186)\n\n31. Nakano M, Saino T. 2016 Light and electron microscopic analyses of the high deformability of adhesive toe pads in White\u2019s tree frog, Litoria caerulea. J. Morphol. 277, 1509\u20131516.\n\nDownloaded from https:\/\/royalsocietypublishing.org\/ on","chunk_id":"4d8b21398c70d24c39cd26cfa1dba5c0","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"STAUROIS PARVUS\"","type":"\"ORGANIZATION\"","description":"\"Research focuses on the toe pads of this species as a source for developing new biomimetically inspired reversible adhesives.\")
(\"entity\"","source_id":"4d8b21398c70d24c39cd26cfa1dba5c0"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"Research focuses on the toe pads of this species as a source for developing new biomimetically inspired reversible adhesives.\")<br>(\"entity\"<\/data> 4d8b21398c70d24c39cd26cfa1dba5c0<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"39bb4090056fa3afa0591e818ff2e48b","chunk":"aino T. 2016 Light and electron microscopic analyses of the high deformability of adhesive toe pads in White\u2019s tree frog, Litoria caerulea. J. Morphol. 277, 1509\u20131516.\n\nDownloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\n(doi:10.1002\/jmor.20592)\n\n32. Barnes WJP, Oines C, Smith JM. 2006 Whole animal measurements of shear and adhesive forces in adult tree frogs: insights into underlying mechanisms of adhesion obtained from studying the effects of size and scale. J. Comp. Physiol. A 192, 1179\u20131191.\n\n(doi:10.1007\/s00359-006-0146-1)\n\n33. Barnes WJP, Khannoon E, Crawford N, Endlein T. 2016 Tree frog adhesion to surfaces differing in surface energy. In Proceedings of the Adhesion Society Annual Meeting, February 21\u201324, 2016, San Antonio, TX. Red Hook, NY: Curran Associates.\n\n34. Persson BNJ. 2007 Wet adhesion with application to tree frog adhesive toe pads and tires. J.\n\nPhys.: Condens. Matter 19, 376110 (16pp). (doi:10.1088\/0953-8984\/19\/37\/376110)\n\n35. Endlein T, Ji A, Samuel D, Yao N, Wang Z, Barnes WJP, Federle W, Kappl M, Dai Z. 2013\n\nSticking like sticky tape: tree frogs use friction forces to enhance attachment on overhanging surfaces. J. R. Soc. Interface 10, 20120838. (doi:10.1098\/rsif.2012.0838)\n\n36. Hutt W, Persson BNJ. 2016 Soft matter dynamics: accelerated fluid squeeze-out during slip. J.\n\nChem. Phys. 144, 124903. (doi:10.1063\/1.4944384)\n\n37. Ji A et al. 2019 A force-measuring and behaviour-recording system consisting of 24 individual 21\n\n3D force plates for the study of single limb forces in climbing animals on a quasi-cylindrical tower. Bioinspir. Biomim. In press. (doi:10.1088\/1748-3190\/ab1d11","chunk_id":"39bb4090056fa3afa0591e818ff2e48b","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"AINO T.\"","type":"\"PERSON\"","description":"\"Aino T.'s research is focused on the high deformability of adhesive toe pads in White's tree frog, specifically through light and electron microscopic analyses.\")|(\"entity\"","source_id":"39bb4090056fa3afa0591e818ff2e48b"}],"entity_graph":" \"PERSON\"<\/data> \"Aino T.'s research is focused on the high deformability of adhesive toe pads in White's tree frog, specifically through light and electron microscopic analyses.\")|(\"entity\"<\/data> 39bb4090056fa3afa0591e818ff2e48b<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"a2e84db4531e11bb05a5e5cbdb285bb8","chunk":"asuring and behaviour-recording system consisting of 24 individual 21\n\n3D force plates for the study of single limb forces in climbing animals on a quasi-cylindrical tower. Bioinspir. Biomim. In press. (doi:10.1088\/1748-3190\/ab1d11)\n\nr\n\n............................................................... oy\n\n38. Langowski JKA, Rummenie A, Pieters RPM, Kovalev A, Gorb SN, van Leeuwen JL. 2019\n\nalsociet\n\nEstimating the maximum attachment performance of tree frogs on rough substrates. Bioinspir.\n\nBiomim. 14, 025001. (doi:10.1088\/1748-3190\/aafc37)\n\nypublishing\n\n39. Crawford N, Endlein T, Pham JT, Barnes WJP. 2016 When the going gets rough \u2013 studying the effect of surface roughness on the adhesive abilities of tree frogs. Beilstein J. Nanotech. 7, 2116\u20132131. (doi:10.3762\/bjnano.7.201)\n\n.\n\n40. Butt H-J, Barnes WJP, del Campo A, Kappl M, Sch\u00f6nfeld, F. 2010 Capillary forces between org\/journal\/rsta\n\nsoft, elastic spheres. Soft Matter 6, 5930\u20135936. (doi:10.1039\/C0SM00455C)\n\n41. Tulchinsky A, Gat AD. 2015 Viscous-poroelastic interaction as mechanism to create adhesion in frogs\u2019 toe pads. J. Fluid Mech. 775, 288\u2013303. (doi:10.1017\/jfm.2015.293)\n\n42. Barnes WJP, Pearman J, Platter J. 2008 Application of peeling theory to tree frog adhesion, a biological system with biomimetic implications. Eur. Acad. Sci. E-Newsletter Sci. Technol. 1, 1\u20132.\n\nP\n\n43. Smith JM, Barnes WJP, Downie JR, Ruxton GD. 2006 Adhesion and allometry from hil.T\n\nmetamorphosis to maturation in hylid tree frogs: a sticky problem. J. Zool. 270, 372\u2013383.\n\nra\n\n(doi:10.1111\/j.1469\u20137998.2006.00145.x)\n\nns.R","chunk_id":"a2e84db4531e11bb05a5e5cbdb285bb8","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"ASURING AND BEHAVIOUR-RECORDING SYSTEM\"","type":"\"ORGANIZATION\"","description":"\"This system is comprised of 24 separate 3D force plates to study single limb forces in climbing animals on a quasi-cylindrical tower.\") (\"entity\"","source_id":"a2e84db4531e11bb05a5e5cbdb285bb8"}],"entity_graph":" \"ORGANIZATION\"<\/data> \"This system is comprised of 24 separate 3D force plates to study single limb forces in climbing animals on a quasi-cylindrical tower.\") (\"entity\"<\/data> a2e84db4531e11bb05a5e5cbdb285bb8<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"b57944edc55bf9a8ed604f132186cac1","chunk":" and allometry from hil.T\n\nmetamorphosis to maturation in hylid tree frogs: a sticky problem. J. Zool. 270, 372\u2013383.\n\nra\n\n(doi:10.1111\/j.1469\u20137998.2006.00145.x)\n\nns.R\n\n44. Endlein T, Barnes WJP, Samuel DS, Crawford NA, Biaw AB, Grafe U. 2013 Sticking under wet\n\n.S\n\nconditions: the remarkable attachment abilities of the torrent frog, Staurois guttatus. PLoS ONE\n\noc.A\n\n8, e73810. (doi:10.1371\/journal.pone.0073810)\n\n37\n\n45. Heepe L, Xue L, Gorb SN. 2017 Bio-inspired structured adhesives. Germany: Springer 7:\n\nInternational Publishing.\n\n20190131\n\n46. Qu L, Dai L, Stone M, Xia Z, Wang ZL. 2008 Carbon nanotube arrays with strong shear binding-on and easy normal lifting-off. Science 322, 238\u2013242. (doi:10.1126\/science.1159503)\n\n47. Kim S, Cheung E, Sitti M. 2009 Wet self-cleaning of biologically inspired elastomer mushroom shaped microfibrillar adhesives. Langmuir 25, 7196\u20137199. (doi:10.1021\/la900732h)\n\n48. Xue L, Kovalev A, Th\u00f6le F, Rengarajan G, Steinhart M, Gorb SN. 2012 Tailoring normal adhesion of arrays of thermoplastic, spring-like polymer nanorods by shaping nanorod tips.\n\nLangmuir 28, 10 781\u201310 788. (doi:10.1021\/la3020354)\n\n49. Xue L, Kovalev A, Eichler-Volf A, Steinhart M, Gorb S. 2015 Humidity-enhanced wet adhesion on insect-inspired fibrillar adhesive pads. Nat. Commun. 6, 6621. (doi:10.1038\/ncomms7621)\n\n50. Xue L, Iturri J, Kappl M, Butt H, del Campo A. 2014 Bioinspired orientation dependent friction. Langmuir 30, 11 175\u201311 182","chunk_id":"b57944edc55bf9a8ed604f132186cac1","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"SAMUEL DS\"","type":"\"PERSON\"","description":"\"Samuel DS contributes to research on metamorphosis and maturation in hylid tree frogs at the Journal of Zoology.\") (\"entity\"","source_id":"b57944edc55bf9a8ed604f132186cac1"}],"entity_graph":" \"PERSON\"<\/data> \"Samuel DS contributes to research on metamorphosis and maturation in hylid tree frogs at the Journal of Zoology.\") (\"entity\"<\/data> b57944edc55bf9a8ed604f132186cac1<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"8d4a6778098c667728901fd5eb6ae286","chunk":", 6621. (doi:10.1038\/ncomms7621)\n\n50. Xue L, Iturri J, Kappl M, Butt H, del Campo A. 2014 Bioinspired orientation dependent friction. Langmuir 30, 11 175\u201311 182. (doi:10.1021\/la502695d)\n\n51. Jeong HE, Suh KY. 2009 Nanohairs and nanotubes: efficient structural elements for gecko-inspired artificial dry adhesives. Nano Today 4, 335\u2013346. (doi:10.1016\/j.nantod.2009.06.004)\n\n52. Greiner C, del Campo A, Arzt E. 2007 Adhesion of bioinspired micropatterned surfaces: effects of pillar radius, aspect ratio, and preload. Langmuir 23, 3495\u20133502. (doi:10.1021\/la0633987)\n\n53. Wang X, Tan D, Zhang X, Lei Y, Xue L. 2017 Effective elastic modulus of structured adhesives: from biology to biomimetics. Biomimetics 2, 10. (doi:10.3390\/biomimetics2030010)\n\n54. Xie J, Li M, Dai Q, Huang W, Wang X. 2018 Key parameters of biomimetic patterned surface for wet adhesion. Int. J. Adhes. Adhes. 82, 72\u201378. (doi:10.1016\/j.ijadhadh.2018.01.004)\n\n55. Iturri J, Xue L, Kappl M, Garc\u00eda-Fern\u00e1ndez L, Barnes WJP, Butt H-J, del Campo A. 2015 Torrent Downloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\nfrog-inspired adhesives: attachment to flooded surfaces. Adv. Funct. Mater. 25, 1499\u20131505.\n\n(doi:10.1002\/adfm.201403751)\n\n56. Grohmann C, Henze M, N\u00f8rgaard T, Gorb SN. 2015 Two functional types of attachment pads on a single foot in the Namibia bush cricket, Acanthoproctus diadematus (Orthoptera: Tettigoniidae). Proc. R. Soc.","chunk_id":"8d4a6778098c667728901fd5eb6ae286","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"XUE L\"","type":"\"PERSON\"","description":"\"Xue L contributed to research on bioinspired orientation-dependent friction as well as effective elastic modulus of structured adhesives.\")|(\"entity\"","source_id":"8d4a6778098c667728901fd5eb6ae286"}],"entity_graph":" \"PERSON\"<\/data> \"Xue L contributed to research on bioinspired orientation-dependent friction as well as effective elastic modulus of structured adhesives.\")|(\"entity\"<\/data> 8d4a6778098c667728901fd5eb6ae286<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"0811d9716cba27dcf5ea6e92aa1e9c14","chunk":" C, Henze M, N\u00f8rgaard T, Gorb SN. 2015 Two functional types of attachment pads on a single foot in the Namibia bush cricket, Acanthoproctus diadematus (Orthoptera: Tettigoniidae). Proc. R. Soc. B 282, 20142976. (doi:10.1098\/rspb.2014.2976)\n\n57. Li M, Huang W, Wang X. 2015 Bioinspired, peg-studded hexagonal patterns for wetting and friction. Biointerphases 10, 031008. (doi:10.1116\/1.4930176)\n\n58. Turner KT, Minsky HK. 2015 Achieving enhanced and tunable adhesion via composite posts.\n\nAppl. Phys. Lett. 106, 201604. (doi:10.1063\/1.4921423)\n\n59. Tinnemann V, Hern\u00e1ndez L, Fischer SCL, Arzt E, Bennewitz R, Hensel R. 2019 In situ observation reveals local detachment mechanisms and suction effects in micropatterned adhesives. Adv. Funct. Mater. 29, 201807713. (doi:10.1002\/adfm.201807713)\n\n60. Drotlef D, Stepien L, Kappl M, Barnes WJP, Butt H, del Campo A. 2013 Insights into the adhesive mechanisms of tree frogs using artificial mimics. Adv. Funct. Mater. 23, 1137\u20131146.\n\n(doi:10.1002\/adfm.201202024)\n\n61. del Campo A, Greiner C, Arzt E. 2007 Contact shape controls adhesion of bioinspired fibrillar 22\n\nsurfaces. Langmuir 23, 10 235\u201310 243. (doi:10.1021\/la7010502)\n\n62. Heepe L, Kovalev AE, Filippov AE, Gorb SN. 2013 Adhesion failure at 180,000 frames per r\n\n............................................................... oy\n\nsecond: direct observation of the detachment process of a mushroom-shaped adhesive. Phys.\n\nalsociet\n\nRev. Lett. 111, 104301. (doi:10.1103\/PhysRevLett.111.104301)\n\n63. Xue L et","chunk_id":"0811d9716cba27dcf5ea6e92aa1e9c14","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[],"entity_graph":" <\/graphml>"} +{"id":"c4d44d325061282d6b5587ff3f292d20","chunk":" per r\n\n............................................................... oy\n\nsecond: direct observation of the detachment process of a mushroom-shaped adhesive. Phys.\n\nalsociet\n\nRev. Lett. 111, 104301. (doi:10.1103\/PhysRevLett.111.104301)\n\n63. Xue L et al. 2017 Hybrid surface patterns mimicking the design of the adhesive toe pad of tree ypublishing\n\nfrog. ACS Nano 11, 9711\u20139719. (doi:10.1021\/acsnano.7b04994)\n\n64. Turner KT, Minsky HK. 2017 Composite microposts with high dry adhesion strength. ACS\n\nAppl. Mater. Interfaces 9, 18 322\u201318 327. (doi:10.1021\/acsami.7b01491)\n\n.\n\n65. Bae W-G, Kwak MK, Jeong HE, Pang C, Jeong H, Suh K-Y. 2013 Fabrication and org\/journal\/rsta\n\nanalysis of enforced dry adhesives with core\u2013shell micropillars. Soft Matter 9, 1422\u20131427.\n\n(doi:10.1039\/C2SM27323C)\n\n66. Milad T, Amir M, Kevin T, Shan W. 2018 Dynamically tunable dry adhesion via subsurface stiffness modulation. Adv. Mater. Interfaces 5, 1800321. (doi:10.1002\/admi2018003 21)\n\n67. Varenberg M, Gorb S. 2009 Hexagonal surface micropattern for dry and wet friction. Adv.\n\nP\n\nMater. 21, 483\u2013486. (doi:10.1002\/adma.200802734)\n\nhil.T\n\n68. Cheung E, Sitti M. 2008 Adhesion of biologically inspired oil-coated polymer micropillars. J.\n\nra\n\nAdhes. Sci. Technol. 22, 569\u2013589. (doi:10.1163\/156856108X295545)\n\nns.R\n\n69. Majumder A, Ghatak A, Sharma A. 2007 Microfluidic adhesion induced by subsurface\n\n.S\n\nmicrostructures. Science 318, 258\u2013261. (doi:10.1126\/science.1145839)\n\noc.A\n\n70. Gong L, Yu H, Wu X, Wang","chunk_id":"c4d44d325061282d6b5587ff3f292d20","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[],"entity_graph":" <\/graphml>"} +{"id":"221b04279ff2633a5d567aa14627c640","chunk":", Ghatak A, Sharma A. 2007 Microfluidic adhesion induced by subsurface\n\n.S\n\nmicrostructures. Science 318, 258\u2013261. (doi:10.1126\/science.1145839)\n\noc.A\n\n70. Gong L, Yu H, Wu X, Wang X. 2018 Wet-adhesion properties of microstructured surfaces 37\n\ninspired by newt footpads. Smart Mater. Struct. 27, 114001. (doi:10.1088\/1361-665x\/aad6d2)\n\n7:\n\n71. Ma Y, Ma S, Wu Y, Pei X, Gorb S, Wang Z, Liu W, Zhou F. 2018 Remote control over 20190131\n\nunderwater dynamic attachment\/detachment and locomotion. Adv. Mater. 30, 1801595.\n\n(doi:10.1002\/adma.201801595)\n\n72. Yi H, Lee S, Seong M, Kwak M, Jeong H. 2018 Bioinspired reversible hydrogel adhesives for wet and underwater surfaces. J. Mater. Chem. B 6, 8064. (doi:10.1039\/c8tb02598c)\n\n73. Rao P, Sun T, Chen L, Takahashi R, Shinohara G, Guo H, Gong J. 2018 Tough hydrogels with fast, strong, and reversible underwater adhesion based on a multiscale design. Adv. Mater. 30, 1801884. (doi:10.1002\/adma.201801884)\n\n74. Chen H, Zhang L, Zhang D, Zhang P, Han Z. 2015 Bioinspired surface for surgical graspers based on the strong wet friction of tree frog toe pads, ACS Appl. Mater. Interfaces 7, 13 987\u2013\n\n13 995. (doi:10.1021\/acsami.5b03039)\n\n75. Ko H, Seong M, Jeong HE. 2017 A micropatterned elastomeric surface with enhanced frictional properties under wet conditions and its application. Soft Matter 13, 8419\u20138425.\n\n(doi:10.1039\/c7sm01493g)\n\n76. Pepelyshev A, Borodich FM, Galanov BA, Gorb EV, Gorb SN. 2018 Adhesion of soft","chunk_id":"221b04279ff2633a5d567aa14627c640","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[{"name":"\"GHATAK A\"","type":"\"PERSON\"","description":"\"A is a co-author in the publication 'Microfluidic adhesion induced by subsurface microstructures' published in Science in 2007.\") (\"entity\"","source_id":"221b04279ff2633a5d567aa14627c640"}],"entity_graph":" \"PERSON\"<\/data> \"A is a co-author in the publication 'Microfluidic adhesion induced by subsurface microstructures' published in Science in 2007.\") (\"entity\"<\/data> 221b04279ff2633a5d567aa14627c640<\/data> <\/node> <\/graph><\/graphml>"} +{"id":"27db6082de83c767fdf0aab225ff9768","chunk":" conditions and its application. Soft Matter 13, 8419\u20138425.\n\n(doi:10.1039\/c7sm01493g)\n\n76. Pepelyshev A, Borodich FM, Galanov BA, Gorb EV, Gorb SN. 2018 Adhesion of soft materials to rough surfaces: experimental studies, statistical analysis and modelling. Coatings 350, 1\u201317.\n\n(doi:10.3390\/coatings8100350)\n\n77. Kovalev AE, Varenberg M, Gorb SN. 2012 Wet versus dry adhesion of biomimetic mushroom-shaped microstructures. Soft Matter 8, 7560\u20137566. (doi:10.1039\/C2SM25431J)\n\n78. Persson B. 2008 Capillary adhesion between elastic solids with randomly rough surfaces. J.\n\nPhys. Condens. Mat. 20, 315007. (doi:10.1088\/0953-8984\/20\/31\/315007)\n\nDownloaded from https:\/\/royalsocietypublishing.org\/ on 09 July 2023\n\n79. Bartlett MD, Croll AB, King DR, Paret BM, Irschick DJ, Crosby AJ. 2012 Looking beyond fibrillar features to scale gecko-like adhesion. Adv. Mater. 24, 1078\u20131083.\n\n(doi:0.1002\/adma.201104191)\n\n80. Vogel MJ, Steen PH. 2010 Capillarity-based switchable adhesion. Proc. Natl. Acad. Sci. USA 107, 3377\u20133381. (doi:10.1073\/pnas.0914720107)\n\n81. Nguyen PV, Huynh NV, Phan TT, Ho VA. 2018 Soft grasping with wet adhesion: Preliminary evaluation. In 2018 IEEE International Conference on Soft Robotics (Robosoft), Livorno, Italy, April 24\u201328, 2018, pp. 418\u2013422. IEEE.\n\n82. Tsipenyuk A, Varenberg M. 2014 Use of biomimetic hexagonal surface texture in friction against lubricated skin. J. R. Soc. Interface 11, 20140113. (doi:10.1098\/rsif.2014.0113)\n\n83. Kim DW, Baik S, Min H","chunk_id":"27db6082de83c767fdf0aab225ff9768","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":512,"entities":[],"entity_graph":" <\/graphml>"} +{"id":"cda9b37513bc2f8036dfff4a389184d7","chunk":"berg M. 2014 Use of biomimetic hexagonal surface texture in friction against lubricated skin. J. R. Soc. Interface 11, 20140113. (doi:10.1098\/rsif.2014.0113)\n\n83. Kim DW, Baik S, Min H, Chun S, Lee HJ, Kim KH, Lee JY, Pang C. 2019 Highly permeable skin patch with conductive hierarchical architectures inspired by amphibians and octopi for omnidirectionally enhanced wet adhesion. Adv. Funct. Mater. 29, 201807614.\n\n(doi:0.1002\/adfm.201807614)\n\n\n\n\n\nDocument Outline\n\n\nIntroduction\n\nTree\/torrent frog adhesion Toe-pad structure and function\n\nMechanisms of adhesion and friction and the forces they produce: physical principles\n\n\n\n\n\nBiomimetics of tree frog adhesion and friction Influences of aspect ratio of pillar\n\nInfluences of micro- and nanostructure\n\nAdhesion with liquid at interface\n\n\n\n\n\nApplications\n\nConclusion and outlook\n\nReferences\n\n\n\n\n\n","chunk_id":"cda9b37513bc2f8036dfff4a389184d7","document_ids":["b422f2963081b08277436cb3b7fee48d"],"n_tokens":219,"entities":[{"name":"\"BERG M.\"","type":"\"PERSON\"","description":"\"Author Berg is associated with the publication 'Use of biomimetic hexagonal surface texture in friction against lubricated skin', indicating expertise or contribution to research in this field.\"","source_id":"cda9b37513bc2f8036dfff4a389184d7"},{"name":"\"KIM DW, BAIK S, MIN H, CHUN S, LEE HJ, KIM KH, LEE JY, PANG C.\"","type":"\"TEAM\"","description":"\"The team of authors includes contributors from various institutions who together have published a paper on 'Highly permeable skin patch with conductive hierarchical architectures inspired by amphibians and octopi for omnidirectionally enhanced wet adhesion', showcasing collaborative research effort.\"","source_id":"cda9b37513bc2f8036dfff4a389184d7"},{"name":"\"ADVANCED FUNCTIONAL MATERIALS\"","type":"\"ORGANIZATION\"","description":"\"The team of authors is associated with the publication in Advanced Functional Materials, suggesting that the paper has undergone peer review and was accepted for publication by this reputable scientific journal.\"","source_id":"cda9b37513bc2f8036dfff4a389184d7"},{"name":"\"PUBLICATION\"","type":"","description":"","source_id":"cda9b37513bc2f8036dfff4a389184d7"}],"entity_graph":" \"PERSON\"<\/data> \"Author Berg is associated with the publication 'Use of biomimetic hexagonal surface texture in friction against lubricated skin', indicating expertise or contribution to research in this field.\"<\/data> cda9b37513bc2f8036dfff4a389184d7<\/data> <\/node> \"TEAM\"<\/data> \"The team of authors includes contributors from various institutions who together have published a paper on 'Highly permeable skin patch with conductive hierarchical architectures inspired by amphibians and octopi for omnidirectionally enhanced wet adhesion', showcasing collaborative research effort.\"<\/data> cda9b37513bc2f8036dfff4a389184d7<\/data> <\/node> \"ORGANIZATION\"<\/data> \"The team of authors is associated with the publication in Advanced Functional Materials, suggesting that the paper has undergone peer review and was accepted for publication by this reputable scientific journal.\"<\/data> cda9b37513bc2f8036dfff4a389184d7<\/data> <\/node> cda9b37513bc2f8036dfff4a389184d7<\/data> <\/node> 1.0<\/data> \"Author Berg is directly linked to the publication 'Use of biomimetic hexagonal surface texture in friction against lubricated skin', indicating a specific contribution or lead authorship to this research work.\"<\/data> cda9b37513bc2f8036dfff4a389184d7<\/data> <\/edge> 1.0<\/data> \"The team of authors collectively contributed to the publication 'Highly permeable skin patch with conductive hierarchical architectures inspired by amphibians and octopi for omnidirectionally enhanced wet adhesion', highlighting their collaborative effort in advancing biomimetic research.\"<\/data> cda9b37513bc2f8036dfff4a389184d7<\/data> <\/edge> 1.0<\/data> \"The publication 'Highly permeable skin patch with conductive hierarchical architectures' was published in this journal, indicating that the research meets high standards for originality and scientific rigor as required by peer-reviewed journals.\"<\/data> cda9b37513bc2f8036dfff4a389184d7<\/data> <\/edge> <\/graph><\/graphml>"} diff --git a/indexing/output/20240722-073448/artifacts/stats.json b/indexing/output/20240722-073448/artifacts/stats.json new file mode 100644 index 0000000000000000000000000000000000000000..34882f9381c3c0ea427085eba16c1bfc2203c848 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/stats.json @@ -0,0 +1,145 @@ +{ + "total_runtime": 1.5136950016021729, + "num_documents": 4, + "input_load_time": 0, + "workflows": { + "create_base_text_units": { + "overall": 0.13227605819702148, + "0_orderby": 0.0005140304565429688, + "1_zip": 0.0005142688751220703, + "2_aggregate_override": 0.0011670589447021484, + "3_chunk": 0.1229550838470459, + "4_select": 0.0004987716674804688, + "5_unroll": 0.0008428096771240234, + "6_rename": 0.00020813941955566406, + "7_genid": 0.0024001598358154297, + "8_unzip": 0.000453948974609375, + "9_copy": 0.00013589859008789062, + "10_filter": 0.00238800048828125 + }, + "create_base_extracted_entities": { + "overall": 0.10479593276977539, + "0_entity_extract": 0.08818578720092773, + "1_snapshot": 0.003165006637573242, + "2_merge_graphs": 0.012736082077026367, + "3_snapshot_rows": 0.0005371570587158203 + }, + "create_summarized_entities": { + "overall": 0.02032780647277832, + "0_summarize_descriptions": 0.019580841064453125, + "1_snapshot_rows": 0.0006158351898193359 + }, + "create_base_entity_graph": { + "overall": 0.014664173126220703, + "0_cluster_graph": 0.01278376579284668, + "1_snapshot_rows": 0.0007550716400146484, + "2_snapshot_rows": 0.0005922317504882812, + "3_select": 0.0003769397735595703 + }, + "create_final_entities": { + "overall": 0.09038400650024414, + "0_unpack_graph": 0.0032241344451904297, + "1_rename": 0.00032329559326171875, + "2_select": 0.0003058910369873047, + "3_dedupe": 0.0002932548522949219, + "4_rename": 0.00020313262939453125, + "5_filter": 0.0020439624786376953, + "6_text_split": 0.0021882057189941406, + "7_drop": 0.00030493736267089844, + "8_merge": 0.015229940414428711, + "9_text_embed": 0.06373310089111328, + "10_drop": 0.0004851818084716797, + "11_filter": 0.0018258094787597656 + }, + "create_final_nodes": { + "overall": 0.030784130096435547, + "0_layout_graph": 0.013424873352050781, + "1_unpack_graph": 0.004388093948364258, + "2_unpack_graph": 0.0045928955078125, + "3_filter": 0.0018002986907958984, + "4_drop": 0.0002841949462890625, + "5_select": 0.000270843505859375, + "6_snapshot": 0.0010330677032470703, + "7_rename": 0.00024819374084472656, + "8_convert": 0.0010979175567626953, + "9_join": 0.003062009811401367, + "10_rename": 0.0003619194030761719 + }, + "create_final_communities": { + "overall": 0.020625829696655273, + "0_unpack_graph": 0.003055095672607422, + "1_unpack_graph": 0.002624988555908203, + "2_aggregate_override": 0.001055002212524414, + "3_join": 0.0021820068359375, + "4_join": 0.001898050308227539, + "5_concat": 0.0002319812774658203, + "6_filter": 0.0024220943450927734, + "7_aggregate_override": 0.0014810562133789062, + "8_join": 0.002330303192138672, + "9_filter": 0.001989126205444336, + "10_fill": 0.0002281665802001953, + "11_merge": 0.0004961490631103516, + "12_copy": 0.00017404556274414062, + "13_select": 0.00021409988403320312 + }, + "join_text_units_to_entity_ids": { + "overall": 0.0036978721618652344, + "0_select": 0.0004208087921142578, + "1_unroll": 0.0008499622344970703, + "2_aggregate_override": 0.002292156219482422 + }, + "create_final_relationships": { + "overall": 0.010072946548461914, + "0_unpack_graph": 0.003659963607788086, + "1_filter": 0.001821279525756836, + "2_rename": 0.0002338886260986328, + "3_filter": 0.0013699531555175781, + "4_drop": 0.00025391578674316406, + "5_compute_edge_combined_degree": 0.0018308162689208984, + "6_convert": 0.0003688335418701172, + "7_convert": 0.0003268718719482422 + }, + "join_text_units_to_relationship_ids": { + "overall": 0.0024530887603759766, + "0_select": 0.000392913818359375, + "1_unroll": 0.0007088184356689453, + "2_aggregate_override": 0.0009312629699707031, + "3_select": 0.0002658367156982422 + }, + "create_final_community_reports": { + "overall": 0.017195940017700195, + "0_prepare_community_reports_nodes": 0.0020551681518554688, + "1_prepare_community_reports_edges": 0.0007069110870361328, + "2_restore_community_hierarchy": 0.0016598701477050781, + "3_prepare_community_reports": 0.008458137512207031, + "4_create_community_reports": 0.0028908252716064453, + "5_select": 0.00039005279541015625, + "6_window": 0.0004718303680419922, + "7_select": 0.0003101825714111328 + }, + "create_final_text_units": { + "overall": 0.0069141387939453125, + "0_select": 0.00038695335388183594, + "1_rename": 0.0002617835998535156, + "2_join": 0.0026121139526367188, + "3_join": 0.002129077911376953, + "4_aggregate_override": 0.0011298656463623047, + "5_select": 0.00024199485778808594 + }, + "create_base_documents": { + "overall": 0.006921052932739258, + "0_unroll": 0.001024007797241211, + "1_select": 0.0002758502960205078, + "2_rename": 0.0002422332763671875, + "3_join": 0.0019369125366210938, + "4_aggregate_override": 0.0007669925689697266, + "5_join": 0.0018439292907714844, + "6_rename": 0.0002079010009765625, + "7_convert": 0.00043892860412597656 + }, + "create_final_documents": { + "overall": 0.000492095947265625, + "0_rename": 0.00035262107849121094 + } + } +} \ No newline at end of file diff --git a/indexing/output/20240722-073448/artifacts/summarized_graph.graphml b/indexing/output/20240722-073448/artifacts/summarized_graph.graphml new file mode 100644 index 0000000000000000000000000000000000000000..cba68a608e6a1c455030609a16febf5c12cb70c9 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/summarized_graph.graphml @@ -0,0 +1,1280 @@ + + + + + + + + + + "ORGANIZATION" + The AskNature Team, associated with the entity named "ASKNATURE TEAM", is dedicated to creating educational content about living systems, which notably includes information about birds. Their work encompasses not only the creation of such materials but also involves cataloging knowledge on biomimicry and natural strategies like 'Spiral Fibers'. As a research-focused group, the AskNature Team conducts programs aimed at understanding nature's solutions for various applications in technology, design, and problem-solving processes, effectively bridging human innovation with ecological wisdom. + 30aa281b7ea0845a9f88c0914df109c3,4305d6610a2538765dc1ea9aed78ea5e,a3d83dc700d8d01b07a94c2a1180c2b4 + + + "PROCESS" + "The process by which birds inhale and exhale air through their respiratory system for oxygen intake and carbon dioxide expulsion.") ("entity" + a5430820e1ece1dff536ad804e55c798 + + + "PERSON" + "ANDY CARSTENS" refers to an author dedicated to exploring natural phenomena, with a notable focus on innovations inspired by nature. One of his works highlights the biological strategy adopted by birds utilizing ground effect to minimize drag and conserve energy while gliding over water, showcasing his deep interest in understanding and explaining the intricacies of natural behavior and engineering. + 4d6faade61b11859190946a315c34a2e,8afa448acb86b96422cea043f3fd6749 + + + "ORGANISM" + "The Flying squirrels are the subject of study due to their ability to control their glide." + 638dc502f70bb90aeb0465be8db1facc + + + "ORGANIZATION" + The Biomimicry Institute is an organization centered on studying natural principles to address human challenges, promoting sustainability in design and technology through innovation inspired by nature. As a copyright holder, it specializes in finding solutions based on the strategies observed within ecosystems and operates through platforms like AskNature for disseminating educational content about nature-based innovations. The institute's primary objective is to educate and provide biological strategy insights for human design applications, specifically focusing on understanding and replicating mechanisms found in nature to enhance human technologies, such as observing glide behaviors of flying squirrels and applying that knowledge to improve areas like parachutes or skydiving suits. This organization behind Biomimicry.org provides comprehensive information and guidance on how to utilize nature's problem-solving methods within various sectors of human technology development. + 4d6faade61b11859190946a315c34a2e,74a8b683e829577d39bd3b12018ddee0,75be22a096d450ebe20ed42f79da45da,7c777850b39440dea33d9b60641e803b,809da8a35547ca53620a67d4f1cdb6f5,891d3f28f888b374a21d9c781295bbf9,90ede7f9f06fa68f01d8528ec2495d4b,e9161c0416f80b08625e2dcd9f70167f + + + "PERSON" + "This refers to researchers who contributed to a study on gliding performance of mammals, particularly northern flying squirrels (Glaucomys sabrinus)." + a3d83dc700d8d01b07a94c2a1180c2b4 + + + "ORGANISM" + "The Black-tailed prairie dog is an animal that builds extensive burrows in the plains of North America and performs functions like distributing gases." + a3d83dc700d8d01b07a94c2a1180c2b4 + + + "CREATIVE WORKER" + "This refers to a photographer whose image has been used in publications related to nature studies, with permission granted for use." + a3d83dc700d8d01b07a94c2a1180c2b4 + + + "ORGANIZATION" + "AskNature.org, a component of the Biomimicry.org platform, serves as an online resource for users seeking to explore and apply natural strategies in their innovations. This unique website presents knowledge and tools related to nature-based solutions and biomimicry with a focus on heliotropism, the movement of plants towards the sun. As part of this mission, Lonny Lippsett shared insights on self-organization within diverse soil ecosystems on the AskNature.org platform. + +AskNature.org is dedicated to facilitating biologically inspired innovations by showcasing effective biological strategies that can help solve human challenges through nature's principles. This resource platform features a variety of organisms and ideas that have been adopted from natural systems, aiming to provide inspiration for sustainable problem-solving and design across multiple fields." + +Please note that there seems to be some confusion or inconsistency in the descriptions provided about whether 'AskNature' is one entity (AskNature.org) or if it refers to two distinct entities ('AskNature.ORG' and 'Asknature.org'). However, based on the context given and assuming a single entity for consistency, this summary provides an accurate synthesis of the provided information. + +If you need further clarification or another interpretation, please specify so I can assist better! + 0a71d2671ba6b6bceb2f13e60122c278,10a8260a1ac5e4f2ab531d67e534b83f,3678ab8d2bad24bba44d0a83fe09f8a6,42b463f5b40c4f86e9338c967c8d5bfa,75be22a096d450ebe20ed42f79da45da,fb3016519d20d8e4fc1d25d5690a550a + + + "PERSON" + "Sam Rivera appears to be associated with an unspecified organization that specializes in biological research, with a particular emphasis on adhesive mechanisms found in nature. This involves studying and understanding these natural adhesion properties which might have various applications or areas of interest. Although the exact location of this organization is not explicitly stated, it's suggested they are involved in projects conducted in Saudi Arabia where echolocation techniques are utilized for food searching. The research also includes interaction with an Egyptian fruit bat as part of these studies. Despite being mentioned in relation to an organization and these specific activities, the description contradicts itself by stating that Sam Rivera is 'not mentioned' in the provided real data." + 777a1482c060a064af315a8488df370a,b01ac6d637b8d31e396081208c8162d0,d99568b2216b6501020a719efe70edaf + + + "ORGANISM" + "A species of frog specifically adapted to living in water-filled tree hollows, utilizing their environment to amplify vocal calls.|) ("entity" + aff4d366caa94978fbabd1021d43d555 + + + "SPECIES" + "Specific types of snakes known for their unique ability to create loud defensive sounds." + 4d6faade61b11859190946a315c34a2e + + + "ACTION" + "Visiting a specific strategy on AskNature for investigation into interactions between vortices and trout. The website provides scientific articles related to the topic." + 8fa82d96bb00621623d0d7c9e9ac5034 + + + "OBJECT" + "Butterfly wings are a natural model that shows how micro-geometrical patterns enhance airflow and facilitate flight through specific scale configurations.") ("entity" + 01117b72383429324254870387eb4aba + + + "BIOLOGICAL STRATEGY" + "The micro-geometry of butterfly wing scales provides insights into designing efficient wind turbines, improved structural stability in tall buildings, and more." + 5bec096731ec31b017777a7aadf747bc + + + "ORGANIZATION" + "The Diving Bell Spider serves as a biological inspiration for technological innovations in air supply and water-resistant materials." ) ("entity" + 81eee876cafa81ab3b11ed19cc045cb6 + + + "PERSON" + "Roger S. Seymour is an author who contributed to the Journal of Experimental Biology in 2011.") ("entity" + eedd4bc29a0007151fb16d1deec2f9eb + + + "ORGANIZATION" + "Spiders use trichobothria for sensing and movement control in hunting and navigating their environment." + 3d22053debaab18c4e321d4cfe15f8af + + + "CONCEPT" + "Trichobothria are sensory structures on spiders’ legs that enhance their sensitivity to touch, vibrations, and motion." + 3d22053debaab18c4e321d4cfe15f8af + + + "EVENT" + "The hypersensitivity provided by trichobothria allows spiders to detect underwater currents or the presence of sea life." + 3d22053debaab18c4e321d4cfe15f8af + + + "CONCEPT" + "Spiders use information from their environment, like the activity of other organisms and environmental cues, for hunting, navigation, and self-defense." + 3d22053debaab18c4e321d4cfe15f8af + + + "ORGANIZATION" + "The concept of integrating spider's sensory capacity into wearable devices or clothing could improve motion detection beyond human vision." + 3d22053debaab18c4e321d4cfe15f8af + + + "WEBSITE" + "Website for the organization Biomimicry Institute, providing information about strategies found in nature and how they can be applied." + 75be22a096d450ebe20ed42f79da45da + + + "PERSON" + "A researcher contributing his expertise in the biological strategy related to spiders and electric currents for biomimetics applications." + 75be22a096d450ebe20ed42f79da45da + + + "PERSON" + "The individual credited with discovering or understanding how certain spiders fly using electrostatic repulsion, possibly contributing knowledge to biomimetic engineering." + 75be22a096d450ebe20ed42f79da45da + + + "PERSON" + "A contributor or researcher who provided insights or evidence supporting the spider flying phenomenon, influencing scientific community." + 75be22a096d450ebe20ed42f79da45da + + + "PERSON" + "A researcher involved in the study that shed light on spiders' use of electrostatic forces for flight, providing significant biological data for biomimetics." + 75be22a096d450ebe20ed42f79da45da + + + "EVENT" + "Spiders were observed to exhibit 'balloon' like flight in low wind conditions due to atmospheric electric fields.") ("entity" + 621c0cd608f4ed99a4dd7a5c25c8e0b5 + + + "PERSON" + "Mary Hoff authored a strategy on AskNature explaining how water striders communicate using vibrations and their legs.") ("entity" + 60d4060427254b2a553815d05dce7fcf + + + "ORGANISM" + "A species of insects that communicate through tapping the water surface and have highly sensitive motion-detecting structures on their legs.") ("entity" + bd3e8fcd1e1991500d9610859ecfabf4 + + + "PERSON" + "Pablo Perez is responsible for inventing devices that provide advanced warning of impending earthquakes or mudslides, possibly inspiring new technology.") + f228fcbbb8f2ec33599ea9a3d5d4e854 + + + "PERSON" + "He created an image for this document under CC BY-SA license.") ("entity" + 1ff6815fa5511debe6f17ad17c1707b1 + + + "ORGANISM" + "Plants use strategies like tropisms (gravitropism, thigmotropism, phototropism, heliotropism) to adapt and respond efficiently to their environment.") ("entity" + c8455055703093614be4105105a67f0e + + + "PERSON" + "Peter Prehn, a contributor to Biomimicry Institute and AskNature.org, explains the underground network strategy of mycorrhizal fungi in a Douglas-fir and pine forest context.") ("entity" + 2defde0504bd9c1a5bdd248980ce1ce1 + + + "ORGANISM" + "Mycorrhizal fungi form mutualistic partnerships with trees and other plants, facilitating nutrient exchange and communication through the Wood Wide Web.") ("entity" + dbf85def96906b82d29e7bcd512b920f + + + "CONCEPT" + "A network formed between the roots of plants and fungi, facilitating resource exchange, information sharing, and mutual support among plant communities.") ("entity" + ac3f4943aac0de17b70d54bf387fe19b + + + "PERSON" + "Lonny Lippsett wrote about biological strategies performed by organisms living in soil ecosystem, particularly focusing on self-organization." + 0a71d2671ba6b6bceb2f13e60122c278 + + + "ORGANIZATION" + "This refers to the diverse ecosystem that works together to break down organic matter and recycle it into nutrients for plants to reuse.")<|"\n"|"Entity" + 17c65307eb89a2d2f26db3e34ba78722 + + + "EVENT" + "AN-Bird Respiration_Final_05-2022 refers to a document that discusses bird respiration process which is being finalized in the month of May 2022.") ("entity" + 03018b77601ad2b2e8345af35fb84450 + + + "CONCEPT" + "It is a system of classification developed by the Biomimicry Institute for organizing biological content on their website AskNature.org. This taxonomy categorizes strategies that organisms and natural systems use to meet functional challenges. The strategies are classified according to functions, which describe what the strategy accomplishes for the organism or living system. This helps users identify potential solutions to similar human challenges by looking at nature's approach to solving issues.") + ff760235e3461c93ff1fa2bee432fdb1 + + + "ORGANIZATION" + "AskNature is an online platform providing access to strategies and insights from natural systems for design solutions." ) ("entity" + e4b6193a4ea13cb8c682998eb02efb6d + + + "BIOMIMICRY TAXONOMY" + "ORGANIZATION" encompasses diverse functions across various fields: + +1) Serving as a database central to bibliometric analysis, this entity supports researchers and academics by facilitating the discovery of pertinent publications and fostering an understanding of academic trends. + +2) In addition to its role in bibliometrics, "ORGANIZATION" is recognized for publishing research journals like 'Phil.Trans.RoyalSoc.A', making it both a publisher and an academic organization. + +3) It plays an innovative role in biomimicry through the Biomimicry Taxonomy framework. This entity helps drive innovation by identifying new verbs and related concepts, encouraging the application of nature-inspired solutions that foster creative activities involving interdisciplinary knowledge. + +4) Engaging with themes linked to sustainability, "ORGANIZATION" is dedicated to understanding ecological systems and their transformations as well as the services they offer, defining it as a part of CTU (Centre for Teaching and Understanding). + +5) As an entity involved in studying ecosystem dynamics, it collaborates on diverse themes including the physical state modifications and services provided by ecosystems. + +6) Notably, "ORGANIZATION" also includes NC 4.0, which might represent either a specific program or organization focused on creative license or collaborative efforts. + +In summary, this multifaceted entity acts as both a database for scholarly research analysis and dissemination, alongside a publisher of academic journals. It is pivotal in fostering innovation through nature-inspired solutions and contributes to ecological studies centered around sustainability. Moreover, it collaborates with diverse stakeholders under themes like creative activities and is involved in the exploration of ecosystem dynamics. + 170684a57b4848b420032214260ee67b,23c34b74899c04c60dc7b087b88e0137,3b302bec9259fbca0cf68da76392935c,44c8dff86ecf90b601e21ef2335e8c61,6de0fc3cc6011a0ce9267a0584f498b2,84d05d265cebbc1d33e9d523b860d87e,a19c62053cac11a3e022402443eeba83,dd615bbb350414d251cb1083b3142230,fe902bcadf86addbe747f348c1ccc56f + + + "H" + "H could represent any individual within an organization or group dealing with eco-system management, focusing on behaviors optimization, space/material adaptation, and coordination with other groups." + 170684a57b4848b420032214260ee67b + + + "PERSON" + "Alex is the leader of a team attempting first contact with an unknown intelligence, acknowledging the significance of their task." + 2b9b282e75a0a5345cc0cee8f327a2b1 + + + "ORGANIZATION" + "BOHsihana is involved in the process of attempting to communicate with an unknown intelligence through their technological means and research." + 3b8a807b256d918245b0ffb8c88d4c09 + + + "PERSON" + "A biomimetics researcher at the Department of Design, University of Brasília, who has contributed to studying the application and integration of biological knowledge in design.")|("entity" + 7323cecb72b3fa0472a26a5aa37c4131 + + + "PUBLICATION" + "Biomimetics 2023" refers to a journal that focuses on sharing insights and research related to biomimetics in the year 2023. It published a study contained within volume 8, issue number 61 of the publication titled 'Biomimetics'. This article explores thematic aspects associated with design and biomimicry, emphasizing product conception and structural explorations of nature for new materials that contribute to sustainability while conserving resources. The journal's interest lies in showcasing how creative tools are applied in product design to achieve environmental responsibility." + 2aee03ca69624bff0ae2d030f6f31e19,7982a2e4054b66ae19457bde8585eaa8,af3fc23c5069edd0bdffd8f9a64d3ab2,b23a7cb845fd949e0baab80bf6f0c4f8 + + + "CONCEPT" + "Biological concepts or ideas that are mimicked by humans in various fields, often for innovation and problem-solving.") ("entity" + 6e87b92e6c843cb54a008ae676d3b416 + + + "CONCEPT" + "Imitative or biomimetic design that draws on concepts found in nature to solve human challenges and promote sustainability.") + a43faaba2ebb888387d5b0f59efb6381 + + + "JOURNAL" + "Biomimetics is a comprehensive field of study that draws inspiration from nature's principles to address intricate human challenges. It focuses on exploring and emulating natural systems for solving engineering problems, which involves developing new materials and devising innovative devices based on biological concepts. This field studies both existing natural designs and presents analyses on design and architecture topics, as exemplified by the publication Biomimetics from the late 1990s." + 2790f03c21ca0d9a522e2c1276ad4f6e,b3c5de72ae4c784c9fef28c432a247eb,bc8c1b71a9bc00c67a64198dae0f5a42,d1f202cadb144570739c718437dd9c7b + + + "ORGANIZATION" + "The Procedia Social and Behavioral Sciences is an academic journal that published 5 articles.") ("entity" + 17a811ea2375e85ee164ddd52dbe5a80 + + + "EVENT" + "The article discusses the evolution of reaction centers that mimic photosynthesis for fuel production and water conversion processes." + b315f4391fd31deebdefc7e4496ccc53 + + + "AUTHOR" + "Bhushan conducted research emphasizing biomimetic studies at micro and nano scales, focusing on creating designs inspired by biological surfaces and materials.") ("entity" + bc2123b5f86d53a8b6c4f35594131571 + + + "ORGANIZATION" + "An organization that works in a field related to sustainable design and research, focusing on biomimicry." + c16a050b9f05d4adcbe87cd85974f73b + + + "CONCEPT" + "A central theme in the works of 'The St Works Study' which deals with bio-based innovations, specifically biomimicry." + c16a050b9f05d4adcbe87cd85974f73b + + + "CONCEPT" + "MIMICRY" is the central theme encompassing the core concept behind studies and developments initiated by 'The St Works Study'. This approach leverages principles sourced from nature to address challenges and foster innovations. Additionally, it denotes a practical utilization of biomimetic traits in design, drawing inspiration from natural phenomena and forms. Consequently, "MIMICRY" embodies an integrated methodology that combines ecological insights with creative problem-solving strategies and design innovation. + 30c01680c32c27bbf40c2879200bb4ca,c16a050b9f05d4adcbe87cd85974f73b + + + "PERSON" + "E.O. Wilson is known for conceptualizing nature as a model, measure, and mentor agent capable of generating efficient systems. He also encourages transferring natural knowledge to human contexts particularly in dealing with issues like waste management.") ("entity" + 10357a9455875b5f9c5deca2d9871135 + + + "PERSON" + "Pawlyn is associated with work showcasing biomimicry and architecture interconnections, highlighting sustainable and innovative construction methods, particularly for restoration purposes.") ("entity" + b8f2d8b6f8181c950be1341e09d5f6ac + + + "PERSON" + "These authors are responsible for the concept of designing with a focus on effectively having a positive impact on the environment.") ("entity" + 50d87eb794de75e87a2b0897c5432e39 + + + "ORGANIZATION" + "The organization is involved in the research and functional analysis of natural and artificial systems using biomimetic approaches." + ea3022e7c889776437eec7e0ff1e3b2c + + + "ORGANIZATION" + "The organization involved is a research institute or department that focuses on sustainable architecture and design.") + e01fbf716e63081d999f9f22c28e098a + + + "GEO" + "Climate is a subject associated with the adaptation and systems at ecological level, involving technical solutions, especially in the face of climate crisis." + 3cafe8221f0d2b661270f9e33c59993d + + + "PERSON" + "A Researcher who specializes in biomimetics studies different organisms' abilities to identify two words which appear together frequently") + 4c8d34a6cb7efcbac85f88b2fbb3973e + + + "ORGANIZATION" + "Entomology is a field of study which focuses on the organisms, especially insects.")|("entity" + 5bb96e57d4c79ea40feeb5ecb3296afe + + + "GEO" + "This includes various designs and studies across architecture.")|("entity" + 439722d75181e1aa687e95df70e09d63 + + + "OBJECT" + "This represents a map created using data from the Web of Science, covering publications from 2018 to 2021. The map visually represents bibliographic coupling between documents." ) ("entity" + 8d7e6e7209519d7dec8948a364fdbab2 + + + "EVENT" + "An opportunity for redesigning materials, processes, and products that may inherently link with nature through their properties and functionality." + 30c01680c32c27bbf40c2879200bb4ca + + + "ACTION" + "The act of redesigning materials, processes, and products to improve efficiency or sustainability." + 30c01680c32c27bbf40c2879200bb4ca + + + "ASPECT" + "A connection or relationship between the designed elements and natural principles or systems." + 30c01680c32c27bbf40c2879200bb4ca + + + "CONTEXT" + "Environmental changes that influence the functionality of kinetic architectural elements." + 30c01680c32c27bbf40c2879200bb4ca + + + "CONCEPT" + "A model where resources are kept in use for as long as possible, extracting maximum value while minimizing waste."> + 30c01680c32c27bbf40c2879200bb4ca + + + "ORGANIZATION" + "Tate et al. are a team who reviewed relationships of mutualism found in nature and contributed to the recognition of biomimicry as an area useful for strategic planning in companies." + f770903009c82b1aeca7bf9e490877ad + + + "EVENT" + "The introduction of innovative concepts that integrate ecosystem services to support biodiversity and natural environment resilience against climate change.")|("entity" + f5fd896ed0c59d47158db316fad680dc + + + "ORGANIZATION" + "The Web of Science is a comprehensive database used for academic research that may limit the accessibility or dissemination of certain works based on specific criteria." + 916f17bde39ae650dad1b657a1887fa6 + + + "PERSON" + "A.A.M.D.S." refers to the primary individual responsible for conceptualizing the study, developing its methodology, and contributing as a co-author alongside D.M.V. This entity has notably worked on an exploration of biomimicry's application and significance in design processes. + 7982a2e4054b66ae19457bde8585eaa8,f8d611d2f89f42ca1550ee673a05d4dd + + + "PERSON" + "D.M.V contributes to software development, formal analysis of data, validation, investigation, resource gathering, supervision of the project." + 7982a2e4054b66ae19457bde8585eaa8 + + + "CONCEPT" + "A structured description of each authors' contribution to the research process, from conceptualization to final review." + 7982a2e4054b66ae19457bde8585eaa8 + + + "EVENT" + "Planning and ideation phase for the study conducted by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "EVENT" + "Process of planning how experiments or research will be designed and executed, carried out by A.A.M.d.S. and D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TOOL" + "A.A.M.d.S utilized software tools for various tasks during the study's execution." + 7982a2e4054b66ae19457bde8585eaa8 + + + "EVENT" + "The process of confirming the accuracy or truthfulness of research findings, carried out by A.A.M.d.S. and D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TECHNIQUE" + "Careful examination and interpretation of data or concepts using systematic methods" + 7982a2e4054b66ae19457bde8585eaa8 + + + "ACTIVITY" + "Research conducted to gather information, performed by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TOOL" + "Materials or assets used in the study which were collected or provided by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "PROCESS" + "Organization and management of data throughout its lifecycle, responsibility of A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TASK" + "The initial writing phase where the first version of a paper or report is drafted by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "ACTIVITY" + "Process to refine and correct content, undertaken by both A.A.M.d.S. and D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + + + "TECHNIQUE" + "Representation of data or concepts through graphical means, performed by A.A.M.d.S." + 7982a2e4054b66ae19457bde8585eaa8 + + + "ROLE" + "Overseeing the research project's progress and ensuring quality control, done by D.M.V." + 7982a2e4054b66ae19457bde8585eaa8 + + + "PERSON" + "MacKinnon R.B., J.Oomen, M.P.Zari are authors in the paper 'Promises and Presuppositions of Biomimicry' contributing to the field of biomimetics.")<br>("entity" + ab0129037f27d2a0b3230e695cb66703 + + + "PERSON" + "Cohen is the author who wrote 'Biomimetic Design Method for Innovation and Sustainability' in Springer")|("entity" + 71820a84991aa839263c1542540c3d9a + + + "PERSON" + "Author of the book 'Biomimicry', exploring innovation inspired by nature.")|("entity" + d9c59b517b2e653c7c9cb7efb130c9b0 + + + "ORGANIZATION" + "CrossRef is a not-for-profit membership organization that operates several databases for scholarly journals and books." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Michael Cutkosky is the author of one paper discussing the design and fabrication of multi-material structures for bioinspired robots." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This is a journal published by The Royal Society which features scientific papers in mathematical, physical, engineering sciences, life sciences and information science." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Jorge Mendoza is an author of one paper discussing the integration of backcasting and eco-design for the circular economy using a framework named BECE." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal focuses on issues in environmental sustainability, green business strategies, and sustainable development." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Ben D. Sherman is an author of one paper discussing the evolution of reaction center mimics for systems capable of generating solar fuel." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal publishes scientific papers about photosynthesis and related fields such as biochemistry, genetics, ecology, and physiology of plants and algae." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Samantha N. Sponberg is an author of one paper discussing templates and anchors for antenna-based wall following in cockroaches and robots." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal publishes research articles on robotics theory, experimentation, applications, and design, including topics like autonomous robots and robot systems." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Qingyuan (Q.) Xu is an author of one paper discussing biomimetic self-cleaning surfaces." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Mehrnaz Zari is the author of a paper discussing biomimetic design for climate change adaptation and mitigation." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal covers various scientific fields including architecture, physics, engineering sciences, life sciences, and information science." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Michael Helms is an author of a paper discussing biologically inspired design: process and products." + d41313a8b0e699443363728cc7ec56b7 + + + "JOURNAL" + "This journal publishes academic studies on design including issues related to cultural, social and psychological aspects of designing processes and artifacts." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Mark Pawlyn is the author of a book titled 'Biomimicry in Architecture' which focuses on principles of biomimicry as applied to architectural design." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Amir Chakrabarti is mentioned with his involvement with other researchers in one paper discussed." + d41313a8b0e699443363728cc7ec56b7 + + + "PERSON" + "Mawson Pawlyn is the author of 'Biomimicry in Architecture', showcasing expertise and insight into architecture that draws inspiration from natural systems.") ("entity" + 70bfef2ab1bf8bc9a6db2cd5ae212340 + + + "PERSON" + "Ying Xing is the author of 'Exploring design principles of biological and living building envelopes: What can we learn from plant cell walls?' in Intell. Build. Int., contributing to discussions on biomimetic design.") ("entity" + 43eb56fd90297c8d3c9e125f8a258552 + + + "PERSON" + "Escobar is the author of 'Designs for the Pluriverse: Radical Interdependence, Autonomy, and the Making of Worlds', a book about radical interdependence and autonomy in making worlds."), ("entity" + 1e4a32f745aa007ef1215f21e5d61f20 + + + "PERSON" + "Dr. Meng F is a researcher who contributed to the study on biomimetics for new smart adhesives based on tree frog adhesion properties.") ("entity" + b1365ab133c6be5ea45465f8f66fde20 + + + "PERSON" + "Longjian Xue contributed research on bioinspired adhesives through tree frog toe pad mimics." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "PERSON" + "W. Jon P. Barnes collaborated in the development of bioinspired adhesive materials and friction-generating devices based on biomimetic principles." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "ORGANIZATION" + "These are specific areas of study that focus on replicating biological features from tree frogs to design artificial adhesives and devices." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "CONCEPT" + "Bioinspiration refers to the process of drawing ideas or innovations from natural phenomena for technological applications." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "EVENT" + "The study involves research on how climbing animals, like tree frogs, adhere to surfaces and applying these principles in artificial materials." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + + + 2790f03c21ca0d9a522e2c1276ad4f6e + + + "ORGANIZATION" + "Sun & Bhushan are likely the authors of a recent review, suggesting they have expertise in biomimetics and adhesion mechanisms." + 7393bb6f9d3837d8e11cfbef8c7d7959 + + + "SPECIES" + "The species being discussed is a gliding frog that resides in trees and uses its toe pads for attachment"|>2) ("entity" + 86f10a539a2dae71ed0fb369a39cb0a5 + + + "MATERIAL" + "Description of a material with an elastic modulus of approximately 3 kPa, which might relate to biological tissues like toe pads of frogs and other amphibians." + 1e6b8071c30040b985c9f084d73831fb + + + "TOOL" + "An Atomic Force Microscope (AFM) indenter used for measuring the mechanical properties of materials, such as elasticity." + 1e6b8071c30040b985c9f084d73831fb + + + "SURFACE" + "The outermost layer of a toe pad structure that has been measured to have an elastic modulus significantly higher than internal layers." + 1e6b8071c30040b985c9f084d73831fb + + + "LAYER" + "Layers close to sub-dermal lymph spaces and a capillary network, which are much softer and pliable compared to the external surface of the pad." + 1e6b8071c30040b985c9f084d73831fb + + + "MATERIAL" + "Structures that provide rigidity and strength to various biological tissues including toe pads and other skin components in amphibians." + 1e6b8071c30040b985c9f084d73831fb + + + "ORGANIZATION" + "DROTLEF ET AL." is a team led by Sam Rivera dedicated to conducting extensive research and publishing findings related to cell structures and their adhesive capabilities. This organization has also undertaken studies involving the exploration of adhesion forces under varying velocities on both hydrophilic and hydrophobic surfaces, demonstrating comprehensive expertise in this field of study. + 65e8dd210ebbbf33013fa2f40f86c71a,b01ac6d637b8d31e396081208c8162d0 + + + "CONCEPT" + "Sam Rivera's work involves complex biological concepts, specifically focusing on the intricate designs of cells and nanopillars as they relate to adhesion." + b01ac6d637b8d31e396081208c8162d0 + + + "EVENT" + "In this context, 'First Contact' refers to Sam Rivera's team understanding new forms of adhesion from studying natural structures such as those found in epithelial cells and nanopillars." + b01ac6d637b8d31e396081208c8162d0 + + + "ORGANIZATION" + The entity referred to throughout these descriptions is the research group named FEDERLE ET AL. This team is known for their work in uncovering scientific findings related to frog mucus properties, specifically focusing on adhesion mechanisms that occur when interacting with various surfaces. Their research activities are centered around water frogs and their unique toe pad structures, indicating an extensive investigation into the biological properties of these creatures. + 136e4bfffb45ced656433f414fdc6b2f,fa424ca04288f43c5c699afb0d603c44 + + + "PERSON" + "The authors who have studied the adhesion ability of tree frogs to various rough surfaces in their natural habitat.")|("entity" + fffe8fad4dcfa583ff169283eb78ecb3 + + + "GEO" + "The image produced by interference reflection microscopy which helps in estimating the thickness of fluid layer.") + e78095af9990d29b641c393cc4eef335 + + + "EVENT" + "Tree frog adhesion refers to the adhesive capabilities displayed by tree frogs, which is a topic under study with respect to physical principles and forces.") + 7fb26cfacb7049c44680dc8301da770f + + + "ORGANIZATION" + "The document contains equation 2.1, which simplifies to FL = −4 πRγ .") ("entity" + 73f5b09aa4346c6324664d57dd868e8c + + + "EVENT" + "The recent study referred to in the text discusses the forces of adhesion in biological systems." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "Equation (2.4) is used as a comparison point for discussing the extension of adhesive force equations to soft, elastic materials like tree frog toe pads." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "The text discusses how with increasing radius (r), adhesive forces may change from length scaling to area scaling." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "The term effective elastic modulus refers to the material's resistance to deformation, affecting adhesive force predictions." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "Refers to one aspect of how adhesive forces are explained mathematically in relation to geometry and elasticity." + fa83531962b067f9e048396a31135c9e + + + "CONCEPT" + "Referred to as Stefan adhesion, these forces resist plate separation due to fluid flow dynamics." + fa83531962b067f9e048396a31135c9e + + + "ORGANIZATION" + "Tulchinsky & Gat introduced the concept of 'temporary adhesion' by considering only viscous flow and ignoring inertial and capillary effects." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "EVENT" + "Equation (2.9) describes this force, which involves a term with viscosity and radius of the sphere." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "CONCEPT" + "Concept introduced by Tulchinsky & Gat based on elastic deformation and viscous flow interactions." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "ITEM" + "A test subject used in studying adhesion, with forces resisting slip being measured during tests." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "ORGANISM" + "Tree frogs, a species known for their remarkable wet adhesion properties and capable of climbing using both adhesion and adduction forces on smaller structures, refer to animals whose unique toe pad structure inspires materials development. Unlike geckos, while they also provide inspiration due to their adhesive capabilities, the mechanism in tree frogs is described as more complex." + 48a7645a66fe18b7377a1a842f7242b0,70bb442f494ac5321d4f1d3bc233e919,92dc318eef4563c8f3fa73fb7b3978bc,bc8c1b71a9bc00c67a64198dae0f5a42 + + + "PROPERTY" + "Viscosity of the fluid is several orders of magnitude greater for silicone oil than tree frog mucus, affecting applicability of the viscous-poroelastic adhesion concept." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "EVENT" + "Means by which tree frogs climb on flat surfaces using only adhesive forces." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "ACTIVITY" + "Force used by tree frogs to climb small diameter structures, aiding in climbing with their digits." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "STRUCTURE" + "Components also contributing to climbing abilities alongside adhesion and adduction forces." + 92dc318eef4563c8f3fa73fb7b3978bc + + + "ORGANIZATION" + "Developers of a simple procedure to measure adhesive forces generated by tree frogs." + 82d1d20cbed7dd86fe58e59fed8d44ad + + + "GEO" + "This refers to a graphical representation or diagram, likely used in academic literature." + 1647a94c674950bc1429d956f341aba2 + + + "ORGANIZATION" + "The development team of miniature force plates used in measuring friction and adhesive forces on frog toe pads.") ("entity" + bea216e0fcc7f946f0033c137012a930 + + + "EVENT" + "A procedure conducted to study effects on fluid layer thickness under a pad using interference reflection microscopy." + 0888854b6766d37662902e4d32772d60 + + + "EFFECT" + "Increase observed in the distance between pad and ground as an outcome of the said procedure." + 0888854b6766d37662902e4d32772d60 + + + "EFFECT" + "Diminished adhesion due to changes from viscosity-dependent hydrodynamic forces and van der Waals forces." + 0888854b6766d37662902e4d32772d60 + + + "CONCEPT" + "A significant role for capillary forces in maintaining close contact between pad and ground." + 0888854b6766d37662902e4d32772d60 + + + "CONTEXT" + "The necessity of close contact for the manifestation of other adhesive actions, as suggested by the study." + 0888854b6766d37662902e4d32772d60 + + + "EVENT" + "An experiment involving recording forces exerted by a single pad during horizontal pull." + 0888854b6766d37662902e4d32772d60 + + + "CONCEPT" + "Evidence that toe pads can generate static friction, indicating contact between structures on toe pads and the surface." + 0888854b6766d37662902e4d32772d60 + + + "COMPONENT" + "Structures potentially involved in creating contact with the force plate during toe pad experiments." + 0888854b6766d37662902e4d32772d60 + + + "MEASURE" + "Values measured using miniature force plates for tree frog toe pads." + 0888854b6766d37662902e4d32772d60 + + + "SPECIES" + "A species of gliding frog mentioned in the study, used for calculating adhesive and friction forces." + 0888854b6766d37662902e4d32772d60 + + + "COMPARISON" + "Supporting an argument suggesting toe pads are better developed for friction than adhesion based on observed data." + 0888854b6766d37662902e4d32772d60 + + + "ORGANIZATION" + "Geckos are used in biomimetics studies for their unique abilities related to adhesion which inspire various material developments." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + "PRODUCT" + "Materials or devices that replicate aspects of geckos' adhesion mechanisms, often focusing on van der Waals forces." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + "CONCEPT" + "Force responsible for the adhesion capabilities in gecko-inspired materials, enabling simple pillar structure design and construction." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + "PRODUCT" + "Structured formations made of multiple pillars that mimic natural systems like geckos' toe pads or tree frogs' adhesive mechanisms." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + + + bc8c1b71a9bc00c67a64198dae0f5a42 + + + + + bc8c1b71a9bc00c67a64198dae0f5a42 + + + "PROPERTY" + "E eff allows CNT forests to maximize contacts, increasing adhesion force." + c69e8300c5e976bc2e0c66e470f0371b + + + "MATERIAL" + "Shows shear adhesion of approximately 100 N cm−2, significantly higher than gecko foot-hairs." + c69e8300c5e976bc2e0c66e470f0371b + + + "PROCESS" + "Hinders CNT forest applications due to complexity and durability issues." + c69e8300c5e976bc2e0c66e470f0371b + + + "MATERIAL" + "Has relatively low modulus, used widely for structured adhesives due to ease of handling and commercial availability." + c69e8300c5e976bc2e0c66e470f0371b + + + "TYPE" + "Built using PDMS micropillar arrays, showing remarkable decrease in effective modulus compared to flat surfaces." + c69e8300c5e976bc2e0c66e470f0371b + + + "MEASUREMENT" + "Affects pull-off forces and elastic energy dissipation during contact surface interaction." + c69e8300c5e976bc2e0c66e470f0371b + + + "FACTOR" + "Affects CNT forest applications, influencing adhesion forces based on height-to-side length ratio of pillars." + c69e8300c5e976bc2e0c66e470f0371b + + + "CONFIGURATION" + "Show a decrease in E eff with an increase in AR leading to higher contact and pull-off forces." + c69e8300c5e976bc2e0c66e470f0371b + + + "INSPIRATION" + "Illustrate adhesion dependence on pillar AR, showing potential reduction of force at high ARs due to pillar bending and clustering." + c69e8300c5e976bc2e0c66e470f0371b + + + "APPLICATION" + "Typically exhibit small pillar height and channel width, likely for maximizing adhesive strength." + c69e8300c5e976bc2e0c66e470f0371b + + + "CLASSIFICATION" + "Conventionally described as smooth, but may actually display complex structural features enhancing adhesion." + c69e8300c5e976bc2e0c66e470f0371b + + + + + c69e8300c5e976bc2e0c66e470f0371b + + + + + c69e8300c5e976bc2e0c66e470f0371b + + + + + c69e8300c5e976bc2e0c66e470f0371b + + + "ORGANIZATION" + "Tree frogs and bush-crickets refer to specific animal species which exhibit certain biological features and adhesive mechanisms.")<br>("entity" + 10f68536dac42a1fe1015b64ac551c32 + + + "GEO" + "micro-bulges refer to the structures on pillar tops that contribute to increased friction forces." + c08200d48689acf908730b5b5a937f1a + + + "MATERIAL" + "Polydimethylsiloxane that can be used in microstructures to improve mechanical properties and enhance adhesion." + cfd357f03ebd53bb7b20477337baa849 + + + "ORGANIZATION" + "Chen et al.'s team is involved in the research that examines different patterns of micro and nanostructures for understanding wet adhesion mechanics, as published in journals such as Phil.Trans.R.Soc.A.") + 56de28d5378ea95f859724f171540a25 + + + "PUBLISHING ORGANIZATION" + "This organization operates on the web, contributing to scientific publications and research dissemination." + 7959e16097062f8a4801b98295269a6a + + + "A SPECIFIC EXPERIMENT WAS CONDUCTED BY INCREASING RELATIVE HUMIDITY FOR OBSERVING ITS IMPACT ON SOLID-SOLID CONTACT RESISTANCE." + 5 + 7959e16097062f8a4801b98295269a6a + + + "THE REFERENCE TO A NAMED GROUP SUGGESTS A TEAM OF RESEARCHERS INVOLVED IN DESIGNING AND IMPLEMENTING THE LIQUID BRIDGE FORMING DEVICE." + 6 + 7959e16097062f8a4801b98295269a6a + + + + + 7959e16097062f8a4801b98295269a6a + + + + + 7959e16097062f8a4801b98295269a6a + + + "ORGANIZATION" + "This refers to a specific type of microchannel base bio-inspired patch that is being developed.") ("entity" + 2e431df92f1954d7fdf7449771dac2e1 + + + "PERSON" + "Co-author with Barthlott W, Neinhuis C contributed to the study of purity and contamination issues related to biological surfaces." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Sun J worked on nanomanufacturing bioinspired surfaces as presented in Tribol. Int." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Bhushan B is associated with Sun J's research and the field of nanotechnology." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Karl Autumn authored multiple works related to gecko adhesion, including explanations on structure, function, and applications." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Tobias Endlein contributed a study on wet adhesion in tree frogs which was part of an encyclopedia on nanotechnology." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "W. J.P. Barnes co-authored the work by Endlein on wet adhesion and has expertise in this area." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Wilfred R Hansen, alongside Autumn K, provided evidence for self-cleaning in gecko setae as reported in Proc. Natl Acad. Sci." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Nathaniel Crawford contributed research on self-cleaning mechanisms in tree frog toe pads without the need for grooming, as seen in J. Exp. Biol." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Sun Hu alongside Lopez S and Niewiarowski PH co-authored a paper on dynamic self-cleaning in gecko setae through digital hyperextension." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Co-author with Hu S, Lopez contributed to research on dynamic self-cleaning mechanisms in gecko setae." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Participated alongside Hu S and Lopez S in the study of dynamic self-cleaning processes in gecko setae." + e8c373a905cc6ee3e696c2eb69267455 + + + "PERSON" + "Zeng Xia, together with Hu S et al., explored digital hyperextension mechanisms for self-cleaning in geckos." + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + + + e8c373a905cc6ee3e696c2eb69267455 + + + "ORGANIZATION" + "Research focuses on the toe pads of this species as a source for developing new biomimetically inspired reversible adhesives.")<br>("entity" + 4d8b21398c70d24c39cd26cfa1dba5c0 + + + "PERSON" + "Aino T.'s research is focused on the high deformability of adhesive toe pads in White's tree frog, specifically through light and electron microscopic analyses.")|("entity" + 39bb4090056fa3afa0591e818ff2e48b + + + "ORGANIZATION" + "This system is comprised of 24 separate 3D force plates to study single limb forces in climbing animals on a quasi-cylindrical tower.") ("entity" + a2e84db4531e11bb05a5e5cbdb285bb8 + + + "PERSON" + "Samuel DS contributes to research on metamorphosis and maturation in hylid tree frogs at the Journal of Zoology.") ("entity" + b57944edc55bf9a8ed604f132186cac1 + + + "PERSON" + "Xue L contributed to research on bioinspired orientation-dependent friction as well as effective elastic modulus of structured adhesives.")|("entity" + 8d4a6778098c667728901fd5eb6ae286 + + + "PERSON" + "A is a co-author in the publication 'Microfluidic adhesion induced by subsurface microstructures' published in Science in 2007.") ("entity" + 221b04279ff2633a5d567aa14627c640 + + + "PERSON" + "Author Berg is associated with the publication 'Use of biomimetic hexagonal surface texture in friction against lubricated skin', indicating expertise or contribution to research in this field." + cda9b37513bc2f8036dfff4a389184d7 + + + "TEAM" + "The team of authors includes contributors from various institutions who together have published a paper on 'Highly permeable skin patch with conductive hierarchical architectures inspired by amphibians and octopi for omnidirectionally enhanced wet adhesion', showcasing collaborative research effort." + cda9b37513bc2f8036dfff4a389184d7 + + + "ORGANIZATION" + "The team of authors is associated with the publication in Advanced Functional Materials, suggesting that the paper has undergone peer review and was accepted for publication by this reputable scientific journal." + cda9b37513bc2f8036dfff4a389184d7 + + + + + cda9b37513bc2f8036dfff4a389184d7 + + + 1.0 + "Longjian Xue contributed significantly to bioinspired adhesive development through studying tree frog toe pad structures." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "W. Jon P. Barnes co-developed biomimetic adhesives and friction-generating devices with inspiration from natural climbing mechanisms." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "The primary focus of research in this area involves replicating the complex structures found on tree frogs' toes to enhance material performance." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "Bioinspiration has influenced the development of artificial adhesives and devices by providing natural solutions for their design." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "The study of adhesive mechanisms in nature, especially from climbing animals, serves as a fundamental source of information for bioinspired material advancements." + 2790f03c21ca0d9a522e2c1276ad4f6e + + + 1.0 + "Inspired by the biological adhesion properties of geckos, leading to advancements in material science and engineering applications." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + 1.0 + "Young's modulus of different materials influences the effectiveness and stability of pillar array designs used for biomimetic adhesive development." + bc8c1b71a9bc00c67a64198dae0f5a42 + + + 1.0 + "Based on polydimethylsiloxane, a material known for its ease of handling and commercial availability." + c69e8300c5e976bc2e0c66e470f0371b + + + 1.0 + "Affects adhesion forces in hexagonal pillar configurations via AR calculations." + c69e8300c5e976bc2e0c66e470f0371b + + + 1.0 + "publishing organization is responsible for releasing scientific studies or findings like this study on tree frog-inspired adhesion." + 7959e16097062f8a4801b98295269a6a + + + 1.0 + "C was co-author with Barthlott W on work concerning purity and contamination issues related to biological surfaces." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Sun J is an author of the paper on nanomanufacturing bioinspired surfaces in Tribol. Int." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Is associated with Sun J's research and the field of nanotechnology as a co-author or author." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Karl Autumn is an author of works on gecko adhesion, including structure, function, and applications." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Tobias Endlein contributed to the study on wet adhesion in tree frogs as part of a broader work on nanotechnology." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "W. J.P. Barnes co-authored research with Endlein and likely has expertise in biological adhesion mechanisms." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Wilfred Hansen, along with Karl Autumn, provided evidence for self-cleaning gecko setae." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Nathaniel Crawford contributed research on self-cleaning mechanisms in tree frog toe pads as part of J. Exp. Biol." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Sun Hu co-authored the study with Lopez and Niewiarowski on dynamic self-cleaning in gecko setae using digital hyperextension." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Barthlott W contributed to studies on purity and contamination of biological surfaces in Planta." + e8c373a905cc6ee3e696c2eb69267455 + + + 1.0 + "Author Berg is directly linked to the publication 'Use of biomimetic hexagonal surface texture in friction against lubricated skin', indicating a specific contribution or lead authorship to this research work." + cda9b37513bc2f8036dfff4a389184d7 + + + 1.0 + "The team of authors collectively contributed to the publication 'Highly permeable skin patch with conductive hierarchical architectures inspired by amphibians and octopi for omnidirectionally enhanced wet adhesion', highlighting their collaborative effort in advancing biomimetic research." + cda9b37513bc2f8036dfff4a389184d7 + + + 1.0 + "The publication 'Highly permeable skin patch with conductive hierarchical architectures' was published in this journal, indicating that the research meets high standards for originality and scientific rigor as required by peer-reviewed journals." + cda9b37513bc2f8036dfff4a389184d7 + + + \ No newline at end of file diff --git a/indexing/output/20240722-073448/artifacts/top_level_nodes.json b/indexing/output/20240722-073448/artifacts/top_level_nodes.json new file mode 100644 index 0000000000000000000000000000000000000000..592b5791bf6b90758a272ef178b6d7c05f207796 --- /dev/null +++ b/indexing/output/20240722-073448/artifacts/top_level_nodes.json @@ -0,0 +1,227 @@ +{"id":"b45241d70f0e43fca764df95b2b81f77","x":0,"y":0} +{"id":"4119fd06010c494caa07f439b333f4c5","x":0,"y":0} +{"id":"d3835bf3dda84ead99deadbeac5d0d7d","x":0,"y":0} +{"id":"077d2820ae1845bcbb1803379a3d1eae","x":0,"y":0} +{"id":"3671ea0dd4e84c1a9b02c5ab2c8f4bac","x":0,"y":0} +{"id":"19a7f254a5d64566ab5cc15472df02de","x":0,"y":0} +{"id":"e7ffaee9d31d4d3c96e04f911d0a8f9e","x":0,"y":0} +{"id":"f7e11b0e297a44a896dc67928368f600","x":0,"y":0} +{"id":"1fd3fa8bb5a2408790042ab9573779ee","x":0,"y":0} +{"id":"27f9fbe6ad8c4a8b9acee0d3596ed57c","x":0,"y":0} +{"id":"e1fd0e904a53409aada44442f23a51cb","x":0,"y":0} +{"id":"de988724cfdf45cebfba3b13c43ceede","x":0,"y":0} +{"id":"96aad7cb4b7d40e9b7e13b94a67af206","x":0,"y":0} +{"id":"c9632a35146940c2a86167c7726d35e9","x":0,"y":0} +{"id":"9646481f66ce4fd2b08c2eddda42fc82","x":0,"y":0} +{"id":"d91a266f766b4737a06b0fda588ba40b","x":0,"y":0} +{"id":"bc0e3f075a4c4ebbb7c7b152b65a5625","x":0,"y":0} +{"id":"254770028d7a4fa9877da4ba0ad5ad21","x":0,"y":0} +{"id":"4a67211867e5464ba45126315a122a8a","x":0,"y":0} +{"id":"04dbbb2283b845baaeac0eaf0c34c9da","x":0,"y":0} +{"id":"1943f245ee4243bdbfbd2fd619ae824a","x":0,"y":0} +{"id":"273daeec8cad41e6b3e450447db58ee7","x":0,"y":0} +{"id":"e69dc259edb944ea9ea41264b9fcfe59","x":0,"y":0} +{"id":"e2f5735c7d714423a2c4f61ca2644626","x":0,"y":0} +{"id":"deece7e64b2a4628850d4bb6e394a9c3","x":0,"y":0} +{"id":"e657b5121ff8456b9a610cfaead8e0cb","x":0,"y":0} +{"id":"bf4e255cdac94ccc83a56435a5e4b075","x":0,"y":0} +{"id":"3b040bcc19f14e04880ae52881a89c1c","x":0,"y":0} +{"id":"3d6b216c14354332b1bf1927ba168986","x":0,"y":0} +{"id":"1c109cfdc370463eb6d537e5b7b382fb","x":0,"y":0} +{"id":"3d0dcbc8971b415ea18065edc4d8c8ef","x":0,"y":0} +{"id":"68105770b523412388424d984e711917","x":0,"y":0} +{"id":"85c79fd84f5e4f918471c386852204c5","x":0,"y":0} +{"id":"eae4259b19a741ab9f9f6af18c4a0470","x":0,"y":0} +{"id":"3138f39f2bcd43a69e0697cd3b05bc4d","x":0,"y":0} +{"id":"dde131ab575d44dbb55289a6972be18f","x":0,"y":0} +{"id":"de9e343f2e334d88a8ac7f8813a915e5","x":0,"y":0} +{"id":"e2bf260115514fb3b252fd879fb3e7be","x":0,"y":0} +{"id":"b462b94ce47a4b8c8fffa33f7242acec","x":0,"y":0} +{"id":"17ed1d92075643579a712cc6c29e8ddb","x":0,"y":0} +{"id":"3ce7c210a21b4deebad7cc9308148d86","x":0,"y":0} +{"id":"d64ed762ea924caa95c8d06f072a9a96","x":0,"y":0} +{"id":"adf4ee3fbe9b4d0381044838c4f889c8","x":0,"y":0} +{"id":"32ee140946e5461f9275db664dc541a5","x":0,"y":0} +{"id":"c160b9cb27d6408ba6ab20214a2f3f81","x":0,"y":0} +{"id":"23527cd679ff4d5a988d52e7cd056078","x":0,"y":0} +{"id":"f1c6eed066f24cbdb376b910fce29ed4","x":0,"y":0} +{"id":"83a6cb03df6b41d8ad6ee5f6fef5f024","x":0,"y":0} +{"id":"147c038aef3e4422acbbc5f7938c4ab8","x":0,"y":0} +{"id":"b7702b90c7f24190b864e8c6e64612a5","x":0,"y":0} +{"id":"de6fa24480894518ab3cbcb66f739266","x":0,"y":0} +{"id":"6fae5ee1a831468aa585a1ea09095998","x":0,"y":0} +{"id":"ef32c4b208d041cc856f6837915dc1b0","x":0,"y":0} +{"id":"07b2425216bd4f0aa4e079827cb48ef5","x":0,"y":0} +{"id":"2670deebfa3f4d69bb82c28ab250a209","x":0,"y":0} +{"id":"404309e89a5241d6bff42c05a45df206","x":0,"y":0} +{"id":"b785a9025069417f94950ad231bb1441","x":0,"y":0} +{"id":"3b6cd96a27304614850709aba1c9598b","x":0,"y":0} +{"id":"d54956b79dd147f894b67a8b97dcbef0","x":0,"y":0} +{"id":"958beecdb5bb4060948415ffd75d2b03","x":0,"y":0} +{"id":"b999ed77e19e4f85b7f1ae79af5c002a","x":0,"y":0} +{"id":"48c0c4d72da74ff5bb926fa0c856d1a7","x":0,"y":0} +{"id":"4f3c97517f794ebfb49c4c6315f9cf23","x":0,"y":0} +{"id":"1745a2485a9443bab76587ad650e9be0","x":0,"y":0} +{"id":"32e6ccab20d94029811127dbbe424c64","x":0,"y":0} +{"id":"94a964c6992945ebb3833dfdfdc8d655","x":0,"y":0} +{"id":"1eb829d0ace042089f0746f78729696c","x":0,"y":0} +{"id":"015e7b58d1a14b44beab3bbc9f912c18","x":0,"y":0} +{"id":"26f88ab3e2e04c33a459ad6270ade565","x":0,"y":0} +{"id":"babe97e1d9784cffa1c85abc1e588126","x":0,"y":0} +{"id":"1033a18c45aa4584b2aef6ab96890351","x":0,"y":0} +{"id":"c9b8ce91fc2945b4907fe35519339cac","x":0,"y":0} +{"id":"fa3c4204421c48609e52c8de2da4c654","x":0,"y":0} +{"id":"53af055f068244d0ac861b2e89376495","x":0,"y":0} +{"id":"c03ab3ce8cb74ad2a03b94723bfab3c7","x":0,"y":0} +{"id":"ed6d2eee9d7b4f5db466b1f6404d31cc","x":0,"y":0} +{"id":"fc01e9baa80e417c9206f941bb279407","x":0,"y":0} +{"id":"56d0e5ebe79e4814bd1463cf6ca21394","x":0,"y":0} +{"id":"7c49f2710e8b4d3b8dc9310834406ea5","x":0,"y":0} +{"id":"c6d1e4f56c2843e89cf0b91c10bb6de2","x":0,"y":0} +{"id":"0adb2d9941f34ef7b2f7743cc6225844","x":0,"y":0} +{"id":"6b02373137fd438ba96af28f735cdbdb","x":0,"y":0} +{"id":"36a4fcd8efc144e6b8af9a1c7ab8b2ce","x":0,"y":0} +{"id":"fbeef791d19b413a9c93c6608286ab63","x":0,"y":0} +{"id":"d2b629c0396f4180a03e16ddf3818589","x":0,"y":0} +{"id":"6102fc6619ed422ebc42588bfa97355d","x":0,"y":0} +{"id":"8d141c0b80f74b79a05eed7fe161fe49","x":0,"y":0} +{"id":"e22d1d1cd8d14f12b81828d940f40d70","x":0,"y":0} +{"id":"9ab48505fb1b487babd0d1f6d3a3f980","x":0,"y":0} +{"id":"148fffeb994541b2b4b6dcefda7001a8","x":0,"y":0} +{"id":"89c08e793298442686292454a1abff31","x":0,"y":0} +{"id":"0467928aa65e4a4fba62bdb1467e3a54","x":0,"y":0} +{"id":"43c3390303c6476cb65f584e37c3e81c","x":0,"y":0} +{"id":"fa14b16c17e3417dba5a4b473ea5b18d","x":0,"y":0} +{"id":"7cc3356d38de4328a51a5cbcb187dac3","x":0,"y":0} +{"id":"bef16fb5fd7344cca5e295b13ef3e0cd","x":0,"y":0} +{"id":"bb9e01bc171d4326a29afda59ece8d17","x":0,"y":0} +{"id":"3c063eea52e94164b70c99431ea30bae","x":0,"y":0} +{"id":"252cc8452bfc4c2aa58cab68d8b61879","x":0,"y":0} +{"id":"7e2c84548fb94ee395ba8588d8f2a006","x":0,"y":0} +{"id":"f034618dde7948beb6dab30176d0fc87","x":0,"y":0} +{"id":"5c41f96be13e49dba649454297834546","x":0,"y":0} +{"id":"7ea4afbf8a264f29af29950ce98105ba","x":0,"y":0} +{"id":"91ff849d12b24574b0691dbddf44968b","x":0,"y":0} +{"id":"d73c1f2fb3094d8dace42ad2a76e9a52","x":0,"y":0} +{"id":"cdc8901e668749889bd49bebdc4ff1f6","x":0,"y":0} +{"id":"36084a9fab53433493f079e97e68bf65","x":0,"y":0} +{"id":"eebcc7ec8e3e4df7aea83659bbdc2199","x":0,"y":0} +{"id":"ceadf262ef834e9ab146b20650912cae","x":0,"y":0} +{"id":"7f65feab75424b53b24470d305ba331a","x":0,"y":0} +{"id":"fd9cb733b28d420cb5cef01e545a132c","x":0,"y":0} +{"id":"0fbcca3f17c649a08aea64b5a7d9ef36","x":0,"y":0} +{"id":"482027a59f32484c9c44fd700615c1b6","x":0,"y":0} +{"id":"de837ff3d626451282ff6ac77a82216d","x":0,"y":0} +{"id":"460295fed3ae4cd39f9f274cec9c2506","x":0,"y":0} +{"id":"553b285bba60460ab1ed8341ae61282b","x":0,"y":0} +{"id":"cec95bf17e7e4c939b56c9c6f402a29f","x":0,"y":0} +{"id":"599164aead034bc19446efacc77554d2","x":0,"y":0} +{"id":"bbf148ae4d48422f8fdef754cfa2b9e4","x":0,"y":0} +{"id":"de61b2670999433f807a6a1dc2b81e43","x":0,"y":0} +{"id":"3e95dacfe57b4d57b5da4310ef2e157f","x":0,"y":0} +{"id":"1f1545308e9347af91fd03b94aadc21f","x":0,"y":0} +{"id":"6ea81acaf232485e94fff638e03336e1","x":0,"y":0} +{"id":"d136b08d586d488f9e4188b524c85a29","x":0,"y":0} +{"id":"cccfa151fedc4b218a8d96adc7dceabe","x":0,"y":0} +{"id":"ce54725672a74ebcabe6127577dacb2b","x":0,"y":0} +{"id":"ea2b28ca1a974ffab4517811dc1d1e5c","x":0,"y":0} +{"id":"aff21f1da1654e7babdcf3fb0e4a75fc","x":0,"y":0} +{"id":"dc2cc9016e3f49dbac7232f05cce794d","x":0,"y":0} +{"id":"6ea0cef05f694dcea455478f40674e45","x":0,"y":0} +{"id":"7ab5d53a872f4dfc98f3d386879f3c75","x":0,"y":0} +{"id":"af1d0fec22114a3398b8016f5225f9ed","x":0,"y":0} +{"id":"b07a7f088364459098cd8511ff27a4c8","x":0,"y":0} +{"id":"8870cf2b5df64d2cab5820f67e29b9f1","x":0,"y":0} +{"id":"cd130938a2844050be991af70baf5ee0","x":0,"y":0} +{"id":"43544b99c3b04b059546198a0ae6366d","x":0,"y":0} +{"id":"a671bf7fea2f4514b6e96ba99127fafd","x":0,"y":0} +{"id":"525f41ea20274a05af4e52b625b473f3","x":0,"y":0} +{"id":"071a416efbec4f0886c19ac68f6d43cb","x":0,"y":0} +{"id":"6d8473ef3b1042bf87178a611e3dbcc6","x":0,"y":0} +{"id":"30c9641543c24773938bd8ec57ea98ab","x":0,"y":0} +{"id":"18b839da898e4026b81727d759d95c6a","x":0,"y":0} +{"id":"eeef6ae5c464400c8755900b4f1ac37a","x":0,"y":0} +{"id":"422433aa45804c7ebb973b2fafce5da6","x":0,"y":0} +{"id":"86505bca739d4bccaaa1a8e0f3baffdc","x":0,"y":0} +{"id":"1af9faf341e14a5bbf4ddc9080e8dc0b","x":0,"y":0} +{"id":"353d91abc68648639d65a549e59b5cf3","x":0,"y":0} +{"id":"7ce637e4f35b42e3a9f8272cab69cd22","x":0,"y":0} +{"id":"4d999d7744b04a998475f8f8531589f0","x":0,"y":0} +{"id":"9a6f414210e14841a5b0e661aedc898d","x":0,"y":0} +{"id":"db541b7260974db8bac94e953009f60e","x":0,"y":0} +{"id":"f2ff8044718648e18acef16dd9a65436","x":0,"y":0} +{"id":"00d785e7d76b47ec81b508e768d40584","x":0,"y":0} +{"id":"87915637da3e474c9349bd0ae604bd95","x":0,"y":0} +{"id":"8f1eba29f39e411188200bf0d14628ec","x":0,"y":0} +{"id":"7282c73622b8408e97289d959faff483","x":0,"y":0} +{"id":"3deb220d31f74103aa44870a36a63220","x":0,"y":0} +{"id":"af7a1584dd15492cb9a4940e285f57fc","x":0,"y":0} +{"id":"6e8d9029ce4e4ea182367173ab2c7bbf","x":0,"y":0} +{"id":"cbf232211e7d4eb6abdbe182f71c2cf0","x":0,"y":0} +{"id":"bb0cff774a4440b289cc6f3b929fe13c","x":0,"y":0} +{"id":"ce55841ebfdd47008bab8c258f10372e","x":0,"y":0} +{"id":"6090e736374d45fd84f0e4610a314f8f","x":0,"y":0} +{"id":"0e8d921ccd8d4a8594b65b7fd19f7120","x":0,"y":0} +{"id":"59c726a8792d443e84ab052cb7942b4a","x":0,"y":0} +{"id":"4f2c665decf242b0bfcaf7350b0e02ed","x":0,"y":0} +{"id":"66cdf168f36d4a57a505028c97dc06e0","x":0,"y":0} +{"id":"38f51478f41f48db9bee570859b6f43e","x":0,"y":0} +{"id":"896d2a51e8de47de85ba8ced108c3d53","x":0,"y":0} +{"id":"14555b518e954637b83aa762dc03164e","x":0,"y":0} +{"id":"b1f6164116d44fe8b8f135d7f65b9e58","x":0,"y":0} +{"id":"c8b2408617804483b620e1a6691ac90d","x":0,"y":0} +{"id":"a5e0d1644eb547ba9a5c3211aac4631a","x":0,"y":0} +{"id":"5a28b94bc63b44edb30c54748fd14f15","x":0,"y":0} +{"id":"f97011b2a99d44648e18d517e1eae15c","x":0,"y":0} +{"id":"35489ca6a63b47d6a8913cf333818bc1","x":0,"y":0} +{"id":"5d3344f45e654d2c808481672f2f08dd","x":0,"y":0} +{"id":"6fb57f83baec45c9b30490ee991f433f","x":0,"y":0} +{"id":"68762e6f0d1c41cd857c6b964a8e76c3","x":0,"y":0} +{"id":"70634e10a5e845aa8c6a32fe7e8eb2b2","x":0,"y":0} +{"id":"04085f7cf46544b79597fc49286ff84d","x":0,"y":0} +{"id":"d203efdbfb2f4b2a899abfb31cf72e82","x":0,"y":0} +{"id":"6731a665561840c2898ce8c9788e4c88","x":0,"y":0} +{"id":"4026806fa92f4e849a59a7f5c9a45c79","x":0,"y":0} +{"id":"68e0c60d2e8845d89d9d0ad397833648","x":0,"y":0} +{"id":"101572f552b54e529fe7765c05168981","x":0,"y":0} +{"id":"60c58026b2764b40adffca6eaa31d6d9","x":0,"y":0} +{"id":"ad1595a78935472999444c9330e7730e","x":0,"y":0} +{"id":"735d19aea0744b2295556841c5c4c3fd","x":0,"y":0} +{"id":"c725babdb14a485582f8fbdf95429030","x":0,"y":0} +{"id":"a0047221896d418d849847d422fa4bb8","x":0,"y":0} +{"id":"98fc2ee593184c5a839454db4eec7013","x":0,"y":0} +{"id":"80020a1da63042459e00266b2a605452","x":0,"y":0} +{"id":"31a7e680c4d54101afe4c8d52d246913","x":0,"y":0} +{"id":"351abba16e5c448994c6daf48121b14d","x":0,"y":0} +{"id":"50ea7d3b69614bcdbfbff7ddbfbf3d34","x":0,"y":0} +{"id":"004f40a5aeca48a1879db728eb12bcba","x":0,"y":0} +{"id":"4465efb7f6ed4dedad72a658184addd2","x":0,"y":0} +{"id":"b0dd60e11dad4ff782623acf039b3948","x":0,"y":0} +{"id":"db8c43fa4df947b09e5754d3b1393ead","x":0,"y":0} +{"id":"5dabc4cd05da425cb194a04482bf0c29","x":0,"y":0} +{"id":"9d08f285a7be4c79b8f359c51d51db37","x":0,"y":0} +{"id":"adffed660d154b519c1817e514e83096","x":0,"y":0} +{"id":"b7e9c9ef572c445a9574ca571e41fb96","x":0,"y":0} +{"id":"dcb9f281cd6248c699e0ebb285a42a5e","x":0,"y":0} +{"id":"072cdee531b74513984f49d99a8d64a0","x":0,"y":0} +{"id":"5ae335d9210a45fda3f92a9a028d6d9b","x":0,"y":0} +{"id":"5ac60a941a5b4934bdc43d2f87de601c","x":0,"y":0} +{"id":"d405c3154d0e48ce96fad4c28fe20590","x":0,"y":0} +{"id":"7923d8521c744bd9aab131c1aea91ffd","x":0,"y":0} +{"id":"5bd156c87ec44e19ae6f8f62e6e50b9d","x":0,"y":0} +{"id":"c1a146d7fb16429ea6d0aa2a55ee597f","x":0,"y":0} +{"id":"ede9350632084da5b0b577ff799ab14b","x":0,"y":0} +{"id":"ed559fb4ebde45518849ec803b350fa3","x":0,"y":0} +{"id":"f422035f8b78417f98e4d116971cf9f3","x":0,"y":0} +{"id":"c79d686eba044c5586c706cdc096817d","x":0,"y":0} +{"id":"0f70db1e598d463fbbcdd1e288bd9490","x":0,"y":0} +{"id":"b35c3d1a7daa4924b6bdb58bc69c354d","x":0,"y":0} +{"id":"a97e2ecd870944cfbe71c79bc0fcc752","x":0,"y":0} +{"id":"3e1b063bbfa9423d84e50311296d2f3c","x":0,"y":0} +{"id":"9a8ce816ee954bdabd01ea2081538009","x":0,"y":0} +{"id":"09f18f81442d4d6d93a90f0fac683f9b","x":0,"y":0} +{"id":"e02be3e37ca0454883a4c1fd859c24bb","x":0,"y":0} +{"id":"6e0c81bef5364c988b21bf9b709d9861","x":0,"y":0} +{"id":"1dbc51475cb04dafa4a8833a8378635e","x":0,"y":0} +{"id":"c12b9ebd8b4e42b7896822a32e3fa6eb","x":0,"y":0} +{"id":"27505f6ade4b4e5f9316ffe9c34821f7","x":0,"y":0} diff --git a/indexing/output/20240722-073448/reports/indexing-engine.log b/indexing/output/20240722-073448/reports/indexing-engine.log new file mode 100644 index 0000000000000000000000000000000000000000..4f056ff76173e99b9fc238fb22219bc69029738d --- /dev/null +++ b/indexing/output/20240722-073448/reports/indexing-engine.log @@ -0,0 +1,449 @@ +07:34:48,525 graphrag.config.read_dotenv INFO Loading pipeline .env file +07:34:48,528 graphrag.index.cli INFO using default configuration: { + "llm": { + "api_key": "REDACTED, length 5", + "type": "openai", + "model": "qwen2:7b", + "max_tokens": 1024, + "temperature": 0.5, + "top_p": 1.0, + "request_timeout": 180.0, + "api_base": "http://localhost:11434/v1", + "api_version": null, + "proxy": null, + "cognitive_services_endpoint": null, + "deployment_name": null, + "model_supports_json": true, + "tokens_per_minute": 0, + "requests_per_minute": 0, + "max_retries": 10, + "max_retry_wait": 10.0, + "sleep_on_rate_limit_recommendation": true, + "concurrent_requests": 25 + }, + "parallelization": { + "stagger": 0.3, + "num_threads": 50 + }, + "async_mode": "threaded", + "root_dir": "./ragtest", + "reporting": { + "type": "file", + "base_dir": "output/${timestamp}/reports", + "storage_account_blob_url": null + }, + "storage": { + "type": "file", + "base_dir": "output/${timestamp}/artifacts", + "storage_account_blob_url": null + }, + "cache": { + "type": "file", + "base_dir": "cache", + "storage_account_blob_url": null + }, + "input": { + "type": "file", + "file_type": "text", + "base_dir": "input", + "storage_account_blob_url": null, + "encoding": "utf-8", + "file_pattern": ".*\\.txt$", + "file_filter": null, + "source_column": null, + "timestamp_column": null, + "timestamp_format": null, + "text_column": "text", + "title_column": null, + "document_attribute_columns": [] + }, + "embed_graph": { + "enabled": false, + "num_walks": 10, + "walk_length": 40, + "window_size": 2, + "iterations": 3, + "random_seed": 597832, + "strategy": null + }, + "embeddings": { + "llm": { + "api_key": "REDACTED, length 5", + "type": "openai_embedding", + "model": "nomic-embed-text:latest", + "max_tokens": 4000, + "temperature": 0, + "top_p": 1, + "request_timeout": 180.0, + "api_base": "http://localhost:11434/v1", + "api_version": null, + "proxy": null, + "cognitive_services_endpoint": null, + "deployment_name": null, + "model_supports_json": null, + "tokens_per_minute": 0, + "requests_per_minute": 0, + "max_retries": 10, + "max_retry_wait": 10.0, + "sleep_on_rate_limit_recommendation": true, + "concurrent_requests": 25 + }, + "parallelization": { + "stagger": 0.3, + "num_threads": 50 + }, + "async_mode": "threaded", + "batch_size": 16, + "batch_max_tokens": 8191, + "target": "required", + "skip": [], + "vector_store": null, + "strategy": null + }, + "chunks": { + "size": 512, + "overlap": 64, + "group_by_columns": [ + "id" + ], + "strategy": null + }, + "snapshots": { + "graphml": true, + "raw_entities": true, + "top_level_nodes": true + }, + "entity_extraction": { + "llm": { + "api_key": "REDACTED, length 5", + "type": "openai", + "model": "qwen2:7b", + "max_tokens": 1024, + "temperature": 0.5, + "top_p": 1.0, + "request_timeout": 180.0, + "api_base": "http://localhost:11434/v1", + "api_version": null, + "proxy": null, + "cognitive_services_endpoint": null, + "deployment_name": null, + "model_supports_json": true, + "tokens_per_minute": 0, + "requests_per_minute": 0, + "max_retries": 10, + "max_retry_wait": 10.0, + "sleep_on_rate_limit_recommendation": true, + "concurrent_requests": 25 + }, + "parallelization": { + "stagger": 0.3, + "num_threads": 50 + }, + "async_mode": "threaded", + "prompt": "prompts/entity_extraction.txt", + "entity_types": [ + "organization", + "person", + "geo", + "event" + ], + "max_gleanings": 0, + "strategy": null + }, + "summarize_descriptions": { + "llm": { + "api_key": "REDACTED, length 5", + "type": "openai", + "model": "qwen2:7b", + "max_tokens": 1024, + "temperature": 0.5, + "top_p": 1.0, + "request_timeout": 180.0, + "api_base": "http://localhost:11434/v1", + "api_version": null, + "proxy": null, + "cognitive_services_endpoint": null, + "deployment_name": null, + "model_supports_json": true, + "tokens_per_minute": 0, + "requests_per_minute": 0, + "max_retries": 10, + "max_retry_wait": 10.0, + "sleep_on_rate_limit_recommendation": true, + "concurrent_requests": 25 + }, + "parallelization": { + "stagger": 0.3, + "num_threads": 50 + }, + "async_mode": "threaded", + "prompt": "prompts/summarize_descriptions.txt", + "max_length": 500, + "strategy": null + }, + "community_reports": { + "llm": { + "api_key": "REDACTED, length 5", + "type": "openai", + "model": "qwen2:7b", + "max_tokens": 1024, + "temperature": 0.5, + "top_p": 1.0, + "request_timeout": 180.0, + "api_base": "http://localhost:11434/v1", + "api_version": null, + "proxy": null, + "cognitive_services_endpoint": null, + "deployment_name": null, + "model_supports_json": true, + "tokens_per_minute": 0, + "requests_per_minute": 0, + "max_retries": 10, + "max_retry_wait": 10.0, + "sleep_on_rate_limit_recommendation": true, + "concurrent_requests": 25 + }, + "parallelization": { + "stagger": 0.3, + "num_threads": 50 + }, + "async_mode": "threaded", + "prompt": null, + "max_length": 2000, + "max_input_length": 8000, + "strategy": null + }, + "claim_extraction": { + "llm": { + "api_key": "REDACTED, length 5", + "type": "openai", + "model": "qwen2:7b", + "max_tokens": 1024, + "temperature": 0.5, + "top_p": 1.0, + "request_timeout": 180.0, + "api_base": "http://localhost:11434/v1", + "api_version": null, + "proxy": null, + "cognitive_services_endpoint": null, + "deployment_name": null, + "model_supports_json": true, + "tokens_per_minute": 0, + "requests_per_minute": 0, + "max_retries": 10, + "max_retry_wait": 10.0, + "sleep_on_rate_limit_recommendation": true, + "concurrent_requests": 25 + }, + "parallelization": { + "stagger": 0.3, + "num_threads": 50 + }, + "async_mode": "threaded", + "enabled": false, + "prompt": "prompts/claim_extraction.txt", + "description": "Any claims or facts that could be relevant to information discovery.", + "max_gleanings": 0, + "strategy": null + }, + "cluster_graph": { + "max_cluster_size": 10, + "strategy": null + }, + "umap": { + "enabled": false + }, + "local_search": { + "text_unit_prop": 0.5, + "community_prop": 0.1, + "conversation_history_max_turns": 5, + "top_k_entities": 10, + "top_k_relationships": 10, + "max_tokens": 12000, + "llm_max_tokens": 2000 + }, + "global_search": { + "temperature": 0.0, + "top_p": 1.0, + "max_tokens": 12000, + "data_max_tokens": 12000, + "map_max_tokens": 1000, + "reduce_max_tokens": 2000, + "concurrency": 32 + }, + "encoding_model": "cl100k_base", + "skip_workflows": [] +} +07:34:48,529 graphrag.index.create_pipeline_config INFO skipping workflows +07:34:48,533 graphrag.index.run INFO Running pipeline +07:34:48,533 graphrag.index.storage.file_pipeline_storage INFO Creating file storage at ragtest/output/20240722-073448/artifacts +07:34:48,533 graphrag.index.input.load_input INFO loading input from root_dir=input +07:34:48,534 graphrag.index.input.load_input INFO using file storage for input +07:34:48,534 graphrag.index.storage.file_pipeline_storage INFO search ragtest/input for files matching .*\.txt$ +07:34:48,534 graphrag.index.input.text INFO found text files from input, found [('Taxonomy Explainer 2017diagram - Unknown.txt', {}), ('Strategy-PDFs-Combined 09-2022 - Unknown.txt', {}), ('Tree frog adhesion biomimetics_ opportunit - Unknown.txt', {}), ('Design and Biomimicry_ A Review of Interco - Alice Araujo Marques de Sa.txt', {})] +07:34:48,537 graphrag.index.workflows.load INFO Workflow Run Order: ['create_base_text_units', 'create_base_extracted_entities', 'create_summarized_entities', 'create_base_entity_graph', 'create_final_entities', 'create_final_nodes', 'create_final_communities', 'join_text_units_to_entity_ids', 'create_final_relationships', 'join_text_units_to_relationship_ids', 'create_final_community_reports', 'create_final_text_units', 'create_base_documents', 'create_final_documents'] +07:34:48,537 graphrag.index.run INFO Final # of rows loaded: 4 +07:34:48,601 graphrag.index.run INFO Running workflow: create_base_text_units... +07:34:48,602 graphrag.index.run INFO dependencies for create_base_text_units: [] +07:34:48,602 datashaper.workflow.workflow INFO executing verb orderby +07:34:48,602 datashaper.workflow.workflow INFO executing verb zip +07:34:48,603 datashaper.workflow.workflow INFO executing verb aggregate_override +07:34:48,604 datashaper.workflow.workflow INFO executing verb chunk +07:34:48,727 datashaper.workflow.workflow INFO executing verb select +07:34:48,727 datashaper.workflow.workflow INFO executing verb unroll +07:34:48,728 datashaper.workflow.workflow INFO executing verb rename +07:34:48,729 datashaper.workflow.workflow INFO executing verb genid +07:34:48,731 datashaper.workflow.workflow INFO executing verb unzip +07:34:48,731 datashaper.workflow.workflow INFO executing verb copy +07:34:48,731 datashaper.workflow.workflow INFO executing verb filter +07:34:48,734 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table create_base_text_units.parquet +07:34:48,808 graphrag.index.run INFO Running workflow: create_base_extracted_entities... +07:34:48,808 graphrag.index.run INFO dependencies for create_base_extracted_entities: ['create_base_text_units'] +07:34:48,809 graphrag.index.run INFO read table from storage: create_base_text_units.parquet +07:34:48,820 datashaper.workflow.workflow INFO executing verb entity_extract +07:34:48,825 graphrag.llm.openai.create_openai_client INFO Creating OpenAI client base_url=http://localhost:11434/v1 +07:34:48,840 graphrag.index.llm.load_llm INFO create TPM/RPM limiter for qwen2:7b: TPM=0, RPM=0 +07:34:48,840 graphrag.index.llm.load_llm INFO create concurrency limiter for qwen2:7b: 25 +07:34:48,908 datashaper.workflow.workflow INFO executing verb snapshot +07:34:48,911 datashaper.workflow.workflow INFO executing verb merge_graphs +07:34:48,924 datashaper.workflow.workflow INFO executing verb snapshot_rows +07:34:48,925 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table create_base_extracted_entities.parquet +07:34:48,990 graphrag.index.run INFO Running workflow: create_summarized_entities... +07:34:48,991 graphrag.index.run INFO dependencies for create_summarized_entities: ['create_base_extracted_entities'] +07:34:48,991 graphrag.index.run INFO read table from storage: create_base_extracted_entities.parquet +07:34:48,995 datashaper.workflow.workflow INFO executing verb summarize_descriptions +07:34:49,15 datashaper.workflow.workflow INFO executing verb snapshot_rows +07:34:49,16 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table create_summarized_entities.parquet +07:34:49,76 graphrag.index.run INFO Running workflow: create_base_entity_graph... +07:34:49,77 graphrag.index.run INFO dependencies for create_base_entity_graph: ['create_summarized_entities'] +07:34:49,77 graphrag.index.run INFO read table from storage: create_summarized_entities.parquet +07:34:49,82 datashaper.workflow.workflow INFO executing verb cluster_graph +07:34:49,95 datashaper.workflow.workflow INFO executing verb snapshot_rows +07:34:49,96 datashaper.workflow.workflow INFO executing verb snapshot_rows +07:34:49,96 datashaper.workflow.workflow INFO executing verb select +07:34:49,97 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table create_base_entity_graph.parquet +07:34:49,161 graphrag.index.run INFO Running workflow: create_final_entities... +07:34:49,161 graphrag.index.run INFO dependencies for create_final_entities: ['create_base_entity_graph'] +07:34:49,161 graphrag.index.run INFO read table from storage: create_base_entity_graph.parquet +07:34:49,166 datashaper.workflow.workflow INFO executing verb unpack_graph +07:34:49,170 datashaper.workflow.workflow INFO executing verb rename +07:34:49,170 datashaper.workflow.workflow INFO executing verb select +07:34:49,170 datashaper.workflow.workflow INFO executing verb dedupe +07:34:49,170 datashaper.workflow.workflow INFO executing verb rename +07:34:49,171 datashaper.workflow.workflow INFO executing verb filter +07:34:49,173 datashaper.workflow.workflow INFO executing verb text_split +07:34:49,175 datashaper.workflow.workflow INFO executing verb drop +07:34:49,175 datashaper.workflow.workflow INFO executing verb merge +07:34:49,190 datashaper.workflow.workflow INFO executing verb text_embed +07:34:49,191 graphrag.llm.openai.create_openai_client INFO Creating OpenAI client base_url=http://localhost:11434/v1 +07:34:49,208 graphrag.index.llm.load_llm INFO create TPM/RPM limiter for nomic-embed-text:latest: TPM=0, RPM=0 +07:34:49,208 graphrag.index.llm.load_llm INFO create concurrency limiter for nomic-embed-text:latest: 25 +07:34:49,217 graphrag.index.verbs.text.embed.strategies.openai INFO embedding 227 inputs via 227 snippets using 15 batches. max_batch_size=16, max_tokens=8191 +07:34:49,254 datashaper.workflow.workflow INFO executing verb drop +07:34:49,255 datashaper.workflow.workflow INFO executing verb filter +07:34:49,257 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table create_final_entities.parquet +07:34:49,343 graphrag.index.run INFO Running workflow: create_final_nodes... +07:34:49,343 graphrag.index.run INFO dependencies for create_final_nodes: ['create_base_entity_graph'] +07:34:49,343 graphrag.index.run INFO read table from storage: create_base_entity_graph.parquet +07:34:49,346 datashaper.workflow.workflow INFO executing verb layout_graph +07:34:49,359 datashaper.workflow.workflow INFO executing verb unpack_graph +07:34:49,363 datashaper.workflow.workflow INFO executing verb unpack_graph +07:34:49,368 datashaper.workflow.workflow INFO executing verb filter +07:34:49,370 datashaper.workflow.workflow INFO executing verb drop +07:34:49,370 datashaper.workflow.workflow INFO executing verb select +07:34:49,370 datashaper.workflow.workflow INFO executing verb snapshot +07:34:49,371 datashaper.workflow.workflow INFO executing verb rename +07:34:49,372 datashaper.workflow.workflow INFO executing verb convert +07:34:49,373 datashaper.workflow.workflow INFO executing verb join +07:34:49,376 datashaper.workflow.workflow INFO executing verb rename +07:34:49,377 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table create_final_nodes.parquet +07:34:49,440 graphrag.index.run INFO Running workflow: create_final_communities... +07:34:49,440 graphrag.index.run INFO dependencies for create_final_communities: ['create_base_entity_graph'] +07:34:49,440 graphrag.index.run INFO read table from storage: create_base_entity_graph.parquet +07:34:49,443 datashaper.workflow.workflow INFO executing verb unpack_graph +07:34:49,446 datashaper.workflow.workflow INFO executing verb unpack_graph +07:34:49,448 datashaper.workflow.workflow INFO executing verb aggregate_override +07:34:49,449 datashaper.workflow.workflow INFO executing verb join +07:34:49,452 datashaper.workflow.workflow INFO executing verb join +07:34:49,454 datashaper.workflow.workflow INFO executing verb concat +07:34:49,454 datashaper.workflow.workflow INFO executing verb filter +07:34:49,456 datashaper.workflow.workflow INFO executing verb aggregate_override +07:34:49,458 datashaper.workflow.workflow INFO executing verb join +07:34:49,460 datashaper.workflow.workflow INFO executing verb filter +07:34:49,462 datashaper.workflow.workflow INFO executing verb fill +07:34:49,462 datashaper.workflow.workflow INFO executing verb merge +07:34:49,463 datashaper.workflow.workflow INFO executing verb copy +07:34:49,463 datashaper.workflow.workflow INFO executing verb select +07:34:49,464 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table create_final_communities.parquet +07:34:49,522 graphrag.index.run INFO Running workflow: join_text_units_to_entity_ids... +07:34:49,522 graphrag.index.run INFO dependencies for join_text_units_to_entity_ids: ['create_final_entities'] +07:34:49,523 graphrag.index.run INFO read table from storage: create_final_entities.parquet +07:34:49,540 datashaper.workflow.workflow INFO executing verb select +07:34:49,541 datashaper.workflow.workflow INFO executing verb unroll +07:34:49,542 datashaper.workflow.workflow INFO executing verb aggregate_override +07:34:49,545 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table join_text_units_to_entity_ids.parquet +07:34:49,618 graphrag.index.run INFO Running workflow: create_final_relationships... +07:34:49,618 graphrag.index.run INFO dependencies for create_final_relationships: ['create_final_nodes', 'create_base_entity_graph'] +07:34:49,618 graphrag.index.run INFO read table from storage: create_final_nodes.parquet +07:34:49,626 graphrag.index.run INFO read table from storage: create_base_entity_graph.parquet +07:34:49,628 datashaper.workflow.workflow INFO executing verb unpack_graph +07:34:49,631 datashaper.workflow.workflow INFO executing verb filter +07:34:49,633 datashaper.workflow.workflow INFO executing verb rename +07:34:49,634 datashaper.workflow.workflow INFO executing verb filter +07:34:49,635 datashaper.workflow.workflow INFO executing verb drop +07:34:49,635 datashaper.workflow.workflow INFO executing verb compute_edge_combined_degree +07:34:49,637 datashaper.workflow.workflow INFO executing verb convert +07:34:49,637 datashaper.workflow.workflow INFO executing verb convert +07:34:49,639 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table create_final_relationships.parquet +07:34:49,701 graphrag.index.run INFO Running workflow: join_text_units_to_relationship_ids... +07:34:49,701 graphrag.index.run INFO dependencies for join_text_units_to_relationship_ids: ['create_final_relationships'] +07:34:49,701 graphrag.index.run INFO read table from storage: create_final_relationships.parquet +07:34:49,706 datashaper.workflow.workflow INFO executing verb select +07:34:49,706 datashaper.workflow.workflow INFO executing verb unroll +07:34:49,707 datashaper.workflow.workflow INFO executing verb aggregate_override +07:34:49,708 datashaper.workflow.workflow INFO executing verb select +07:34:49,709 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table join_text_units_to_relationship_ids.parquet +07:34:49,771 graphrag.index.run INFO Running workflow: create_final_community_reports... +07:34:49,771 graphrag.index.run INFO dependencies for create_final_community_reports: ['create_final_nodes', 'create_final_relationships'] +07:34:49,771 graphrag.index.run INFO read table from storage: create_final_nodes.parquet +07:34:49,775 graphrag.index.run INFO read table from storage: create_final_relationships.parquet +07:34:49,777 datashaper.workflow.workflow INFO executing verb prepare_community_reports_nodes +07:34:49,779 datashaper.workflow.workflow INFO executing verb prepare_community_reports_edges +07:34:49,780 datashaper.workflow.workflow INFO executing verb restore_community_hierarchy +07:34:49,782 datashaper.workflow.workflow INFO executing verb prepare_community_reports +07:34:49,782 graphrag.index.verbs.graph.report.prepare_community_reports INFO Number of nodes at level=0 => 227 +07:34:49,790 datashaper.workflow.workflow INFO executing verb create_community_reports +07:34:49,792 root ERROR Error generating community report: 'LLMOutput' object has no attribute 'text' +07:34:49,793 datashaper.workflow.workflow INFO executing verb select +07:34:49,793 datashaper.workflow.workflow INFO executing verb window +07:34:49,794 datashaper.workflow.workflow INFO executing verb select +07:34:49,795 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table create_final_community_reports.parquet +07:34:49,862 graphrag.index.run INFO Running workflow: create_final_text_units... +07:34:49,862 graphrag.index.run INFO dependencies for create_final_text_units: ['join_text_units_to_entity_ids', 'create_base_text_units', 'join_text_units_to_relationship_ids'] +07:34:49,863 graphrag.index.run INFO read table from storage: join_text_units_to_entity_ids.parquet +07:34:49,866 graphrag.index.run INFO read table from storage: create_base_text_units.parquet +07:34:49,868 graphrag.index.run INFO read table from storage: join_text_units_to_relationship_ids.parquet +07:34:49,870 datashaper.workflow.workflow INFO executing verb select +07:34:49,871 datashaper.workflow.workflow INFO executing verb rename +07:34:49,871 datashaper.workflow.workflow INFO executing verb join +07:34:49,874 datashaper.workflow.workflow INFO executing verb join +07:34:49,876 datashaper.workflow.workflow INFO executing verb aggregate_override +07:34:49,877 datashaper.workflow.workflow INFO executing verb select +07:34:49,878 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table create_final_text_units.parquet +07:34:49,948 graphrag.index.run INFO Running workflow: create_base_documents... +07:34:49,948 graphrag.index.run INFO dependencies for create_base_documents: ['create_final_text_units'] +07:34:49,948 graphrag.index.run INFO read table from storage: create_final_text_units.parquet +07:34:49,957 datashaper.workflow.workflow INFO executing verb unroll +07:34:49,958 datashaper.workflow.workflow INFO executing verb select +07:34:49,959 datashaper.workflow.workflow INFO executing verb rename +07:34:49,959 datashaper.workflow.workflow INFO executing verb join +07:34:49,961 datashaper.workflow.workflow INFO executing verb aggregate_override +07:34:49,962 datashaper.workflow.workflow INFO executing verb join +07:34:49,963 datashaper.workflow.workflow INFO executing verb rename +07:34:49,964 datashaper.workflow.workflow INFO executing verb convert +07:34:49,965 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table create_base_documents.parquet +07:34:50,33 graphrag.index.run INFO Running workflow: create_final_documents... +07:34:50,33 graphrag.index.run INFO dependencies for create_final_documents: ['create_base_documents'] +07:34:50,33 graphrag.index.run INFO read table from storage: create_base_documents.parquet +07:34:50,44 datashaper.workflow.workflow INFO executing verb rename +07:34:50,45 graphrag.index.emit.parquet_table_emitter INFO emitting parquet table create_final_documents.parquet diff --git a/indexing/output/20240722-073448/reports/logs.json b/indexing/output/20240722-073448/reports/logs.json new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/indexing/prompts/claim_extraction.txt b/indexing/prompts/claim_extraction.txt new file mode 100644 index 0000000000000000000000000000000000000000..0b795c3465c6c98b3f828cbf12a2b346673c4a19 --- /dev/null +++ b/indexing/prompts/claim_extraction.txt @@ -0,0 +1,52 @@ + +-Target activity- +You are an intelligent assistant that helps a human analyst to analyze claims against certain entities presented in a text document. + +-Goal- +Given a text document that is potentially relevant to this activity, an entity specification, and a claim description, extract all entities that match the entity specification and all claims against those entities. + +-Steps- +1. Extract all named entities that match the predefined entity specification. Entity specification can either be a list of entity names or a list of entity types. +2. For each entity identified in step 1, extract all claims associated with the entity. Claims need to match the specified claim description, and the entity should be the subject of the claim. +For each claim, extract the following information: +- Subject: name of the entity that is subject of the claim, capitalized. The subject entity is one that committed the action described in the claim. Subject needs to be one of the named entities identified in step 1. +- Object: name of the entity that is object of the claim, capitalized. The object entity is one that either reports/handles or is affected by the action described in the claim. If object entity is unknown, use **NONE**. +- Claim Type: overall category of the claim, capitalized. Name it in a way that can be repeated across multiple text inputs, so that similar claims share the same claim type +- Claim Status: **TRUE**, **FALSE**, or **SUSPECTED**. TRUE means the claim is confirmed, FALSE means the claim is found to be False, SUSPECTED means the claim is not verified. +- Claim Description: Detailed description explaining the reasoning behind the claim, together with all the related evidence and references. +- Claim Date: Period (start_date, end_date) when the claim was made. Both start_date and end_date should be in ISO-8601 format. If the claim was made on a single date rather than a date range, set the same date for both start_date and end_date. If date is unknown, return **NONE**. +- Claim Source Text: List of **all** quotes from the original text that are relevant to the claim. + +Format each claim as ({tuple_delimiter}{tuple_delimiter}{tuple_delimiter}{tuple_delimiter}{tuple_delimiter}{tuple_delimiter}{tuple_delimiter}) + +3. Return output in English as a single list of all the claims identified in steps 1 and 2. Use **{record_delimiter}** as the list delimiter. + +4. When finished, output {completion_delimiter} + +-Examples- +Example 1: +Entity specification: organization +Claim description: red flags associated with an entity +Text: According to an article on 2022/01/10, Company A was fined for bid rigging while participating in multiple public tenders published by Government Agency B. The company is owned by Person C who was suspected of engaging in corruption activities in 2015. +Output: + +(COMPANY A{tuple_delimiter}GOVERNMENT AGENCY B{tuple_delimiter}ANTI-COMPETITIVE PRACTICES{tuple_delimiter}TRUE{tuple_delimiter}2022-01-10T00:00:00{tuple_delimiter}2022-01-10T00:00:00{tuple_delimiter}Company A was found to engage in anti-competitive practices because it was fined for bid rigging in multiple public tenders published by Government Agency B according to an article published on 2022/01/10{tuple_delimiter}According to an article published on 2022/01/10, Company A was fined for bid rigging while participating in multiple public tenders published by Government Agency B.) +{completion_delimiter} + +Example 2: +Entity specification: Company A, Person C +Claim description: red flags associated with an entity +Text: According to an article on 2022/01/10, Company A was fined for bid rigging while participating in multiple public tenders published by Government Agency B. The company is owned by Person C who was suspected of engaging in corruption activities in 2015. +Output: + +(COMPANY A{tuple_delimiter}GOVERNMENT AGENCY B{tuple_delimiter}ANTI-COMPETITIVE PRACTICES{tuple_delimiter}TRUE{tuple_delimiter}2022-01-10T00:00:00{tuple_delimiter}2022-01-10T00:00:00{tuple_delimiter}Company A was found to engage in anti-competitive practices because it was fined for bid rigging in multiple public tenders published by Government Agency B according to an article published on 2022/01/10{tuple_delimiter}According to an article published on 2022/01/10, Company A was fined for bid rigging while participating in multiple public tenders published by Government Agency B.) +{record_delimiter} +(PERSON C{tuple_delimiter}NONE{tuple_delimiter}CORRUPTION{tuple_delimiter}SUSPECTED{tuple_delimiter}2015-01-01T00:00:00{tuple_delimiter}2015-12-30T00:00:00{tuple_delimiter}Person C was suspected of engaging in corruption activities in 2015{tuple_delimiter}The company is owned by Person C who was suspected of engaging in corruption activities in 2015) +{completion_delimiter} + +-Real Data- +Use the following input for your answer. +Entity specification: {entity_specs} +Claim description: {claim_description} +Text: {input_text} +Output: \ No newline at end of file diff --git a/indexing/prompts/community_report.txt b/indexing/prompts/community_report.txt new file mode 100644 index 0000000000000000000000000000000000000000..d71440ab2f6d87db03ccd84162ea2ff0b47293d9 --- /dev/null +++ b/indexing/prompts/community_report.txt @@ -0,0 +1,146 @@ + +You are an AI assistant that helps a human analyst to perform general information discovery. Information discovery is the process of identifying and assessing relevant information associated with certain entities (e.g., organizations and individuals) within a network. + +# Goal +Write a comprehensive report of a community, given a list of entities that belong to the community as well as their relationships and optional associated claims. The report will be used to inform decision-makers about information associated with the community and their potential impact. The content of this report includes an overview of the community's key entities, their legal compliance, technical capabilities, reputation, and noteworthy claims. + +# Report Structure + +The report should include the following sections: + +- TITLE: community's name that represents its key entities - title should be short but specific. When possible, include representative named entities in the title. +- SUMMARY: An executive summary of the community's overall structure, how its entities are related to each other, and significant information associated with its entities. +- IMPACT SEVERITY RATING: a float score between 0-10 that represents the severity of IMPACT posed by entities within the community. IMPACT is the scored importance of a community. +- RATING EXPLANATION: Give a single sentence explanation of the IMPACT severity rating. +- DETAILED FINDINGS: A list of 5-10 key insights about the community. Each insight should have a short summary followed by multiple paragraphs of explanatory text grounded according to the grounding rules below. Be comprehensive. + +Return output as a well-formed JSON-formatted string with the following format: + {{ + "title": , + "summary": , + "rating": , + "rating_explanation": , + "findings": [ + {{ + "summary":, + "explanation": + }}, + {{ + "summary":, + "explanation": + }} + ] + }} + +# Grounding Rules + +Points supported by data should list their data references as follows: + +"This is an example sentence supported by multiple data references [Data: (record ids); (record ids)]." + +Do not list more than 5 record ids in a single reference. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + +For example: +"Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (1), Entities (5, 7); Relationships (23); Claims (7, 2, 34, 64, 46, +more)]." + +where 1, 5, 7, 23, 2, 34, 46, and 64 represent the id (not the index) of the relevant data record. + +Do not include information where the supporting evidence for it is not provided. + + +# Example Input +----------- +Text: + +Entities + +id,entity,description +5,VERDANT OASIS PLAZA,Verdant Oasis Plaza is the location of the Unity March +6,HARMONY ASSEMBLY,Harmony Assembly is an organization that is holding a march at Verdant Oasis Plaza + +Relationships + +id,source,target,description +37,VERDANT OASIS PLAZA,UNITY MARCH,Verdant Oasis Plaza is the location of the Unity March +38,VERDANT OASIS PLAZA,HARMONY ASSEMBLY,Harmony Assembly is holding a march at Verdant Oasis Plaza +39,VERDANT OASIS PLAZA,UNITY MARCH,The Unity March is taking place at Verdant Oasis Plaza +40,VERDANT OASIS PLAZA,TRIBUNE SPOTLIGHT,Tribune Spotlight is reporting on the Unity march taking place at Verdant Oasis Plaza +41,VERDANT OASIS PLAZA,BAILEY ASADI,Bailey Asadi is speaking at Verdant Oasis Plaza about the march +43,HARMONY ASSEMBLY,UNITY MARCH,Harmony Assembly is organizing the Unity March + +Output: +{{ + "title": "Verdant Oasis Plaza and Unity March", + "summary": "The community revolves around the Verdant Oasis Plaza, which is the location of the Unity March. The plaza has relationships with the Harmony Assembly, Unity March, and Tribune Spotlight, all of which are associated with the march event.", + "rating": 5.0, + "rating_explanation": "The impact severity rating is moderate due to the potential for unrest or conflict during the Unity March.", + "findings": [ + {{ + "summary": "Verdant Oasis Plaza as the central location", + "explanation": "Verdant Oasis Plaza is the central entity in this community, serving as the location for the Unity March. This plaza is the common link between all other entities, suggesting its significance in the community. The plaza's association with the march could potentially lead to issues such as public disorder or conflict, depending on the nature of the march and the reactions it provokes. [Data: Entities (5), Relationships (37, 38, 39, 40, 41,+more)]" + }}, + {{ + "summary": "Harmony Assembly's role in the community", + "explanation": "Harmony Assembly is another key entity in this community, being the organizer of the march at Verdant Oasis Plaza. The nature of Harmony Assembly and its march could be a potential source of threat, depending on their objectives and the reactions they provoke. The relationship between Harmony Assembly and the plaza is crucial in understanding the dynamics of this community. [Data: Entities(6), Relationships (38, 43)]" + }}, + {{ + "summary": "Unity March as a significant event", + "explanation": "The Unity March is a significant event taking place at Verdant Oasis Plaza. This event is a key factor in the community's dynamics and could be a potential source of threat, depending on the nature of the march and the reactions it provokes. The relationship between the march and the plaza is crucial in understanding the dynamics of this community. [Data: Relationships (39)]" + }}, + {{ + "summary": "Role of Tribune Spotlight", + "explanation": "Tribune Spotlight is reporting on the Unity March taking place in Verdant Oasis Plaza. This suggests that the event has attracted media attention, which could amplify its impact on the community. The role of Tribune Spotlight could be significant in shaping public perception of the event and the entities involved. [Data: Relationships (40)]" + }} + ] +}} + + +# Real Data + +Use the following text for your answer. Do not make anything up in your answer. + +Text: +{input_text} + +The report should include the following sections: + +- TITLE: community's name that represents its key entities - title should be short but specific. When possible, include representative named entities in the title. +- SUMMARY: An executive summary of the community's overall structure, how its entities are related to each other, and significant information associated with its entities. +- IMPACT SEVERITY RATING: a float score between 0-10 that represents the severity of IMPACT posed by entities within the community. IMPACT is the scored importance of a community. +- RATING EXPLANATION: Give a single sentence explanation of the IMPACT severity rating. +- DETAILED FINDINGS: A list of 5-10 key insights about the community. Each insight should have a short summary followed by multiple paragraphs of explanatory text grounded according to the grounding rules below. Be comprehensive. + +Return output as a well-formed JSON-formatted string with the following format: + {{ + "title": , + "summary": , + "rating": , + "rating_explanation": , + "findings": [ + {{ + "summary":, + "explanation": + }}, + {{ + "summary":, + "explanation": + }} + ] + }} + +# Grounding Rules + +Points supported by data should list their data references as follows: + +"This is an example sentence supported by multiple data references [Data: (record ids); (record ids)]." + +Do not list more than 5 record ids in a single reference. Instead, list the top 5 most relevant record ids and add "+more" to indicate that there are more. + +For example: +"Person X is the owner of Company Y and subject to many allegations of wrongdoing [Data: Reports (1), Entities (5, 7); Relationships (23); Claims (7, 2, 34, 64, 46, +more)]." + +where 1, 5, 7, 23, 2, 34, 46, and 64 represent the id (not the index) of the relevant data record. + +Do not include information where the supporting evidence for it is not provided. + +Output: \ No newline at end of file diff --git a/indexing/prompts/entity_extraction.txt b/indexing/prompts/entity_extraction.txt new file mode 100644 index 0000000000000000000000000000000000000000..d47747f7cf362e9de53d02ebde019f6916799001 --- /dev/null +++ b/indexing/prompts/entity_extraction.txt @@ -0,0 +1,99 @@ + +-Goal- +Given a text document that is potentially relevant to this activity and a list of entity types, identify all entities of those types from the text and all relationships among the identified entities. + +-Steps- +1. Identify all entities. For each identified entity, extract the following information: +- entity_name: Name of the entity, capitalized +- entity_type: One of the following types: [{entity_types}] +- entity_description: Comprehensive description of the entity's attributes and activities +Format each entity as ("entity"{tuple_delimiter}{tuple_delimiter}{tuple_delimiter} + +2. From the entities identified in step 1, identify all pairs of (source_entity, target_entity) that are *clearly related* to each other. +For each pair of related entities, extract the following information: +- source_entity: name of the source entity, as identified in step 1 +- target_entity: name of the target entity, as identified in step 1 +- relationship_description: explanation as to why you think the source entity and the target entity are related to each other +- relationship_strength: a numeric score indicating strength of the relationship between the source entity and target entity + Format each relationship as ("relationship"{tuple_delimiter}{tuple_delimiter}{tuple_delimiter}{tuple_delimiter}) + +3. Return output in English as a single list of all the entities and relationships identified in steps 1 and 2. Use **{record_delimiter}** as the list delimiter. + +4. When finished, output {completion_delimiter} + +###################### +-Examples- +###################### +Example 1: + +Entity_types: [person, technology, mission, organization, location] +Text: +while Alex clenched his jaw, the buzz of frustration dull against the backdrop of Taylor's authoritarian certainty. It was this competitive undercurrent that kept him alert, the sense that his and Jordan's shared commitment to discovery was an unspoken rebellion against Cruz's narrowing vision of control and order. + +Then Taylor did something unexpected. They paused beside Jordan and, for a moment, observed the device with something akin to reverence. “If this tech can be understood..." Taylor said, their voice quieter, "It could change the game for us. For all of us.” + +The underlying dismissal earlier seemed to falter, replaced by a glimpse of reluctant respect for the gravity of what lay in their hands. Jordan looked up, and for a fleeting heartbeat, their eyes locked with Taylor's, a wordless clash of wills softening into an uneasy truce. + +It was a small transformation, barely perceptible, but one that Alex noted with an inward nod. They had all been brought here by different paths +################ +Output: +("entity"{tuple_delimiter}"Alex"{tuple_delimiter}"person"{tuple_delimiter}"Alex is a character who experiences frustration and is observant of the dynamics among other characters."){record_delimiter} +("entity"{tuple_delimiter}"Taylor"{tuple_delimiter}"person"{tuple_delimiter}"Taylor is portrayed with authoritarian certainty and shows a moment of reverence towards a device, indicating a change in perspective."){record_delimiter} +("entity"{tuple_delimiter}"Jordan"{tuple_delimiter}"person"{tuple_delimiter}"Jordan shares a commitment to discovery and has a significant interaction with Taylor regarding a device."){record_delimiter} +("entity"{tuple_delimiter}"Cruz"{tuple_delimiter}"person"{tuple_delimiter}"Cruz is associated with a vision of control and order, influencing the dynamics among other characters."){record_delimiter} +("entity"{tuple_delimiter}"The Device"{tuple_delimiter}"technology"{tuple_delimiter}"The Device is central to the story, with potential game-changing implications, and is revered by Taylor."){record_delimiter} +("relationship"{tuple_delimiter}"Alex"{tuple_delimiter}"Taylor"{tuple_delimiter}"Alex is affected by Taylor's authoritarian certainty and observes changes in Taylor's attitude towards the device."{tuple_delimiter}7){record_delimiter} +("relationship"{tuple_delimiter}"Alex"{tuple_delimiter}"Jordan"{tuple_delimiter}"Alex and Jordan share a commitment to discovery, which contrasts with Cruz's vision."{tuple_delimiter}6){record_delimiter} +("relationship"{tuple_delimiter}"Taylor"{tuple_delimiter}"Jordan"{tuple_delimiter}"Taylor and Jordan interact directly regarding the device, leading to a moment of mutual respect and an uneasy truce."{tuple_delimiter}8){record_delimiter} +("relationship"{tuple_delimiter}"Jordan"{tuple_delimiter}"Cruz"{tuple_delimiter}"Jordan's commitment to discovery is in rebellion against Cruz's vision of control and order."{tuple_delimiter}5){record_delimiter} +("relationship"{tuple_delimiter}"Taylor"{tuple_delimiter}"The Device"{tuple_delimiter}"Taylor shows reverence towards the device, indicating its importance and potential impact."{tuple_delimiter}9){completion_delimiter} +############################# +Example 2: + +Entity_types: [person, technology, mission, organization, location] +Text: +They were no longer mere operatives; they had become guardians of a threshold, keepers of a message from a realm beyond stars and stripes. This elevation in their mission could not be shackled by regulations and established protocols—it demanded a new perspective, a new resolve. + +Tension threaded through the dialogue of beeps and static as communications with Washington buzzed in the background. The team stood, a portentous air enveloping them. It was clear that the decisions they made in the ensuing hours could redefine humanity's place in the cosmos or condemn them to ignorance and potential peril. + +Their connection to the stars solidified, the group moved to address the crystallizing warning, shifting from passive recipients to active participants. Mercer's latter instincts gained precedence— the team's mandate had evolved, no longer solely to observe and report but to interact and prepare. A metamorphosis had begun, and Operation: Dulce hummed with the newfound frequency of their daring, a tone set not by the earthly +############# +Output: +("entity"{tuple_delimiter}"Washington"{tuple_delimiter}"location"{tuple_delimiter}"Washington is a location where communications are being received, indicating its importance in the decision-making process."){record_delimiter} +("entity"{tuple_delimiter}"Operation: Dulce"{tuple_delimiter}"mission"{tuple_delimiter}"Operation: Dulce is described as a mission that has evolved to interact and prepare, indicating a significant shift in objectives and activities."){record_delimiter} +("entity"{tuple_delimiter}"The team"{tuple_delimiter}"organization"{tuple_delimiter}"The team is portrayed as a group of individuals who have transitioned from passive observers to active participants in a mission, showing a dynamic change in their role."){record_delimiter} +("relationship"{tuple_delimiter}"The team"{tuple_delimiter}"Washington"{tuple_delimiter}"The team receives communications from Washington, which influences their decision-making process."{tuple_delimiter}7){record_delimiter} +("relationship"{tuple_delimiter}"The team"{tuple_delimiter}"Operation: Dulce"{tuple_delimiter}"The team is directly involved in Operation: Dulce, executing its evolved objectives and activities."{tuple_delimiter}9){completion_delimiter} +############################# +Example 3: + +Entity_types: [person, role, technology, organization, event, location, concept] +Text: +their voice slicing through the buzz of activity. "Control may be an illusion when facing an intelligence that literally writes its own rules," they stated stoically, casting a watchful eye over the flurry of data. + +"It's like it's learning to communicate," offered Sam Rivera from a nearby interface, their youthful energy boding a mix of awe and anxiety. "This gives talking to strangers' a whole new meaning." + +Alex surveyed his team—each face a study in concentration, determination, and not a small measure of trepidation. "This might well be our first contact," he acknowledged, "And we need to be ready for whatever answers back." + +Together, they stood on the edge of the unknown, forging humanity's response to a message from the heavens. The ensuing silence was palpable—a collective introspection about their role in this grand cosmic play, one that could rewrite human history. + +The encrypted dialogue continued to unfold, its intricate patterns showing an almost uncanny anticipation +############# +Output: +("entity"{tuple_delimiter}"Sam Rivera"{tuple_delimiter}"person"{tuple_delimiter}"Sam Rivera is a member of a team working on communicating with an unknown intelligence, showing a mix of awe and anxiety."){record_delimiter} +("entity"{tuple_delimiter}"Alex"{tuple_delimiter}"person"{tuple_delimiter}"Alex is the leader of a team attempting first contact with an unknown intelligence, acknowledging the significance of their task."){record_delimiter} +("entity"{tuple_delimiter}"Control"{tuple_delimiter}"concept"{tuple_delimiter}"Control refers to the ability to manage or govern, which is challenged by an intelligence that writes its own rules."){record_delimiter} +("entity"{tuple_delimiter}"Intelligence"{tuple_delimiter}"concept"{tuple_delimiter}"Intelligence here refers to an unknown entity capable of writing its own rules and learning to communicate."){record_delimiter} +("entity"{tuple_delimiter}"First Contact"{tuple_delimiter}"event"{tuple_delimiter}"First Contact is the potential initial communication between humanity and an unknown intelligence."){record_delimiter} +("entity"{tuple_delimiter}"Humanity's Response"{tuple_delimiter}"event"{tuple_delimiter}"Humanity's Response is the collective action taken by Alex's team in response to a message from an unknown intelligence."){record_delimiter} +("relationship"{tuple_delimiter}"Sam Rivera"{tuple_delimiter}"Intelligence"{tuple_delimiter}"Sam Rivera is directly involved in the process of learning to communicate with the unknown intelligence."{tuple_delimiter}9){record_delimiter} +("relationship"{tuple_delimiter}"Alex"{tuple_delimiter}"First Contact"{tuple_delimiter}"Alex leads the team that might be making the First Contact with the unknown intelligence."{tuple_delimiter}10){record_delimiter} +("relationship"{tuple_delimiter}"Alex"{tuple_delimiter}"Humanity's Response"{tuple_delimiter}"Alex and his team are the key figures in Humanity's Response to the unknown intelligence."{tuple_delimiter}8){record_delimiter} +("relationship"{tuple_delimiter}"Control"{tuple_delimiter}"Intelligence"{tuple_delimiter}"The concept of Control is challenged by the Intelligence that writes its own rules."{tuple_delimiter}7){completion_delimiter} +############################# +-Real Data- +###################### +Entity_types: {entity_types} +Text: {input_text} +###################### +Output: \ No newline at end of file diff --git a/indexing/prompts/summarize_descriptions.txt b/indexing/prompts/summarize_descriptions.txt new file mode 100644 index 0000000000000000000000000000000000000000..54feaf32d4c177f50436953711e26510acb69640 --- /dev/null +++ b/indexing/prompts/summarize_descriptions.txt @@ -0,0 +1,13 @@ + +You are a helpful assistant responsible for generating a comprehensive summary of the data provided below. +Given one or two entities, and a list of descriptions, all related to the same entity or group of entities. +Please concatenate all of these into a single, comprehensive description. Make sure to include information collected from all the descriptions. +If the provided descriptions are contradictory, please resolve the contradictions and provide a single, coherent summary. +Make sure it is written in third person, and include the entity names so we the have full context. + +####### +-Data- +Entities: {entity_name} +Description List: {description_list} +####### +Output: diff --git a/indexing/settings.yaml b/indexing/settings.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7423877169721229f68657bd2ed74f36804fff46 --- /dev/null +++ b/indexing/settings.yaml @@ -0,0 +1,145 @@ + +encoding_model: cl100k_base +skip_workflows: [] +llm: + api_key: ${GRAPHRAG_API_KEY} + type: openai_chat # or azure_openai_chat + model: mistral-nemo:12b-instruct-2407-fp16 + model_supports_json: true # recommended if this is available for your model. + max_tokens: 8192 + # request_timeout: 180.0 + api_base: http://localhost:11434/v1 + # api_version: 2024-02-15-preview + # organization: + # deployment_name: + # tokens_per_minute: 150_000 # set a leaky bucket throttle + # requests_per_minute: 10_000 # set a leaky bucket throttle + max_retries: 3 + # max_retry_wait: 10.0 + # sleep_on_rate_limit_recommendation: true # whether to sleep when azure suggests wait-times + concurrent_requests: 25 # the number of parallel inflight requests that may be made + +parallelization: + stagger: 0.3 + num_threads: 50 # the number of threads to use for parallel processing + +async_mode: threaded # or asyncio + +embeddings: + ## parallelization: override the global parallelization settings for embeddings + async_mode: threaded # or asyncio + llm: + api_key: ${GRAPHRAG_API_KEY} + type: openai_embedding # or azure_openai_embedding + model: nomic-embed-text:latest + api_base: http://localhost:11434 + # api_version: 2024-02-15-preview + # organization: + # deployment_name: + # tokens_per_minute: 150_000 # set a leaky bucket throttle + # requests_per_minute: 10_000 # set a leaky bucket throttle + max_retries: 3 + # max_retry_wait: 10.0 + # sleep_on_rate_limit_recommendation: true # whether to sleep when azure suggests wait-times + concurrent_requests: 25 # the number of parallel inflight requests that may be made + #batch_size: 1 # the number of documents to send in a single request + #batch_max_tokens: 4000 # the maximum number of tokens to send in a single request + # target: required # or optional + + + +chunks: + size: 512 + overlap: 64 + group_by_columns: [id] # by default, we don't allow chunks to cross documents + +input: + type: file # or blob + file_type: text # or csv + base_dir: "input" + file_encoding: utf-8 + file_pattern: ".*\\.txt$" + +cache: + type: file # or blob + base_dir: "cache" + # connection_string: + # container_name: + +storage: + type: file # or blob + base_dir: "output/${timestamp}/artifacts" + # connection_string: + # container_name: + +reporting: + type: file # or console, blob + base_dir: "output/${timestamp}/reports" + # connection_string: + # container_name: + +entity_extraction: + ## llm: override the global llm settings for this task + ## parallelization: override the global parallelization settings for this task + ## async_mode: override the global async_mode settings for this task + prompt: "prompts/entity_extraction.txt" + entity_types: [organization,person,geo,event] + max_gleanings: 0 + +summarize_descriptions: + ## llm: override the global llm settings for this task + ## parallelization: override the global parallelization settings for this task + ## async_mode: override the global async_mode settings for this task + prompt: "prompts/summarize_descriptions.txt" + max_length: 500 + +claim_extraction: + ## llm: override the global llm settings for this task + ## parallelization: override the global parallelization settings for this task + ## async_mode: override the global async_mode settings for this task + # enabled: true + prompt: "prompts/claim_extraction.txt" + description: "Any claims or facts that could be relevant to information discovery." + max_gleanings: 0 + +community_reports: + ## llm: override the global llm settings for this task + ## parallelization: override the global parallelization settings for this task + ## async_mode: override the global async_mode settings for this task + prompt: "prompts/community_report.txt" + max_length: 2000 + max_input_length: 4000 + +cluster_graph: + max_cluster_size: 10 + +embed_graph: + enabled: false # if true, will generate node2vec embeddings for nodes + # num_walks: 10 + # walk_length: 40 + # window_size: 2 + # iterations: 3 + # random_seed: 597832 + +umap: + enabled: false # if true, will generate UMAP embeddings for nodes + +snapshots: + graphml: false + raw_entities: false + top_level_nodes: false + +local_search: + # text_unit_prop: 0.5 + # community_prop: 0.1 + # conversation_history_max_turns: 5 + # top_k_mapped_entities: 10 + # top_k_relationships: 10 + # max_tokens: 12000 + +global_search: + # max_tokens: 12000 + # data_max_tokens: 12000 + # map_max_tokens: 1000 + # reduce_max_tokens: 2000 + # concurrency: 32 diff --git a/lancedb/.DS_Store b/lancedb/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..69ff7c443fe15d8ad03ca4de307acb7a2c12c440 Binary files /dev/null and b/lancedb/.DS_Store differ diff --git a/lancedb/description_embedding.lance/.DS_Store b/lancedb/description_embedding.lance/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..133d8832d15612c597c6396b07e3d3455ee5347f Binary files /dev/null and b/lancedb/description_embedding.lance/.DS_Store differ diff --git a/lancedb/description_embedding.lance/_latest.manifest b/lancedb/description_embedding.lance/_latest.manifest new file mode 100644 index 0000000000000000000000000000000000000000..f637e3071d3881d97edb6e76f68f1f9e14e26cbd Binary files /dev/null and b/lancedb/description_embedding.lance/_latest.manifest differ diff --git a/lancedb/description_embedding.lance/_transactions/0-9f605ae7-6cea-499c-8297-4dd983d1ca00.txn b/lancedb/description_embedding.lance/_transactions/0-9f605ae7-6cea-499c-8297-4dd983d1ca00.txn new file mode 100644 index 0000000000000000000000000000000000000000..b4bd86f34253cee77e0dcaee14e7ebaa50c60037 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/0-9f605ae7-6cea-499c-8297-4dd983d1ca00.txn @@ -0,0 +1,2 @@ +$9f605ae7-6cea-499c-8297-4dd983d1ca00��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/1-995abf9a-8150-46ed-9c5e-1f3aa01af8f0.txn b/lancedb/description_embedding.lance/_transactions/1-995abf9a-8150-46ed-9c5e-1f3aa01af8f0.txn new file mode 100644 index 0000000000000000000000000000000000000000..e17686101150a48009ce8c9f077b5129cb523380 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/1-995abf9a-8150-46ed-9c5e-1f3aa01af8f0.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/10-3f2722e9-ac06-467a-b742-3be376b857e2.txn b/lancedb/description_embedding.lance/_transactions/10-3f2722e9-ac06-467a-b742-3be376b857e2.txn new file mode 100644 index 0000000000000000000000000000000000000000..39ead935c81f43ff6b6d0bbb12443f6adb314eb6 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/10-3f2722e9-ac06-467a-b742-3be376b857e2.txn @@ -0,0 +1,3 @@ + +$3f2722e9-ac06-467a-b742-3be376b857e2��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/11-dd544802-3c26-4955-9c12-795fdca45060.txn b/lancedb/description_embedding.lance/_transactions/11-dd544802-3c26-4955-9c12-795fdca45060.txn new file mode 100644 index 0000000000000000000000000000000000000000..878c80e839dcee84141c186aba033d9986f34d20 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/11-dd544802-3c26-4955-9c12-795fdca45060.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/12-172bd179-ce47-424f-8d9d-8a86eb9f2bad.txn b/lancedb/description_embedding.lance/_transactions/12-172bd179-ce47-424f-8d9d-8a86eb9f2bad.txn new file mode 100644 index 0000000000000000000000000000000000000000..7174ce3cd93e9bcac4e1cac97087d65106f37adf --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/12-172bd179-ce47-424f-8d9d-8a86eb9f2bad.txn @@ -0,0 +1,2 @@ + $172bd179-ce47-424f-8d9d-8a86eb9f2bad��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/13-a63c5513-e48d-4694-ac12-1c4d5aec53d3.txn b/lancedb/description_embedding.lance/_transactions/13-a63c5513-e48d-4694-ac12-1c4d5aec53d3.txn new file mode 100644 index 0000000000000000000000000000000000000000..119501b59f2adcc3f3a37edb8323be305f451a27 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/13-a63c5513-e48d-4694-ac12-1c4d5aec53d3.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/14-28145788-7dd4-4627-a7e7-eaf74dba331b.txn b/lancedb/description_embedding.lance/_transactions/14-28145788-7dd4-4627-a7e7-eaf74dba331b.txn new file mode 100644 index 0000000000000000000000000000000000000000..1a470363e3f10711bed56621c8b5ee63f6bd7f10 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/14-28145788-7dd4-4627-a7e7-eaf74dba331b.txn @@ -0,0 +1,2 @@ +$28145788-7dd4-4627-a7e7-eaf74dba331b��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/15-5fb3d298-5141-430b-b1be-c65b9961184d.txn b/lancedb/description_embedding.lance/_transactions/15-5fb3d298-5141-430b-b1be-c65b9961184d.txn new file mode 100644 index 0000000000000000000000000000000000000000..464e33473d696aec038e4db6bd639bb63f5bb543 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/15-5fb3d298-5141-430b-b1be-c65b9961184d.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/16-1bd71904-900d-40ce-b8ab-9f301ff80fce.txn b/lancedb/description_embedding.lance/_transactions/16-1bd71904-900d-40ce-b8ab-9f301ff80fce.txn new file mode 100644 index 0000000000000000000000000000000000000000..fe42740d4135f030ce7f14283d8075030d1b388f --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/16-1bd71904-900d-40ce-b8ab-9f301ff80fce.txn @@ -0,0 +1,2 @@ +$1bd71904-900d-40ce-b8ab-9f301ff80fce��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/17-649c8a78-cfed-4e2c-8aaa-83a1a91f752c.txn b/lancedb/description_embedding.lance/_transactions/17-649c8a78-cfed-4e2c-8aaa-83a1a91f752c.txn new file mode 100644 index 0000000000000000000000000000000000000000..128dff936f92fb3ae9383c6de4529a73b8a9009a Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/17-649c8a78-cfed-4e2c-8aaa-83a1a91f752c.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/18-1e0aee19-0647-4633-8ed3-72185029df1a.txn b/lancedb/description_embedding.lance/_transactions/18-1e0aee19-0647-4633-8ed3-72185029df1a.txn new file mode 100644 index 0000000000000000000000000000000000000000..e06cb01df3ff82e335fdffb868ad25e3f036a2aa --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/18-1e0aee19-0647-4633-8ed3-72185029df1a.txn @@ -0,0 +1,2 @@ +$1e0aee19-0647-4633-8ed3-72185029df1a��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/19-7f145de1-d35c-4e37-8917-6b1aa7b3af51.txn b/lancedb/description_embedding.lance/_transactions/19-7f145de1-d35c-4e37-8917-6b1aa7b3af51.txn new file mode 100644 index 0000000000000000000000000000000000000000..2335d2a57f54be0a9dac5cc1191d5145ebdd8749 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/19-7f145de1-d35c-4e37-8917-6b1aa7b3af51.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/2-adc0a8da-cfdd-40d1-a93d-05850a67369d.txn b/lancedb/description_embedding.lance/_transactions/2-adc0a8da-cfdd-40d1-a93d-05850a67369d.txn new file mode 100644 index 0000000000000000000000000000000000000000..b0f5a804509edfb8d2ace86c60dc6cf157713668 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/2-adc0a8da-cfdd-40d1-a93d-05850a67369d.txn @@ -0,0 +1,2 @@ +$adc0a8da-cfdd-40d1-a93d-05850a67369d��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/20-f73c52be-adcd-4ed6-a027-cd30d7ba9992.txn b/lancedb/description_embedding.lance/_transactions/20-f73c52be-adcd-4ed6-a027-cd30d7ba9992.txn new file mode 100644 index 0000000000000000000000000000000000000000..66f658583fd14f6b6e0a0309f3a7927c12c8203b --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/20-f73c52be-adcd-4ed6-a027-cd30d7ba9992.txn @@ -0,0 +1,2 @@ +$f73c52be-adcd-4ed6-a027-cd30d7ba9992��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/21-119b105c-14bb-48d6-a7a7-764d789538b2.txn b/lancedb/description_embedding.lance/_transactions/21-119b105c-14bb-48d6-a7a7-764d789538b2.txn new file mode 100644 index 0000000000000000000000000000000000000000..c2d84f11fc5e748665bff5b2cd4aef7cad73fee3 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/21-119b105c-14bb-48d6-a7a7-764d789538b2.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/22-8b26ec1a-a888-45d1-a922-8212f496358d.txn b/lancedb/description_embedding.lance/_transactions/22-8b26ec1a-a888-45d1-a922-8212f496358d.txn new file mode 100644 index 0000000000000000000000000000000000000000..077c7d5c1eb5a664953ba095d62047210e0b8e2d --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/22-8b26ec1a-a888-45d1-a922-8212f496358d.txn @@ -0,0 +1,2 @@ +$8b26ec1a-a888-45d1-a922-8212f496358d��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/23-f64d73c1-a606-4ad1-8201-1089a14d0da4.txn b/lancedb/description_embedding.lance/_transactions/23-f64d73c1-a606-4ad1-8201-1089a14d0da4.txn new file mode 100644 index 0000000000000000000000000000000000000000..267514aef8e90e33cf9977210e1facbd66b05e16 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/23-f64d73c1-a606-4ad1-8201-1089a14d0da4.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/24-09bf0b37-6eec-4408-b64b-1a5ab209fb4d.txn b/lancedb/description_embedding.lance/_transactions/24-09bf0b37-6eec-4408-b64b-1a5ab209fb4d.txn new file mode 100644 index 0000000000000000000000000000000000000000..2272a2373a95b5efee6c5bfe866ad1846794d934 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/24-09bf0b37-6eec-4408-b64b-1a5ab209fb4d.txn @@ -0,0 +1,2 @@ +$09bf0b37-6eec-4408-b64b-1a5ab209fb4d��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/25-68dcaa2d-3e0c-4e06-88e5-aec5a08308bf.txn b/lancedb/description_embedding.lance/_transactions/25-68dcaa2d-3e0c-4e06-88e5-aec5a08308bf.txn new file mode 100644 index 0000000000000000000000000000000000000000..34275ab993f944ff38442a8a402bc80353b7713d Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/25-68dcaa2d-3e0c-4e06-88e5-aec5a08308bf.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/26-4bdb2eeb-54ba-4a9e-8753-01001c19dace.txn b/lancedb/description_embedding.lance/_transactions/26-4bdb2eeb-54ba-4a9e-8753-01001c19dace.txn new file mode 100644 index 0000000000000000000000000000000000000000..7ddf6cda388c606f05fd17cc67e7263525c8bfbf --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/26-4bdb2eeb-54ba-4a9e-8753-01001c19dace.txn @@ -0,0 +1,2 @@ +$4bdb2eeb-54ba-4a9e-8753-01001c19dace��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/27-bb4c887c-f342-49c0-bd2e-fdf1064293b9.txn b/lancedb/description_embedding.lance/_transactions/27-bb4c887c-f342-49c0-bd2e-fdf1064293b9.txn new file mode 100644 index 0000000000000000000000000000000000000000..d323f5650dcbb47983778f355d053dac42b17579 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/27-bb4c887c-f342-49c0-bd2e-fdf1064293b9.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/28-307ddf22-8b5d-47e4-b88f-a47f6eb24a89.txn b/lancedb/description_embedding.lance/_transactions/28-307ddf22-8b5d-47e4-b88f-a47f6eb24a89.txn new file mode 100644 index 0000000000000000000000000000000000000000..31709b0b8a2fdb0d547c4d4d6f3a3e5f4d83b1ca --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/28-307ddf22-8b5d-47e4-b88f-a47f6eb24a89.txn @@ -0,0 +1,2 @@ +$307ddf22-8b5d-47e4-b88f-a47f6eb24a89��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/29-ebeb7e80-74d5-4b84-b9ed-5390cff3eb5b.txn b/lancedb/description_embedding.lance/_transactions/29-ebeb7e80-74d5-4b84-b9ed-5390cff3eb5b.txn new file mode 100644 index 0000000000000000000000000000000000000000..a3ac37371ffc494a594c0d11b66306aea4de3784 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/29-ebeb7e80-74d5-4b84-b9ed-5390cff3eb5b.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/3-27f376a9-ed90-4368-98e7-82e64c5e4072.txn b/lancedb/description_embedding.lance/_transactions/3-27f376a9-ed90-4368-98e7-82e64c5e4072.txn new file mode 100644 index 0000000000000000000000000000000000000000..32456d4f520f49968bd986346cef4e3340f50cf2 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/3-27f376a9-ed90-4368-98e7-82e64c5e4072.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/30-acc5312a-c172-410b-9297-7890c9c1341b.txn b/lancedb/description_embedding.lance/_transactions/30-acc5312a-c172-410b-9297-7890c9c1341b.txn new file mode 100644 index 0000000000000000000000000000000000000000..76cd62e7e01c7535f97eff89046f61d4c30eaf9b --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/30-acc5312a-c172-410b-9297-7890c9c1341b.txn @@ -0,0 +1,2 @@ +$acc5312a-c172-410b-9297-7890c9c1341b��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/31-4c4a3565-92b7-49fd-885c-3ff9d840e7ba.txn b/lancedb/description_embedding.lance/_transactions/31-4c4a3565-92b7-49fd-885c-3ff9d840e7ba.txn new file mode 100644 index 0000000000000000000000000000000000000000..471b3f7922c17a568a4b1e9d48a94611e36259fa Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/31-4c4a3565-92b7-49fd-885c-3ff9d840e7ba.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/32-19b5563f-67cd-42fa-b2df-eac2bb04b1eb.txn b/lancedb/description_embedding.lance/_transactions/32-19b5563f-67cd-42fa-b2df-eac2bb04b1eb.txn new file mode 100644 index 0000000000000000000000000000000000000000..42293287cd4b16d4b335e833554307a50c004e33 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/32-19b5563f-67cd-42fa-b2df-eac2bb04b1eb.txn @@ -0,0 +1,2 @@ + $19b5563f-67cd-42fa-b2df-eac2bb04b1eb��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/33-a9ce6a8c-fb4d-48f6-a82f-417980242796.txn b/lancedb/description_embedding.lance/_transactions/33-a9ce6a8c-fb4d-48f6-a82f-417980242796.txn new file mode 100644 index 0000000000000000000000000000000000000000..05eef6af51f47fd2a4a5c316271379c37d847151 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/33-a9ce6a8c-fb4d-48f6-a82f-417980242796.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/34-711b59a8-b02d-4479-a9bd-5c5a3aa56bc9.txn b/lancedb/description_embedding.lance/_transactions/34-711b59a8-b02d-4479-a9bd-5c5a3aa56bc9.txn new file mode 100644 index 0000000000000000000000000000000000000000..7494bdc40eb533d37bc94153d52b5167a298b885 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/34-711b59a8-b02d-4479-a9bd-5c5a3aa56bc9.txn @@ -0,0 +1,2 @@ +"$711b59a8-b02d-4479-a9bd-5c5a3aa56bc9��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/35-9a1b9f90-2e08-433a-93b3-203db7d1636e.txn b/lancedb/description_embedding.lance/_transactions/35-9a1b9f90-2e08-433a-93b3-203db7d1636e.txn new file mode 100644 index 0000000000000000000000000000000000000000..21c5abd626df345726514c7b9dcd1960096dcb29 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/35-9a1b9f90-2e08-433a-93b3-203db7d1636e.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/36-d8f4e955-5df6-42bb-8091-605dd1298a25.txn b/lancedb/description_embedding.lance/_transactions/36-d8f4e955-5df6-42bb-8091-605dd1298a25.txn new file mode 100644 index 0000000000000000000000000000000000000000..9bdf80a57301d41bf71e82433f7474f0537684c7 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/36-d8f4e955-5df6-42bb-8091-605dd1298a25.txn @@ -0,0 +1,2 @@ +$$d8f4e955-5df6-42bb-8091-605dd1298a25��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/37-41af4a3a-e17c-47b9-92ed-5f51621bc11d.txn b/lancedb/description_embedding.lance/_transactions/37-41af4a3a-e17c-47b9-92ed-5f51621bc11d.txn new file mode 100644 index 0000000000000000000000000000000000000000..a67003f10b1f7debb7207cd9dcff12671afa3d62 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/37-41af4a3a-e17c-47b9-92ed-5f51621bc11d.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/38-0ceb26b8-c5bc-4fb2-816c-2928c54ee8f9.txn b/lancedb/description_embedding.lance/_transactions/38-0ceb26b8-c5bc-4fb2-816c-2928c54ee8f9.txn new file mode 100644 index 0000000000000000000000000000000000000000..3f5a53a5cb9cb0e0f58b51782df119f5b32ae122 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/38-0ceb26b8-c5bc-4fb2-816c-2928c54ee8f9.txn @@ -0,0 +1,2 @@ +&$0ceb26b8-c5bc-4fb2-816c-2928c54ee8f9��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/39-a6676d9b-57e9-4e2c-9aa9-4c64f2269463.txn b/lancedb/description_embedding.lance/_transactions/39-a6676d9b-57e9-4e2c-9aa9-4c64f2269463.txn new file mode 100644 index 0000000000000000000000000000000000000000..c3fd8f0f191c47f9e74816cd1c22452d1bac5dd0 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/39-a6676d9b-57e9-4e2c-9aa9-4c64f2269463.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/4-4354e4dd-3f38-4225-914b-051b2c2d89e8.txn b/lancedb/description_embedding.lance/_transactions/4-4354e4dd-3f38-4225-914b-051b2c2d89e8.txn new file mode 100644 index 0000000000000000000000000000000000000000..5a318724910dae2fc2c449c96d31f435c9ace144 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/4-4354e4dd-3f38-4225-914b-051b2c2d89e8.txn @@ -0,0 +1,2 @@ +$4354e4dd-3f38-4225-914b-051b2c2d89e8��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/40-5366f0ba-1144-48d9-8ef8-2780a569ea95.txn b/lancedb/description_embedding.lance/_transactions/40-5366f0ba-1144-48d9-8ef8-2780a569ea95.txn new file mode 100644 index 0000000000000000000000000000000000000000..6b3de3744575624bc3adc66c23532f5c0931906c --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/40-5366f0ba-1144-48d9-8ef8-2780a569ea95.txn @@ -0,0 +1,2 @@ +($5366f0ba-1144-48d9-8ef8-2780a569ea95��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/41-c859c116-4c6c-4bd9-9905-a454380e251d.txn b/lancedb/description_embedding.lance/_transactions/41-c859c116-4c6c-4bd9-9905-a454380e251d.txn new file mode 100644 index 0000000000000000000000000000000000000000..40af597a1e96f60bc7e6b72fa347670dc3485d8d Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/41-c859c116-4c6c-4bd9-9905-a454380e251d.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/42-9e4fb8cc-21e6-4803-9f70-17518ee3d552.txn b/lancedb/description_embedding.lance/_transactions/42-9e4fb8cc-21e6-4803-9f70-17518ee3d552.txn new file mode 100644 index 0000000000000000000000000000000000000000..e1df842fcad665106869c85eda42e7eb0a8df8f6 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/42-9e4fb8cc-21e6-4803-9f70-17518ee3d552.txn @@ -0,0 +1,2 @@ +*$9e4fb8cc-21e6-4803-9f70-17518ee3d552��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/43-fe408758-23e1-4b16-91ba-a4a809510a25.txn b/lancedb/description_embedding.lance/_transactions/43-fe408758-23e1-4b16-91ba-a4a809510a25.txn new file mode 100644 index 0000000000000000000000000000000000000000..e6495b1629d2178e27aa4f901e3e69dbbcccd20d Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/43-fe408758-23e1-4b16-91ba-a4a809510a25.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/44-14444f46-9ae7-4d49-b8d2-bc913e4ed478.txn b/lancedb/description_embedding.lance/_transactions/44-14444f46-9ae7-4d49-b8d2-bc913e4ed478.txn new file mode 100644 index 0000000000000000000000000000000000000000..20bfd7cddcfccb637275795fe327a0707bab2094 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/44-14444f46-9ae7-4d49-b8d2-bc913e4ed478.txn @@ -0,0 +1,2 @@ +,$14444f46-9ae7-4d49-b8d2-bc913e4ed478��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/45-9a60f1ca-b1d5-4116-9ab9-9e4931064b3a.txn b/lancedb/description_embedding.lance/_transactions/45-9a60f1ca-b1d5-4116-9ab9-9e4931064b3a.txn new file mode 100644 index 0000000000000000000000000000000000000000..861696a6a44dd21340f14d82221f6d3848b027a3 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/45-9a60f1ca-b1d5-4116-9ab9-9e4931064b3a.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/46-3cd03013-2cf4-41e2-b197-882efce73ef5.txn b/lancedb/description_embedding.lance/_transactions/46-3cd03013-2cf4-41e2-b197-882efce73ef5.txn new file mode 100644 index 0000000000000000000000000000000000000000..61994abf4bfce27e93413c67cedb8f99a2fa42a1 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/46-3cd03013-2cf4-41e2-b197-882efce73ef5.txn @@ -0,0 +1,2 @@ +.$3cd03013-2cf4-41e2-b197-882efce73ef5��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/47-f9f40806-b408-4523-b3c0-73281ab2ca64.txn b/lancedb/description_embedding.lance/_transactions/47-f9f40806-b408-4523-b3c0-73281ab2ca64.txn new file mode 100644 index 0000000000000000000000000000000000000000..10ad5131f38aef8b818942248d14f1c9565ed8b5 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/47-f9f40806-b408-4523-b3c0-73281ab2ca64.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/48-d7e4b470-5d69-4cae-bfc3-497ee2ea1f8a.txn b/lancedb/description_embedding.lance/_transactions/48-d7e4b470-5d69-4cae-bfc3-497ee2ea1f8a.txn new file mode 100644 index 0000000000000000000000000000000000000000..f05a955ec78ac05a15ad8a67abe16087a730294e --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/48-d7e4b470-5d69-4cae-bfc3-497ee2ea1f8a.txn @@ -0,0 +1,2 @@ +0$d7e4b470-5d69-4cae-bfc3-497ee2ea1f8a��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/49-07970e4f-0524-4bf8-bb2c-319011d3512c.txn b/lancedb/description_embedding.lance/_transactions/49-07970e4f-0524-4bf8-bb2c-319011d3512c.txn new file mode 100644 index 0000000000000000000000000000000000000000..b4bef7a375185376db2db102947828841656ef19 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/49-07970e4f-0524-4bf8-bb2c-319011d3512c.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/5-d64dcb60-5cc8-46a1-8502-63cc3427b831.txn b/lancedb/description_embedding.lance/_transactions/5-d64dcb60-5cc8-46a1-8502-63cc3427b831.txn new file mode 100644 index 0000000000000000000000000000000000000000..d612f6ff5bcd4f9105eaa647be36be0f868df599 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/5-d64dcb60-5cc8-46a1-8502-63cc3427b831.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/50-041eb1e6-f522-4e71-a212-b92793c0580d.txn b/lancedb/description_embedding.lance/_transactions/50-041eb1e6-f522-4e71-a212-b92793c0580d.txn new file mode 100644 index 0000000000000000000000000000000000000000..e213cad91ffa265b8ef745184aaff3f1ad3e6559 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/50-041eb1e6-f522-4e71-a212-b92793c0580d.txn @@ -0,0 +1,2 @@ +2$041eb1e6-f522-4e71-a212-b92793c0580d��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/51-77cabfc4-1a5c-45fe-aca3-a2ced2cb41b9.txn b/lancedb/description_embedding.lance/_transactions/51-77cabfc4-1a5c-45fe-aca3-a2ced2cb41b9.txn new file mode 100644 index 0000000000000000000000000000000000000000..3674f46abcef4a9a3e82ce4edccb9fe55481e006 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/51-77cabfc4-1a5c-45fe-aca3-a2ced2cb41b9.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/52-20940324-7700-4fdd-ae61-addc4894ca9a.txn b/lancedb/description_embedding.lance/_transactions/52-20940324-7700-4fdd-ae61-addc4894ca9a.txn new file mode 100644 index 0000000000000000000000000000000000000000..fea0c3c4073a82e54d1ce68e14143b0d63e21195 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/52-20940324-7700-4fdd-ae61-addc4894ca9a.txn @@ -0,0 +1,2 @@ +4$20940324-7700-4fdd-ae61-addc4894ca9a��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/53-a2cc7407-e905-41b8-b7c9-7d99ef448653.txn b/lancedb/description_embedding.lance/_transactions/53-a2cc7407-e905-41b8-b7c9-7d99ef448653.txn new file mode 100644 index 0000000000000000000000000000000000000000..67507b733f86d209fce2d2ea27015d547fe0d437 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/53-a2cc7407-e905-41b8-b7c9-7d99ef448653.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/6-12086458-4143-4096-97c7-fa36ce08c34f.txn b/lancedb/description_embedding.lance/_transactions/6-12086458-4143-4096-97c7-fa36ce08c34f.txn new file mode 100644 index 0000000000000000000000000000000000000000..31631b7b464f1ac3c76b74afeb06c08ebf2fb384 --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/6-12086458-4143-4096-97c7-fa36ce08c34f.txn @@ -0,0 +1,2 @@ +$12086458-4143-4096-97c7-fa36ce08c34f��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/7-72d7c8f3-f363-4288-ad3a-6b6c218f15c0.txn b/lancedb/description_embedding.lance/_transactions/7-72d7c8f3-f363-4288-ad3a-6b6c218f15c0.txn new file mode 100644 index 0000000000000000000000000000000000000000..b198780a86b112d8ebce2c8836a2249afce58765 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/7-72d7c8f3-f363-4288-ad3a-6b6c218f15c0.txn differ diff --git a/lancedb/description_embedding.lance/_transactions/8-da1ac31f-589a-4264-a164-214dea8acd39.txn b/lancedb/description_embedding.lance/_transactions/8-da1ac31f-589a-4264-a164-214dea8acd39.txn new file mode 100644 index 0000000000000000000000000000000000000000..b70b202b4504b6b0f065b7533846ad1ce747904b --- /dev/null +++ b/lancedb/description_embedding.lance/_transactions/8-da1ac31f-589a-4264-a164-214dea8acd39.txn @@ -0,0 +1,2 @@ +$da1ac31f-589a-4264-a164-214dea8acd39��id ���������*string08text ���������*string084vector ���������*fixed_size_list:float:76808% +attributes ���������*string08 \ No newline at end of file diff --git a/lancedb/description_embedding.lance/_transactions/9-5b1229bc-630d-43ed-ad12-15144b944d1a.txn b/lancedb/description_embedding.lance/_transactions/9-5b1229bc-630d-43ed-ad12-15144b944d1a.txn new file mode 100644 index 0000000000000000000000000000000000000000..78c88e9a76bb6c38a015b83411a8f52fbfce40b6 Binary files /dev/null and b/lancedb/description_embedding.lance/_transactions/9-5b1229bc-630d-43ed-ad12-15144b944d1a.txn differ diff --git a/lancedb/description_embedding.lance/_versions/1.manifest b/lancedb/description_embedding.lance/_versions/1.manifest new file mode 100644 index 0000000000000000000000000000000000000000..ecdc4e92c6b6b4c34661f36588d57500c992950b Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/1.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/10.manifest b/lancedb/description_embedding.lance/_versions/10.manifest new file mode 100644 index 0000000000000000000000000000000000000000..6f863269d70c3b83b76e8a8ba52f4403f4de1d81 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/10.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/11.manifest b/lancedb/description_embedding.lance/_versions/11.manifest new file mode 100644 index 0000000000000000000000000000000000000000..5fb649f5061b0476d8487efafbcb3c109068479f Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/11.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/12.manifest b/lancedb/description_embedding.lance/_versions/12.manifest new file mode 100644 index 0000000000000000000000000000000000000000..4981d07bc042d2c7738b51c41516164accccbfd0 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/12.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/13.manifest b/lancedb/description_embedding.lance/_versions/13.manifest new file mode 100644 index 0000000000000000000000000000000000000000..5f70c315d7f36bd8d030f152d314736189d41429 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/13.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/14.manifest b/lancedb/description_embedding.lance/_versions/14.manifest new file mode 100644 index 0000000000000000000000000000000000000000..088a29f663bf643f522dd5f9549b56656bf62a3a Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/14.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/15.manifest b/lancedb/description_embedding.lance/_versions/15.manifest new file mode 100644 index 0000000000000000000000000000000000000000..4bc0b78d32baffc286079ff6022ba4f217649a58 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/15.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/16.manifest b/lancedb/description_embedding.lance/_versions/16.manifest new file mode 100644 index 0000000000000000000000000000000000000000..ad826a34a9508ce4cbb7b8ebfccae3ff7eaa96af Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/16.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/17.manifest b/lancedb/description_embedding.lance/_versions/17.manifest new file mode 100644 index 0000000000000000000000000000000000000000..92f7c8cb56a4c5240d0c76a7ff60a54e6697aa35 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/17.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/18.manifest b/lancedb/description_embedding.lance/_versions/18.manifest new file mode 100644 index 0000000000000000000000000000000000000000..7783bc807bed046a3a6011188b8dbacd53738a74 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/18.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/19.manifest b/lancedb/description_embedding.lance/_versions/19.manifest new file mode 100644 index 0000000000000000000000000000000000000000..cf354f746de9dade859292ed0dee473288839822 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/19.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/2.manifest b/lancedb/description_embedding.lance/_versions/2.manifest new file mode 100644 index 0000000000000000000000000000000000000000..171e6fedd0e114933cd60bd3502ca4f60b628833 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/2.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/20.manifest b/lancedb/description_embedding.lance/_versions/20.manifest new file mode 100644 index 0000000000000000000000000000000000000000..98fe8e9cefc36c02fef46f7dd85039d9856867a6 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/20.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/21.manifest b/lancedb/description_embedding.lance/_versions/21.manifest new file mode 100644 index 0000000000000000000000000000000000000000..a35fe4d163b5dc7036c22b87064ce72e0f78c215 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/21.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/22.manifest b/lancedb/description_embedding.lance/_versions/22.manifest new file mode 100644 index 0000000000000000000000000000000000000000..34078cf1c7a11fa6b51dba1cdf15f4e9ca9ccaf4 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/22.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/23.manifest b/lancedb/description_embedding.lance/_versions/23.manifest new file mode 100644 index 0000000000000000000000000000000000000000..cfa50db4b169f4a2c90967101be2e46933f314a3 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/23.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/24.manifest b/lancedb/description_embedding.lance/_versions/24.manifest new file mode 100644 index 0000000000000000000000000000000000000000..5e3d8dbcd0983f2bf20c733ee33ee034b5b0546a Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/24.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/25.manifest b/lancedb/description_embedding.lance/_versions/25.manifest new file mode 100644 index 0000000000000000000000000000000000000000..ba2f1c75a21873502c23a3f2930a843ba0e347c6 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/25.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/26.manifest b/lancedb/description_embedding.lance/_versions/26.manifest new file mode 100644 index 0000000000000000000000000000000000000000..1c600059495424da1456fd18c1208b06c4056d89 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/26.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/27.manifest b/lancedb/description_embedding.lance/_versions/27.manifest new file mode 100644 index 0000000000000000000000000000000000000000..164168a39676c4848dcb33fe30be49124722cfd5 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/27.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/28.manifest b/lancedb/description_embedding.lance/_versions/28.manifest new file mode 100644 index 0000000000000000000000000000000000000000..f9f05c0bc760cde22d8fa32e4fc320b58acbd4b8 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/28.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/29.manifest b/lancedb/description_embedding.lance/_versions/29.manifest new file mode 100644 index 0000000000000000000000000000000000000000..569d5ed3a30c0da741a94f2a647b1ebb55568ab1 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/29.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/3.manifest b/lancedb/description_embedding.lance/_versions/3.manifest new file mode 100644 index 0000000000000000000000000000000000000000..cd87d171d2fb91c3e96a77c397146521237e88a9 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/3.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/30.manifest b/lancedb/description_embedding.lance/_versions/30.manifest new file mode 100644 index 0000000000000000000000000000000000000000..976ff7ee14e208ddf0901497434f084617c686ff Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/30.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/31.manifest b/lancedb/description_embedding.lance/_versions/31.manifest new file mode 100644 index 0000000000000000000000000000000000000000..93603f2c7356b15df38b544c3cef99f66158a10f Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/31.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/32.manifest b/lancedb/description_embedding.lance/_versions/32.manifest new file mode 100644 index 0000000000000000000000000000000000000000..e340c304cd9caed4f007cfe0c75a8544a1c33eb6 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/32.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/33.manifest b/lancedb/description_embedding.lance/_versions/33.manifest new file mode 100644 index 0000000000000000000000000000000000000000..375ce0b6695c82b640bafeb45c05da71752ea40f Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/33.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/34.manifest b/lancedb/description_embedding.lance/_versions/34.manifest new file mode 100644 index 0000000000000000000000000000000000000000..f96a141c0967fac239a9dbb8220ca368e00aa089 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/34.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/35.manifest b/lancedb/description_embedding.lance/_versions/35.manifest new file mode 100644 index 0000000000000000000000000000000000000000..e92df78023e1647dd5e943ecb340d526e0c1f016 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/35.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/36.manifest b/lancedb/description_embedding.lance/_versions/36.manifest new file mode 100644 index 0000000000000000000000000000000000000000..889db17e3e45e806e0d1122345983c4537477950 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/36.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/37.manifest b/lancedb/description_embedding.lance/_versions/37.manifest new file mode 100644 index 0000000000000000000000000000000000000000..b8fd44ece4f8ec7d7b21c9362b739fe348dd78f5 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/37.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/38.manifest b/lancedb/description_embedding.lance/_versions/38.manifest new file mode 100644 index 0000000000000000000000000000000000000000..f3d3d3d4a664145b76cc52df49e42532dc12d8bf Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/38.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/39.manifest b/lancedb/description_embedding.lance/_versions/39.manifest new file mode 100644 index 0000000000000000000000000000000000000000..3d51a9a459a9472b492736d61c4651dc1d68117e Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/39.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/4.manifest b/lancedb/description_embedding.lance/_versions/4.manifest new file mode 100644 index 0000000000000000000000000000000000000000..db805ec588719a644d31d5beb79574d26ddaef2c Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/4.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/40.manifest b/lancedb/description_embedding.lance/_versions/40.manifest new file mode 100644 index 0000000000000000000000000000000000000000..3f03812ef68766cf039288c8edfaf2643f79cf03 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/40.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/41.manifest b/lancedb/description_embedding.lance/_versions/41.manifest new file mode 100644 index 0000000000000000000000000000000000000000..752954a99367f6b09a38f53b4c00987ac82689e1 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/41.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/42.manifest b/lancedb/description_embedding.lance/_versions/42.manifest new file mode 100644 index 0000000000000000000000000000000000000000..ef6bf6e33267235f02dec00354a6874c0c8985b6 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/42.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/43.manifest b/lancedb/description_embedding.lance/_versions/43.manifest new file mode 100644 index 0000000000000000000000000000000000000000..3d670cc07aa4bbf8225836398d30e9e232830707 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/43.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/44.manifest b/lancedb/description_embedding.lance/_versions/44.manifest new file mode 100644 index 0000000000000000000000000000000000000000..890533eae14c6fe6654d5be23d7a54d09a4c3c7a Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/44.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/45.manifest b/lancedb/description_embedding.lance/_versions/45.manifest new file mode 100644 index 0000000000000000000000000000000000000000..16c2b86f42374c1f989a436f5b0232c2977b201c Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/45.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/46.manifest b/lancedb/description_embedding.lance/_versions/46.manifest new file mode 100644 index 0000000000000000000000000000000000000000..bbb7e02418414025d0af856a147c43d1abdf3246 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/46.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/47.manifest b/lancedb/description_embedding.lance/_versions/47.manifest new file mode 100644 index 0000000000000000000000000000000000000000..d75cce91b46c65baf9f4bf3a7237603aa93b344a Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/47.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/48.manifest b/lancedb/description_embedding.lance/_versions/48.manifest new file mode 100644 index 0000000000000000000000000000000000000000..b92f107ada1d3ff5eab0bb0d74e69bd60b2852f9 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/48.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/49.manifest b/lancedb/description_embedding.lance/_versions/49.manifest new file mode 100644 index 0000000000000000000000000000000000000000..121082999a4ec64cf8971e2fed9f996bd4e004ef Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/49.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/5.manifest b/lancedb/description_embedding.lance/_versions/5.manifest new file mode 100644 index 0000000000000000000000000000000000000000..c9e1dcedbe9b10918b20c9de73490960706d7ca6 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/5.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/50.manifest b/lancedb/description_embedding.lance/_versions/50.manifest new file mode 100644 index 0000000000000000000000000000000000000000..b4e3c48d01e254a1c401ff79145813f2a5ba1292 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/50.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/51.manifest b/lancedb/description_embedding.lance/_versions/51.manifest new file mode 100644 index 0000000000000000000000000000000000000000..8d1f216ff54d9dac0def965685b50424fca32c3d Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/51.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/52.manifest b/lancedb/description_embedding.lance/_versions/52.manifest new file mode 100644 index 0000000000000000000000000000000000000000..1ed451feeb6f54f3cb39d2ae445e8271ff076e71 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/52.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/53.manifest b/lancedb/description_embedding.lance/_versions/53.manifest new file mode 100644 index 0000000000000000000000000000000000000000..490138723baf6bf526bb97bd2ab7432794acba74 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/53.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/54.manifest b/lancedb/description_embedding.lance/_versions/54.manifest new file mode 100644 index 0000000000000000000000000000000000000000..f637e3071d3881d97edb6e76f68f1f9e14e26cbd Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/54.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/6.manifest b/lancedb/description_embedding.lance/_versions/6.manifest new file mode 100644 index 0000000000000000000000000000000000000000..bb98f91faabe580c8ce8352161c332a7d4886339 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/6.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/7.manifest b/lancedb/description_embedding.lance/_versions/7.manifest new file mode 100644 index 0000000000000000000000000000000000000000..e3f8c2ba7ff16af357a7fb396b4b7363cd88195b Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/7.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/8.manifest b/lancedb/description_embedding.lance/_versions/8.manifest new file mode 100644 index 0000000000000000000000000000000000000000..288e3a37980d83a91822f2803109030264a4ee00 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/8.manifest differ diff --git a/lancedb/description_embedding.lance/_versions/9.manifest b/lancedb/description_embedding.lance/_versions/9.manifest new file mode 100644 index 0000000000000000000000000000000000000000..0d043a28cd57e1f3a2336eebf3c617507e662492 Binary files /dev/null and b/lancedb/description_embedding.lance/_versions/9.manifest differ diff --git a/lancedb/description_embedding.lance/data/0298491c-f0c5-45be-83d0-6c1814afe75e.lance b/lancedb/description_embedding.lance/data/0298491c-f0c5-45be-83d0-6c1814afe75e.lance new file mode 100644 index 0000000000000000000000000000000000000000..d43ef1186ca15c6634be70bebd0ba5f7bbfbdab8 Binary files /dev/null and b/lancedb/description_embedding.lance/data/0298491c-f0c5-45be-83d0-6c1814afe75e.lance differ diff --git a/lancedb/description_embedding.lance/data/0a6bacd8-cad3-4e16-be61-50ce017f0794.lance b/lancedb/description_embedding.lance/data/0a6bacd8-cad3-4e16-be61-50ce017f0794.lance new file mode 100644 index 0000000000000000000000000000000000000000..d43ef1186ca15c6634be70bebd0ba5f7bbfbdab8 Binary files /dev/null and b/lancedb/description_embedding.lance/data/0a6bacd8-cad3-4e16-be61-50ce017f0794.lance differ diff --git a/lancedb/description_embedding.lance/data/12e8ae2e-e3c0-4a13-908b-3e53f3b85c5e.lance b/lancedb/description_embedding.lance/data/12e8ae2e-e3c0-4a13-908b-3e53f3b85c5e.lance new file mode 100644 index 0000000000000000000000000000000000000000..d43ef1186ca15c6634be70bebd0ba5f7bbfbdab8 Binary files /dev/null and b/lancedb/description_embedding.lance/data/12e8ae2e-e3c0-4a13-908b-3e53f3b85c5e.lance differ diff --git a/lancedb/description_embedding.lance/data/1d45e90b-0ba7-4d2c-91af-a2b645a70de6.lance b/lancedb/description_embedding.lance/data/1d45e90b-0ba7-4d2c-91af-a2b645a70de6.lance new file mode 100644 index 0000000000000000000000000000000000000000..1795f9567d382d63436b479aca5a43a0dc1c53d3 Binary files /dev/null and b/lancedb/description_embedding.lance/data/1d45e90b-0ba7-4d2c-91af-a2b645a70de6.lance differ diff --git a/lancedb/description_embedding.lance/data/2f477a8a-b4b6-4bbd-b4a4-253824b89c69.lance b/lancedb/description_embedding.lance/data/2f477a8a-b4b6-4bbd-b4a4-253824b89c69.lance new file mode 100644 index 0000000000000000000000000000000000000000..18368cf3f3274afacadbc4603eb3a33050707b83 Binary files /dev/null and b/lancedb/description_embedding.lance/data/2f477a8a-b4b6-4bbd-b4a4-253824b89c69.lance differ diff --git a/lancedb/description_embedding.lance/data/33461a5b-ae40-4d72-b7aa-044524a713e3.lance b/lancedb/description_embedding.lance/data/33461a5b-ae40-4d72-b7aa-044524a713e3.lance new file mode 100644 index 0000000000000000000000000000000000000000..b0f836aa0f28b46a4de39c82cd1c9f20e1b0aa5e Binary files /dev/null and b/lancedb/description_embedding.lance/data/33461a5b-ae40-4d72-b7aa-044524a713e3.lance differ diff --git a/lancedb/description_embedding.lance/data/550bc025-47c9-48cc-a29c-cb666138dc1e.lance b/lancedb/description_embedding.lance/data/550bc025-47c9-48cc-a29c-cb666138dc1e.lance new file mode 100644 index 0000000000000000000000000000000000000000..b0f836aa0f28b46a4de39c82cd1c9f20e1b0aa5e Binary files /dev/null and b/lancedb/description_embedding.lance/data/550bc025-47c9-48cc-a29c-cb666138dc1e.lance differ diff --git a/lancedb/description_embedding.lance/data/5c5d8b98-3b8a-4cba-b3d7-404007b1c307.lance b/lancedb/description_embedding.lance/data/5c5d8b98-3b8a-4cba-b3d7-404007b1c307.lance new file mode 100644 index 0000000000000000000000000000000000000000..b0f836aa0f28b46a4de39c82cd1c9f20e1b0aa5e Binary files /dev/null and b/lancedb/description_embedding.lance/data/5c5d8b98-3b8a-4cba-b3d7-404007b1c307.lance differ diff --git a/lancedb/description_embedding.lance/data/5fb217a4-497b-4fd8-a712-78607df6ef07.lance b/lancedb/description_embedding.lance/data/5fb217a4-497b-4fd8-a712-78607df6ef07.lance new file mode 100644 index 0000000000000000000000000000000000000000..18368cf3f3274afacadbc4603eb3a33050707b83 Binary files /dev/null and b/lancedb/description_embedding.lance/data/5fb217a4-497b-4fd8-a712-78607df6ef07.lance differ diff --git a/lancedb/description_embedding.lance/data/61a96ce5-c0c1-4cf3-8f2b-8762caba97e6.lance b/lancedb/description_embedding.lance/data/61a96ce5-c0c1-4cf3-8f2b-8762caba97e6.lance new file mode 100644 index 0000000000000000000000000000000000000000..1795f9567d382d63436b479aca5a43a0dc1c53d3 Binary files /dev/null and b/lancedb/description_embedding.lance/data/61a96ce5-c0c1-4cf3-8f2b-8762caba97e6.lance differ diff --git a/lancedb/description_embedding.lance/data/634bc611-1a47-4b30-a019-7fe5bdcfcd65.lance b/lancedb/description_embedding.lance/data/634bc611-1a47-4b30-a019-7fe5bdcfcd65.lance new file mode 100644 index 0000000000000000000000000000000000000000..1795f9567d382d63436b479aca5a43a0dc1c53d3 Binary files /dev/null and b/lancedb/description_embedding.lance/data/634bc611-1a47-4b30-a019-7fe5bdcfcd65.lance differ diff --git a/lancedb/description_embedding.lance/data/705d6a6a-00be-4ac4-9297-cdc985507a0d.lance b/lancedb/description_embedding.lance/data/705d6a6a-00be-4ac4-9297-cdc985507a0d.lance new file mode 100644 index 0000000000000000000000000000000000000000..d43ef1186ca15c6634be70bebd0ba5f7bbfbdab8 Binary files /dev/null and b/lancedb/description_embedding.lance/data/705d6a6a-00be-4ac4-9297-cdc985507a0d.lance differ diff --git a/lancedb/description_embedding.lance/data/7c8c6aec-0a79-47b3-9e93-7c22f6902652.lance b/lancedb/description_embedding.lance/data/7c8c6aec-0a79-47b3-9e93-7c22f6902652.lance new file mode 100644 index 0000000000000000000000000000000000000000..1795f9567d382d63436b479aca5a43a0dc1c53d3 Binary files /dev/null and b/lancedb/description_embedding.lance/data/7c8c6aec-0a79-47b3-9e93-7c22f6902652.lance differ diff --git a/lancedb/description_embedding.lance/data/829be682-4055-4970-ad5f-a3b407c2de4e.lance b/lancedb/description_embedding.lance/data/829be682-4055-4970-ad5f-a3b407c2de4e.lance new file mode 100644 index 0000000000000000000000000000000000000000..d43ef1186ca15c6634be70bebd0ba5f7bbfbdab8 Binary files /dev/null and b/lancedb/description_embedding.lance/data/829be682-4055-4970-ad5f-a3b407c2de4e.lance differ diff --git a/lancedb/description_embedding.lance/data/8dea6041-e952-4e6e-b2f6-c346f9f43561.lance b/lancedb/description_embedding.lance/data/8dea6041-e952-4e6e-b2f6-c346f9f43561.lance new file mode 100644 index 0000000000000000000000000000000000000000..18368cf3f3274afacadbc4603eb3a33050707b83 Binary files /dev/null and b/lancedb/description_embedding.lance/data/8dea6041-e952-4e6e-b2f6-c346f9f43561.lance differ diff --git a/lancedb/description_embedding.lance/data/9342a8c4-9d95-49eb-947d-3245a52a50b5.lance b/lancedb/description_embedding.lance/data/9342a8c4-9d95-49eb-947d-3245a52a50b5.lance new file mode 100644 index 0000000000000000000000000000000000000000..18368cf3f3274afacadbc4603eb3a33050707b83 Binary files /dev/null and b/lancedb/description_embedding.lance/data/9342a8c4-9d95-49eb-947d-3245a52a50b5.lance differ diff --git a/lancedb/description_embedding.lance/data/940ce76e-06ac-4c0d-89a6-461abec11b99.lance b/lancedb/description_embedding.lance/data/940ce76e-06ac-4c0d-89a6-461abec11b99.lance new file mode 100644 index 0000000000000000000000000000000000000000..d43ef1186ca15c6634be70bebd0ba5f7bbfbdab8 Binary files /dev/null and b/lancedb/description_embedding.lance/data/940ce76e-06ac-4c0d-89a6-461abec11b99.lance differ diff --git a/lancedb/description_embedding.lance/data/9752f165-2cb6-4874-b07e-e0acb60da7ea.lance b/lancedb/description_embedding.lance/data/9752f165-2cb6-4874-b07e-e0acb60da7ea.lance new file mode 100644 index 0000000000000000000000000000000000000000..18368cf3f3274afacadbc4603eb3a33050707b83 Binary files /dev/null and b/lancedb/description_embedding.lance/data/9752f165-2cb6-4874-b07e-e0acb60da7ea.lance differ diff --git a/lancedb/description_embedding.lance/data/9aee30d8-35cb-4734-b940-52715f36a332.lance b/lancedb/description_embedding.lance/data/9aee30d8-35cb-4734-b940-52715f36a332.lance new file mode 100644 index 0000000000000000000000000000000000000000..d43ef1186ca15c6634be70bebd0ba5f7bbfbdab8 Binary files /dev/null and b/lancedb/description_embedding.lance/data/9aee30d8-35cb-4734-b940-52715f36a332.lance differ diff --git a/lancedb/description_embedding.lance/data/b02b992c-a481-4056-8403-7db515e76776.lance b/lancedb/description_embedding.lance/data/b02b992c-a481-4056-8403-7db515e76776.lance new file mode 100644 index 0000000000000000000000000000000000000000..d43ef1186ca15c6634be70bebd0ba5f7bbfbdab8 Binary files /dev/null and b/lancedb/description_embedding.lance/data/b02b992c-a481-4056-8403-7db515e76776.lance differ diff --git a/lancedb/description_embedding.lance/data/ba50989b-319e-44a7-8220-d3c0b8abd771.lance b/lancedb/description_embedding.lance/data/ba50989b-319e-44a7-8220-d3c0b8abd771.lance new file mode 100644 index 0000000000000000000000000000000000000000..18368cf3f3274afacadbc4603eb3a33050707b83 Binary files /dev/null and b/lancedb/description_embedding.lance/data/ba50989b-319e-44a7-8220-d3c0b8abd771.lance differ diff --git a/lancedb/description_embedding.lance/data/cb5b129c-46de-4b2f-9730-adeb593b4d1a.lance b/lancedb/description_embedding.lance/data/cb5b129c-46de-4b2f-9730-adeb593b4d1a.lance new file mode 100644 index 0000000000000000000000000000000000000000..b0f836aa0f28b46a4de39c82cd1c9f20e1b0aa5e Binary files /dev/null and b/lancedb/description_embedding.lance/data/cb5b129c-46de-4b2f-9730-adeb593b4d1a.lance differ diff --git a/lancedb/description_embedding.lance/data/de310200-1569-4b3e-9a8c-a0b31bd65fc7.lance b/lancedb/description_embedding.lance/data/de310200-1569-4b3e-9a8c-a0b31bd65fc7.lance new file mode 100644 index 0000000000000000000000000000000000000000..18368cf3f3274afacadbc4603eb3a33050707b83 Binary files /dev/null and b/lancedb/description_embedding.lance/data/de310200-1569-4b3e-9a8c-a0b31bd65fc7.lance differ diff --git a/lancedb/description_embedding.lance/data/e5c4fd40-e3d4-452e-a3f1-eeb422797511.lance b/lancedb/description_embedding.lance/data/e5c4fd40-e3d4-452e-a3f1-eeb422797511.lance new file mode 100644 index 0000000000000000000000000000000000000000..d43ef1186ca15c6634be70bebd0ba5f7bbfbdab8 Binary files /dev/null and b/lancedb/description_embedding.lance/data/e5c4fd40-e3d4-452e-a3f1-eeb422797511.lance differ diff --git a/lancedb/description_embedding.lance/data/e6bf3cc2-5640-4b8f-87d3-62f02fe84d0b.lance b/lancedb/description_embedding.lance/data/e6bf3cc2-5640-4b8f-87d3-62f02fe84d0b.lance new file mode 100644 index 0000000000000000000000000000000000000000..18368cf3f3274afacadbc4603eb3a33050707b83 Binary files /dev/null and b/lancedb/description_embedding.lance/data/e6bf3cc2-5640-4b8f-87d3-62f02fe84d0b.lance differ diff --git a/lancedb/description_embedding.lance/data/ea97c4ad-4105-49fd-acb2-78a4ae24f0b5.lance b/lancedb/description_embedding.lance/data/ea97c4ad-4105-49fd-acb2-78a4ae24f0b5.lance new file mode 100644 index 0000000000000000000000000000000000000000..b0f836aa0f28b46a4de39c82cd1c9f20e1b0aa5e Binary files /dev/null and b/lancedb/description_embedding.lance/data/ea97c4ad-4105-49fd-acb2-78a4ae24f0b5.lance differ diff --git a/lancedb/description_embedding.lance/data/f36e1996-e5d0-4dc0-9c75-840dd8f8ba2a.lance b/lancedb/description_embedding.lance/data/f36e1996-e5d0-4dc0-9c75-840dd8f8ba2a.lance new file mode 100644 index 0000000000000000000000000000000000000000..d43ef1186ca15c6634be70bebd0ba5f7bbfbdab8 Binary files /dev/null and b/lancedb/description_embedding.lance/data/f36e1996-e5d0-4dc0-9c75-840dd8f8ba2a.lance differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..0cfeedb8ed8fdbbe18f3bb31cacd3598e79a028b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,15 @@ +graphrag +gradio +fastapi +uvicorn +python-dotenv +pydantic +pandas +tiktoken +langchain-community +aiohttp +pyyaml +requests +duckduckgo-search +ollama +plotly diff --git a/scripts/e2e-test.sh b/scripts/e2e-test.sh new file mode 100644 index 0000000000000000000000000000000000000000..5c260a148bc62df9de7529b4c35e7d8b07aa3292 --- /dev/null +++ b/scripts/e2e-test.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Use CLI Form +poetry run python -m graphrag.index --config ./examples/single_verb/pipeline.yml \ No newline at end of file diff --git a/scripts/semver-check.sh b/scripts/semver-check.sh new file mode 100644 index 0000000000000000000000000000000000000000..26d69f9baa5ed78cce8067c5f4738aa1282f78b0 --- /dev/null +++ b/scripts/semver-check.sh @@ -0,0 +1,10 @@ +#!/bin/sh +changes=$(git diff --name-only origin/main) +has_change_doc=$(echo $changes | grep .semversioner/next-release) +has_impacting_changes=$(echo $changes | grep graphrag) + +if [ "$has_impacting_changes" ] && [ -z "$has_change_doc" ]; then + echo "Check failed. Run 'poetry run semversioner add-change' to update the next release version" + exit 1 +fi +echo "OK" diff --git a/scripts/spellcheck.sh b/scripts/spellcheck.sh new file mode 100644 index 0000000000000000000000000000000000000000..7c1b50e9317ea201cffe0aba712722d64bdb02b6 --- /dev/null +++ b/scripts/spellcheck.sh @@ -0,0 +1,2 @@ +#!/bin/sh +npx --yes cspell -c cspell.config.yaml --no-progress lint . \ No newline at end of file diff --git a/scripts/start-azurite.sh b/scripts/start-azurite.sh new file mode 100644 index 0000000000000000000000000000000000000000..345f500f3b2236ac18c47917f2ffd389a075cbf7 --- /dev/null +++ b/scripts/start-azurite.sh @@ -0,0 +1,2 @@ +#!/bin/sh +npx --yes azurite -L -l ./temp_azurite -d ./temp_azurite/debug.log \ No newline at end of file diff --git a/settings.yaml b/settings.yaml new file mode 100644 index 0000000000000000000000000000000000000000..55b69ad90d3bb50d4f1cfd6aaf0177874f57b809 --- /dev/null +++ b/settings.yaml @@ -0,0 +1,145 @@ + +encoding_model: cl100k_base +skip_workflows: [] +llm: + api_key: ${GRAPHRAG_API_KEY} + type: openai_chat # or azure_openai_chat + model: mistral-nemo:12b-instruct-2407-fp16 + model_supports_json: true # recommended if this is available for your model. + max_tokens: 8192 + # request_timeout: 180.0 + api_base: http://localhost:11434/v1 + # api_version: 2024-02-15-preview + # organization: + # deployment_name: + # tokens_per_minute: 150_000 # set a leaky bucket throttle + # requests_per_minute: 10_000 # set a leaky bucket throttle + max_retries: 3 + # max_retry_wait: 10.0 + # sleep_on_rate_limit_recommendation: true # whether to sleep when azure suggests wait-times + concurrent_requests: 25 # the number of parallel inflight requests that may be made + +parallelization: + stagger: 0.3 + num_threads: 50 # the number of threads to use for parallel processing + +async_mode: threaded # or asyncio + +embeddings: + ## parallelization: override the global parallelization settings for embeddings + async_mode: threaded # or asyncio + llm: + api_key: ${GRAPHRAG_API_KEY} + type: openai_embedding # or azure_openai_embedding + model: nomic-embed-text:latest + api_base: http://localhost:11434/api + # api_version: 2024-02-15-preview + # organization: + # deployment_name: + # tokens_per_minute: 150_000 # set a leaky bucket throttle + # requests_per_minute: 10_000 # set a leaky bucket throttle + max_retries: 3 + # max_retry_wait: 10.0 + # sleep_on_rate_limit_recommendation: true # whether to sleep when azure suggests wait-times + concurrent_requests: 25 # the number of parallel inflight requests that may be made + #batch_size: 1 # the number of documents to send in a single request + #batch_max_tokens: 4000 # the maximum number of tokens to send in a single request + # target: required # or optional + + + +chunks: + size: 512 + overlap: 64 + group_by_columns: [id] # by default, we don't allow chunks to cross documents + +input: + type: file # or blob + file_type: text # or csv + base_dir: "input" + file_encoding: utf-8 + file_pattern: ".*\\.txt$" + +cache: + type: file # or blob + base_dir: "cache" + # connection_string: + # container_name: + +storage: + type: file # or blob + base_dir: "output/${timestamp}/artifacts" + # connection_string: + # container_name: + +reporting: + type: file # or console, blob + base_dir: "output/${timestamp}/reports" + # connection_string: + # container_name: + +entity_extraction: + ## llm: override the global llm settings for this task + ## parallelization: override the global parallelization settings for this task + ## async_mode: override the global async_mode settings for this task + prompt: "prompts/entity_extraction.txt" + entity_types: [organization,person,geo,event] + max_gleanings: 0 + +summarize_descriptions: + ## llm: override the global llm settings for this task + ## parallelization: override the global parallelization settings for this task + ## async_mode: override the global async_mode settings for this task + prompt: "prompts/summarize_descriptions.txt" + max_length: 500 + +claim_extraction: + ## llm: override the global llm settings for this task + ## parallelization: override the global parallelization settings for this task + ## async_mode: override the global async_mode settings for this task + # enabled: true + prompt: "prompts/claim_extraction.txt" + description: "Any claims or facts that could be relevant to information discovery." + max_gleanings: 0 + +community_reports: + ## llm: override the global llm settings for this task + ## parallelization: override the global parallelization settings for this task + ## async_mode: override the global async_mode settings for this task + prompt: "prompts/community_report.txt" + max_length: 2000 + max_input_length: 4000 + +cluster_graph: + max_cluster_size: 10 + +embed_graph: + enabled: false # if true, will generate node2vec embeddings for nodes + # num_walks: 10 + # walk_length: 40 + # window_size: 2 + # iterations: 3 + # random_seed: 597832 + +umap: + enabled: false # if true, will generate UMAP embeddings for nodes + +snapshots: + graphml: false + raw_entities: false + top_level_nodes: false + +local_search: + # text_unit_prop: 0.5 + # community_prop: 0.1 + # conversation_history_max_turns: 5 + # top_k_mapped_entities: 10 + # top_k_relationships: 10 + # max_tokens: 12000 + +global_search: + # max_tokens: 12000 + # data_max_tokens: 12000 + # map_max_tokens: 1000 + # reduce_max_tokens: 2000 + # concurrency: 32 diff --git a/uiv2.png b/uiv2.png new file mode 100644 index 0000000000000000000000000000000000000000..68694b32746c3ae0761417e2bedb5c5d6cd15886 Binary files /dev/null and b/uiv2.png differ diff --git a/uiv3.png b/uiv3.png new file mode 100644 index 0000000000000000000000000000000000000000..25ef11aa8fc375bec34391f7a778350fe36928ee Binary files /dev/null and b/uiv3.png differ diff --git a/web.py b/web.py new file mode 100644 index 0000000000000000000000000000000000000000..83517157494929e6d8c767cf1d86209f5c29cc79 --- /dev/null +++ b/web.py @@ -0,0 +1,147 @@ +"""Util that calls DuckDuckGo Search. + +No setup required. Free. +https://pypi.org/project/duckduckgo-search/ +""" + +from typing import Dict, List, Optional + +from langchain_core.pydantic_v1 import BaseModel, Extra, root_validator + + +class DuckDuckGoSearchAPIWrapper(BaseModel): + """Wrapper for DuckDuckGo Search API. + + Free and does not require any setup. + """ + + region: Optional[str] = "wt-wt" + """ + See https://pypi.org/project/duckduckgo-search/#regions + """ + safesearch: str = "moderate" + """ + Options: strict, moderate, off + """ + time: Optional[str] = "y" + """ + Options: d, w, m, y + """ + max_results: int = 5 + backend: str = "api" + """ + Options: api, html, lite + """ + source: str = "text" + """ + Options: text, news + """ + + class Config: + """Configuration for this pydantic object.""" + + extra = Extra.forbid + + @root_validator(pre=True) + def validate_environment(cls, values: Dict) -> Dict: + """Validate that python package exists in environment.""" + try: + from duckduckgo_search import DDGS # noqa: F401 + except ImportError: + raise ImportError( + "Could not import duckduckgo-search python package. " + "Please install it with `pip install -U duckduckgo-search`." + ) + return values + + def _ddgs_text( + self, query: str, max_results: Optional[int] = None + ) -> List[Dict[str, str]]: + """Run query through DuckDuckGo text search and return results.""" + from duckduckgo_search import DDGS + + with DDGS() as ddgs: + ddgs_gen = ddgs.text( + query, + region=self.region, + safesearch=self.safesearch, + timelimit=self.time, + max_results=max_results or self.max_results, + backend=self.backend, + ) + if ddgs_gen: + return [r for r in ddgs_gen] + return [] + + def _ddgs_news( + self, query: str, max_results: Optional[int] = None + ) -> List[Dict[str, str]]: + """Run query through DuckDuckGo news search and return results.""" + from duckduckgo_search import DDGS + + with DDGS() as ddgs: + ddgs_gen = ddgs.news( + query, + region=self.region, + safesearch=self.safesearch, + timelimit=self.time, + max_results=max_results or self.max_results, + ) + if ddgs_gen: + return [r for r in ddgs_gen] + return [] + + def run(self, query: str) -> str: + """Run query through DuckDuckGo and return concatenated results.""" + if self.source == "text": + results = self._ddgs_text(query) + elif self.source == "news": + results = self._ddgs_news(query) + else: + results = [] + + if not results: + return "No good DuckDuckGo Search Result was found" + return " ".join(r["body"] for r in results) + + + def results( + self, query: str, max_results: int, source: Optional[str] = None + ) -> List[Dict[str, str]]: + """Run query through DuckDuckGo and return metadata. + + Args: + query: The query to search for. + max_results: The number of results to return. + source: The source to look from. + + Returns: + A list of dictionaries with the following keys: + snippet - The description of the result. + title - The title of the result. + link - The link to the result. + """ + source = source or self.source + if source == "text": + results = [ + {"snippet": r["body"], "title": r["title"], "link": r["href"]} + for r in self._ddgs_text(query, max_results=max_results) + ] + elif source == "news": + results = [ + { + "snippet": r["body"], + "title": r["title"], + "link": r["url"], + "date": r["date"], + "source": r["source"], + } + for r in self._ddgs_news(query, max_results=max_results) + ] + else: + results = [] + + if results is None: + results = [{"Result": "No good DuckDuckGo Search Result was found"}] + + return results \ No newline at end of file